Changeset 5873 for geovis


Ignore:
Timestamp:
Sep 17, 2015, 11:03:08 AM (9 years ago)
Author:
ldelgass
Message:

Checkpoint commit: add support for wfs, tfs, csv (via vrt in gdal), experiments
with new render-to-texture objectid picker in osgearth 2.7.

Location:
geovis/trunk
Files:
4 added
7 edited

Legend:

Unmodified
Added
Removed
  • geovis/trunk/Makefile.in

    r5852 r5873  
    126126                FileUtil.cpp \
    127127                IData.cpp \
     128                Picker.cpp \
    128129                PPMWriter.cpp \
    129130                ReadBuffer.cpp \
     
    131132                RendererCmd.cpp \
    132133                RenderServer.cpp \
     134                ScaleBar.cpp \
     135                Stats.cpp \
    133136                TGAWriter.cpp \
    134137                Trace.cpp \
    135                 ScaleBar.cpp \
    136                 Stats.cpp
     138                Util.cpp
    137139
    138140ifdef USE_THREADS
     
    201203idatatest.o: IData.h
    202204md5.o: md5.h
     205Picker.o: Picker.h Renderer.h Trace.h
    203206PPMWriter.o: PPMWriter.h ResponseQueue.h Trace.h
    204207ReadBuffer.o: ReadBuffer.h Trace.h
    205 Renderer.o: Renderer.h Trace.h MouseCoordsTool.h ScaleBar.h FileUtil.h
     208Renderer.o: Renderer.h Trace.h Picker.h MouseCoordsTool.h ScaleBar.h FileUtil.h
    206209RendererCmd.o: Renderer.h ReadBuffer.h ResponseQueue.h Trace.h CmdProc.h PPMWriter.h TGAWriter.h
    207210RenderServer.o: RenderServer.h RendererCmd.h Renderer.h ReadBuffer.h ResponseQueue.h Trace.h PPMWriter.h TGAWriter.h Stats.h
     
    210213Stats.o: Stats.h RenderServer.h Trace.h md5.h
    211214Trace.o: Trace.h
     215Util.o: Util.h
  • geovis/trunk/RenderServer.cpp

    r5775 r5873  
    4040#endif
    4141
    42 #if OSGEARTH_MIN_VERSION_REQUIRED(2, 6, 1)
     42#if OSGEARTH_MIN_VERSION_REQUIRED(2, 7, 0)
    4343#define NEW_VIEWPOINT_API
    4444#endif
  • geovis/trunk/Renderer.cpp

    r5852 r5873  
    4848#include <osgEarth/DateTime>
    4949#if OSGEARTH_MIN_VERSION_REQUIRED(2, 7, 0)
     50#ifdef USE_RTT_PICKER
     51#include <osgEarth/Registry>
     52#include <osgEarthUtil/RTTPicker>
     53#include <osgEarthFeatures/FeatureIndex>
     54#else
    5055#include <osgEarth/IntersectionPicker>
     56#endif
    5157#include <osgEarthUtil/GraticuleNode>
    5258#else
     
    6773#include <osgEarthAnnotation/ScaleDecoration>
    6874#include <osgEarthUtil/EarthManipulator>
    69 #if OSGEARTH_MIN_VERSION_REQUIRED(2, 5, 1)
     75#if OSGEARTH_MIN_VERSION_REQUIRED(2, 6, 0)
    7076#include <osgEarthUtil/Sky>
    7177#include <osgEarthDrivers/sky_simple/SimpleSkyOptions>
     
    8692
    8793#include "Renderer.h"
     94#ifdef USE_RTT_PICKER
     95#include "Picker.h"
     96#endif
    8897#include "IData.h"
    8998#include "ColorMap.h"
     
    95104#include "Trace.h"
    96105
    97 #if OSGEARTH_MIN_VERSION_REQUIRED(2, 6, 1)
     106#if OSGEARTH_MIN_VERSION_REQUIRED(2, 7, 0)
    98107#define NEW_VIEWPOINT_API
    99108#endif
     
    503512    _hbox->addControl(_scaleLabel.get());
    504513    _hbox->addControl(_scaleBar.get());
    505 #if OSGEARTH_MIN_VERSION_REQUIRED(2, 5, 1)
     514#if OSGEARTH_MIN_VERSION_REQUIRED(2, 6, 0)
    506515    osgEarth::Util::Controls::ControlCanvas::getOrCreate(_viewer.get())->addControl(_hbox.get());
    507516#else
     
    540549        case GRATICULE_GEODETIC: {
    541550            osgEarth::Util::GraticuleOptions opt;
    542             opt.color() = osgEarth::Symbology::Color(1, 0, 0);
    543             opt.labelColor() = osgEarth::Symbology::Color(1, 0, 0);
     551            opt.color() = osgEarth::Symbology::Color(1, 1, 0);
     552            opt.labelColor() = osgEarth::Symbology::Color(1, 1, 0);
    544553            opt.lineWidth() = 1.0;
    545554            osgEarth::Util::GraticuleNode *gr = new osgEarth::Util::GraticuleNode(_mapNode.get(), opt);
     
    599608            osgEarth::Util::Controls::LabelControl *readout =
    600609                _coordsCallback->getLabel();
    601 #if OSGEARTH_MIN_VERSION_REQUIRED(2, 5, 1)
     610#if OSGEARTH_MIN_VERSION_REQUIRED(2, 6, 0)
    602611            osgEarth::Util::Controls::ControlCanvas::getOrCreate(_viewer.get())->removeControl(readout);
    603612#else
     
    648657    } else {
    649658        readout = new osgEarth::Util::Controls::LabelControl("", 12.0f);
    650 #if OSGEARTH_MIN_VERSION_REQUIRED(2, 5, 1)
     659#if OSGEARTH_MIN_VERSION_REQUIRED(2, 6, 0)
    651660        osgEarth::Util::Controls::ControlCanvas::getOrCreate(_viewer.get())->addControl(readout);
    652661#else
     
    779788            TRACE("Setting profile bounds: %g %g %g %g",
    780789                  bounds[0], bounds[1], bounds[2], bounds[3]);
    781             mapOpts.profile()->bounds() =
    782                 osgEarth::Bounds(bounds[0], bounds[1], bounds[2], bounds[3]);
     790            if (1) {
     791                osgEarth::SpatialReference *fromSRS = osgEarth::SpatialReference::create("wgs84");
     792                osgEarth::SpatialReference *toSRS = osgEarth::SpatialReference::create(mapOpts.profile()->srsString().get());
     793                osgEarth::Bounds extents(bounds[0], bounds[1], bounds[2], bounds[3]);
     794                extents.transform(fromSRS, toSRS);
     795                mapOpts.profile()->bounds() = extents;
     796                //mapOpts.profile()->numTilesWideAtLod0() = 1;
     797                //mapOpts.profile()->numTilesHighAtLod0() = 2;
     798            } else {
     799                mapOpts.profile()->bounds() =
     800                    osgEarth::Bounds(bounds[0], bounds[1], bounds[2], bounds[3]);
     801            }
    783802        } else {
    784803            mapOpts.profile() = osgEarth::ProfileOptions(profile);
     
    803822    bopts.url() = getBaseImage();
    804823    addImageLayer("base", bopts);
    805 #if OSGEARTH_MIN_VERSION_REQUIRED(2, 5, 1)
     824#if OSGEARTH_MIN_VERSION_REQUIRED(2, 6, 0)
    806825    osgEarth::Drivers::MPTerrainEngine::MPTerrainEngineOptions mpOpt;
    807826#else
     
    812831    //mpOpt.minLOD() = 1;
    813832    // Sets shader uniform for terrain renderer (config var defaults to false)
    814     mpOpt.enableLighting() = false;
     833    if (!_map->isGeocentric()) {
     834        mpOpt.enableLighting() = false;
     835    }
    815836    osgEarth::MapNodeOptions mapNodeOpts(mpOpt);
    816837    // Sets GL_LIGHTING state in MapNode's StateSet (config var defaults to true)
    817     mapNodeOpts.enableLighting() = true;
     838    //mapNodeOpts.enableLighting() = true;
    818839    //mapNodeOpts.getTerrainOptions().loadingPolicy().mapLoadingThreadsPerCore() = 1;
    819840    //mapNodeOpts.getTerrainOptions().loadingPolicy().numLoadingThreads() = 1;
     
    824845    if (_map->isGeocentric()) {
    825846        osgEarth::DateTime now;
    826 #if OSGEARTH_MIN_VERSION_REQUIRED(2, 5, 1)
     847#if OSGEARTH_MIN_VERSION_REQUIRED(2, 6, 0)
    827848        TRACE("Creating SkyNode");
    828849        osgEarth::Drivers::SimpleSky::SimpleSkyOptions skyOpts;
     
    834855        _skyNode->addChild(mapNode);
    835856        _skyNode->attach(_viewer.get(), 0);
    836         _sceneRoot = _skyNode;
     857        _sceneRoot = new osg::Group();
     858        _sceneRoot->addChild(_skyNode.get());
     859        //_sceneRoot = _skyNode;
    837860#else
    838861        _sceneRoot = new osg::Group();
     
    863886        initMouseCoordsTool();
    864887    }
     888#ifdef USE_RTT_PICKER
     889    if (_picker.valid()) {
     890        _picker = NULL;
     891        _viewer->removeEventHandler(_picker.get());
     892    }
     893    if (!_picker.valid()) {
     894        _picker = new osgEarth::Util::RTTPicker;
     895        _picker->addChild(_sceneRoot.get());
     896        //osg::ref_ptr<HoverCallback> callback = new HoverCallback(this);
     897        osg::ref_ptr<SelectCallback> callback = new SelectCallback(this);
     898        _picker->setDefaultCallback(callback.get());
     899        _viewer->addEventHandler(_picker.get());
     900    }
     901#endif
    865902    initControls();
    866903    //_viewer->setSceneData(_sceneRoot.get());
     
    880917}
    881918
     919void Renderer::setSkyAmbient(float value)
     920{
     921#if OSG_MIN_VERSION_REQUIRED(2, 7, 0)
     922    if (_skyNode.valid()) {
     923        _skyNode->setMinimumAmbient(osg::Vec4f(value, value, value, 1.0f));
     924        _needsRedraw = true;
     925    }
     926#endif
     927}
     928
    882929void Renderer::setLighting(bool state)
    883930{
     
    930977void Renderer::setTerrainColor(const osg::Vec4f& color)
    931978{
    932    
     979    // XXX: Don't know how to change this at runtime without a map reset
    933980    _needsRedraw = true;
    934981}
     
    936983void Renderer::setTerrainLighting(bool state)
    937984{
     985    if (_skyNode.valid()) {
     986        _skyNode->setLighting((state ? osg::StateAttribute::ON : osg::StateAttribute::OFF));
     987    } else {
    938988#if 1
    939     if (!_mapNode.valid()) {
    940         ERROR("No map node");
    941         return;
    942     }
    943     // XXX: HACK alert
    944     // Find the terrain engine container (might be above one or more decorators)
    945     osg::Group *group = _mapNode->getTerrainEngine();
    946     while (group->getParent(0) != NULL && group->getParent(0) != _mapNode.get()) {
    947         group = group->getParent(0);
    948     }
    949     if (group != NULL && group->getParent(0) == _mapNode.get()) {
    950         TRACE("Setting terrain lighting: %d", state ? 1 : 0);
    951         if (group->getOrCreateStateSet()->getUniform("oe_mode_GL_LIGHTING") != NULL) {
    952             group->getStateSet()->getUniform("oe_mode_GL_LIGHTING")->set(state);
     989        if (!_mapNode.valid()) {
     990            ERROR("No map node");
     991            return;
     992        }
     993        // XXX: HACK alert
     994        // Find the terrain engine container (might be above one or more decorators)
     995        osg::Group *group = _mapNode->getTerrainEngine();
     996        while (group->getParent(0) != NULL && group->getParent(0) != _mapNode.get()) {
     997            group = group->getParent(0);
     998        }
     999        if (group != NULL && group->getParent(0) == _mapNode.get()) {
     1000            TRACE("Setting terrain lighting: %d", state ? 1 : 0);
     1001            if (group->getOrCreateStateSet()->getUniform("oe_mode_GL_LIGHTING") != NULL) {
     1002                group->getStateSet()->getUniform("oe_mode_GL_LIGHTING")->set(state);
     1003            } else {
     1004                ERROR("Can't get terrain lighting uniform");
     1005            }
    9531006        } else {
    954             ERROR("Can't get terrain lighting uniform");
    955         }
    956     } else {
    957         ERROR("Can't find terrain engine container");
    958     }
     1007            ERROR("Can't find terrain engine container");
     1008        }
    9591009#else
    960     if (_stateManip.valid()) {
    961         _stateManip->setLightingEnabled(state);
    962     }
    963 #endif
     1010        if (_stateManip.valid()) {
     1011            _stateManip->setLightingEnabled(state);
     1012        }
     1013#endif
     1014    }
    9641015    _needsRedraw = true;
    9651016}
     
    12641315    }
    12651316    osgEarth::ImageLayerOptions layerOpts(name, opts);
    1266 #if OSGEARTH_MIN_VERSION_REQUIRED(2, 5, 1)
     1317#if OSGEARTH_MIN_VERSION_REQUIRED(2, 6, 0)
    12671318    layerOpts.textureCompression() = osg::Texture::USE_IMAGE_DATA_FORMAT;
    12681319#endif
     
    16601711    anno->setName(labelText);
    16611712    _placeNodes->addChild(anno);
     1713#ifndef USE_RTT_PICKER
    16621714    osgEarth::Annotation::DecorationInstaller
    16631715        highlightInstaller("select", new osgEarth::Annotation::HighlightDecoration(osg::Vec4f(1,1,0,0.5)));
     
    16691721    _placeNodes->accept(scaleInstaller);
    16701722    _mapNode->accept(scaleInstaller);
     1723#endif
    16711724#if 0
    16721725    writeScene("/tmp/test.osg");
     
    17211774#endif
    17221775#if OSGEARTH_MIN_VERSION_REQUIRED(2, 7, 0)
     1776#ifdef USE_RTT_PICKER
     1777void Renderer::hoverPlaceNode(int x, int y, bool invertY)
     1778{
     1779    if (!_placeNodes.valid()) {
     1780        TRACE("No place nodes");
     1781        return;
     1782    }
     1783
     1784    return;
     1785
     1786    float mouseX = (float)x;
     1787    float mouseY = (float)y;
     1788    if (invertY) {
     1789        mouseY = ((float)_windowHeight - mouseY);
     1790    }
     1791    if (_picker->pick(_viewer.get(), mouseX, mouseY)) {
     1792        INFO("Hover pick queued: %g %g", mouseX, mouseY);
     1793    } else {
     1794        INFO("Failed to queue pick: %g %g", mouseX, mouseY);
     1795    }
     1796}
     1797
     1798void Renderer::deletePlaceNode(int x, int y, bool invertY)
     1799{
     1800    if (!_placeNodes.valid()) {
     1801        TRACE("No place nodes");
     1802        return;
     1803    }
     1804    return;
     1805    osg::ref_ptr<osgEarth::Util::RTTPicker> picker = new osgEarth::Util::RTTPicker;
     1806    picker->addChild(_placeNodes.get());
     1807    osg::ref_ptr<DeleteCallback> callback = new DeleteCallback(this);
     1808    float mouseX = (float)x;
     1809    float mouseY = (float)y;
     1810    if (invertY) {
     1811        mouseY = ((float)_windowHeight - mouseY);
     1812    }
     1813    if (picker->pick(_viewer.get(), mouseX, mouseY, callback)) {
     1814        TRACE("Delete pick queued: %g %g", mouseX, mouseY);
     1815    }
     1816}
     1817#else
    17231818void Renderer::hoverPlaceNode(int x, int y, bool invertY)
    17241819{
     
    17681863    }
    17691864}
    1770 
    17711865void Renderer::deletePlaceNode(int x, int y, bool invertY)
    17721866{
     
    18101904#endif
    18111905}
     1906#endif
    18121907#else
    18131908void Renderer::hoverPlaceNode(int x, int y, bool invertY)
     
    19452040void Renderer::setModelLayerOpacity(const char *name, double opacity)
    19462041{
    1947 #if OSGEARTH_MIN_VERSION_REQUIRED(2, 5, 0)
    19482042    if (!_map.valid()) {
    19492043        ERROR("No map");
     
    19572051        TRACE("Model layer not found: %s", name);
    19582052    }
    1959 #endif
    19602053}
    19612054#if 0
     
    22582351void Renderer::mouseMotion(double x, double y)
    22592352{
     2353#if 1
     2354    osgGA::EventQueue *queue = getEventQueue();
     2355    if (queue != NULL) {
     2356        queue->mouseMotion((float)x, (float)y);
     2357        _needsRedraw = true;
     2358    }
     2359#else
    22602360    if (_mouseCoordsTool.valid()) {
    2261 #if 1
    2262         osgGA::EventQueue *queue = getEventQueue();
    2263         if (queue != NULL) {
    2264             queue->mouseMotion((float)x, (float)y);
    2265             _needsRedraw = true;
    2266         }
    2267 #else
    22682361        if (_viewer.valid() && _coordsCallback.valid()) {
    22692362            osgEarth::GeoPoint mapPt;
     
    22752368            _needsRedraw = true;
    22762369        }
    2277 #endif
    2278     }
     2370    }
     2371#endif
    22792372}
    22802373
  • geovis/trunk/Renderer.h

    r5852 r5873  
    3636#include <osgEarthAnnotation/AnnotationNode>
    3737#include <osgEarthAnnotation/FeatureNode>
    38 #if OSGEARTH_MIN_VERSION_REQUIRED(2, 5, 1)
     38#if OSGEARTH_MIN_VERSION_REQUIRED(2, 6, 0)
    3939#include <osgEarthUtil/Sky>
    4040#else
    4141#include <osgEarthUtil/SkyNode>
     42#endif
     43#if OSGEARTH_MIN_VERSION_REQUIRED(2, 7, 0)
     44#define USE_RTT_PICKER
     45#include <osgEarthUtil/RTTPicker>
    4246#endif
    4347#include <osgEarthUtil/EarthManipulator>
     
    231235    void setEphemerisTime(int year, int month, int day, double hours);
    232236
     237    void setSkyAmbient(float ambientLevel);
     238
    233239    // Image raster layers
    234240
     
    503509    }
    504510
     511    std::set<osgEarth::Annotation::AnnotationNode*>& getHovered()
     512    { return _hovered; }
     513    std::set<osgEarth::Annotation::AnnotationNode*>& getSelected()
     514    { return _selected; }
     515    osg::Group *getSceneRoot()
     516    { return _sceneRoot.get(); }
     517    osgEarth::MapNode *getMapNode()
     518    { return _mapNode.get(); }
     519    osg::Group *getAnnotations()
     520    {
     521        initAnnotations();
     522        return _annotations.get();
     523    }
     524    osg::Group *getPlaceNodes()
     525    {
     526        initAnnotations();
     527        return _placeNodes.get();
     528    }
     529
    505530private:
    506531    typedef std::tr1::unordered_map<ColorMapId, osg::ref_ptr<osg::TransferFunction1D> > ColorMapHashmap;
     
    559584    double _anchorLat, _anchorLong;
    560585    osg::ref_ptr<osgEarth::Annotation::FeatureNode> _selectionBox;
     586#ifdef USE_RTT_PICKER
     587    osg::ref_ptr<osgEarth::Util::RTTPicker> _picker;
     588#endif
    561589    osg::ref_ptr<osg::Group> _placeNodes;
    562590    std::set<osgEarth::Annotation::AnnotationNode *> _hovered;
  • geovis/trunk/RendererCmd.cpp

    r5857 r5873  
    3333#include <osgEarthSymbology/RenderSymbol>
    3434
    35 #if OSGEARTH_MIN_VERSION_REQUIRED(2, 5, 1)
     35#if OSGEARTH_MIN_VERSION_REQUIRED(2, 6, 0)
    3636#include <osgEarthDrivers/osg/ColorRampOptions>
    3737#endif
     
    4343#include <osgEarthDrivers/model_feature_geom/FeatureGeomModelOptions>
    4444#include <osgEarthDrivers/feature_ogr/OGRFeatureOptions>
     45#include <osgEarthDrivers/feature_tfs/TFSFeatureOptions>
     46#include <osgEarthDrivers/feature_wfs/WFSFeatureOptions>
    4547
    4648#include "Trace.h"
     
    5961#include "CommandQueue.h"
    6062#endif
    61 
    62 #if OSGEARTH_MIN_VERSION_REQUIRED(2, 6, 1)
     63#include "Util.h"
     64
     65#if OSGEARTH_MIN_VERSION_REQUIRED(2, 7, 0)
    6366#define NEW_VIEWPOINT_API
    6467#endif
     
    160163
    161164static osgEarth::Symbology::TextSymbol::Alignment
    162 ParseTextAlignment(const char *align,
     165ParseTextAlignment(const char *str,
    163166                   osgEarth::Symbology::TextSymbol::Alignment defAlign =
    164167                   osgEarth::Symbology::TextSymbol::ALIGN_LEFT_BASE_LINE)
    165168{
    166169    osgEarth::Symbology::TextSymbol::Alignment alignment = defAlign;
    167     if (align[0] == 'l' && strcmp(align, "left_top") == 0) {
     170    if (str[0] == 'l' && strcmp(str, "left_top") == 0) {
    168171        alignment = osgEarth::Symbology::TextSymbol::ALIGN_LEFT_TOP;
    169     } else if (align[0] == 'l' && strcmp(align, "left_center") == 0) {
     172    } else if (str[0] == 'l' && strcmp(str, "left_center") == 0) {
    170173        alignment = osgEarth::Symbology::TextSymbol::ALIGN_LEFT_CENTER;
    171     } else if (align[0] == 'l' && strcmp(align, "left_bottom") == 0) {
     174    } else if (str[0] == 'l' && strcmp(str, "left_bottom") == 0) {
    172175        alignment = osgEarth::Symbology::TextSymbol::ALIGN_LEFT_BOTTOM;
    173     } else if (align[0] == 'c' && strcmp(align, "center_top") == 0) {
     176    } else if (str[0] == 'c' && strcmp(str, "center_top") == 0) {
    174177        alignment = osgEarth::Symbology::TextSymbol::ALIGN_CENTER_TOP;
    175     } else if (align[0] == 'c' && strcmp(align, "center_center") == 0) {
     178    } else if (str[0] == 'c' && strcmp(str, "center_center") == 0) {
    176179        alignment = osgEarth::Symbology::TextSymbol::ALIGN_CENTER_CENTER;
    177     } else if (align[0] == 'c' && strcmp(align, "center_bottom") == 0) {
     180    } else if (str[0] == 'c' && strcmp(str, "center_bottom") == 0) {
    178181        alignment = osgEarth::Symbology::TextSymbol::ALIGN_CENTER_BOTTOM;
    179     } else if (align[0] == 'r' && strcmp(align, "right_top") == 0) {
     182    } else if (str[0] == 'r' && strcmp(str, "right_top") == 0) {
    180183        alignment = osgEarth::Symbology::TextSymbol::ALIGN_RIGHT_TOP;
    181     } else if (align[0] == 'r' && strcmp(align, "right_center") == 0) {
     184    } else if (str[0] == 'r' && strcmp(str, "right_center") == 0) {
    182185        alignment = osgEarth::Symbology::TextSymbol::ALIGN_RIGHT_CENTER;
    183     } else if (align[0] == 'r' && strcmp(align, "right_bottom") == 0) {
     186    } else if (str[0] == 'r' && strcmp(str, "right_bottom") == 0) {
    184187        alignment = osgEarth::Symbology::TextSymbol::ALIGN_RIGHT_BOTTOM;
    185     } else if (align[0] == 'l' && strcmp(align, "left_baseline") == 0) {
     188    } else if (str[0] == 'l' && strcmp(str, "left_baseline") == 0) {
    186189        alignment = osgEarth::Symbology::TextSymbol::ALIGN_LEFT_BASE_LINE;
    187     } else if (align[0] == 'c' && strcmp(align, "center_baseline") == 0) {
     190    } else if (str[0] == 'c' && strcmp(str, "center_baseline") == 0) {
    188191        alignment = osgEarth::Symbology::TextSymbol::ALIGN_CENTER_BASE_LINE;
    189     } else if (align[0] == 'r' && strcmp(align, "right_baseline") == 0) {
     192    } else if (str[0] == 'r' && strcmp(str, "right_baseline") == 0) {
    190193        alignment = osgEarth::Symbology::TextSymbol::ALIGN_RIGHT_BASE_LINE;
    191     } else  if (align[0] == 'l' && strcmp(align, "left_bottom_baseline") == 0) {
     194    } else  if (str[0] == 'l' && strcmp(str, "left_bottom_baseline") == 0) {
    192195        alignment = osgEarth::Symbology::TextSymbol::ALIGN_LEFT_BOTTOM_BASE_LINE;
    193     } else if (align[0] == 'c' && strcmp(align, "center_bottom_baseline") == 0) {
     196    } else if (str[0] == 'c' && strcmp(str, "center_bottom_baseline") == 0) {
    194197        alignment = osgEarth::Symbology::TextSymbol::ALIGN_CENTER_BOTTOM_BASE_LINE;
    195     } else if (align[0] == 'r' && strcmp(align, "right_bottom_baseline") == 0) {
     198    } else if (str[0] == 'r' && strcmp(str, "right_bottom_baseline") == 0) {
    196199        alignment = osgEarth::Symbology::TextSymbol::ALIGN_RIGHT_BOTTOM_BASE_LINE;
    197200    }
     
    199202}
    200203
     204static osgEarth::Symbology::IconSymbol::Alignment
     205ParseIconAlignment(const char *str,
     206                   osgEarth::Symbology::IconSymbol::Alignment defAlign =
     207                   osgEarth::Symbology::IconSymbol::ALIGN_CENTER_BOTTOM)
     208{
     209    osgEarth::Symbology::IconSymbol::Alignment alignment = defAlign;
     210    if (str[0] == 'l' && strcmp(str, "left_top") == 0) {
     211        alignment = osgEarth::Symbology::IconSymbol::ALIGN_LEFT_TOP;
     212    } else if (str[0] == 'l' && strcmp(str, "left_center") == 0) {
     213        alignment = osgEarth::Symbology::IconSymbol::ALIGN_LEFT_CENTER;
     214    } else if (str[0] == 'l' && strcmp(str, "left_bottom") == 0) {
     215        alignment = osgEarth::Symbology::IconSymbol::ALIGN_LEFT_BOTTOM;
     216    } else if (str[0] == 'c' && strcmp(str, "center_top") == 0) {
     217        alignment = osgEarth::Symbology::IconSymbol::ALIGN_CENTER_TOP;
     218    } else if (str[0] == 'c' && strcmp(str, "center_center") == 0) {
     219        alignment = osgEarth::Symbology::IconSymbol::ALIGN_CENTER_CENTER;
     220    } else if (str[0] == 'c' && strcmp(str, "center_bottom") == 0) {
     221        alignment = osgEarth::Symbology::IconSymbol::ALIGN_CENTER_BOTTOM;
     222    } else if (str[0] == 'r' && strcmp(str, "right_top") == 0) {
     223        alignment = osgEarth::Symbology::IconSymbol::ALIGN_RIGHT_TOP;
     224    } else if (str[0] == 'r' && strcmp(str, "right_center") == 0) {
     225        alignment = osgEarth::Symbology::IconSymbol::ALIGN_RIGHT_CENTER;
     226    } else if (str[0] == 'r' && strcmp(str, "right_bottom") == 0) {
     227        alignment = osgEarth::Symbology::IconSymbol::ALIGN_RIGHT_BOTTOM;
     228    }
     229    return alignment;
     230}
     231
     232static osgEarth::Symbology::InstanceSymbol::Placement
     233ParseInstancePlacement(const char *str,
     234                       osgEarth::Symbology::InstanceSymbol::Placement defPlacement =
     235                       osgEarth::Symbology::InstanceSymbol::PLACEMENT_VERTEX)
     236{
     237    osgEarth::Symbology::InstanceSymbol::Placement placement = defPlacement;
     238    if (str[0] == 'v' && strcmp(str, "vertex") == 0) {
     239        placement = osgEarth::Symbology::InstanceSymbol::PLACEMENT_VERTEX;
     240    } else if (str[0] == 'c' && strcmp(str, "centroid") == 0) {
     241        placement = osgEarth::Symbology::InstanceSymbol::PLACEMENT_CENTROID;
     242    } else if (str[0] == 'i' && strcmp(str, "interval") == 0) {
     243        placement = osgEarth::Symbology::InstanceSymbol::PLACEMENT_INTERVAL;
     244    } else if (str[0] == 'r' && strcmp(str, "random") == 0) {
     245        placement = osgEarth::Symbology::InstanceSymbol::PLACEMENT_RANDOM;
     246    }
     247    return placement;
     248}
     249#if 0
     250static osgEarth::Symbology::AltitudeSymbol::Clamping
     251ParseClamping(const char *str,
     252              osgEarth::Symbology::AltitudeSymbol::Clamping defTechnique =
     253              osgEarth::Symbology::AltitudeSymbol::CLAMP_NONE)
     254{
     255    osgEarth::Symbology::AltitudeSymbol::Clamping clamping = defTechnique;
     256    if (str[0] == 'n' && strcmp(str, "none") == 0) {
     257        clamping = osgEarth::Symbology::AltitudeSymbol::CLAMP_NONE;
     258    } else if (str[0] == 't' && strcmp(str, "terrain") == 0) {
     259        clamping = osgEarth::Symbology::AltitudeSymbol::CLAMP_TO_TERRAIN;
     260    } else if (str[0] == 'r' && strcmp(str, "relative") == 0) {
     261        clamping = osgEarth::Symbology::AltitudeSymbol::CLAMP_RELATIVE_TO_TERRAIN;
     262    } else if (str[0] == 'a' && strcmp(str, "absolute") == 0) {
     263        clamping = osgEarth::Symbology::AltitudeSymbol::CLAMP_ABSOLUTE;
     264    }
     265    return clamping;
     266}
     267
     268static osgEarth::Symbology::AltitudeSymbol::Technique
     269ParseClampingTechnique(const char *str,
     270                       osgEarth::Symbology::AltitudeSymbol::Technique defTechnique =
     271                       osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_DRAPE)
     272{
     273    osgEarth::Symbology::AltitudeSymbol::Technique technique = defTechnique;
     274    if (str[0] == 'd' && strcmp(str, "drape") == 0) {
     275        technique = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_DRAPE;
     276    } else if (str[0] == 'g' && strcmp(str, "gpu") == 0) {
     277        technique = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_GPU;
     278    } else if (str[0] == 's' && strcmp(str, "scene") == 0) {
     279        technique = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_SCENE;
     280    } else if (str[0] == 'm' && strcmp(str, "map") == 0) {
     281        technique = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_MAP;
     282    }
     283    return technique;
     284}
     285#endif
    201286static int
    202287CameraDeleteViewpointOp(ClientData clientData, Tcl_Interp *interp, int objc,
     
    11301215        float minRange = 0.f;
    11311216        float maxRange = FLT_MAX;
    1132 #if OSGEARTH_MIN_VERSION_REQUIRED(2, 5, 1)
     1217#if OSGEARTH_MIN_VERSION_REQUIRED(2, 6, 0)
    11331218        if (driver[0] == 'c' && strcmp(driver, "colorramp") == 0) {
    11341219            osgEarth::Drivers::ColorRampOptions colorRampOpts;
     
    12561341            return TCL_ERROR;
    12571342        }
    1258     } else if (type[0] == 'p' && strcmp(type, "point") == 0) {
    1259         osgEarth::Drivers::OGRFeatureOptions opts;
    1260         char *urlIn = Tcl_GetString(objv[5]);
     1343    } else if (type[0] == 'i' && strcmp(type, "icon") == 0) {
     1344        char *driver = Tcl_GetString(objv[5]);
     1345        char *format = Tcl_GetString(objv[6]);
     1346        if (format && strlen(format) > 0 &&
     1347            strcmp(format, "json") != 0 && strcmp(format, "gml") != 0) {
     1348            Tcl_AppendResult(interp, "unknown format \"", format,
     1349                             "\": should be 'json' or 'gml'", (char*)NULL);
     1350            return TCL_ERROR;
     1351        }
     1352        char *typeName = Tcl_GetString(objv[7]);
     1353        char *urlIn = Tcl_GetString(objv[8]);
    12611354        std::string url = g_renderer->getCanonicalPath(std::string(urlIn));
    12621355        if (url.empty()) {
     
    12651358            return TCL_ERROR;
    12661359        }
     1360        char *icon = Tcl_GetString(objv[9]);
     1361        char *scaleExpr = Tcl_GetString(objv[10]);
     1362        char *headingExpr = Tcl_GetString(objv[11]);
     1363        bool declutter = false;
     1364        if (GetBooleanFromObj(interp, objv[12], &declutter) != TCL_OK) {
     1365            return TCL_ERROR;
     1366        }
     1367        char *placementStr = Tcl_GetString(objv[13]);
     1368        char *alignStr = Tcl_GetString(objv[14]);
     1369
     1370        osgEarth::Symbology::Style style;
     1371        osgEarth::Symbology::IconSymbol *is = style.getOrCreateSymbol<osgEarth::Symbology::IconSymbol>();
     1372        if (icon != NULL && strlen(icon) > 0) {
     1373            if (strcmp(icon, "pin") == 0) {
     1374                is->url()->setLiteral(g_renderer->getPinIcon());
     1375            } else {
     1376                is->url() = osgEarth::Symbology::StringExpression(icon);
     1377            }
     1378        } else {
     1379            is->url()->setLiteral(g_renderer->getPinIcon());
     1380        }
     1381        if (scaleExpr != NULL && strlen(scaleExpr) > 0) {
     1382            is->scale() = osgEarth::Symbology::NumericExpression(scaleExpr);
     1383        }
     1384        if (headingExpr != NULL && strlen(headingExpr) > 0) {
     1385            is->heading() = osgEarth::Symbology::NumericExpression(headingExpr);
     1386        }
     1387        is->declutter() = declutter;
     1388        is->occlusionCull() = false;
     1389        is->occlusionCullAltitude() = 200000;
     1390        is->alignment() = ParseIconAlignment(alignStr, osgEarth::Symbology::IconSymbol::ALIGN_CENTER_BOTTOM);
     1391        is->placement() = ParseInstancePlacement(placementStr, osgEarth::Symbology::InstanceSymbol::PLACEMENT_VERTEX);
     1392        //is->density() = 1.0f; // For PLACEMENT_INTERVAL/RANDOM
     1393#if 0
     1394        osgEarth::Symbology::AltitudeSymbol *alt = style.getOrCreateSymbol<osgEarth::Symbology::AltitudeSymbol>();
     1395        alt->clamping() = osgEarth::Symbology::AltitudeSymbol::CLAMP_TO_TERRAIN;
     1396        alt->technique() = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_DRAPE;
     1397        //alt->technique() = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_GPU;
     1398#endif
     1399#ifdef USE_DEPTH_OFFSET
     1400        osgEarth::Symbology::RenderSymbol* rs = style.getOrCreateSymbol<osgEarth::Symbology::RenderSymbol>();
     1401        rs->depthOffset()->enabled() = true;
     1402        rs->depthOffset()->minBias() = 1000;
     1403#endif
     1404        osgEarth::Drivers::FeatureGeomModelOptions geomOpts;
     1405        geomOpts.styles() = new osgEarth::Symbology::StyleSheet();
     1406        geomOpts.styles()->addStyle(style);
     1407        geomOpts.enableLighting() = false;
     1408        geomOpts.minRange() = 0.f;
     1409        geomOpts.maxRange() = FLT_MAX;
     1410        //geomOpts.renderOrder() = int;
     1411        //geomOpts.depthTestEnabled() = bool;
     1412        if (driver[0] == 'o' && strcmp(driver, "ogr") == 0) {
     1413            osgEarth::Drivers::OGRFeatureOptions opts;
     1414            if (osgDB::getLowerCaseFileExtension(url) == "csv") {
     1415                url = loadCSVLayer(url.c_str());
     1416            }
     1417            opts.url() = url;
     1418            geomOpts.featureOptions() = opts;
     1419        } else if (driver[0] == 't' && strcmp(driver, "tfs") == 0) {
     1420            osgEarth::Drivers::TFSFeatureOptions opts;
     1421            opts.url() = url;
     1422            opts.format() = format;
     1423            geomOpts.featureOptions() = opts;
     1424        } else if (driver[0] == 'w' && strcmp(driver, "wfs") == 0) {
     1425            osgEarth::Drivers::WFSFeatureOptions opts;
     1426            opts.url() = url;
     1427            opts.outputFormat() = format;
     1428            opts.typeName() = typeName;
     1429            geomOpts.featureOptions() = opts;
     1430        } else {
     1431            Tcl_AppendResult(interp, "unknown feature driver \"", driver,
     1432                             "\": should be 'ogr', 'tfs', or 'wfs'", (char*)NULL);
     1433            return TCL_ERROR;
     1434        }
     1435        g_renderer->addModelLayer(name, geomOpts);
     1436    } else if (type[0] == 'p' && strcmp(type, "point") == 0) {
     1437        char *driver = Tcl_GetString(objv[5]);
     1438        char *format = Tcl_GetString(objv[6]);
     1439        if (format && strlen(format) > 0 &&
     1440            strcmp(format, "json") != 0 && strcmp(format, "gml") != 0) {
     1441            Tcl_AppendResult(interp, "unknown format \"", format,
     1442                             "\": should be 'json' or 'gml'", (char*)NULL);
     1443            return TCL_ERROR;
     1444        }
     1445        char *typeName = Tcl_GetString(objv[7]);
     1446        char *urlIn = Tcl_GetString(objv[8]);
     1447        std::string url = g_renderer->getCanonicalPath(std::string(urlIn));
     1448        if (url.empty()) {
     1449            Tcl_AppendResult(interp, "file not found: \"",
     1450                             urlIn, "\"", (char*)NULL);
     1451            return TCL_ERROR;
     1452        }
    12671453        float r, g, b;
    1268         if (GetFloatFromObj(interp, objv[6], &r) != TCL_OK ||
    1269             GetFloatFromObj(interp, objv[7], &g) != TCL_OK ||
    1270             GetFloatFromObj(interp, objv[8], &b) != TCL_OK) {
     1454        if (GetFloatFromObj(interp, objv[9], &r) != TCL_OK ||
     1455            GetFloatFromObj(interp, objv[10], &g) != TCL_OK ||
     1456            GetFloatFromObj(interp, objv[11], &b) != TCL_OK) {
    12711457            return TCL_ERROR;
    12721458        }
    12731459        float ptSize;
    1274         if (GetFloatFromObj(interp, objv[9], &ptSize) != TCL_OK) {
    1275             return TCL_ERROR;
    1276         }
    1277         opts.url() = url;
     1460        if (GetFloatFromObj(interp, objv[12], &ptSize) != TCL_OK) {
     1461            return TCL_ERROR;
     1462        }
    12781463
    12791464        osgEarth::Symbology::Style style;
     
    12841469        osgEarth::Symbology::AltitudeSymbol *alt = style.getOrCreateSymbol<osgEarth::Symbology::AltitudeSymbol>();
    12851470        alt->clamping() = osgEarth::Symbology::AltitudeSymbol::CLAMP_TO_TERRAIN;
    1286         alt->technique() = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_DRAPE;
    1287         //alt->technique() = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_GPU;
     1471        //alt->technique() = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_DRAPE;
     1472        alt->technique() = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_GPU;
    12881473#endif
    1289 #if 0
     1474#ifdef USE_DEPTH_OFFSET
    12901475        osgEarth::Symbology::RenderSymbol* rs = style.getOrCreateSymbol<osgEarth::Symbology::RenderSymbol>();
    12911476        rs->depthOffset()->enabled() = true;
     
    12931478#endif
    12941479        osgEarth::Drivers::FeatureGeomModelOptions geomOpts;
    1295         geomOpts.featureOptions() = opts;
    12961480        geomOpts.styles() = new osgEarth::Symbology::StyleSheet();
    12971481        geomOpts.styles()->addStyle(style);
     
    12991483        geomOpts.minRange() = 0.f;
    13001484        geomOpts.maxRange() = FLT_MAX;
    1301         //geomOpts.renderOrder = int;
    1302         //geomOpts.depthTestEnabled = bool;
     1485        //geomOpts.renderOrder() = int;
     1486        //geomOpts.depthTestEnabled() = bool;
     1487        if (driver[0] == 'o' && strcmp(driver, "ogr") == 0) {
     1488            osgEarth::Drivers::OGRFeatureOptions opts;
     1489            if (osgDB::getLowerCaseFileExtension(url) == "csv") {
     1490                url = loadCSVLayer(url.c_str());
     1491            }
     1492            opts.url() = url;
     1493            geomOpts.featureOptions() = opts;
     1494        } else if (driver[0] == 't' && strcmp(driver, "tfs") == 0) {
     1495            osgEarth::Drivers::TFSFeatureOptions opts;
     1496            opts.url() = url;
     1497            opts.format() = format;
     1498            geomOpts.featureOptions() = opts;
     1499        } else if (driver[0] == 'w' && strcmp(driver, "wfs") == 0) {
     1500            osgEarth::Drivers::WFSFeatureOptions opts;
     1501            opts.url() = url;
     1502            opts.outputFormat() = format;
     1503            opts.typeName() = typeName;
     1504            geomOpts.featureOptions() = opts;
     1505        } else {
     1506            Tcl_AppendResult(interp, "unknown feature driver \"", driver,
     1507                             "\": should be 'ogr', 'tfs', or 'wfs'", (char*)NULL);
     1508            return TCL_ERROR;
     1509        }
    13031510        g_renderer->addModelLayer(name, geomOpts);
    13041511    } else if (type[0] == 'p' && strcmp(type, "polygon") == 0) {
    1305         osgEarth::Drivers::OGRFeatureOptions opts;
    1306         char *urlIn = Tcl_GetString(objv[5]);
     1512        char *driver = Tcl_GetString(objv[5]);
     1513        char *format = Tcl_GetString(objv[6]);
     1514        if (format && strlen(format) > 0 &&
     1515            strcmp(format, "json") != 0 && strcmp(format, "gml") != 0) {
     1516            Tcl_AppendResult(interp, "unknown format \"", format,
     1517                             "\": should be 'json' or 'gml'", (char*)NULL);
     1518            return TCL_ERROR;
     1519        }
     1520        char *typeName = Tcl_GetString(objv[7]);
     1521        char *urlIn = Tcl_GetString(objv[8]);
    13071522        std::string url = g_renderer->getCanonicalPath(std::string(urlIn));
    13081523        if (url.empty()) {
     
    13121527        }
    13131528        float r, g, b;
    1314         if (GetFloatFromObj(interp, objv[6], &r) != TCL_OK ||
    1315             GetFloatFromObj(interp, objv[7], &g) != TCL_OK ||
    1316             GetFloatFromObj(interp, objv[8], &b) != TCL_OK) {
    1317             return TCL_ERROR;
    1318         }
    1319         opts.url() = url;
     1529        if (GetFloatFromObj(interp, objv[9], &r) != TCL_OK ||
     1530            GetFloatFromObj(interp, objv[10], &g) != TCL_OK ||
     1531            GetFloatFromObj(interp, objv[11], &b) != TCL_OK) {
     1532            return TCL_ERROR;
     1533        }
    13201534
    13211535        osgEarth::Symbology::Style style;
    13221536        osgEarth::Symbology::PolygonSymbol *ps = style.getOrCreateSymbol<osgEarth::Symbology::PolygonSymbol>();
    13231537        ps->fill()->color() = osgEarth::Symbology::Color(r, g, b);
    1324 #if 1
    1325         osgEarth::Symbology::AltitudeSymbol *alt = style.getOrCreateSymbol<osgEarth::Symbology::AltitudeSymbol>();
    1326         alt->clamping() = osgEarth::Symbology::AltitudeSymbol::CLAMP_TO_TERRAIN;
    1327         alt->technique() = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_DRAPE;
    1328         //alt->technique() = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_GPU;
    1329 #endif
    1330         osgEarth::Symbology::RenderSymbol* rs = style.getOrCreateSymbol<osgEarth::Symbology::RenderSymbol>();
    1331         rs->depthOffset()->enabled() = true;
    1332         rs->depthOffset()->minBias() = 1000;
    1333 
    1334         osgEarth::Drivers::FeatureGeomModelOptions geomOpts;
    1335         geomOpts.featureOptions() = opts;
    1336         geomOpts.styles() = new osgEarth::Symbology::StyleSheet();
    1337         geomOpts.styles()->addStyle(style);
    1338         geomOpts.enableLighting() = false;
    1339         geomOpts.minRange() = 0.f;
    1340         geomOpts.maxRange() = FLT_MAX;
    1341         g_renderer->addModelLayer(name, geomOpts);
    1342     } else if (type[0] == 'l' && strcmp(type, "line") == 0) {
    1343         osgEarth::Drivers::OGRFeatureOptions opts;
    1344         char *urlIn = Tcl_GetString(objv[5]);
    1345         std::string url = g_renderer->getCanonicalPath(std::string(urlIn));
    1346         if (url.empty()) {
    1347             Tcl_AppendResult(interp, "file not found: \"",
    1348                              urlIn, "\"", (char*)NULL);
    1349             return TCL_ERROR;
    1350         }
    1351         float r, g, b;
    1352         if (GetFloatFromObj(interp, objv[6], &r) != TCL_OK ||
    1353             GetFloatFromObj(interp, objv[7], &g) != TCL_OK ||
    1354             GetFloatFromObj(interp, objv[8], &b) != TCL_OK) {
    1355             return TCL_ERROR;
    1356         }
    1357         float lineWidth;
    1358         if (GetFloatFromObj(interp, objv[9], &lineWidth) != TCL_OK) {
    1359             return TCL_ERROR;
    1360         }
    1361         opts.url() = url;
    1362 
    1363         osgEarth::Symbology::Style style;
     1538
    13641539        osgEarth::Symbology::LineSymbol *ls = style.getOrCreateSymbol<osgEarth::Symbology::LineSymbol>();
    1365         ls->stroke()->color() = osgEarth::Symbology::Color(r, g, b);
    1366         ls->stroke()->width() = lineWidth;
     1540        ls->stroke()->color() = osgEarth::Symbology::Color(0, 0, 0);
     1541        ls->stroke()->width() = 1.0f;
     1542        ls->stroke()->widthUnits() = osgEarth::Units::PIXELS;
     1543        ls->stroke()->lineCap() = osgEarth::Symbology::Stroke::LINECAP_FLAT; // _SQUARE, _ROUND
     1544        //ls->stroke()->roundingRatio() = 0.4f;
     1545        ls->stroke()->lineJoin() = osgEarth::Symbology::Stroke::LINEJOIN_MITRE; // _ROUND
     1546        //ls->stroke()->stipplePattern() = 0; // Bitmask: unsigned short
     1547        //ls->stroke()->stippleFactor() = 0; // num reps: unsigned
    13671548#if 1
    13681549        osgEarth::Symbology::AltitudeSymbol *alt = style.getOrCreateSymbol<osgEarth::Symbology::AltitudeSymbol>();
     
    13711552        alt->technique() = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_GPU;
    13721553#endif
    1373 #if 1
     1554#ifdef USE_DEPTH_OFFSET
    13741555        osgEarth::Symbology::RenderSymbol* rs = style.getOrCreateSymbol<osgEarth::Symbology::RenderSymbol>();
    13751556        rs->depthOffset()->enabled() = true;
     
    13771558#endif
    13781559        osgEarth::Drivers::FeatureGeomModelOptions geomOpts;
    1379         geomOpts.featureOptions() = opts;
    13801560        geomOpts.styles() = new osgEarth::Symbology::StyleSheet();
    13811561        geomOpts.styles()->addStyle(style);
     
    13831563        geomOpts.minRange() = 0.f;
    13841564        geomOpts.maxRange() = FLT_MAX;
    1385         if (objc > 10) {
     1565        if (driver[0] == 'o' && strcmp(driver, "ogr") == 0) {
     1566            osgEarth::Drivers::OGRFeatureOptions opts;
     1567            if (osgDB::getLowerCaseFileExtension(url) == "csv") {
     1568                url = loadCSVLayer(url.c_str());
     1569            }
     1570            opts.url() = url;
     1571            geomOpts.featureOptions() = opts;
     1572        } else if (driver[0] == 't' && strcmp(driver, "tfs") == 0) {
     1573            osgEarth::Drivers::TFSFeatureOptions opts;
     1574            opts.url() = url;
     1575            opts.format() = format;
     1576            geomOpts.featureOptions() = opts;
     1577        } else if (driver[0] == 'w' && strcmp(driver, "wfs") == 0) {
     1578            osgEarth::Drivers::WFSFeatureOptions opts;
     1579            opts.url() = url;
     1580            opts.outputFormat() = format;
     1581            opts.typeName() = typeName;
     1582            geomOpts.featureOptions() = opts;
     1583        } else {
     1584            Tcl_AppendResult(interp, "unknown feature driver \"", driver,
     1585                             "\": should be 'ogr', 'tfs', or 'wfs'", (char*)NULL);
     1586            return TCL_ERROR;
     1587        }
     1588        g_renderer->addModelLayer(name, geomOpts);
     1589    } else if (type[0] == 'l' && strcmp(type, "line") == 0) {
     1590        char *driver = Tcl_GetString(objv[5]);
     1591        char *format = Tcl_GetString(objv[6]);
     1592        if (format && strlen(format) > 0 &&
     1593            strcmp(format, "json") != 0 && strcmp(format, "gml") != 0) {
     1594            Tcl_AppendResult(interp, "unknown format \"", format,
     1595                             "\": should be 'json' or 'gml'", (char*)NULL);
     1596            return TCL_ERROR;
     1597        }
     1598        char *typeName = Tcl_GetString(objv[7]);
     1599        char *urlIn = Tcl_GetString(objv[8]);
     1600        std::string url = g_renderer->getCanonicalPath(std::string(urlIn));
     1601        if (url.empty()) {
     1602            Tcl_AppendResult(interp, "file not found: \"",
     1603                             urlIn, "\"", (char*)NULL);
     1604            return TCL_ERROR;
     1605        }
     1606        float r, g, b;
     1607        if (GetFloatFromObj(interp, objv[9], &r) != TCL_OK ||
     1608            GetFloatFromObj(interp, objv[10], &g) != TCL_OK ||
     1609            GetFloatFromObj(interp, objv[11], &b) != TCL_OK) {
     1610            return TCL_ERROR;
     1611        }
     1612        float lineWidth;
     1613        if (GetFloatFromObj(interp, objv[12], &lineWidth) != TCL_OK) {
     1614            return TCL_ERROR;
     1615        }
     1616
     1617        osgEarth::Symbology::Style style;
     1618        osgEarth::Symbology::LineSymbol *ls = style.getOrCreateSymbol<osgEarth::Symbology::LineSymbol>();
     1619        ls->stroke()->color() = osgEarth::Symbology::Color(r, g, b);
     1620        ls->stroke()->width() = lineWidth;
     1621        ls->stroke()->widthUnits() = osgEarth::Units::PIXELS;
     1622        ls->stroke()->lineCap() = osgEarth::Symbology::Stroke::LINECAP_FLAT; // _SQUARE, _ROUND
     1623        //ls->stroke()->roundingRatio() = 0.4f;
     1624        ls->stroke()->lineJoin() = osgEarth::Symbology::Stroke::LINEJOIN_MITRE; // _ROUND
     1625        //ls->stroke()->stipplePattern() = 0; // Bitmask: unsigned short
     1626        //ls->stroke()->stippleFactor() = 0; // num reps: unsigned
     1627#if 1
     1628        osgEarth::Symbology::AltitudeSymbol *alt = style.getOrCreateSymbol<osgEarth::Symbology::AltitudeSymbol>();
     1629        alt->clamping() = osgEarth::Symbology::AltitudeSymbol::CLAMP_TO_TERRAIN;
     1630        //alt->technique() = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_DRAPE;
     1631        alt->technique() = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_GPU;
     1632#endif
     1633#ifdef USE_DEPTH_OFFSET
     1634        osgEarth::Symbology::RenderSymbol* rs = style.getOrCreateSymbol<osgEarth::Symbology::RenderSymbol>();
     1635        rs->depthOffset()->enabled() = true;
     1636        rs->depthOffset()->minBias() = 1000;
     1637#endif
     1638        osgEarth::Drivers::FeatureGeomModelOptions geomOpts;
     1639        geomOpts.styles() = new osgEarth::Symbology::StyleSheet();
     1640        geomOpts.styles()->addStyle(style);
     1641        geomOpts.enableLighting() = false;
     1642        geomOpts.minRange() = 0.f;
     1643        geomOpts.maxRange() = FLT_MAX;
     1644        if (objc > 13) {
    13861645            float min, max;
    1387             if (GetFloatFromObj(interp, objv[10], &min) != TCL_OK ||
    1388                 GetFloatFromObj(interp, objv[11], &max) != TCL_OK) {
     1646            if (GetFloatFromObj(interp, objv[13], &min) != TCL_OK ||
     1647                GetFloatFromObj(interp, objv[14], &max) != TCL_OK) {
    13891648                return TCL_ERROR;
    13901649            }
     
    13921651            geomOpts.maxRange() = max;
    13931652        }
     1653        if (driver[0] == 'o' && strcmp(driver, "ogr") == 0) {
     1654            osgEarth::Drivers::OGRFeatureOptions opts;
     1655            if (osgDB::getLowerCaseFileExtension(url) == "csv") {
     1656                url = loadCSVLayer(url.c_str());
     1657            }
     1658            opts.url() = url;
     1659            geomOpts.featureOptions() = opts;
     1660        } else if (driver[0] == 't' && strcmp(driver, "tfs") == 0) {
     1661            osgEarth::Drivers::TFSFeatureOptions opts;
     1662            opts.url() = url;
     1663            opts.format() = format;
     1664            geomOpts.featureOptions() = opts;
     1665        } else if (driver[0] == 'w' && strcmp(driver, "wfs") == 0) {
     1666            osgEarth::Drivers::WFSFeatureOptions opts;
     1667            opts.url() = url;
     1668            opts.outputFormat() = format;
     1669            opts.typeName() = typeName;
     1670            geomOpts.featureOptions() = opts;
     1671        } else {
     1672            Tcl_AppendResult(interp, "unknown feature driver \"", driver,
     1673                             "\": should be 'ogr', 'tfs', or 'wfs'", (char*)NULL);
     1674            return TCL_ERROR;
     1675        }
    13941676        g_renderer->addModelLayer(name, geomOpts);
    13951677   } else if (type[0] == 't' && strcmp(type, "text") == 0) {
    1396         osgEarth::Drivers::OGRFeatureOptions opts;
    1397         char *urlIn = Tcl_GetString(objv[5]);
     1678        char *driver = Tcl_GetString(objv[5]);
     1679        char *format = Tcl_GetString(objv[6]);
     1680        if (format && strlen(format) > 0 &&
     1681            strcmp(format, "json") != 0 && strcmp(format, "gml") != 0) {
     1682            Tcl_AppendResult(interp, "unknown format \"", format,
     1683                             "\": should be 'json' or 'gml'", (char*)NULL);
     1684            return TCL_ERROR;
     1685        }
     1686        char *typeName = Tcl_GetString(objv[7]);
     1687        char *urlIn = Tcl_GetString(objv[8]);
    13981688        std::string url = g_renderer->getCanonicalPath(std::string(urlIn));
    13991689        if (url.empty()) {
     
    14021692            return TCL_ERROR;
    14031693        }
    1404         char *content = Tcl_GetString(objv[6]);
    1405         char *priority = Tcl_GetString(objv[7]);
     1694        char *content = Tcl_GetString(objv[9]);
     1695        char *priority = Tcl_GetString(objv[10]);
    14061696        float fgR, fgG, fgB;
    14071697        float bgR, bgG, bgB;
    14081698        float haloWidth, ftSize;
    1409         if (GetFloatFromObj(interp, objv[8], &fgR) != TCL_OK ||
    1410             GetFloatFromObj(interp, objv[9], &fgG) != TCL_OK ||
    1411             GetFloatFromObj(interp, objv[10], &fgB) != TCL_OK ||
    1412             GetFloatFromObj(interp, objv[11], &bgR) != TCL_OK ||
    1413             GetFloatFromObj(interp, objv[12], &bgG) != TCL_OK ||
    1414             GetFloatFromObj(interp, objv[13], &bgB) != TCL_OK ||
    1415             GetFloatFromObj(interp, objv[14], &haloWidth) != TCL_OK ||
    1416             GetFloatFromObj(interp, objv[15], &ftSize) != TCL_OK) {
     1699        osg::Vec2s pixelOffset(0, 0);
     1700        if (GetFloatFromObj(interp, objv[11], &fgR) != TCL_OK ||
     1701            GetFloatFromObj(interp, objv[12], &fgG) != TCL_OK ||
     1702            GetFloatFromObj(interp, objv[13], &fgB) != TCL_OK ||
     1703            GetFloatFromObj(interp, objv[14], &bgR) != TCL_OK ||
     1704            GetFloatFromObj(interp, objv[15], &bgG) != TCL_OK ||
     1705            GetFloatFromObj(interp, objv[16], &bgB) != TCL_OK ||
     1706            GetFloatFromObj(interp, objv[17], &haloWidth) != TCL_OK ||
     1707            GetFloatFromObj(interp, objv[18], &ftSize) != TCL_OK) {
    14171708            return TCL_ERROR;
    14181709        }
    14191710        bool removeDupes, declutter;
    1420         if (GetBooleanFromObj(interp, objv[16], &removeDupes) != TCL_OK ||
    1421             GetBooleanFromObj(interp, objv[17], &declutter) != TCL_OK) {
     1711        if (GetBooleanFromObj(interp, objv[19], &removeDupes) != TCL_OK ||
     1712            GetBooleanFromObj(interp, objv[20], &declutter) != TCL_OK) {
    14221713            return TCL_ERROR;
    14231714        }
    14241715        osgEarth::Symbology::TextSymbol::Alignment alignment =
    1425             ParseTextAlignment(Tcl_GetString(objv[18]));
    1426         opts.url() = url;
     1716            ParseTextAlignment(Tcl_GetString(objv[21]));
     1717        int xoff, yoff;
     1718        if (Tcl_GetIntFromObj(interp, objv[22], &xoff) != TCL_OK ||
     1719            Tcl_GetIntFromObj(interp, objv[23], &yoff) != TCL_OK) {
     1720            return TCL_ERROR;
     1721        }
     1722        pixelOffset.x() = (short)xoff;
     1723        pixelOffset.y() = (short)yoff;
    14271724
    14281725        osgEarth::Symbology::Style style;
     
    14401737        ts->alignment() = alignment;
    14411738        ts->declutter() = declutter;
     1739        ts->pixelOffset() = pixelOffset;
    14421740        ts->encoding() = osgEarth::Symbology::TextSymbol::ENCODING_UTF8;
    1443 
     1741#ifdef USE_DEPTH_OFFSET
    14441742        osgEarth::Symbology::RenderSymbol* rs = style.getOrCreateSymbol<osgEarth::Symbology::RenderSymbol>();
    14451743        rs->depthOffset()->enabled() = true;
    14461744        rs->depthOffset()->minBias() = 1000;
    1447 
     1745#endif
    14481746        osgEarth::Drivers::FeatureGeomModelOptions geomOpts;
    1449         geomOpts.featureOptions() = opts;
    14501747        geomOpts.styles() = new osgEarth::Symbology::StyleSheet();
    14511748        geomOpts.styles()->addStyle(style);
     
    14531750        geomOpts.minRange() = 0.f;
    14541751        geomOpts.maxRange() = FLT_MAX;
    1455         if (objc > 19) {
     1752        if (objc > 24) {
    14561753            float min, max;
    1457             if (GetFloatFromObj(interp, objv[19], &min) != TCL_OK ||
    1458                 GetFloatFromObj(interp, objv[20], &max) != TCL_OK) {
     1754            if (GetFloatFromObj(interp, objv[24], &min) != TCL_OK ||
     1755                GetFloatFromObj(interp, objv[25], &max) != TCL_OK) {
    14591756                return TCL_ERROR;
    14601757            }
    14611758            geomOpts.minRange() = min;
    14621759            geomOpts.maxRange() = max;
     1760        }
     1761        if (driver[0] == 'o' && strcmp(driver, "ogr") == 0) {
     1762            osgEarth::Drivers::OGRFeatureOptions opts;
     1763            if (osgDB::getLowerCaseFileExtension(url) == "csv") {
     1764                url = loadCSVLayer(url.c_str());
     1765            }
     1766            opts.url() = url;
     1767            geomOpts.featureOptions() = opts;
     1768        } else if (driver[0] == 't' && strcmp(driver, "tfs") == 0) {
     1769            osgEarth::Drivers::TFSFeatureOptions opts;
     1770            opts.url() = url;
     1771            opts.format() = format;
     1772            geomOpts.featureOptions() = opts;
     1773        } else if (driver[0] == 'w' && strcmp(driver, "wfs") == 0) {
     1774            osgEarth::Drivers::WFSFeatureOptions opts;
     1775            opts.url() = url;
     1776            opts.outputFormat() = format;
     1777            opts.typeName() = typeName;
     1778            geomOpts.featureOptions() = opts;
     1779        } else {
     1780            Tcl_AppendResult(interp, "unknown feature driver \"", driver,
     1781                             "\": should be 'ogr', 'tfs', or 'wfs'", (char*)NULL);
     1782            return TCL_ERROR;
    14631783        }
    14641784        g_renderer->addModelLayer(name, geomOpts);
     
    19262246
    19272247static int
     2248MapTerrainAmbientOp(ClientData clientData, Tcl_Interp *interp, int objc,
     2249                    Tcl_Obj *const *objv)
     2250{
     2251    float ambient;
     2252    if (GetFloatFromObj(interp, objv[3], &ambient) != TCL_OK) {
     2253        return TCL_ERROR;
     2254    }
     2255    g_renderer->setSkyAmbient(ambient);
     2256    return TCL_OK;
     2257}
     2258
     2259static int
    19282260MapTerrainColorOp(ClientData clientData, Tcl_Interp *interp, int objc,
    19292261                  Tcl_Obj *const *objv)
     
    20172349
    20182350static CmdSpec mapTerrainOps[] = {
     2351    {"ambient",   1, MapTerrainAmbientOp,   4, 4, "val"},
    20192352    {"color",     1, MapTerrainColorOp,     6, 6, "r g b"},
    20202353    {"edges",     1, MapTerrainEdgesOp,     4, 4, "bool"},
  • geovis/trunk/geovis_protocol.txt

    r5775 r5873  
    172172
    173173Feature/model layers:
    174 map layer add <layerName> point <url> <r> <g> <b> <size>
     174In the following:
     175<driver> = ogr|tfs|wfs
     176<format> = json|gml (for tfs or wfs driver)
     177<typeName> = layer name for wfs driver
     178
     179map layer add <layerName> icon <driver> <format> <typeName> <url> <icon> <scale> <heading> <declutter> <placement> <alignment>
     180    Add an icon feature layer from a file or URL
     181map layer add <layerName> point <driver> <format> <typeName> <url> <r> <g> <b> <size>
    175182    Add a point feature layer from a file or URL
    176 map layer add <layerName> polygon <url> <r> <g> <b> <width>
     183map layer add <layerName> polygon <driver> <format> <typeName> <url> <r> <g> <b> <width>
    177184    Add a polygon feature layer from a file or URL
    178 map layer add <layerName> line <url> <r> <g> <b> <width>
     185map layer add <layerName> line <driver> <format> <typeName> <url> <r> <g> <b> <width>
    179186    Add a line feature layer from a file or URL
    180 map layer add <layerName> text <url> <content> <priority> <fgR> <fgG> <fgB> <bgR> <bgG> <bgB> <haloWidth> <fontSize> <removeDupes> <declutter> <alignment> <visibilityRangeMin> <visibilityRangeMax>
     187map layer add <layerName> text <driver> <format> <typeName> <url> <content> <priority> <fgR> <fgG> <fgB> <bgR> <bgG> <bgB> <haloWidth> <fontSize> <removeDupes> <declutter> <alignment> <xoffset> <yoffset> <visibilityRangeMin> <visibilityRangeMax>
    181188    Add a text symbol layer from a file or URL
    182189
  • geovis/trunk/idatatest.cpp

    r5852 r5873  
    3636    std::cout << std::endl << std::endl;
    3737    Buffer buff;
    38     getFile(3, "station.csv", &buff);
     38    getFile(3, "//station.csv", &buff);
    3939    std::cout << std::endl << std::endl;
    4040    std::cout << "station.csv size: " << buff.size << std::endl;
Note: See TracChangeset for help on using the changeset viewer.