コード例 #1
0
ファイル: CropFilter.cpp プロジェクト: aarnchng/osggis
bool
getIsectPoint( const GeoPoint& p1, const GeoPoint& p2, const GeoPoint& p3, const GeoPoint& p4, GeoPoint& out )
{
    double denom = (p4.y()-p3.y())*(p2.x()-p1.x()) - (p4.x()-p3.x())*(p2.y()-p1.y());
    if ( denom == 0.0 )
    {
        out = GeoPoint::invalid(); // parallel lines
        return false;
    }

    double ua_num = (p4.x()-p3.x())*(p1.y()-p3.y()) - (p4.y()-p3.y())*(p1.x()-p3.x());
    double ub_num = (p2.x()-p1.x())*(p1.y()-p3.y()) - (p2.y()-p1.y())*(p1.x()-p3.x());

    double ua = ua_num/denom;
    double ub = ub_num/denom;

    if ( ua < 0.0 || ua > 1.0 ) // || ub < 0.0 || ub > 1.0 )
    {
        out = GeoPoint::invalid(); // isect point is on line, but not on line segment
        return false;
    }

    double x = p1.x() + ua*(p2.x()-p1.x());
    double y = p1.y() + ua*(p2.y()-p1.y());
    double z = p1.getDim() > 2? p1.z() + ua*(p2.z()-p1.z()) : 0.0; //right?
    out = GeoPoint( x, y, z, p1.getSRS() );
    return true;
}
コード例 #2
0
static void applyBlast(GeoPoint& center, double radius, double offset, const TileKey& key, osg::HeightField* heightField)
{
    //Get the extents of the tile
    double xmin, ymin, xmax, ymax;
    key.getExtent().getBounds(xmin, ymin, xmax, ymax);

    int tileSize = heightField->getNumColumns();

    // Iterate over the output heightfield and sample the data that was read into it.
    double dx = (xmax - xmin) / (tileSize-1);
    double dy = (ymax - ymin) / (tileSize-1);     

    const SpatialReference* srs = SpatialReference::create("wgs84");

    for (int c = 0; c < tileSize; ++c)
    {
        double geoX = xmin + (dx * (double)c);
        for (int r = 0; r < tileSize; ++r)
        {
            double geoY = ymin + (dy * (double)r);

            GeoPoint geo(srs, geoX, geoY, center.z(), ALTMODE_ABSOLUTE);

            double distance = geo.distanceTo( center );
            double ratio = distance / radius;
            if (ratio <= 1.0)
            {
                double weight = 1.0 - osg::clampBetween(ratio, 0.0, 1.0);
                if (weight > 0)
                {
                    float h = center.z() + offset * weight;
                    heightField->setHeight(c, r, h);
                }
            }
            
            /*


            if ( boundary->contains2D(geo.x(), geo.y()) )
            {
                float h = heightField->getHeight( c, r );
                if (h == NO_DATA_VALUE)
                {
                    //h = deformation._offset;
                }
                else
                {
                    //h += deformation._offset;                    
                    h = deformation._offset;
                }
                heightField->setHeight(c, r, h);
            } 
            */
        }
    }
}
コード例 #3
0
/* method: z of class  GeoPoint */
static int tolua_Lua_ScriptEngine_tolua_GeoPoint_z00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
 tolua_Error tolua_err;
 if (
 !tolua_isusertype(tolua_S,1,"GeoPoint",0,&tolua_err) ||
 !tolua_isnoobj(tolua_S,2,&tolua_err)
 )
 goto tolua_lerror;
 else
#endif
 {
  GeoPoint* self = (GeoPoint*)  tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
 if (!self) tolua_error(tolua_S,"invalid 'self' in function 'z'",NULL);
#endif
 {
  double tolua_ret = (double)  self->z();
 tolua_pushnumber(tolua_S,(double)tolua_ret);
 }
 }
 return 1;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'z'.",&tolua_err);
 return 0;
