void
PolyhedralLineOfSightNode::recalculateExtent()
{
    // get a local2world matrix for the map position:
    GeoPoint absMapPos = getPosition();
    absMapPos.makeAbsolute( getMapNode()->getTerrain() );
    osg::Matrix local2world;
    absMapPos.createLocalToWorld( local2world );

    // local offsets (east and north)
    osg::Vec3d x( _distance.as(Units::METERS), 0.0, 0.0 );
    osg::Vec3d y( 0.0, _distance.as(Units::METERS), 0.0 );

    // convert these to map coords:
    GeoPoint easting, northing;
    easting.fromWorld( getMapNode()->getMapSRS(), x * local2world );
    northing.fromWorld( getMapNode()->getMapSRS(), y * local2world );

    // calculate the offsets:
    double d_easting = easting.x() - absMapPos.x();
    double d_northing = northing.y() - absMapPos.y();

    // update the extent.
    _extent = GeoExtent(
        getMapNode()->getMapSRS(),
        absMapPos.x() - d_easting, absMapPos.y() - d_northing,
        absMapPos.x() + d_easting, absMapPos.y() + d_northing );

    OE_INFO << LC << "Cached extent = " << _extent.toString() << std::endl;
}
Esempio n. 2
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( s_mapNode->getMapSRS(), world );

            // Depending on the level of detail key you request, you will get a mesh that should line up exactly with the highest resolution mesh that the terrain engine will draw.
            // At level 15 that is a 257x257 heightfield.  If you select a higher lod, the mesh will be less dense.
            TileKey key = s_mapNode->getMap()->getProfile()->createTileKey(mapPoint.x(), mapPoint.y(), 15);
            OE_NOTICE << "Creating tile " << key.str() << std::endl;
            osg::ref_ptr<osg::Node> node = s_mapNode->getTerrainEngine()->createTile(key);
            if (node.valid())
            {
                // Extract the triangles from the node that was created and do our own rendering.  Simulates what you would do when passing in the triangles to a physics engine.
                OE_NOTICE << "Created tile for " << key.str() << std::endl;
                CollectTrianglesVisitor v;
                node->accept(v);
                node = v.buildNode();

                if (_node.valid())
                {
                    s_root->removeChild( _node.get() );
                }

                osg::Group* group = new osg::Group;

                // Show the actual mesh.
                group->addChild( node.get() );

                _node = group;

                // Clamp the marker to the intersection of the triangles created by osgEarth.  This should line up with the mesh that is actually rendered.
                double z = 0.0;
                s_mapNode->getTerrain()->getHeight( node, s_mapNode->getMapSRS(), mapPoint.x(), mapPoint.y(), &z);

                GeoTransform* xform = new GeoTransform();
                xform->setPosition( osgEarth::GeoPoint(s_mapNode->getMapSRS(),mapPoint.x(),  mapPoint.y(), z, ALTMODE_ABSOLUTE) );
                xform->addChild( marker.get() );
                group->addChild( xform );

                s_root->addChild( _node.get() );
            }
            else
            {
                OE_NOTICE << "Failed to create tile for " << key.str() << std::endl;
            }
        }
    }
