Index: /geovis/trunk/Makefile.in
===================================================================
--- /geovis/trunk/Makefile.in	(revision 4634)
+++ /geovis/trunk/Makefile.in	(revision 4635)
@@ -145,5 +145,9 @@
 SERVER=geovis
 
-.PHONY: all docs install clean clean-docs distclean
+resources	= \
+		$(srcdir)/resources/placemark32.png \
+		$(srcdir)/resources/world.tif
+
+.PHONY: all docs install install-resources clean clean-docs distclean
 
 all: $(SERVER)
@@ -156,6 +160,15 @@
 	$(CXX) -o $@ $(SERVER_OBJS) $(LIBS)
 
-install: all
+install: install-server install-resources
+
+install-server: all
 	$(INSTALL_PROGRAM) $(SERVER) $(bindir)
+
+install-resources:
+	$(MKDIR_P) $(libdir)/resources
+	@for i in $(resources) ; do \
+	    echo "installing $$i..." ; \
+	    $(INSTALL_DATA) $$i $(libdir)/resources ; \
+	done
 
 %.o: %.cpp
Index: /geovis/trunk/RenderServer.cpp
===================================================================
--- /geovis/trunk/RenderServer.cpp	(revision 4634)
+++ /geovis/trunk/RenderServer.cpp	(revision 4635)
@@ -292,5 +292,5 @@
     signal(SIGPIPE, SIG_IGN);
 
-    //const char *resourcePath = NULL;
+    std::string resourcePath;
     while (1) {
         int c = getopt(argc, argv, "p:i:o:");
@@ -300,5 +300,5 @@
         switch (c) {
         case 'p':
-            //resourcePath = optarg;
+            resourcePath = optarg;
             break;
         case 'i': {
@@ -351,4 +351,9 @@
     g_renderer = new Renderer();
     g_inBufPtr = new ReadBuffer(g_fdIn, 1<<12);
+
+    if (resourcePath.empty()) {
+        resourcePath = "/usr/share/osgearth/data";
+    }
+    g_renderer->setResourcePath(resourcePath);
 
     Tcl_Interp *interp = Tcl_CreateInterp();
Index: /geovis/trunk/Renderer.cpp
===================================================================
--- /geovis/trunk/Renderer.cpp	(revision 4634)
+++ /geovis/trunk/Renderer.cpp	(revision 4635)
@@ -78,6 +78,6 @@
      (((t2).tv_sec - (t1).tv_sec))*1.0e+3 + (double)((t2).tv_usec - (t1).tv_usec)/1.0e+3)
 
-#define BASE_IMAGE "/usr/share/osgearth/data/world.tif"
-#define PIN_ICON "/usr/share/osgearth/data/placemark32.png"
+#define BASE_IMAGE "world.tif"
+#define PIN_ICON "placemark32.png"
 
 using namespace GeoVis;
@@ -107,55 +107,4 @@
         TRACE("Setting base URI: %s", _baseURI.c_str());
     }
-
-#if 0
-    initViewer();
-
-    osgEarth::MapOptions mapOpts;
-    mapOpts.coordSysType() = osgEarth::MapOptions::CSTYPE_PROJECTED;
-    mapOpts.profile() = osgEarth::ProfileOptions("global-mercator");
-    osgEarth::Map *map = new osgEarth::Map(mapOpts);
-    _map = map;
-    osgEarth::Drivers::GDALOptions bopts;
-    bopts.url() = BASE_IMAGE;
-    addImageLayer("base", bopts);
-#ifdef USE_OSGEARTH_TRUNK
-    osgEarth::Drivers::MPTerrainEngine::MPTerrainEngineOptions mpOpt;
-#else
-    osgEarth::Drivers::MPTerrainEngineOptions mpOpt;
-#endif
-    // Set background layer color
-    mpOpt.color() = osg::Vec4(1, 1, 1, 1);
-    //mpOpt.minLOD() = 1;
-    osgEarth::MapNodeOptions mapNodeOpts(mpOpt);
-    mapNodeOpts.enableLighting() = false;
-    osgEarth::MapNode *mapNode = new osgEarth::MapNode(map, mapNodeOpts);
-    _mapNode = mapNode;
-    _sceneRoot = new osg::Group;
-    _sceneRoot->addChild(mapNode);
-    _viewer->setSceneData(_sceneRoot.get());
-
-    initEarthManipulator();
-    initControls();
-
-    finalizeViewer();
-#endif
-
-#ifdef DEBUG
-    if (_viewer.valid() && _viewer->getViewerStats() != NULL) {
-        TRACE("Enabling stats");
-        _viewer->getViewerStats()->collectStats("scene", true);
-    }
-#endif
-#if 0
-    if (_viewer.valid()) {
-        osgViewer::ViewerBase::Windows windows;
-        _viewer->getWindows(windows);
-        if (windows.size() == 1) {
-            windows[0]->setSyncToVBlank(false);
-        } else {
-            ERROR("Num windows: %lu", windows.size());
-        }
-    }
-#endif
 }
 