#endif
}
コード例 #4
0
ファイル: ElevationLOD.cpp プロジェクト: JohnDr/osgearth
void ElevationLOD::traverse( osg::NodeVisitor& nv)
{
    if (nv.getVisitorType() ==  osg::NodeVisitor::CULL_VISITOR)
    {
        osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>( &nv );
        osg::Vec3d eye, center, up;        
        eye = cv->getViewPoint();

        float height = eye.z();
        if (_srs)
        {
            GeoPoint mapPoint;
            mapPoint.fromWorld( _srs, eye );        
            height = mapPoint.z();
        }

        //OE_NOTICE << "Height " << height << std::endl;

        if (height >= _minElevation && height <= _maxElevation)
        {
            osg::Group::traverse( nv );
        }
        else
        {
            //OE_NOTICE << "Elevation " << height << " outside of range " << _minElevation << " to " << _maxElevation << std::endl;
        }
    }
    else
    {
        osg::Group::traverse( nv );
    }
}
コード例 #5
0
ファイル: ElevationLOD.cpp プロジェクト: 2php/osgearth
void ElevationLOD::traverse( osg::NodeVisitor& nv)
{
    if (nv.getVisitorType()   == osg::NodeVisitor::CULL_VISITOR &&
        nv.getTraversalMode() == osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN )
    {
        bool rangeOK     = true;
        bool altitudeOK  = true;

        // first test the range:
        if ( _minRange.isSet() || _maxRange.isSet() )
        {
            float range = nv.getDistanceToViewPoint( getBound().center(), true );
            rangeOK =
                (!_minRange.isSet() || (range >= *_minRange)) &&
                (!_maxRange.isSet() || (range <= *_maxRange));
        }

        if ( rangeOK )
        {
            if ( _minElevation.isSet() || _maxElevation.isSet() )
            {
                double alt;

                // first see if we have a precalculated elevation:
                osgUtil::CullVisitor* cv = Culling::asCullVisitor(nv);

                osg::Vec3d eye = cv->getViewPoint();

                if ( _srs && !_srs->isProjected() )
                {
                    GeoPoint mapPoint;
                    mapPoint.fromWorld( _srs.get(), eye );
                    alt = mapPoint.z();
                }
                else
                {
                    alt = eye.z();
                }

                // account for the LOD scale
                alt *= cv->getLODScale();

                altitudeOK =
                    (!_minElevation.isSet() || (alt >= *_minElevation)) &&
                    (!_maxElevation.isSet() || (alt <= *_maxElevation));
            }

            if ( altitudeOK )
            {
                std::for_each(_children.begin(),_children.end(),osg::NodeAcceptOp(nv));
            }
        }
    }
    else
    {
        osg::Group::traverse( nv );
    }
}
コード例 #6
0
bool
AnnotationNode::makeAbsolute( GeoPoint& mapPoint, osg::Node* patch ) const
{
    // in terrain-clamping mode, force it to HAT=0:
    if ( _altitude.valid() && (
        _altitude->clamping() == AltitudeSymbol::CLAMP_TO_TERRAIN || 
        _altitude->clamping() == AltitudeSymbol::CLAMP_RELATIVE_TO_TERRAIN) )
    {
        mapPoint.altitudeMode() = ALTMODE_RELATIVE;
        //If we're clamping to the terrain
        if (_altitude->clamping() == AltitudeSymbol::CLAMP_TO_TERRAIN)
        {
            mapPoint.z() = 0.0;
        }
    }

    // if the point's already absolute and we're not clamping it, nop.
    if ( mapPoint.altitudeMode() == ALTMODE_ABSOLUTE )
    {
        return true;
    }

    // calculate the absolute Z of the map point.
    if ( getMapNode() )
    {
        // find the terrain height at the map point:
        double hamsl;
        if (getMapNode()->getTerrain()->getHeight(patch, mapPoint.getSRS(), mapPoint.x(), mapPoint.y(), &hamsl, 0L))
        {
            // apply any scale/offset in the symbology:
            if ( _altitude.valid() )
            {
                if ( _altitude->verticalScale().isSet() )
                    hamsl *= _altitude->verticalScale()->eval();
                if ( _altitude->verticalOffset().isSet() )
                    hamsl += _altitude->verticalOffset()->eval();
            }
            mapPoint.z() += hamsl;
        }
        mapPoint.altitudeMode() = ALTMODE_ABSOLUTE;
        return true;
    }

    return false;
}
コード例 #7
0
ファイル: TerrainProfileGraph.cpp プロジェクト: 2php/osgearth
void TerrainProfileGraph::mouseReleaseEvent(QMouseEvent* e)
{
  if (_selecting)
  {
    double selectEnd = mapToScene(e->pos()).x();

    double zoomStart = osg::minimum(_selectStart, selectEnd);
    double zoomEnd = osg::maximum(_selectStart, selectEnd);

    double startDistanceFactor = ((zoomStart - _graphField.x()) / (double)_graphField.width());
    double endDistanceFactor = ((zoomEnd - _graphField.x()) / (double)_graphField.width());

    osg::Vec3d worldStart, worldEnd;
    _calculator->getStart(ALTMODE_ABSOLUTE).toWorld(worldStart);
    _calculator->getEnd(ALTMODE_ABSOLUTE).toWorld(worldEnd);

    double newStartWorldX = (worldEnd.x() - worldStart.x()) * startDistanceFactor + worldStart.x();
    double newStartWorldY = (worldEnd.y() - worldStart.y()) * startDistanceFactor + worldStart.y();
    double newStartWorldZ = (worldEnd.z() - worldStart.z()) * startDistanceFactor + worldStart.z();

    GeoPoint newStart;
    newStart.fromWorld(_calculator->getStart().getSRS(), osg::Vec3d(newStartWorldX, newStartWorldY, newStartWorldZ));
    newStart.z() = 0.0;

    double newEndWorldX = (worldEnd.x() - worldStart.x()) * endDistanceFactor + worldStart.x();
    double newEndWorldY = (worldEnd.y() - worldStart.y()) * endDistanceFactor + worldStart.y();
    double newEndtWorldZ = (worldEnd.z() - worldStart.z()) * endDistanceFactor + worldStart.z();

    GeoPoint newEnd;
    newEnd.fromWorld(_calculator->getStart().getSRS(), osg::Vec3d(newEndWorldX, newEndWorldY, newEndtWorldZ));
    newEnd.z() = 0.0;

    if (osg::absolute(newEnd.x() - newStart.x()) > 0.001 || osg::absolute(newEnd.y() - newStart.y()) > 0.001)
    {
      _calculator->setStartEnd(newStart, newEnd);
    }
    else
    {
      _selecting = false;
      drawHoverCursor(mapToScene(e->pos()));
    }
  }

  _selecting = false;
}
コード例 #8
0
ファイル: MouseCoordsTool.cpp プロジェクト: JohnDr/osgearth
void
MouseCoordsLabelCallback::set( const GeoPoint& mapCoords, osg::View* view, MapNode* mapNode )
{
    if ( _label.valid() )
    {
        _label->setText( Stringify()
            <<  _formatter->format( mapCoords )
            << ", " << mapCoords.z() );
    }
}
コード例 #9
0
ファイル: GeoPoint.cpp プロジェクト: aarnchng/osggis
bool
GeoPoint::operator == ( const GeoPoint& rhs ) const
{
    return
        isValid() && rhs.isValid() &&
        SpatialReference::equivalent( getSRS(), rhs.getSRS() ) &&
        getDim() == rhs.getDim() &&
        x() == rhs.x() &&
        (getDim() < 2 || y() == rhs.y()) &&
        (getDim() < 3 || z() == rhs.z());
}
コード例 #10
0
    void update( float x, float y, osgViewer::View* view )
    {
        bool yes = false;

        // look under the mouse:
        osg::Vec3d world;
        if ( _terrain->getWorldCoordsUnderMouse(view, x, y, world) )
        {
            // convert to map coords:
            GeoPoint mapPoint;
            mapPoint.fromWorld( _terrain->getSRS(), world );

            // do an elevation query:
            double query_resolution = 0.1; // 1/10th of a degree
            double out_hamsl        = 0.0;
            double out_resolution   = 0.0;

            bool ok = _query.getElevation( 
                mapPoint,
                out_hamsl,
                query_resolution, 
                &out_resolution );

            if ( ok )
            {
                // convert to geodetic to get the HAE:
                mapPoint.z() = out_hamsl;
                GeoPoint mapPointGeodetic( s_mapNode->getMapSRS()->getGeodeticSRS(), mapPoint );

                static LatLongFormatter s_f;

                s_posLabel->setText( Stringify()
                    << std::fixed << std::setprecision(2) 
                    << s_f.format(mapPointGeodetic.y())
                    << ", " 
                    << s_f.format(mapPointGeodetic.x()) );

                s_mslLabel->setText( Stringify() << out_hamsl );
                s_haeLabel->setText( Stringify() << mapPointGeodetic.z() );
                s_resLabel->setText( Stringify() << out_resolution );
                yes = true;
            }
        }

        if (!yes)
        {
            s_posLabel->setText( "-" );
            s_mslLabel->setText( "-" );
            s_haeLabel->setText( "-" );
            s_resLabel->setText( "-" );
        }
    }
コード例 #11
0
ファイル: OrthoNode.cpp プロジェクト: dlsyaim/osgEarthX
bool
OrthoNode::setPosition( const GeoPoint& position )
{
    MapNode* mapNode = getMapNode();
    if ( mapNode )
    {
        // first transform the point to the map's SRS:
        const SpatialReference* mapSRS = mapNode->getMapSRS();
		//$$$注释
        //GeoPoint mapPos = mapSRS ? position.transform(mapSRS) : position;
        //if ( !mapPos.isValid() )
        //    return false;

        //_mapPosition = mapPos;

		//$$$修改
		if ( mapSRS && position.isValid() )//position原来SRS信息不为空
		{
			position.transform( mapSRS );
			_mapPosition = position;
		}
		else if ( mapSRS )
		{
			_mapPosition = GeoPoint( mapSRS, position.x(), position.y(), position.z() );//position原来SRS信息为空
		}
		else
		{
			_mapPosition = position;
		}

    }
    else
    {
        _mapPosition = position;
    }

    // make sure the node is set up for auto-z-update if necessary:
    configureForAltitudeMode( _mapPosition.altitudeMode() );

    // and update the node.
    if ( !updateTransforms(_mapPosition) )
        return false;

    return true;
}
コード例 #12
0
ファイル: Draggers.cpp プロジェクト: chuckshaw/osgearth
void Dragger::updateTransform(osg::Node* patch)
{
    osg::Matrixd matrix;
    GeoPoint mapPoint;
    _mapNode->getMap()->toMapPoint( _position, mapPoint );
    //Get the height
    if (_position.altitudeMode() == ALTMODE_RELATIVE)
    {
        double hamsl;
        if (_mapNode->getTerrain()->getHeight(mapPoint.x(), mapPoint.y(), &hamsl, 0L, patch))
        {
            mapPoint.z() += hamsl;
        }
        mapPoint.altitudeMode() = ALTMODE_ABSOLUTE;
    }            
    mapPoint.createLocalToWorld( matrix );
    setMatrix( matrix );
}
コード例 #13
0
        bool visitPoint( GeoPoint& p )
        {
            bool ok = true;

            // pull it out of the source reference frame:
            p.set( p * src_rf );

            // reproject it:
            if ( handle )
                ok = OCTTransform( handle, 1, &p.x(), &p.y(), &p.z() ) != 0;

            // push it into the new reference frame:
            p.set( p * to_srs->getReferenceFrame() );

            p = p.getDim() == 2? GeoPoint( p.x(), p.y(), to_srs ) : GeoPoint( p.x(), p.y(), p.z(), to_srs );

            return ok;
        }