Esempio n. 3
0
void
LabelNode::updateLayoutData()
{
    if (!_dataLayout.valid())
    {
        _dataLayout = new ScreenSpaceLayoutData();
    }

    // re-apply annotation drawable-level stuff as neccesary.
    for (unsigned i = 0; i < _geode->getNumChildren(); ++i)
    {
        _geode->getChild(i)->setUserData(_dataLayout.get());
    }
    
    _dataLayout->setPriority(getPriority());
    
    GeoPoint location = getPosition();
    location.makeGeographic();
    double latRad;
    double longRad;
    GeoMath::destination(osg::DegreesToRadians(location.y()),
        osg::DegreesToRadians(location.x()),
        _labelRotationRad,
        2500.,
        latRad,
        longRad);

    _geoPointProj.set(osgEarth::SpatialReference::get("wgs84"),
        osg::RadiansToDegrees(longRad),
        osg::RadiansToDegrees(latRad),
        0,
        osgEarth::ALTMODE_ABSOLUTE);

    _geoPointLoc.set(osgEarth::SpatialReference::get("wgs84"),
        //location.getSRS(),
        location.x(),
        location.y(),
        0,
        osgEarth::ALTMODE_ABSOLUTE);

    const TextSymbol* ts = getStyle().get<TextSymbol>();
    if (ts)
    {
        _dataLayout->setPixelOffset(ts->pixelOffset().get());
        
        if (_followFixedCourse)
        {
            osg::Vec3d p0, p1;
            _geoPointLoc.toWorld(p0);
            _geoPointProj.toWorld(p1);
            _dataLayout->setAnchorPoint(p0);
            _dataLayout->setProjPoint(p1);
        }
    }
}
Esempio n. 4
0
 virtual void onPositionChanged(const Dragger* sender, const osgEarth::GeoPoint& position)
 {
     //Convert to lat/lon
     GeoPoint p;
     position.transform(SpatialReference::create( "epsg:4326"), p);
     _overlay->setControlPoint(_controlPoint, p.x(), p.y(), _singleVert);
 }
void
CircleNodeEditor::updateDraggers()
{
    LocalizedNodeEditor::updateDraggers();
    if (_radiusDragger)
    {
        const osg::EllipsoidModel* em = _node->getMapNode()->getMapSRS()->getEllipsoid();
        
        // Get the current location of the center of the circle (in lat/long, absolute Z)
        GeoPoint location = _node->getPosition();   
        location.makeGeographic();
        //location.makeAbsolute( _node->getMapNode()->getTerrain() );
        
        //Get the radius of the circle in meters
        double r = static_cast<CircleNode*>(_node.get())->getRadius().as(Units::METERS);

        double lat, lon;
        GeoMath::destination(
            osg::DegreesToRadians( location.y() ), osg::DegreesToRadians( location.x() ), 
            _bearing, r, lat, lon, em->getRadiusEquator() );

        GeoPoint draggerLocation( 
            location.getSRS(),
            osg::RadiansToDegrees(lon),
            osg::RadiansToDegrees(lat));

        draggerLocation.z() = 0;

        _radiusDragger->setPosition( draggerLocation, false );
    }
}
Esempio n. 6
0
/* method: x of class  GeoPoint */
static int tolua_Lua_ScriptEngine_tolua_GeoPoint_x00(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 'x'",NULL);
#endif
 {
  double tolua_ret = (double)  self->x();
 tolua_pushnumber(tolua_S,(double)tolua_ret);
 }
 }
 return 1;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'x'.",&tolua_err);
 return 0;