@@ -179,4 +128,18 @@
 
     TRACE("Leave");
+}
+
+std::string Renderer::getBaseImage()
+{
+    std::ostringstream oss;
+    oss << _resourcePath << "/" << BASE_IMAGE;
+    return oss.str();
+}
+
+std::string Renderer::getPinIcon()
+{
+    std::ostringstream oss;
+    oss << _resourcePath << "/" << PIN_ICON;
+    return oss.str();
 }
 
@@ -301,4 +264,20 @@
     _viewer->addEventHandler(_stateManip);
     //_viewer->addEventHandler(new osgViewer::StatsHandler());
+
+#ifdef DEBUG
+    if (_viewer->getViewerStats() != NULL) {
+        TRACE("Enabling stats");
+        _viewer->getViewerStats()->collectStats("scene", true);
+    }
+#endif
+#if 0
+    osgViewer::ViewerBase::Windows windows;
+    _viewer->getWindows(windows);
+    if (windows.size() == 1) {
+        windows[0]->setSyncToVBlank(false);
+    } else {
+        ERROR("Num windows: %lu", windows.size());
+    }
+#endif
 }
 
@@ -709,5 +688,5 @@
     _map = map;
     osgEarth::Drivers::GDALOptions bopts;
-    bopts.url() = BASE_IMAGE;
+    bopts.url() = getBaseImage();
     addImageLayer("base", bopts);
 #ifdef USE_OSGEARTH_TRUNK
@@ -1255,5 +1234,5 @@
 
     osgEarth::Symbology::Style pin;
-    pin.getOrCreate<osgEarth::Symbology::IconSymbol>()->url()->setLiteral(PIN_ICON);
+    pin.getOrCreate<osgEarth::Symbology::IconSymbol>()->url()->setLiteral(getPinIcon());
     osgEarth::Annotation::AnnotationNode *anno = new osgEarth::Annotation::PlaceNode(_mapNode, osgEarth::GeoPoint(geoSRS, longitude, latitude), labelText, pin);
     _placeNodes->addChild(anno);
Index: /geovis/trunk/Renderer.h
===================================================================
--- /geovis/trunk/Renderer.h	(revision 4634)
+++ /geovis/trunk/Renderer.h	(revision 4635)
@@ -129,4 +129,14 @@
     virtual ~Renderer();
 
+    void setResourcePath(std::string& path)
+    {
+        TRACE("Set resource path to %s", path.c_str());
+        _resourcePath = path;
+    }
+
+    std::string getBaseImage();
+
+    std::string getPinIcon();
+
     // Colormaps
 
@@ -453,4 +463,5 @@
     ColorMapHashmap _colorMaps;
 
+    std::string _resourcePath;
     std::string _baseURI;
     std::string _cacheDir;
Index: /geovis/trunk/RendererCmd.cpp
===================================================================
--- /geovis/trunk/RendererCmd.cpp	(revision 4634)
+++ /geovis/trunk/RendererCmd.cpp	(revision 4635)
@@ -13,4 +13,5 @@
 #include <string>
 #include <sstream>
+#include <limits>
 #include <vector>
 #include <unistd.h>
@@ -766,5 +767,111 @@
     return (*proc) (clientData, interp, objc, objv);
 }