コード例 #14
0
void LOSCreationDialog::centerMapOnNode(osg::Node* node)
{
  if (node && _map.valid() && _manager.valid() && _views)
  {
    AnnotationNode* annoNode = dynamic_cast<AnnotationNode*>(node);
    if (annoNode && annoNode->getAnnotationData() && annoNode->getAnnotationData()->getViewpoint())
    {
      _manager->doAction(this, new SetViewpointAction(osgEarth::Viewpoint(*annoNode->getAnnotationData()->getViewpoint()), *_views));
    }
    else
    {
      osg::Vec3d center = node->getBound().center();

      GeoPoint output;
      output.fromWorld( _map->getSRS(), center );
      //_map->worldPointToMapPoint(center, output);

      _manager->doAction(this, new SetViewpointAction(osgEarth::Viewpoint(
          "center", output.x(), output.y(), output.z(), 0.0, -90.0, 1e5), *_views));
    }
  }
}
コード例 #15
0
ファイル: osgearth_minimap.cpp プロジェクト: 2php/osgearth
int
main(int argc, char** argv)
{
    osg::ArgumentParser arguments(&argc,argv);
    if ( arguments.read("--stencil") )
        osg::DisplaySettings::instance()->setMinimumNumStencilBits( 8 );

    //Setup a CompositeViewer
    osgViewer::CompositeViewer viewer(arguments);

    //Setup our main view that will show the loaded earth file.
    osgViewer::View* mainView = new osgViewer::View();
    mainView->getCamera()->setNearFarRatio(0.00002);
    mainView->setCameraManipulator( new EarthManipulator() );      
    mainView->setUpViewInWindow( 50, 50, 800, 800 );
    viewer.addView( mainView );
    
    //Setup a MiniMap View that will be embedded in the main view
    int miniMapWidth = 400;
    int miniMapHeight = 200;
    osgViewer::View* miniMapView = new osgViewer::View();
    miniMapView->getCamera()->setNearFarRatio(0.00002);
    miniMapView->getCamera()->setViewport( 0, 0, miniMapWidth, miniMapHeight);    
    miniMapView->setCameraManipulator( new EarthManipulator() );    
    miniMapView->getCamera()->setClearColor( osg::Vec4(0,0,0,0));
    miniMapView->getCamera()->setProjectionResizePolicy( osg::Camera::FIXED );
    miniMapView->getCamera()->setProjectionMatrixAsPerspective(30.0, double(miniMapWidth) / double(miniMapHeight), 1.0, 1000.0);
    //Share a graphics context with the main view
    miniMapView->getCamera()->setGraphicsContext( mainView->getCamera()->getGraphicsContext());        
    viewer.addView( miniMapView );
    
    // load an earth file, and support all or our example command-line options
    // and earth file <external> tags    
    osg::Node* node = MapNodeHelper().load( arguments, mainView );
    if ( node )
    {
        MapNode* mapNode = MapNode::findMapNode(node);
    
        //Set the main view's scene data to the loaded earth file
        mainView->setSceneData( node );

        //Setup a group to hold the contents of the MiniMap
        osg::Group* miniMapGroup = new osg::Group;

        MapNode* miniMapNode = makeMiniMapNode();        
        miniMapGroup->addChild( miniMapNode );
       
        //Get the main MapNode so we can do tranformations between it and our minimap
        MapNode* mainMapNode = MapNode::findMapNode( node );
                               
        //Set the scene data for the minimap
        miniMapView->setSceneData( miniMapGroup );        

        //Add a marker we can move around with the main view's eye point
        Style markerStyle;
        markerStyle.getOrCreate<IconSymbol>()->url()->setLiteral( "../data/placemark32.png" );
        PlaceNode* eyeMarker = new PlaceNode(miniMapNode, GeoPoint(miniMapNode->getMapSRS(), 0, 0), "", markerStyle);
        miniMapGroup->addChild( eyeMarker );        
        miniMapGroup->getOrCreateStateSet()->setRenderBinDetails(100, "RenderBin");

        osg::Node* bounds = 0;
  
        while (!viewer.done())
        {
            //Reset the viewport so that the camera's viewport is static and doesn't resize with window resizes
            miniMapView->getCamera()->setViewport( 0, 0, miniMapWidth, miniMapHeight);    

            //Get the eye point of the main view
            osg::Vec3d eye, up, center;
            mainView->getCamera()->getViewMatrixAsLookAt( eye, center, up );

            //Turn the eye into a geopoint and transform it to the minimap's SRS
            GeoPoint eyeGeo;
            eyeGeo.fromWorld( mainMapNode->getMapSRS(), eye );
            eyeGeo.transform( miniMapNode->getMapSRS());

            //We want the marker to be positioned at elevation 0, so zero out any elevation in the eye point
            eyeGeo.z() = 0;           
 
            //Set the position of the marker
            eyeMarker->setPosition( eyeGeo );

            if (bounds)
            {
                miniMapGroup->removeChild( bounds );
            }
            GeoExtent extent = getExtent( mainView );
            bounds = drawBounds( miniMapNode, extent );
            miniMapGroup->addChild( bounds );

            viewer.frame();
        }        
    }
    else
    {
        OE_NOTICE 
            << "\nUsage: " << argv[0] << " file.earth" << std::endl
            << MapNodeHelper().usage() << std::endl;
    }
    return 0;
}
コード例 #16
0
    void update( float x, float y, osgViewer::View* view )
    {
        bool yes = false;

        // look under the mouse:
        osg::Vec3d world;
        osgUtil::LineSegmentIntersector::Intersections hits;
        if ( view->computeIntersections(x, y, hits) )
        {
            world = hits.begin()->getWorldIntersectPoint();

            // convert to map coords:
            GeoPoint mapPoint;
            mapPoint.fromWorld( _terrain->getSRS(), world );
            mapPoint.z() = 0;

            // do an elevation query:
            double query_resolution = 0; // max.
            double out_hamsl        = 0.0;
            double out_resolution   = 0.0;

            bool ok = _query.getElevation( 
                mapPoint,
                out_hamsl,
                query_resolution, 
                &out_resolution );
            mapPoint.z() = out_hamsl;
            _mapPoint = mapPoint;

            

            GeometryFactory factory(SpatialReference::create("wgs84"));
            Geometry* geom = 0;
            if (_tool == TOOL_RECTANGLE)
            {
                geom = factory.createRectangle(mapPoint.vec3d(), _radius,_radius);
            }
            else if (_tool == TOOL_CIRCLE || _tool == TOOL_BLAST)
            {
                geom = factory.createCircle(mapPoint.vec3d(), _radius);
            }

            Feature* feature = new Feature(geom, SpatialReference::create("wgs84"));

            if (_featureNode.valid())
            {
                _root->removeChild( _featureNode );
                _featureNode = 0;
            }

            Style style;
            style.getOrCreateSymbol<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN;
            style.getOrCreateSymbol<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_DRAPE;
            if (_tool != TOOL_BLAST)
            {
                style.getOrCreateSymbol<PolygonSymbol>()->fill()->color() = Color(Color::Cyan, 0.5);
            }
            else
            {
                style.getOrCreateSymbol<PolygonSymbol>()->fill()->color() = Color(Color::Red, 0.5);
            }

            _featureNode = new FeatureNode( s_mapNode,
                feature,
                style);
            _root->addChild( _featureNode );
        }
    }