#endif
}
Esempio n. 7
0
FeatureList
BufferFilter::process( Feature* input, FilterEnv* env )
{
    FeatureList output;

    GeoShapeList& shapes = input->getShapes();

    GeoShapeList new_shapes;

    double b = getDistance();

    if ( env->getInputSRS()->isGeographic() )
    {
        // for geo, convert from meters to degrees
        //TODO: we SHOULD do this for each and every feature buffer segment, but
        //  for how this is a shortcut approximation.
        double bc = b/1.4142;
        osg::Vec2d vec( bc, bc ); //vec.normalize();
        GeoPoint c = input->getExtent().getCentroid();
        osg::Vec2d p0( c.x(), c.y() );
        osg::Vec2d p1;
        Units::convertLinearToAngularVector( vec, Units::METERS, Units::DEGREES, p0, p1 );
        b = (p1-p0).length();
    }

    for( GeoShapeList::iterator i = shapes.begin(); i != shapes.end(); i++ )
    {
        GeoPartList new_parts;
        GeoShape& shape = *i;

        if ( shape.getShapeType() == GeoShape::TYPE_POLYGON )
        {
            GeoShape new_shape( GeoShape::TYPE_POLYGON, shape.getSRS() );
            bufferPolygons( shape, b, new_shape.getParts() );
            new_shapes.push_back( new_shape );
        }
        else if ( shape.getShapeType() == GeoShape::TYPE_LINE )
        {
            if ( getConvertToPolygon() )
            {
                GeoShape new_shape( GeoShape::TYPE_POLYGON, shape.getSRS() );
                bufferLinesToPolygons( shape, b, new_shape );
                new_shapes.push_back( new_shape );
            }
            else
            {
                GeoShape new_shape( GeoShape::TYPE_LINE, shape.getSRS() );
                bufferLinesToLines( shape, b, new_shape );
                new_shapes.push_back( new_shape );
            }
        }
    }

    if ( new_shapes.size() > 0 )
        input->getShapes().swap( new_shapes );

    output.push_back( input );
    return output;
}
void
EllipseNodeEditor::updateDraggers()
{
    LocalizedNodeEditor::updateDraggers();
    if (_majorDragger && _minorDragger)
    {
        const osg::EllipsoidModel* em = _node->getMapNode()->getMap()->getProfile()->getSRS()->getEllipsoid();
        
        //Get the current location of the center of the circle
        GeoPoint location = _node->getPosition();    
        
        //Get the raddi of the ellipse in meters
        EllipseNode* ellipse = static_cast<EllipseNode*>(_node.get());
        double majorR = ellipse->getRadiusMajor().as(Units::METERS);
        double minorR = ellipse->getRadiusMinor().as(Units::METERS);

        double rotation = ellipse->getRotationAngle().as( Units::RADIANS );

        double latRad, lonRad;

        // minor dragger: end of the rotated +Y axis:
        GeoMath::destination(
            osg::DegreesToRadians( location.y() ), osg::DegreesToRadians( location.x() ), 
            rotation, 
            minorR, 
            latRad, lonRad, 
            em->getRadiusEquator());        

        GeoPoint minorLocation(location.getSRS(), osg::RadiansToDegrees( lonRad ), osg::RadiansToDegrees( latRad ));
        minorLocation.z() = 0;       
        _minorDragger->setPosition( minorLocation, false );

        // major dragger: end of the rotated +X axis
        GeoMath::destination(
            osg::DegreesToRadians( location.y() ), 
            osg::DegreesToRadians( location.x() ), 
            rotation + osg::PI_2, 
            majorR, 
            latRad, lonRad, 
            em->getRadiusEquator());                

        GeoPoint majorLocation(location.getSRS(), osg::RadiansToDegrees( lonRad ), osg::RadiansToDegrees( latRad ));
        majorLocation.z() = 0;
        _majorDragger->setPosition( majorLocation, false);
    }
}
Esempio n. 9
0
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;
}
Esempio n. 10
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;
        }
