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; }
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; } } }
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); } } }
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 ); } }
/* 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 }
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); } }
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; }
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; }
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 ); } }
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()); }
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())); } }
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()) ); }
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 )); } }
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; }
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 ); } }
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; }
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; }
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 ); }
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; }
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() ); } } }
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(); }
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; } } }
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 ); } } }
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; }
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(); }
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(); }
/** * 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; }