-
+#if 1
+static int
+MapCoordsOp(ClientData clientData, Tcl_Interp *interp, int objc, 
+            Tcl_Obj *const *objv)
+{
+    int tokenLength;
+    const char *token = Tcl_GetStringFromObj(objv[2], &tokenLength);
+    int numCoords;
+    Tcl_Obj **coords;
+    if (Tcl_ListObjGetElements(interp, objv[3], &numCoords, &coords) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if (numCoords == 0) {
+        Tcl_AppendResult(interp, "no x,y coordinates in list", (char *)NULL);
+        return TCL_ERROR;
+    }
+    if (numCoords & 1) {
+        Tcl_AppendResult(interp, "odd number of x, y coordinates in list",
+                         (char *)NULL);
+        return TCL_ERROR;
+    }
+    const osgEarth::SpatialReference *outSRS = NULL;
+    if (objc > 4) {
+        std::string srsInit;
+        std::string verticalDatum;
+        srsInit = Tcl_GetString(objv[4]);
+        if (objc > 5) {
+            verticalDatum = Tcl_GetString(objv[5]);
+        }
+        outSRS = osgEarth::SpatialReference::get(srsInit, verticalDatum);
+        if (outSRS == NULL) {
+            Tcl_AppendResult(interp, "bad SRS \"", srsInit.c_str(), "\"",
+                             (char*)NULL);
+            return TCL_ERROR;
+        }
+    }
+    Tcl_Obj *listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
+    std::vector<osg::Vec3d> coordVec;
+    for (int i = 0; i < numCoords; i += 2) {
+        int x, y;
+        if ((Tcl_GetIntFromObj(interp, coords[i], &x) != TCL_OK) ||
+            (Tcl_GetIntFromObj(interp, coords[i+1], &y) != TCL_OK)) {
+            return TCL_ERROR;
+        }
+        osgEarth::GeoPoint mapPoint;
+        if (g_renderer->mapMouseCoords(x, y, mapPoint)) {
+            // altmode absolute
+            coordVec.push_back(osg::Vec3d(mapPoint.x(), mapPoint.y(), mapPoint.z()));
+#if 0
+            if (outSRS != NULL) {
+                mapPoint = mapPoint.transform(outSRS);
+                if (!mapPoint.isValid()) {
+                    Tcl_DecrRefCount(listObjPtr);
+                    Tcl_AppendResult(interp, "Could not transform map point to requested SRS", (char*)NULL);
+                    return TCL_ERROR;
+                }
+            }
+            Tcl_Obj *objPtr = Tcl_NewDoubleObj(mapPoint.x());
+            Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+            objPtr = Tcl_NewDoubleObj(mapPoint.y());
+            Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+            objPtr = Tcl_NewDoubleObj(mapPoint.z());
+            Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+#endif
+        } else {
+            coordVec.push_back(osg::Vec3d(std::numeric_limits<double>::quiet_NaN(),
+                                          std::numeric_limits<double>::quiet_NaN(),
+                                          std::numeric_limits<double>::quiet_NaN()));
+#if 0
+            Tcl_Obj *objPtr = Tcl_NewStringObj("NaN", 3);
+            Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+            Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+            Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+#endif
+        }
+    }
+    if (outSRS != NULL) {
+        g_renderer->getMapSRS()->transform(coordVec, outSRS);
+    } else {
+        outSRS = g_renderer->getMapSRS();
+    }
+    for (std::vector<osg::Vec3d>::iterator itr = coordVec.begin();
+         itr != coordVec.end(); ++itr) {
+        Tcl_Obj *objPtr = Tcl_NewDoubleObj(itr->x());
+        Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+        objPtr = Tcl_NewDoubleObj(itr->y());
+        Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+        objPtr = Tcl_NewDoubleObj(itr->z());
+        Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
+    }
+    // send coords to client
+    int listLength;
+    const char *string = Tcl_GetStringFromObj(listObjPtr, &listLength);
+    size_t length = listLength + tokenLength + 
+        outSRS->getHorizInitString().length() +
+        outSRS->getVertInitString().length() +
+        25;
+    char *mesg = new char[length];
+    length = snprintf(mesg, length, "nv>map coords %s {%s} {%s} {%s}\n", token, string,
+                      outSRS->getHorizInitString().c_str(),
+                      outSRS->getVertInitString().c_str());
+    Tcl_DecrRefCount(listObjPtr);
+    queueResponse(mesg, length, Response::VOLATILE);
+    delete [] mesg;
+    return TCL_OK;
+}
+#else
 static int
 MapCoordsOp(ClientData clientData, Tcl_Interp *interp, int objc, 
@@ -821,5 +928,5 @@
     return TCL_OK;
 }
-
+#endif
 static int
 MapGraticuleOp(ClientData clientData, Tcl_Interp *interp, int objc, 
@@ -1636,5 +1743,5 @@
 
 static CmdSpec mapOps[] = {
-    {"coords",   1, MapCoordsOp,          5, 7, "token x y ?srs? ?verticalDatum?"},
+    {"coords",   1, MapCoordsOp,          4, 6, "token coords ?srs? ?verticalDatum?"},
     {"grid",     1, MapGraticuleOp,       3, 4, "bool ?type?"},
     {"layer",    2, MapLayerOp,           3, 0, "op ?params...?"},