Esempio n. 11
0
void Dragger::reclamp( const TileKey& key, osg::Node* tile, const Terrain* terrain )
{    
    GeoPoint p;
    _position.transform( key.getExtent().getSRS(), p );
    // first verify that the control position intersects the tile:
    if ( key.getExtent().contains( p.x(), p.y() ) )
    {
        updateTransform( tile );
    }
}
Esempio n. 12
0
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());
}
Esempio n. 13
0
void
CircleNodeEditor::computeBearing()
{
    _bearing = osg::DegreesToRadians( 90.0 );
    //Get the radius dragger's position
    if (!_radiusDragger->getMatrix().isIdentity())
    {
        // Get the current location of the center of the circle (in lat/long)
        GeoPoint location = _node->getPosition();
        location.makeGeographic();

        // location of the radius dragger (in lat/long)
        GeoPoint radiusLocation;
        radiusLocation.fromWorld( location.getSRS(), _radiusDragger->getMatrix().getTrans() );

        // calculate the bearing b/w the 
        _bearing = GeoMath::bearing(
            osg::DegreesToRadians(location.y()), osg::DegreesToRadians(location.x()),
            osg::DegreesToRadians(radiusLocation.y()), osg::DegreesToRadians(radiusLocation.x()));
    }
}
Esempio n. 14
0
std::string
LatLongFormatter::format( const GeoPoint& p ) const
{
    GeoPoint geo = p;
    if ( !geo.makeGeographic() )
        return "";

    return Stringify()
        << format( Angular(geo.y()) )
        << ", "
        << format( Angular(geo.x()) );
}
Esempio n. 15
0
void
RectangleNode::setLowerLeft( const GeoPoint& lowerLeft )
{
    GeoPoint center = getPosition();

    //Figure out the new width and height
    double earthRadius = center.getSRS()->getEllipsoid()->getRadiusEquator();

    double lat = osg::DegreesToRadians(center.y());
    double lon = osg::DegreesToRadians(center.x());
    double halfWidthMeters  =  _width.as(Units::METERS) / 2.0;
    double halfHeightMeters  = _height.as(Units::METERS) / 2.0;   

    double eastLon, eastLat;
    double westLon, westLat;
    double northLon, northLat;
    double southLon, southLat;

    //Get the current corners
    GeoMath::destination( lat, lon, osg::DegreesToRadians( 90.0 ), halfWidthMeters, eastLat, eastLon, earthRadius );
    GeoMath::destination( lat, lon, osg::DegreesToRadians( -90.0 ), halfWidthMeters, westLat, westLon, earthRadius );
    GeoMath::destination( lat, lon, osg::DegreesToRadians( 0.0 ),  halfHeightMeters, northLat, northLon, earthRadius );
    GeoMath::destination( lat, lon, osg::DegreesToRadians( 180.0 ), halfHeightMeters, southLat, southLon, earthRadius );

    if (osg::DegreesToRadians(lowerLeft.x()) < eastLon && osg::DegreesToRadians(lowerLeft.y()) < northLat)
    {
        westLon = osg::DegreesToRadians(lowerLeft.x());  
        southLat = osg::DegreesToRadians(lowerLeft.y());

        double x = ( eastLon + westLon ) / 2.0;
        double y = ( southLat + northLat) / 2.0;
        setPosition(GeoPoint( center.getSRS(), osg::RadiansToDegrees(x), osg::RadiansToDegrees(y)));

        double width =  GeoMath::distance( y, westLon, y, eastLon, earthRadius);
        double height =  GeoMath::distance( southLat, x, northLat, x, earthRadius);
        setWidth(  Linear(width,  Units::METERS ));
        setHeight( Linear(height, Units::METERS ));
    }
}
Esempio n. 16
0
 bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor*)
 {
     if (ea.getEventType() == ea.KEYDOWN && ea.getKey() == _c)
     {
         osg::Vec3d world;
         _mapNode->getTerrain()->getWorldCoordsUnderMouse(aa.asView(), ea.getX(), ea.getY(), world);
         GeoPoint coords;
         coords.fromWorld(s_activeMap->getSRS(), world);
         osg::ref_ptr<ElevationEnvelope> env = s_activeMap->getElevationPool()->createEnvelope(s_activeMap->getSRS(), 23u);
         float ep_elev = env->getElevation(coords.x(), coords.y());
         OE_NOTICE << "Elevations under mouse. EP=" << ep_elev << "\n";
     }
     return false;
 }