コード例 #17
0
bool ElevationDragger::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
    bool ret = true;
    if (ea.getHandled()) {
        ret = false;
    }
    else
    {
        bool handled = false;
        if (_elevationMode)
        {
            if (ea.getEventType() == osgGA::GUIEventAdapter::PUSH)
            {
                ret = osgEarth::Dragger::handle(ea, aa);
                if (ret) 
                {
                    bool pressedAlt = ((ea.getModKeyMask() & _modKeyMask) > 0);
                    if (pressedAlt)
                    {
                        _pointer.reset();

                        // set movement range
                        // TODO: values 0.0 and 300000.0 are rather experimental
                        GeoPoint posStart(_position.getSRS(), _position.x(), _position.y(), 0.0, ALTMODE_ABSOLUTE);
                        osg::Vec3d posStartXYZ;
                        posStart.toWorld(posStartXYZ);

                        GeoPoint posEnd(_position.getSRS(), _position.x(), _position.y(), 300000.0, ALTMODE_ABSOLUTE);
                        osg::Vec3d posEndXYZ;
                        posEnd.toWorld(posEndXYZ);

                        _projector->setLine(posStartXYZ, posEndXYZ);

                        // set camera
                        osgUtil::LineSegmentIntersector::Intersections intersections;
                        osg::Node::NodeMask intersectionMask = 0xffffffff;
                        osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
                        if (view->computeIntersections(ea.getX(),ea.getY(),intersections, intersectionMask))
                        {
                            for (osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin(); hitr != intersections.end(); ++hitr)
                            {
                                _pointer.addIntersection(hitr->nodePath, hitr->getLocalIntersectPoint());
                            }
                            for (osg::NodePath::iterator itr = _pointer._hitList.front().first.begin(); itr != _pointer._hitList.front().first.end(); ++itr)
                            {
                                ElevationDragger* dragger = dynamic_cast<ElevationDragger*>(*itr);
                                if (dragger==this)
                                {
                                    osg::Camera *rootCamera = view->getCamera();
                                    osg::NodePath nodePath = _pointer._hitList.front().first;
                                    osg::NodePath::reverse_iterator ritr;
                                    for (ritr = nodePath.rbegin(); ritr != nodePath.rend(); ++ritr)
                                    {
                                        osg::Camera* camera = dynamic_cast<osg::Camera*>(*ritr);
                                        if (camera && (camera->getReferenceFrame()!=osg::Transform::RELATIVE_RF || camera->getParents().empty()))
                                        {
                                             rootCamera = camera;
                                             break;
                                        }
                                    }
                                    _pointer.setCamera(rootCamera);
                                    _pointer.setMousePosition(ea.getX(), ea.getY());
                                }
                            }
                        }

                        _elevationDragging = true;
                    }
                }
                handled = true;
            }
            else if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE)
            {
                _elevationDragging = false;
            }
            else if (ea.getEventType() == osgGA::GUIEventAdapter::DRAG) 
            {
                if (_elevationDragging) 
                {
                    _pointer._hitIter = _pointer._hitList.begin();
                    _pointer.setMousePosition(ea.getX(), ea.getY());

                    if (_projector->project(_pointer, _startProjectedPoint)) 
                    {
                        //Get the absolute mapPoint that they've drug it to.
                        GeoPoint projectedPos;
                        projectedPos.fromWorld(_position.getSRS(), _startProjectedPoint);

                        // make sure point is not dragged down below
                        // TODO: think of a better solution / HeightAboveTerrain performance issues?
                        if (projectedPos.z() > 0)
                        {
                            //If the current position is relative, we need to convert the absolute world point to relative.
                            //If the point is absolute then just emit the absolute point.
                            if (_position.altitudeMode() == ALTMODE_RELATIVE)
                            {
                                projectedPos.alt() = _position.alt();
                                projectedPos.altitudeMode() = ALTMODE_RELATIVE;
                            }

                            setPosition( projectedPos );
                            aa.requestRedraw();
                        }
                    }

                    handled = true;
                }
            }
        }
        
        if (!handled) {
            ret = osgEarth::Dragger::handle(ea, aa);
        }
    }
    return ret;
}
コード例 #18
0
    void update( float x, float y, osgViewer::View* view )
    {
        bool yes = false;

        // look under the mouse:
        osg::Vec3d world;
        osgUtil::LineSegmentIntersector::Intersections hits;
        if ( view->computeIntersections(x, y, hits) )
        {
            world = hits.begin()->getWorldIntersectPoint();

            // convert to map coords:
            GeoPoint mapPoint;
            mapPoint.fromWorld( _terrain->getSRS(), world );

            // do an elevation query:
            double query_resolution = 0; // 1/10th of a degree
            double out_hamsl        = 0.0;
            double out_resolution   = 0.0;

            bool ok = _query.getElevation( 
                mapPoint,
                out_hamsl,
                query_resolution, 
                &out_resolution );

            if ( ok )
            {
                // convert to geodetic to get the HAE:
                mapPoint.z() = out_hamsl;
                GeoPoint mapPointGeodetic( s_mapNode->getMapSRS()->getGeodeticSRS(), mapPoint );

                static LatLongFormatter s_f;

                s_posLabel->setText( Stringify()
                    << std::fixed << std::setprecision(2) 
                    << s_f.format(mapPointGeodetic.y())
                    << ", " 
                    << s_f.format(mapPointGeodetic.x()) );

                s_mslLabel->setText( Stringify() << out_hamsl );
                s_haeLabel->setText( Stringify() << mapPointGeodetic.z() );
                s_resLabel->setText( Stringify() << out_resolution );

                yes = true;
            }

            // finally, get a normal ISECT HAE point.
            GeoPoint isectPoint;
            isectPoint.fromWorld( _terrain->getSRS()->getGeodeticSRS(), world );
            s_mapLabel->setText( Stringify() << isectPoint.alt() );
        }

        if (!yes)
        {
            s_posLabel->setText( "-" );
            s_mslLabel->setText( "-" );
            s_haeLabel->setText( "-" );
            s_resLabel->setText( "-" );
        }
    }
