Changeset 4645 for geovis/trunk


Ignore:
Timestamp:
Oct 8, 2014, 10:25:39 AM (10 years ago)
Author:
ldelgass
Message:

Initial take on a selection box

Location:
geovis/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • geovis/trunk/Renderer.cpp

    r4643 r4645  
    2424#endif
    2525
     26#include <osgDB/WriteFile>
    2627#include <osgDB/FileUtils>
    2728#include <osgDB/FileNameUtils>
     
    4546#include <osgEarth/DateTime>
    4647#include <osgEarth/Pickers>
     48#include <osgEarthFeatures/Feature>
     49#include <osgEarthSymbology/Color>
     50#include <osgEarthSymbology/Geometry>
     51#include <osgEarthSymbology/Style>
     52#include <osgEarthSymbology/StyleSheet>
     53#include <osgEarthSymbology/IconSymbol>
     54#include <osgEarthSymbology/LineSymbol>
     55
    4756#include <osgEarthAnnotation/AnnotationNode>
     57#include <osgEarthAnnotation/FeatureNode>
    4858#include <osgEarthAnnotation/PlaceNode>
    4959#include <osgEarthAnnotation/HighlightDecoration>
     
    9991009        return false;
    10001010    }
     1011    bool ret = true;
    10011012    osg::Camera *cam = _viewer->getCamera();
    10021013    osg::Matrixd MVP = cam->getViewMatrix() * cam->getProjectionMatrix();
     
    10191030                     std::numeric_limits<double>::quiet_NaN(),
    10201031                     std::numeric_limits<double>::quiet_NaN());
     1032            ret = false;
    10211033            continue;
    10221034        }
     
    10391051        TRACE("screen: %g,%g,%g", itr->x(), itr->y(), itr->z());
    10401052    }
    1041     return true;
     1053    return ret;
     1054}
     1055
     1056bool Renderer::mouseToLatLong(int mouseX, int mouseY,
     1057                              double *latitude, double *longitude)
     1058{
     1059    if (getMapSRS() == NULL)
     1060        return false;
     1061    const osgEarth::SpatialReference *outSRS =
     1062        getMapSRS()->getGeographicSRS();
     1063    if (outSRS == NULL)
     1064        return false;
     1065    osgEarth::GeoPoint mapPoint;
     1066    if (mapMouseCoords(mouseX, mouseY, mapPoint)) {
     1067        mapPoint = mapPoint.transform(outSRS);
     1068        *longitude = mapPoint.x();
     1069        *latitude = mapPoint.y();
     1070        return true;
     1071    } else {
     1072        return false;
     1073    }
    10421074}
    10431075
     
    12731305}
    12741306
    1275 void Renderer::addPlaceNode(double latitude, double longitude, char *labelText)
     1307void Renderer::initAnnotations()
     1308{
     1309    if (!_annotations.valid()) {
     1310        _annotations = new osg::Group();
     1311        _annotations->setName("Annotations");
     1312        _sceneRoot->addChild(_annotations.get());
     1313        _placeNodes = new osg::Group();
     1314        _placeNodes->setName("Place Nodes");
     1315        osgEarth::Decluttering::setEnabled(_placeNodes->getOrCreateStateSet(), true);
     1316        _annotations->addChild(_placeNodes.get());
     1317    }
     1318}
     1319
     1320void Renderer::initBoxSelection(int x, int y)
     1321{
     1322    double latitude, longitude;
     1323    if (!mouseToLatLong(x, y, &latitude, &longitude)) {
     1324        return;
     1325    }
     1326    _anchorLat = latitude;
     1327    _anchorLong = longitude;
     1328    addRhumbBox(latitude, latitude, longitude, longitude);
     1329}
     1330
     1331void Renderer::updateBoxSelection(int x, int y)
     1332{
     1333    osgEarth::Annotation::FeatureNode *node = _selectionBox.get();
     1334    double nlat, nlong;
     1335    if (!mouseToLatLong(x, y, &nlat, &nlong)) {
     1336        return;
     1337    }
     1338    double latMin, latMax, longMin, longMax;
     1339    if (nlong >= _anchorLong && nlat >= _anchorLat) {
     1340        // +x +y
     1341        longMin = _anchorLong;
     1342        latMin = _anchorLat;
     1343        longMax = nlong;
     1344        latMax = nlat;
     1345    } else if (nlong < _anchorLong && nlat >= _anchorLat) {
     1346        // -x +y
     1347        longMin = nlong;
     1348        latMin = _anchorLat;
     1349        longMax = _anchorLong;
     1350        latMax = nlat;
     1351    } else if (nlong < _anchorLong && nlat < _anchorLat) {
     1352        // -x -y
     1353        longMin = nlong;
     1354        latMin = nlat;
     1355        longMax = _anchorLong;
     1356        latMax = _anchorLat;
     1357    } else {
     1358        // +x -y
     1359        longMin = _anchorLong;
     1360        latMin = nlat;
     1361        longMax = nlong;
     1362        latMax = _anchorLat;
     1363    }
     1364    osgEarth::Symbology::Geometry *geom = node->getFeature()->getGeometry();
     1365    (*geom)[0] = osg::Vec3d(longMax, latMin, 0);
     1366    (*geom)[1] = osg::Vec3d(longMin, latMin, 0);
     1367    (*geom)[2] = osg::Vec3d(longMin, latMax, 0);
     1368    (*geom)[3] = osg::Vec3d(longMax, latMax, 0);
     1369    node->init();
     1370    _needsRedraw = true;
     1371}
     1372
     1373void Renderer::clearBoxSelection()
     1374{
     1375    if (_annotations.valid() && _selectionBox.valid()) {
     1376        _annotations->removeChild(_selectionBox.get());
     1377        _selectionBox = NULL;
     1378    }
     1379    _needsRedraw = true;
     1380}
     1381
     1382void Renderer::addRhumbBox(double latMin, double latMax,
     1383                           double longMin, double longMax)
    12761384{
    12771385    if (!_mapNode.valid()) {
     
    12791387        return;
    12801388    }
    1281     if (!_annotations.valid()) {
    1282         _annotations = new osg::Group();
    1283         _sceneRoot->addChild(_annotations.get());
    1284         _placeNodes = new osg::Group();
    1285         osgEarth::Decluttering::setEnabled(_placeNodes->getOrCreateStateSet(), true);
    1286         _annotations->addChild(_placeNodes.get());
    1287     }
     1389    initAnnotations();
     1390
     1391    if (_selectionBox.valid()) {
     1392        osgEarth::Symbology::Geometry *geom = _selectionBox->getFeature()->getGeometry();
     1393        (*geom)[0] = osg::Vec3d(longMax, latMin, 0);
     1394        (*geom)[1] = osg::Vec3d(longMin, latMin, 0);
     1395        (*geom)[2] = osg::Vec3d(longMin, latMax, 0);
     1396        (*geom)[3] = osg::Vec3d(longMax, latMax, 0);
     1397        _selectionBox->init();
     1398    } else {
     1399        const osgEarth::SpatialReference* geoSRS = _mapNode->getMapSRS()->getGeographicSRS();
     1400        osgEarth::Symbology::Geometry *geom = new osgEarth::Symbology::Polygon();
     1401        geom->push_back(osg::Vec3d(longMax, latMin, 0));
     1402        geom->push_back(osg::Vec3d(longMin, latMin, 0));
     1403        geom->push_back(osg::Vec3d(longMin, latMax, 0));
     1404        geom->push_back(osg::Vec3d(longMax, latMax, 0));
     1405        osgEarth::Symbology::Style boxStyle;
     1406#if 1
     1407        osgEarth::Symbology::PolygonSymbol *poly = boxStyle.getOrCreate<osgEarth::Symbology::PolygonSymbol>();
     1408        poly->fill()->color() = osgEarth::Symbology::Color::Cyan;
     1409        poly->fill()->color().a() = 0.5;
     1410        //#else
     1411        osgEarth::Symbology::LineSymbol *line = boxStyle.getOrCreate<osgEarth::Symbology::LineSymbol>();
     1412        line->stroke()->color() = osgEarth::Symbology::Color::Yellow;
     1413        line->stroke()->width() = 2.0f;
     1414        //line->creaseAngle() = 45.0f;
     1415        line->tessellation() = 10;
     1416#endif
     1417        osgEarth::Symbology::AltitudeSymbol *alt = boxStyle.getOrCreate<osgEarth::Symbology::AltitudeSymbol>();
     1418        alt->clamping() = osgEarth::Symbology::AltitudeSymbol::CLAMP_TO_TERRAIN;
     1419        //alt->technique() = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_GPU;
     1420        alt->technique() = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_DRAPE;
     1421        //alt->technique() = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_SCENE;
     1422#if 0
     1423        osgEarth::Symbology::RenderSymbol* rs = boxStyle.getOrCreateSymbol<osgEarth::Symbology::RenderSymbol>();
     1424        rs->depthOffset()->enabled() = true;
     1425        rs->depthOffset()->minBias() = 1000;
     1426#endif
     1427        osgEarth::Features::Feature *feature = new osgEarth::Features::Feature(geom, geoSRS, boxStyle);
     1428        //feature->geoInterp() = osgEarth::GEOINTERP_GREAT_CIRCLE;
     1429        feature->geoInterp() = osgEarth::GEOINTERP_RHUMB_LINE;
     1430        _selectionBox =
     1431            new osgEarth::Annotation::FeatureNode(_mapNode, feature);
     1432        _annotations->addChild(_selectionBox.get());
     1433    }
     1434
     1435    _needsRedraw = true;
     1436}
     1437
     1438void Renderer::addPlaceNode(double latitude, double longitude, char *labelText)
     1439{
     1440    if (!_mapNode.valid()) {
     1441        ERROR("No map node");
     1442        return;
     1443    }
     1444    initAnnotations();
    12881445
    12891446    const osgEarth::SpatialReference* geoSRS = _mapNode->getMapSRS()->getGeographicSRS();
     
    12911448    osgEarth::Symbology::Style pin;
    12921449    pin.getOrCreate<osgEarth::Symbology::IconSymbol>()->url()->setLiteral(getPinIcon());
    1293     osgEarth::Annotation::AnnotationNode *anno = new osgEarth::Annotation::PlaceNode(_mapNode, osgEarth::GeoPoint(geoSRS, longitude, latitude), labelText, pin);
     1450    osgEarth::Annotation::AnnotationNode *anno =
     1451        new osgEarth::Annotation::PlaceNode(_mapNode, osgEarth::GeoPoint(geoSRS, longitude, latitude), labelText, pin);
    12941452    _placeNodes->addChild(anno);
    12951453    osgEarth::Annotation::DecorationInstaller
     
    13001458        scaleInstaller("hover", new osgEarth::Annotation::ScaleDecoration(1.1f));
    13011459    _placeNodes->accept(scaleInstaller);
     1460#if 0
     1461    writeScene("/tmp/test.osg");
     1462#endif
    13021463    _needsRedraw = true;
    13031464}
     
    13321493            }
    13331494        }
     1495#if 0
     1496        writeScene("/tmp/test.osgt");
     1497#endif
    13341498    }
    13351499    for (std::set<osgEarth::Annotation::AnnotationNode *>::iterator itr = toUnHover.begin();
     
    13741538        TRACE("NO Picker hits");
    13751539    }
     1540#if 0
     1541    writeScene("/tmp/test.osg");
     1542#endif
    13761543}
    13771544
     
    16101777
    16111778    if (_manipulator.valid()) {
     1779        // +y = zoom out, -y = zoom in
    16121780        TRACE("camDist: %g", _manipulator->getDistance());
    1613         // FIXME: zoom here wants y mouse coords in normalized viewport coords
     1781        if ((_mapScale < 0.0 && y > 0.0) ||
     1782            (_mapScale < 0.1 && y < 0.0) ||
     1783            (_mapScale > 40000.0 && y > 0.0))
     1784            return;
    16141785#if 1
    16151786       _manipulator->zoom(0, y);
     
    20012172    //double scaleUSSurveyFeet = scale * 3937.0/1200.0; // US survey foot = 1200/3937 m
    20022173    TRACE("m: %g px: %g m/px: %g", meters, pixelWidth, scale);
     2174    _mapScale = scale;
    20032175    switch (_scaleBarUnits) {
    20042176    case UNITS_NAUTICAL_MILES: {
     
    20882260    return retStr;
    20892261}
     2262
     2263void Renderer::writeScene(const std::string& file)
     2264{
     2265    if (_sceneRoot.valid()) {
     2266        osgDB::writeNodeFile(*_sceneRoot.get(), file);
     2267    }
     2268}
  • geovis/trunk/Renderer.h

    r4636 r4645  
    3232#include <osgEarth/GeoData>
    3333#include <osgEarthAnnotation/AnnotationNode>
     34#include <osgEarthAnnotation/FeatureNode>
    3435#include <osgEarthUtil/EarthManipulator>
    3536#include <osgEarthUtil/MouseCoordsTool>
     
    371372    }
    372373
     374    bool mouseToLatLong(int mouseX, int mouseY, double *latitude, double *longitude);
     375
    373376    bool getWorldCoords(const osgEarth::GeoPoint& mapPt, osg::Vec3d *world);
    374377
     
    423426    std::string getCanonicalPath(const std::string& url) const;
    424427
     428    void writeScene(const std::string& file);
     429
     430    void addRhumbBox(double latMin, double latMax, double longMin, double longMax);
     431
     432    void initBoxSelection(int x, int y);
     433    void updateBoxSelection(int x, int y);
     434    void clearBoxSelection();
     435
    425436private:
    426437    typedef std::tr1::unordered_map<ColorMapId, osg::ref_ptr<osg::TransferFunction1D> > ColorMapHashmap;
     
    429440    void setupCache();
    430441
     442    void initAnnotations();
     443
    431444    void initViewer();
    432445
     
    454467    bool _needsRedraw;
    455468    int _windowWidth, _windowHeight;
     469    double _mapScale;
    456470    float _bgColor[3];
    457471
     
    472486    osg::ref_ptr<osg::Group> _graticule;
    473487    osg::ref_ptr<osg::Group> _annotations;
     488    double _anchorLat, _anchorLong;
     489    osg::ref_ptr<osgEarth::Annotation::FeatureNode> _selectionBox;
    474490    osg::ref_ptr<osg::Group> _placeNodes;
    475491    std::set<osgEarth::Annotation::AnnotationNode *> _hovered;
  • geovis/trunk/RendererCmd.cpp

    r4636 r4645  
    2828#include <osgEarthSymbology/Style>
    2929#include <osgEarthSymbology/StyleSheet>
     30#include <osgEarthSymbology/IconSymbol>
    3031#include <osgEarthSymbology/LineSymbol>
    3132#include <osgEarthSymbology/RenderSymbol>
     
    762763    proc = GetOpFromObj(interp, nKeyOps, keyOps,
    763764                        CMDSPEC_ARG1, objc, objv, 0);
     765    if (proc == NULL) {
     766        return TCL_ERROR;
     767    }
     768    return (*proc) (clientData, interp, objc, objv);
     769}
     770
     771
     772static int
     773MapBoxClearOp(ClientData clientData, Tcl_Interp *interp, int objc,
     774              Tcl_Obj *const *objv)
     775{
     776    g_renderer->clearBoxSelection();
     777
     778    return TCL_OK;
     779}
     780
     781static int
     782MapBoxInitOp(ClientData clientData, Tcl_Interp *interp, int objc,
     783             Tcl_Obj *const *objv)
     784{
     785    int x, y;
     786    if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK ||
     787        Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) {
     788        return TCL_ERROR;
     789    }
     790    g_renderer->initBoxSelection(x, y);
     791    return TCL_OK;
     792}
     793
     794static int
     795MapBoxUpdateOp(ClientData clientData, Tcl_Interp *interp, int objc,
     796               Tcl_Obj *const *objv)
     797{
     798    int x, y;
     799    if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK ||
     800        Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) {
     801        return TCL_ERROR;
     802    }
     803    g_renderer->updateBoxSelection(x, y);
     804    return TCL_OK;
     805}
     806
     807static CmdSpec mapBoxOps[] = {
     808    {"clear",   1, MapBoxClearOp,   3, 3, ""},
     809    {"init",    1, MapBoxInitOp,    5, 5, "x y"},
     810    {"update",  1, MapBoxUpdateOp,  5, 5, "x y"},
     811};
     812static int nMapBoxOps = NumCmdSpecs(mapBoxOps);
     813
     814static int
     815MapBoxOp(ClientData clientData, Tcl_Interp *interp, int objc,
     816         Tcl_Obj *const *objv)
     817{
     818    Tcl_ObjCmdProc *proc;
     819
     820    proc = GetOpFromObj(interp, nMapBoxOps, mapBoxOps,
     821                        CMDSPEC_ARG2, objc, objv, 0);
    764822    if (proc == NULL) {
    765823        return TCL_ERROR;
     
    10211079        osgEarth::Symbology::PolygonSymbol *ls = style.getOrCreateSymbol<osgEarth::Symbology::PolygonSymbol>();
    10221080        ls->fill()->color() = osgEarth::Symbology::Color::White;
    1023 
     1081#if 0
     1082        osgEarth::Symbology::AltitudeSymbol *alt = style.getOrCreateSymbol<osgEarth::Symbology::AltitudeSymbol>();
     1083        alt->clamping() = osgEarth::Symbology::AltitudeSymbol::CLAMP_TO_TERRAIN;
     1084        alt->technique() = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_DRAPE;
     1085        //alt->technique() = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_GPU;
     1086#endif
    10241087        osgEarth::Symbology::RenderSymbol* rs = style.getOrCreateSymbol<osgEarth::Symbology::RenderSymbol>();
    10251088        rs->depthOffset()->enabled() = true;
     
    13301393    // Get lat/long
    13311394    double latitude, longitude;
    1332     const osgEarth::SpatialReference *outSRS =
    1333         g_renderer->getMapSRS()->getGeographicSRS();
    1334     osgEarth::GeoPoint mapPoint;
    1335     if (g_renderer->mapMouseCoords(x, y, mapPoint)) {
    1336         mapPoint = mapPoint.transform(outSRS);
    1337         longitude = mapPoint.x();
    1338         latitude = mapPoint.y();
    1339     } else {
     1395    if (!g_renderer->mouseToLatLong(x, y, &latitude, &longitude)) {
    13401396        USER_ERROR("Can't add pin here");
    13411397        return TCL_OK;
     
    16661722
    16671723static CmdSpec mapOps[] = {
     1724    {"box",      1, MapBoxOp,             3, 0, "op ?params..."},
    16681725    {"coords",   1, MapCoordsOp,          4, 6, "token coords ?srs? ?verticalDatum?"},
    16691726    {"grid",     1, MapGraticuleOp,       3, 4, "bool ?type?"},
Note: See TracChangeset for help on using the changeset viewer.