Esempio n. 17
0
bool
ElevationQuery::getElevation(const GeoPoint&         point,
                             double&                 out_elevation,
                             double                  desiredResolution,
                             double*                 out_actualResolution)
{
    sync();
    if ( point.altitudeMode() == ALTMODE_ABSOLUTE )
    {
        return getElevationImpl( point, out_elevation, desiredResolution, out_actualResolution );
    }
    else
    {
        GeoPoint point_abs( point.getSRS(), point.x(), point.y(), 0.0, ALTMODE_ABSOLUTE );
        return getElevationImpl( point_abs, out_elevation, desiredResolution, out_actualResolution );
    }
}
Esempio n. 18
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;
}
Esempio n. 19
0
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;
}
Esempio n. 20
0
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 );
}
Esempio n. 21
0
float
ElevationQuery::getElevation(const GeoPoint& point,
                             double          desiredResolution,
                             double*         out_actualResolution)
{
    float result = NO_DATA_VALUE;

    sync();
    if ( point.altitudeMode() == ALTMODE_ABSOLUTE )
    {
        getElevationImpl( point, result, desiredResolution, out_actualResolution );
    }
    else
    {
        GeoPoint point_abs( point.getSRS(), point.x(), point.y(), 0.0, ALTMODE_ABSOLUTE );
        getElevationImpl( point_abs, result, desiredResolution, out_actualResolution );
    }

    return result;
}
Esempio n. 22
0
void
MouseCoordsLabelCallback::set( const GeoPoint& mapCoords, osg::View* view, MapNode* mapNode )
{
    if ( _label.valid() )
    {
        if ( _formatter )
        {
            _label->setText( Stringify()
                <<  _formatter->format( mapCoords )
                << ", " << mapCoords.z() );
        }
        else
        {
            _label->setText( Stringify()
                << std::fixed
                << mapCoords.x()
                << ", " << mapCoords.y()
                << ", " << mapCoords.z() );
        }
    }
}
Esempio n. 23
0
GeoPoint
RectangleNode::getCorner( Corner corner ) const
{
    GeoPoint center = getPosition();

    double earthRadius = center.getSRS()->getEllipsoid()->getRadiusEquator();
    double lat = osg::DegreesToRadians(center.y());
    double lon = osg::DegreesToRadians(center.x());
    double halfWidthMeters  =  _width.as(Units::METERS) / 2.0;
    double halfHeightMeters  = _height.as(Units::METERS) / 2.0;   

    double eastLon, eastLat;
    double westLon, westLat;
    double northLon, northLat;
    double southLon, southLat;
        
    GeoMath::destination( lat, lon, osg::DegreesToRadians( 90.0 ), halfWidthMeters, eastLat, eastLon, earthRadius );
    GeoMath::destination( lat, lon, osg::DegreesToRadians( -90.0 ), halfWidthMeters, westLat, westLon, earthRadius );
    GeoMath::destination( lat, lon, osg::DegreesToRadians( 0.0 ),  halfHeightMeters, northLat, northLon, earthRadius );
    GeoMath::destination( lat, lon, osg::DegreesToRadians( 180.0 ), halfHeightMeters, southLat, southLon, earthRadius );

    if (corner == CORNER_LOWER_LEFT)
    {
        return GeoPoint(center.getSRS(), osg::RadiansToDegrees(westLon), osg::RadiansToDegrees(southLat), 0, ALTMODE_RELATIVE);
    }
    else if (corner == CORNER_LOWER_RIGHT)
    {
        return GeoPoint(center.getSRS(), osg::RadiansToDegrees(eastLon), osg::RadiansToDegrees(southLat), 0, ALTMODE_RELATIVE);
    }
    else if (corner == CORNER_UPPER_LEFT)
    {
        return GeoPoint(center.getSRS(), osg::RadiansToDegrees(westLon), osg::RadiansToDegrees(northLat), 0, ALTMODE_RELATIVE);
    }
    else if (corner == CORNER_UPPER_RIGHT)
    {
        return GeoPoint(center.getSRS(), osg::RadiansToDegrees(eastLon), osg::RadiansToDegrees(northLat), 0, ALTMODE_RELATIVE);
    }
    return GeoPoint();
}
Esempio n. 24
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));
    }
  }
}
    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( s_mapNode->getMapSRS(), world );

            TileKey key = s_mapNode->getMap()->getProfile()->createTileKey(mapPoint.x(), mapPoint.y(), 13);
            OE_NOTICE << "Creating tile " << key.str() << std::endl;
            osg::ref_ptr<osg::Node> node = s_mapNode->getTerrainEngine()->createTile(key);
            if (node.valid())
            {
                OE_NOTICE << "Created tile for " << key.str() << std::endl;
                CollectTrianglesVisitor v;
                node->accept(v);

                osg::ref_ptr<osg::Node> output = v.buildNode();
                osgDB::writeNodeFile( *output.get(), "createtile.osgt" );
                OE_NOTICE << "Wrote tile to createtile.osgt\n";
                //osgDB::writeNodeFile(v.buildNode(
                //s_root->addChild(v.buildNode());
            }
            else
            {
                OE_NOTICE << "Failed to create tile for " << key.str() << std::endl;
            }
        }
    }