コード例 #19
0
void
AutoClipPlaneCullCallback::operator()( osg::Node* node, osg::NodeVisitor* nv )
{
    if ( _active )
    {
        osgUtil::CullVisitor* cv = Culling::asCullVisitor(nv);
        if ( cv )
        {
            osgEarth::Map* map = _mapNode.valid() ? _mapNode->getMap() : 0;
            osg::Camera* cam = cv->getCurrentCamera();
            osg::ref_ptr<osg::CullSettings::ClampProjectionMatrixCallback>& clamper = _clampers.get(cam);
            if ( !clamper.valid() )
            {
                clamper = new CustomProjClamper();
                cam->setClampProjectionMatrixCallback( clamper.get() );
                OE_INFO << LC << "Installed custom projeciton matrix clamper" << std::endl;
            }
            else
            {
                CustomProjClamper* c = static_cast<CustomProjClamper*>(clamper.get());

                osg::Vec3d eye, center, up;
                cam->getViewMatrixAsLookAt( eye, center, up );

                // clamp the far clipping plane to the approximate horizon distance
                if ( _autoFarPlaneClamping )
                {
                    double d = eye.length();
                    c->_maxFar = sqrt( d*d - _rp2 );
                }
                else
                {
                    c->_maxFar = DBL_MAX;
                }

                // get the height-above-ellipsoid. If we need to be more accurate, we can use 
                // ElevationQuery in the future..
                //osg::Vec3d loc;
                GeoPoint loc;
                if ( map )
                {
                    loc.fromWorld( map->getSRS(), eye );
                    //map->worldPointToMapPoint( eye, loc );
                }
                else
                {
                    static osg::EllipsoidModel em;
                    osg::Vec3d t;
                    em.convertXYZToLatLongHeight( eye.x(), eye.y(), eye.z(), loc.y(), loc.x(), loc.z() );
                }
                
                //double hae = loc.z();
                double hae = loc.z();
                if (_mapNode.valid())
                {
                    double height = 0.0;
                    _mapNode->getTerrain()->getHeight(loc.getSRS(), loc.x(), loc.y(), &height);
                    //OE_NOTICE << "got height " << height << std::endl;
                    hae -= height;
                    //OE_NOTICE << "HAE=" << hae <<  std::endl;
                }

                // ramp a new near/far ratio based on the HAE.
                c->_nearFarRatio = Utils::remap( hae, 0.0, _haeThreshold, _minNearFarRatio, _maxNearFarRatio );
            }

#if 0
            {
                double n, f, a, v;
                cv->getProjectionMatrix()->getPerspective(v, a, n, f);
                OE_INFO << std::setprecision(16) << "near = " << n << ", far = " << f << ", ratio = " << n/f << std::endl;
            }
#endif
        }
    }
    traverse( node, nv );
}
コード例 #20
0
void
GeodeticGraticule::cull(osgUtil::CullVisitor* cv)
{
    osg::Matrixd viewMatrix = *cv->getModelViewMatrix();

    osg::Vec3d vp = cv->getViewPoint();

    CameraData& cdata = getCameraData(cv->getCurrentCamera());

    // Only update if the view matrix has changed.
    if (viewMatrix != cdata._lastViewMatrix && _mapNode.valid())
    {
        GeoPoint eyeGeo;
        eyeGeo.fromWorld(_mapNode->getMapSRS(), vp);
        cdata._lon = eyeGeo.x();
        cdata._lat = eyeGeo.y();

        osg::Viewport* viewport = cv->getViewport();

        float centerX = viewport->x() + viewport->width() / 2.0;
        float centerY = viewport->y() + viewport->height() / 2.0;

        float offsetCenterX = centerX;
        float offsetCenterY = centerY;

        bool hitValid = false;

        // Try the center of the screen.
        osg::Vec3d focalPoint;
        if (_mapNode->getTerrain()->getWorldCoordsUnderMouse(cv->getCurrentCamera()->getView(), centerX, centerY, focalPoint))
        {
            hitValid = true;
        }

        if (hitValid)
        {
            GeoPoint focalGeo;
            focalGeo.fromWorld(_mapNode->getMapSRS(), focalPoint);
            cdata._lon = focalGeo.x();
            cdata._lat = focalGeo.y();
            // We only store the previous view matrix if we actually got a hit.  Otherwise we still need to update.
            cdata._lastViewMatrix = viewMatrix;
        }

        // Get the view extent.
        cdata._viewExtent = getViewExtent(cv);

        double targetResolution = (cdata._viewExtent.height() / 180.0) / options().gridLines().get();

        double resolution = _resolutions[0];
        for (unsigned int i = 0; i < _resolutions.size(); i++)
        {
            resolution = _resolutions[i];
            if (resolution <= targetResolution)
            {
                break;
            }
        }

        // Trippy
        //resolution = targetResolution;

        // Try to compute an approximate meters to pixel value at this view.
        double dist = osg::clampAbove(eyeGeo.z(), 1.0);
        double halfWidth;

        const osg::Matrix& proj = *cv->getProjectionMatrix();
        bool isOrtho = osg::equivalent(proj(3,3), 1.0);

        if (isOrtho)
        {
            double L, R, B, T, N, F;
            proj.getOrtho(L, R, B, T, N, F);
            halfWidth = 0.5*(R-L);
        }
        else // perspective
        {
            double fovy, aspectRatio, zNear, zFar;
            cv->getProjectionMatrix()->getPerspective(fovy, aspectRatio, zNear, zFar);
            halfWidth = osg::absolute(tan(osg::DegreesToRadians(fovy / 2.0)) * dist);
        }

        cdata._metersPerPixel = (2.0 * halfWidth) / (double)viewport->height();

        if (cdata._resolution != resolution)
        {
            cdata._resolution = (float)resolution;
            cdata._resolutionUniform->set(cdata._resolution);
        }

        OE_TEST << "EW=" << cdata._viewExtent.width() << ", ortho=" << isOrtho << ", hW=" << halfWidth << ", res=" << resolution << ", mPP=" << cdata._metersPerPixel << std::endl;
    }

    // traverse the label pool for this camera.
    cv->pushStateSet(cdata._labelStateset.get());

    for (std::vector< osg::ref_ptr< LabelNode > >::iterator i = cdata._labelPool.begin();
        i != cdata._labelPool.end();
        ++i)
    {
        i->get()->accept(*cv);
    }

    cv->popStateSet();
}
コード例 #21
0
bool
OGR_SpatialReference::transformInPlace( GeoPoint& input ) const
{
    if ( !handle || !input.isValid() ) {
        osgGIS::notify( osg::WARN ) << "Spatial reference or input point is invalid" << std::endl;
        return false;
    }

	OGR_SpatialReference* input_sr = (OGR_SpatialReference*)input.getSRS();
    if ( !input_sr ) {
        osgGIS::notify( osg::WARN ) << "SpatialReference: input point has no SRS" << std::endl;
        return false;
    }

    // first check whether the input point is geocentric - and if so, pre-convert it to geographic:
    if ( input_sr->isGeocentric() )
    {
        input.set( input * input_sr->getInverseReferenceFrame() );
        osg::Vec3d temp = input_sr->getEllipsoid().geocentricToLatLong( input );
        input = GeoPoint( temp, input_sr->getGeographicSRS() ); 
        input_sr = static_cast<OGR_SpatialReference*>( input.getSRS() );
    }

    osg::Vec3d input_vec = input;
    bool crs_equiv = false;
    bool mat_equiv = false;
    testEquivalence( input_sr, /*out*/crs_equiv, /*out*/mat_equiv );

    // pull it out of its source frame:
    if ( !mat_equiv )
    {
        input.set( input * input_sr->inv_ref_frame );
    }    

    bool result = false;

    if ( !crs_equiv )
    {
        OGR_SCOPE_LOCK();

        //TODO: some kind of per-thread cache

        void* xform_handle = OCTNewCoordinateTransformation( input_sr->handle, this->handle );
        if ( !xform_handle ) {
            osgGIS::notify( osg::WARN ) << "Spatial Reference: SRS xform not possible" << std::endl
                << "    From => " << input_sr->getWKT() << std::endl
                << "    To   => " << this->getWKT() << std::endl;
            return false;
        }

        //TODO: figure out why xforming GEOCS x=-180 to another GEOCS doesn't work
        if ( OCTTransform( xform_handle, 1, &input.x(), &input.y(), &input.z() ) )
        {
            result = true;
        }
        else
        {
            osgGIS::notify( osg::WARN ) << "Spatial Reference: Failed to xform a point from "
                << input_sr->getName() << " to " << this->getName()
                << std::endl;
        }

        OCTDestroyCoordinateTransformation( xform_handle );
    }
    else
    {
        result = true;
    }

    // put it into the new ref frame:
    if ( !mat_equiv )
    {
        input.set( input * ref_frame );
    }

    if ( result == true )
    {
        applyTo( input );
    }

    return result;
}
コード例 #22
0
ファイル: GraticuleNode.cpp プロジェクト: rhabacker/osgearth
void GraticuleNode::traverse(osg::NodeVisitor& nv)
{
    if (nv.getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
    {
        updateLabels();
    }
    else if (nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
    {
        osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(&nv);

        osg::Vec3d vp = cv->getViewPoint();

        osg::Matrixd viewMatrix = *cv->getModelViewMatrix();

        // Only update if the view matrix has changed.
        if (viewMatrix != _viewMatrix)
        {            
            GeoPoint eyeGeo;
            eyeGeo.fromWorld( _mapNode->getMapSRS(), vp );
            _lon = eyeGeo.x();
            _lat = eyeGeo.y();            

            osg::Viewport* viewport = cv->getViewport();

            float centerX = viewport->x() + viewport->width() / 2.0;
            float centerY = viewport->y() + viewport->height() / 2.0;

            float offsetCenterX = centerX;
            float offsetCenterY = centerY;

            bool hitValid = false;

            // Try the center of the screen.
            if(_mapNode->getTerrain()->getWorldCoordsUnderMouse(cv->getCurrentCamera()->getView(), centerX, centerY, _focalPoint))
            {
                hitValid = true;
            }

            if (hitValid)
            {
                GeoPoint focalGeo;
                focalGeo.fromWorld( _mapNode->getMapSRS(), _focalPoint );
                _lon = focalGeo.x();
                _lat = focalGeo.y();
                // We only store the previous view matrix if we actually got a hit.  Otherwise we still need to update.
                _viewMatrix = viewMatrix;
            }


            double targetResolution = (_viewExtent.height() / 180.0) / _options.gridLines().get();

            double resolution = _resolutions[0];
            for (unsigned int i = 0; i < _resolutions.size(); i++)
            {
                resolution = _resolutions[i];
                if (resolution <= targetResolution)
                {
                    break;
                }
            }

            // Trippy
            //resolution = targetResolution;

            _viewExtent = getViewExtent( cv );

            // Try to compute an approximate meters to pixel value at this view.
            double fovy, aspectRatio, zNear, zFar;
            cv->getProjectionMatrix()->getPerspective(fovy, aspectRatio, zNear, zFar);
            double dist = osg::clampAbove(eyeGeo.z(), 1.0);
            double halfWidth = osg::absolute( tan(osg::DegreesToRadians(fovy/2.0)) * dist );
            _metersPerPixel = (2.0 * halfWidth) / (double)viewport->height();

            if (_resolution != resolution)
            {
                setResolution(resolution);
            }
        }
    }
    osg::Group::traverse(nv);
}
コード例 #23
0
ファイル: Draggers.cpp プロジェクト: InterAtlas-ML/osgearth
bool Dragger::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
    if (ea.getHandled()) return false;

    osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
    if (!view) return false;
    if (!_mapNode.valid()) return false;

    if (ea.getEventType() == osgGA::GUIEventAdapter::PUSH)
    {
        Picker picker( view, this );
        Picker::Hits hits;

        if ( picker.pick( ea.getX(), ea.getY(), hits ) )
        {
            _dragging = true;

            //Check for and handle vertical dragging if necessary
            bool pressedAlt = _modKeyMask && (ea.getModKeyMask() & _modKeyMask) > 0;
            _elevationDragging = (_defaultMode == Dragger::DRAGMODE_VERTICAL && !pressedAlt) || (_defaultMode == Dragger::DRAGMODE_HORIZONTAL && pressedAlt);

            if (_elevationDragging)
            {
              _pointer.reset();

              // set movement range
              // TODO: values 0.0 and 300000.0 are rather experimental
              GeoPoint posStart(_position.getSRS(), _position.x(), _position.y(), 0.0, ALTMODE_ABSOLUTE);
              osg::Vec3d posStartXYZ;
              posStart.toWorld(posStartXYZ);

              GeoPoint posEnd(_position.getSRS(), _position.x(), _position.y(), 300000.0, ALTMODE_ABSOLUTE);
              osg::Vec3d posEndXYZ;
              posEnd.toWorld(posEndXYZ);

              _projector->setLine(posStartXYZ, posEndXYZ);

              // set camera
              osgUtil::LineSegmentIntersector::Intersections intersections;
              osg::Node::NodeMask intersectionMask = 0xffffffff;
              osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
              if (view->computeIntersections(ea.getX(),ea.getY(),intersections, intersectionMask))
              {
                  for (osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin(); hitr != intersections.end(); ++hitr)
                  {
                      _pointer.addIntersection(hitr->nodePath, hitr->getLocalIntersectPoint());
                  }

                  bool draggerFound = false;
                  for (osgManipulator::PointerInfo::IntersectionList::iterator piit = _pointer._hitList.begin(); piit != _pointer._hitList.end(); ++piit)
                  {
                      for (osg::NodePath::iterator itr = piit->first.begin(); itr != piit->first.end(); ++itr)
                      {
                          Dragger* dragger = dynamic_cast<Dragger*>(*itr);
                          if (dragger==this)
                          {
                            draggerFound = true;
                              osg::Camera *rootCamera = view->getCamera();
                              osg::NodePath nodePath = _pointer._hitList.front().first;
                              osg::NodePath::reverse_iterator ritr;
                              for (ritr = nodePath.rbegin(); ritr != nodePath.rend(); ++ritr)
                              {
                                  osg::Camera* camera = dynamic_cast<osg::Camera*>(*ritr);
                                  if (camera && (camera->getReferenceFrame()!=osg::Transform::RELATIVE_RF || camera->getParents().empty()))
                                  {
                                       rootCamera = camera;
                                       break;
                                  }
                              }
                              _pointer.setCamera(rootCamera);
                              _pointer.setMousePosition(ea.getX(), ea.getY());

                              break;
                          }
                      }

                      if (draggerFound)
                        break;
                  }
              }
            }

            aa.requestRedraw();
            return true;
        }
    }
    else if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE)
    {
        _elevationDragging = false;

        if ( _dragging )
        {
            _dragging = false;
            firePositionChanged();
        }

        aa.requestRedraw();
    }
    else if (ea.getEventType() == osgGA::GUIEventAdapter::DRAG)
    {
        if (_elevationDragging) 
        {
            _pointer._hitIter = _pointer._hitList.begin();
            _pointer.setMousePosition(ea.getX(), ea.getY());

            if (_projector->project(_pointer, _startProjectedPoint)) 
            {
                //Get the absolute mapPoint that they've drug it to.
                GeoPoint projectedPos;
                projectedPos.fromWorld(_position.getSRS(), _startProjectedPoint);

                // make sure point is not dragged down below
                // TODO: think of a better solution / HeightAboveTerrain performance issues?
                if (projectedPos.z() >= _verticalMinimum)
                {
                    //If the current position is relative, we need to convert the absolute world point to relative.
                    //If the point is absolute then just emit the absolute point.
                    if (_position.altitudeMode() == ALTMODE_RELATIVE)
                    {
                        projectedPos.transformZ(ALTMODE_RELATIVE, getMapNode()->getTerrain());
                    }

                    setPosition( projectedPos );
                    aa.requestRedraw();
                }
            }

            return true;
        }
        
        if (_dragging)
        {
            osg::Vec3d world;
            if ( getMapNode() && getMapNode()->getTerrain()->getWorldCoordsUnderMouse(view, ea.getX(), ea.getY(), world) )
            {
                //Get the absolute mapPoint that they've drug it to.
                GeoPoint mapPoint;
                mapPoint.fromWorld( getMapNode()->getMapSRS(), world );
                //_mapNode->getMap()->worldPointToMapPoint(world, mapPoint);

                //If the current position is relative, we need to convert the absolute world point to relative.
                //If the point is absolute then just emit the absolute point.
                if (_position.altitudeMode() == ALTMODE_RELATIVE)
                {
                    mapPoint.alt() = _position.alt();
                    mapPoint.altitudeMode() = ALTMODE_RELATIVE;
                }

                setPosition( mapPoint );
                aa.requestRedraw();
                return true;
            }
        }
    }   
    else if (ea.getEventType() == osgGA::GUIEventAdapter::MOVE)
    {
        Picker picker( view, this );
        Picker::Hits hits;

        if ( picker.pick( ea.getX(), ea.getY(), hits ) )
        {
            setHover( true );
        }
        else
        {
            setHover( false );
        }        
        aa.requestRedraw();
    }
    return false;
}
コード例 #24
0
    void update( float x, float y, osgViewer::View* view )
    {
        bool yes = false;

        // look under the mouse:
        osg::Vec3d world;
        osgUtil::LineSegmentIntersector::Intersections hits;
        if ( view->computeIntersections(x, y, hits) )
        {
            world = hits.begin()->getWorldIntersectPoint();

            // convert to map coords:
            GeoPoint mapPoint;
            mapPoint.fromWorld( _terrain->getSRS(), world );

            // do an elevation query:
            double query_resolution  = 0.0;  // max.
            double actual_resolution = 0.0;
            float elevation          = 0.0f;

            elevation = _query.getElevation( 
                mapPoint,
                query_resolution, 
                &actual_resolution );

            if ( elevation != NO_DATA_VALUE )
            {
                // convert to geodetic to get the HAE:
                mapPoint.z() = elevation;
                GeoPoint mapPointGeodetic( s_mapNode->getMapSRS()->getGeodeticSRS(), mapPoint );

                static LatLongFormatter s_f;

                s_posLabel->setText( Stringify()
                    << std::fixed << std::setprecision(2) 
                    << s_f.format(mapPointGeodetic.y(), true)
                    << ", " 
                    << s_f.format(mapPointGeodetic.x(), false) );

                if (s_mapNode->getMapSRS()->isGeographic())
                {
                    osg::ref_ptr<const SpatialReference> tm = s_mapNode->getMapSRS()->createUTMFromLonLat(mapPointGeodetic.x(), mapPointGeodetic.y());
                    actual_resolution = tm->transformUnits(Distance(actual_resolution, Units::DEGREES), tm.get(), mapPointGeodetic.y());
                }

                s_mslLabel->setText( Stringify() << elevation << " m" );
                s_haeLabel->setText( Stringify() << mapPointGeodetic.z() << " m" );
                s_resLabel->setText( Stringify() << actual_resolution << " m" );

                double egm96z = mapPoint.z();

                VerticalDatum::transform(
                    mapPointGeodetic.getSRS()->getVerticalDatum(),
                    VerticalDatum::get("egm96"),
                    mapPointGeodetic.y(),
                    mapPointGeodetic.x(),
                    egm96z);
                
                s_egm96Label->setText(Stringify() << egm96z << " m");

                yes = true;
            }

            // finally, get a normal ISECT HAE point.
            GeoPoint isectPoint;
            isectPoint.fromWorld( _terrain->getSRS()->getGeodeticSRS(), world );
            s_mapLabel->setText( Stringify() << isectPoint.alt() << " m");

            // and move the marker.
            s_marker->setPosition(mapPoint);
        }

        if (!yes)
        {
            s_posLabel->setText( "-" );
            s_mslLabel->setText( "-" );
            s_haeLabel->setText( "-" );
            s_resLabel->setText( "-" );
            s_egm96Label->setText("-");
        }
    }
コード例 #25
0
bool
ElevationQuery::getElevationImpl(const GeoPoint& point,
                                 float&          out_elevation,
                                 double          desiredResolution,
                                 double*         out_actualResolution)
{
    // assertion.
    if ( !point.isAbsolute() )
    {
        OE_WARN << LC << "Assertion failure; input must be absolute" << std::endl;
        return false;
    }

    osg::Timer_t begin = osg::Timer::instance()->tick();

    // first try the terrain patches.
    if ( _terrainModelLayers.size() > 0 )
    {
        osgUtil::IntersectionVisitor iv;

        if ( _ivrc.valid() )
            iv.setReadCallback(_ivrc.get());

        for(LayerVector::iterator i = _terrainModelLayers.begin(); i != _terrainModelLayers.end(); ++i)
        {
            // find the scene graph for this layer:
            Layer* layer = i->get();
            osg::Node* node = layer->getNode();
            if ( node )
            {
                // configure for intersection:
                osg::Vec3d surface;
                point.toWorld( surface );

                // trivial bounds check:
                if ( node->getBound().contains(surface) )
                {
                    osg::Vec3d nvector;
                    point.createWorldUpVector(nvector);

                    osg::Vec3d start( surface + nvector*5e5 );
                    osg::Vec3d end  ( surface - nvector*5e5 );

                    // first time through, set up the intersector on demand
                    if ( !_lsi.valid() )
                    {
                        _lsi = new osgUtil::LineSegmentIntersector(start, end);
                        _lsi->setIntersectionLimit( _lsi->LIMIT_NEAREST );
                    }
                    else
                    {
                        _lsi->reset();
                        _lsi->setStart( start );
                        _lsi->setEnd  ( end );
                    }

                    // try it.
                    iv.setIntersector( _lsi.get() );
                    node->accept( iv );

                    // check for a result!!
                    if ( _lsi->containsIntersections() )
                    {
                        osg::Vec3d isect = _lsi->getIntersections().begin()->getWorldIntersectPoint();

                        // transform back to input SRS:
                        GeoPoint output;
                        output.fromWorld( point.getSRS(), isect );
                        out_elevation = (float)output.z();
                        if ( out_actualResolution )
                            *out_actualResolution = 0.0;

                        return true;
                    }
                }
                else
                {
                    //OE_INFO << LC << "Trivial rejection (bounds check)" << std::endl;
                }
            }
        }
    } 

    if (_elevationLayers.empty())
    {
        // this means there are no heightfields.
        out_elevation = NO_DATA_VALUE;
        return true;
    }

    // secure map pointer:
    osg::ref_ptr<const Map> map;
    if (!_map.lock(map))
    {
        return false;
    }    

    // tile size (resolution of elevation tiles)
    unsigned tileSize = 257; // yes?

    // default LOD:
    unsigned lod = 23u;

    // attempt to map the requested resolution to an LOD:
    if (desiredResolution > 0.0)
    {
        int level = map->getProfile()->getLevelOfDetailForHorizResolution(desiredResolution, tileSize);
        if ( level > 0 )
            lod = level;
    }

    // do we need a new ElevationEnvelope?
    if (!_envelope.valid() ||
        !point.getSRS()->isHorizEquivalentTo(_envelope->getSRS()) ||
        lod != _envelope->getLOD())
    {        
        _envelope = map->getElevationPool()->createEnvelope(point.getSRS(), lod);
    }

    // sample the elevation, and if requested, the resolution as well:
    if (out_actualResolution)
    {
        std::pair<float, float> result = _envelope->getElevationAndResolution(point.x(), point.y());
        out_elevation = result.first;
        *out_actualResolution = result.second;
    }
    else
    {
        out_elevation = _envelope->getElevation(point.x(), point.y());
    }

    return out_elevation != NO_DATA_VALUE;
}
コード例 #26
0
ファイル: ElevationQuery.cpp プロジェクト: Vantica/osgearth
bool
ElevationQuery::getElevationImpl(const GeoPoint& point, /* abs */
                                 double&         out_elevation,
                                 double          desiredResolution,
                                 double*         out_actualResolution)
{
    // assertion.
    if ( !point.isAbsolute() )
    {
        OE_WARN << LC << "Assertion failure; input must be absolute" << std::endl;
        return false;
    }

    osg::Timer_t begin = osg::Timer::instance()->tick();

    // first try the terrain patches.
    if ( _patchLayers.size() > 0 )
    {
        osgUtil::IntersectionVisitor iv;

        for(std::vector<ModelLayer*>::iterator i = _patchLayers.begin(); i != _patchLayers.end(); ++i)
        {
            // find the scene graph for this layer:
            osg::Node* node = (*i)->getSceneGraph( _mapf.getUID() );
            if ( node )
            {
                // configure for intersection:
                osg::Vec3d surface;
                point.toWorld( surface );

                // trivial bounds check:
                if ( node->getBound().contains(surface) )
                {
                    osg::Vec3d nvector;
                    point.createWorldUpVector(nvector);

                    osg::Vec3d start( surface + nvector*5e5 );
                    osg::Vec3d end  ( surface - nvector*5e5 );
                
                    // first time through, set up the intersector on demand
                    if ( !_patchLayersLSI.valid() )
                    {
                        _patchLayersLSI = new DPLineSegmentIntersector(start, end);
                        _patchLayersLSI->setIntersectionLimit( _patchLayersLSI->LIMIT_NEAREST );
                    }
                    else
                    {
                        _patchLayersLSI->reset();
                        _patchLayersLSI->setStart( start );
                        _patchLayersLSI->setEnd  ( end );
                    }

                    // try it.
                    iv.setIntersector( _patchLayersLSI.get() );
                    node->accept( iv );

                    // check for a result!!
                    if ( _patchLayersLSI->containsIntersections() )
                    {
                        osg::Vec3d isect = _patchLayersLSI->getIntersections().begin()->getWorldIntersectPoint();

                        // transform back to input SRS:
                        GeoPoint output;
                        output.fromWorld( point.getSRS(), isect );
                        out_elevation = output.z();
                        if ( out_actualResolution )
                            *out_actualResolution = 0.0;

                        return true;
                    }
                }
                else
                {
                    //OE_INFO << LC << "Trivial rejection (bounds check)" << std::endl;
                }
            }
        }
    }

    if ( _mapf.elevationLayers().empty() )
    {
        // this means there are no heightfields.
        out_elevation = 0.0;
        return true;        
    }

    // tile size (resolution of elevation tiles)
    unsigned tileSize = std::max(_mapf.getMapOptions().elevationTileSize().get(), 2u);

    //This is the max resolution that we actually have data at this point
    unsigned int bestAvailLevel = getMaxLevel( point.x(), point.y(), point.getSRS(), _mapf.getProfile());

    if (desiredResolution > 0.0)
    {
        unsigned int desiredLevel = _mapf.getProfile()->getLevelOfDetailForHorizResolution( desiredResolution, tileSize );
        if (desiredLevel < bestAvailLevel) bestAvailLevel = desiredLevel;
    }

    OE_DEBUG << LC << "Best available data level " << point.x() << ", " << point.y() << " = "  << bestAvailLevel << std::endl;

    // transform the input coords to map coords:
    GeoPoint mapPoint = point;
    if ( point.isValid() && !point.getSRS()->isHorizEquivalentTo( _mapf.getProfile()->getSRS() ) )
    {
        mapPoint = point.transform(_mapf.getProfile()->getSRS());
        if ( !mapPoint.isValid() )
        {
            OE_WARN << LC << "Fail: coord transform failed" << std::endl;
            return false;
        }
    }    

    // get the tilekey corresponding to the tile we need:
    TileKey key = _mapf.getProfile()->createTileKey( mapPoint.x(), mapPoint.y(), bestAvailLevel );
    if ( !key.valid() )
    {
        OE_WARN << LC << "Fail: coords fall outside map" << std::endl;
        return false;
    }
        
    bool result = false;      
    while (!result)
    {      
        GeoHeightField geoHF;
        TileCache::Record record;
        // Try to get the hf from the cache
        if ( _cache.get( key, record ) )
        {                        
            geoHF = record.value();
        }
        else
        {
            // Create it            
            osg::ref_ptr<osg::HeightField> hf = new osg::HeightField();
            hf->allocate( tileSize, tileSize );

            // Initialize the heightfield to nodata
            for (unsigned int i = 0; i < hf->getFloatArray()->size(); i++)
            {
                hf->getFloatArray()->at( i ) = NO_DATA_VALUE;
            }   

            if (_mapf.populateHeightField(hf, key, false))
            {                
                geoHF = GeoHeightField( hf.get(), key.getExtent() );
                _cache.insert( key, geoHF );
            }
        }

        if (geoHF.valid())
        {            
            float elevation = 0.0f;                 
            result = geoHF.getElevation( mapPoint.getSRS(), mapPoint.x(), mapPoint.y(), _mapf.getMapInfo().getElevationInterpolation(), mapPoint.getSRS(), elevation);                              
            if (result && elevation != NO_DATA_VALUE)
            {                        
                // see what the actual resolution of the heightfield is.
                if ( out_actualResolution )
                    *out_actualResolution = geoHF.getXInterval(); 
                out_elevation = (double)elevation;                
                break;
            }
            else
            {                               
                result = false;
            }
        }

        if (!result)
        {
            key = key.createParentKey();                        
            if (!key.valid())
            {
                break;
            }
        }         
    }

         

    osg::Timer_t end = osg::Timer::instance()->tick();
    _queries++;
    _totalTime += osg::Timer::instance()->delta_s( begin, end );

    return result;
}