Esempio n. 26
0
void
OverlayNode::traverse( osg::NodeVisitor& nv )
{
    if ( !_overlayProxyContainer.valid() )
    {
        osg::Group::traverse( nv );
    }
    else
    {
        if ( nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR )
        {
            if ( _active )
            {
                // do nothing -- culling will happen via the OverlayProxy instead.
            }
            else
            {
                // for a non-active node, just traverse children as usual.
                osg::Group::traverse( nv );
            }
        }

        else if ( nv.getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR )
        {
            if ( _dirty )
            {
                applyChanges();
                _dirty = false;
                ADJUST_UPDATE_TRAV_COUNT( this, -1 );
            }
            
            // traverse children directly, regardles of active status
            osg::Group::traverse( nv );
        }

        else if (dynamic_cast<osgUtil::IntersectionVisitor*>(&nv))
        {
            /*
               In order to properly intersect with overlay geometries, attempt to find the point on the terrain where the pick occurred
               cast a second intersector vertically at that point.

               Currently this is only imlpemented for our custom PrimitiveIntersector.
            */
            osgUtil::IntersectionVisitor* iv = dynamic_cast<osgUtil::IntersectionVisitor*>(&nv);
            osgEarth::PrimitiveIntersector* pi = dynamic_cast<osgEarth::PrimitiveIntersector *>(iv->getIntersector());

            osg::ref_ptr<MapNode> mapNode;
            if (pi && !pi->getOverlayIgnore() && _mapNode.lock(mapNode))
            { 
                osg::NodePath path = iv->getNodePath();
                osg::NodePath prunedNodePath( path.begin(), path.end()-1 );
                osg::Matrix modelToWorld = osg::computeLocalToWorld(prunedNodePath);
                osg::Vec3d worldStart = pi->getStart() * modelToWorld;
                osg::Vec3d worldEnd = pi->getEnd() * modelToWorld;

                osg::ref_ptr<DPLineSegmentIntersector> lsi = new DPLineSegmentIntersector(worldStart, worldEnd);
                osgUtil::IntersectionVisitor ivTerrain(lsi.get());
                mapNode->getTerrainEngine()->accept(ivTerrain);

                if (lsi->containsIntersections())
                {
                  osg::Vec3d worldIntersect = lsi->getFirstIntersection().getWorldIntersectPoint();
                  
                  GeoPoint mapIntersect;
                  mapIntersect.fromWorld(mapNode->getMapSRS(), worldIntersect);

                  osg::Vec3d newMapStart(mapIntersect.x(), mapIntersect.y(), 25000.0);
                  osg::Vec3d newMapEnd(mapIntersect.x(), mapIntersect.y(), -25000.0);

                  osg::Vec3d newWorldStart;
                  mapNode->getMapSRS()->transformToWorld(newMapStart, newWorldStart);

                  osg::Vec3d newWorldEnd;
                  mapNode->getMapSRS()->transformToWorld(newMapEnd, newWorldEnd);

                  osg::Matrix worldToModel;
                  worldToModel.invert(modelToWorld);

                  osg::Vec3d newModelStart = newWorldStart * worldToModel;
                  osg::Vec3d newModelEnd = newWorldEnd * worldToModel;

                  osg::ref_ptr<osgEarth::PrimitiveIntersector> pi2 = new osgEarth::PrimitiveIntersector(osgUtil::Intersector::MODEL, newModelStart, newModelEnd, pi->getThickness(), true);
                  osgUtil::IntersectionVisitor iv2(pi2);
                  iv2.setTraversalMask(iv->getTraversalMask());
                  path[0]->accept(iv2);

                  if (pi2->containsIntersections())
                  {
                    // Insert newlly found intersections into the original intersector.
                    for (PrimitiveIntersector::Intersections::iterator it = pi2->getIntersections().begin(); it != pi2->getIntersections().end(); ++it)
                    {
                      PrimitiveIntersector::Intersection intersection(*it);
                      intersection.ratio = 1.0;
                      pi->insertIntersection(intersection);
                    }
                  }
                }
                else
                {
                  //OE_WARN << LC << "No hits on terrain!" << std::endl;
                }
            }
            else
            {
              osg::Group::traverse( nv );
            }
        }

        // handle other visitor types (like intersections, etc) by simply
        // traversing the child graph.
        else // if ( nv.getNodeVisitor() == osg::NodeVisitor::NODE_VISITOR )
        {
            osg::Group::traverse( nv );
        }
    }
}
Esempio n. 27
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;
}
Esempio n. 28
0
      virtual void onPositionChanged(const Dragger* sender, const osgEarth::GeoPoint& position)
      {
          const osg::EllipsoidModel* em = _node->getMapNode()->getMapSRS()->getEllipsoid();

          GeoPoint radiusLocation(position);
          radiusLocation.makeGeographic();

          //Figure out the distance between the center of the circle and this new location
          GeoPoint center = _node->getPosition();
          center.makeGeographic();

          double distance = GeoMath::distance(osg::DegreesToRadians( center.y() ), osg::DegreesToRadians( center.x() ), 
                                              osg::DegreesToRadians( radiusLocation.y() ), osg::DegreesToRadians( radiusLocation.x() ),
                                              em->getRadiusEquator());
          _node->setRadius( Linear(distance, Units::METERS ) );
          //The position of the radius dragger has changed, so recompute the bearing
          _editor->computeBearing();
      }
Esempio n. 29
0
      virtual void onPositionChanged(const Dragger* sender, const osgEarth::GeoPoint& position)
      {
          const osg::EllipsoidModel* em = _node->getMapNode()->getMapSRS()->getEllipsoid();

          //Figure out the distance between the center of the circle and this new location
          GeoPoint center = _node->getPosition();

          double distance = GeoMath::distance(osg::DegreesToRadians( center.y() ), osg::DegreesToRadians( center.x() ), 
                                              osg::DegreesToRadians( position.y() ), osg::DegreesToRadians( position.x() ),
                                              em->getRadiusEquator());

          double bearing = GeoMath::bearing(osg::DegreesToRadians( center.y() ), osg::DegreesToRadians( center.x() ), 
                                            osg::DegreesToRadians( position.y() ), osg::DegreesToRadians( position.x() ));
        

          //Compute the new angular rotation based on how they moved the point
          if (_major)
          {
              _node->setRotationAngle( Angle( bearing-osg::PI_2, Units::RADIANS ) );
              _node->setRadiusMajor( Distance(distance, Units::METERS ) );
          }
          else // minor
          {
              _node->setRotationAngle( Angle( bearing, Units::RADIANS ) );
              _node->setRadiusMinor( Distance(distance, Units::METERS ) );
          }
          _editor->updateDraggers();
     }
Esempio n. 30
0
    /**
     * Create and return an image for the given TileKey.
     */
    osg::Image* createImage( const TileKey& key, ProgressCallback* progress )
    {
        if (_debugDirect)
        {
            //osg::Image* image = new osg::Image;
            //image->allocateImage(256,256,1, GL_RGB, GL_UNSIGNED_BYTE);
            //return image;

            return osgDB::readImageFile( getDirectURI(key) );
            //return URI(getDirectURI(key)).getImage(_dbOptions.get(), progress);
        }

        // center point of the tile (will be in spherical mercator)
        double x, y;
        key.getExtent().getCentroid(x, y);

        // transform it to lat/long:
        GeoPoint geo;

        GeoPoint( getProfile()->getSRS(), x, y ).transform(
            getProfile()->getSRS()->getGeographicSRS(),
            geo );

        // contact the REST API. Docs are here:
        // http://msdn.microsoft.com/en-us/library/ff701716.aspx

        // construct the request URI:
        std::string request = Stringify()
            << std::setprecision(12)
            << _options.imageryMetadataAPI().get()     // base REST API
            << "/"    << _options.imagerySet().get()   // imagery set to use
            << "/"    << geo.y() << "," << geo.x()     // center point in lat/long
            << "?zl=" << key.getLOD() + 1              // zoom level
            << "&o=json"                               // response format
            << "&key=" << _options.key().get();        // API key

        // check the URI cache.
        URI                  location;
        TileURICache::Record rec;

        if ( _tileURICache.get(request, rec) )
        {
            location = URI(rec.value());
            //CacheStats stats = _tileURICache.getStats();
            //OE_INFO << "Ratio = " << (stats._hitRatio*100) << "%" << std::endl;
        }
        else
        {
            unsigned c = ++_apiCount;
            if ( c % 25 == 0 )
                OE_INFO << LC << "API calls = " << c << std::endl;
            
            // fetch it:
            ReadResult metadataResult = URI(request).readString(_dbOptions, progress);

            if ( metadataResult.failed() )
            {
                // check for a REST error:
                if ( metadataResult.code() == ReadResult::RESULT_SERVER_ERROR )
                {
                    OE_WARN << LC << "REST API request error!" << std::endl;

                    Config metadata;
                    std::string content = metadataResult.getString();
                    metadata.fromJSON( content );
                    ConfigSet errors = metadata.child("errorDetails").children();
                    for(ConfigSet::const_iterator i = errors.begin(); i != errors.end(); ++i )
                    {
                        OE_WARN << LC << "REST API: " << i->value() << std::endl;
                    }
                    return 0L;
                }
                else
                {
                    OE_WARN << LC << "Request error: " << metadataResult.getResultCodeString() << std::endl;
                }
                return 0L;
            }

            // decode it:
            Config metadata;
            if ( !metadata.fromJSON(metadataResult.getString()) )
            {
                OE_WARN << LC << "Error decoding REST API response" << std::endl;
                return 0L;
            }

            // check the vintage field. If it's empty, that means we got a "no data" tile.
            Config* vintageEnd = metadata.find("vintageEnd");
            if ( !vintageEnd || vintageEnd->value().empty() )
            {
                OE_DEBUG << LC << "NO data image encountered." << std::endl;
                return 0L;
            }

            // find the tile URI:
            Config* locationConf= metadata.find("imageUrl");
            if ( !locationConf )
            {
                OE_WARN << LC << "REST API JSON parsing error (imageUrl not found)" << std::endl;
                return 0L;
            }

            location = URI( locationConf->value() );
            _tileURICache.insert( request, location.full() );
        }

        // request the actual tile
        //OE_INFO << "key = " << key.str() << ", URL = " << location->value() << std::endl;

        //osg::Image* image = location.getImage(_dbOptions.get(), progress);
        osg::Image* image = osgDB::readImageFile( location.full() );

        if ( image &&  _geom.valid() )
        {
            GeometryRasterizer rasterizer( image->s(), image->t() );
            rasterizer.draw( _geom.get(), osg::Vec4(1,1,1,1) );
            osg::ref_ptr<osg::Image> overlay = rasterizer.finalize();
            ImageUtils::PixelVisitor<AlphaBlend> blend;
            blend.accept( overlay.get(), image );
        }

        return image;
    }