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; } 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; }
bool AddPointHandler::addPoint( float x, float y, osgViewer::View* view ) { osg::Vec3d world; MapNode* mapNode = _featureNode->getMapNode(); if ( mapNode->getTerrain()->getWorldCoordsUnderMouse( view, x, y, world ) ) { // Get the map point from the world GeoPoint mapPoint; mapPoint.fromWorld( mapNode->getMapSRS(), world ); Feature* feature = _featureNode->getFeature(); if ( feature ) { // Convert the map point to the feature's SRS GeoPoint featurePoint = mapPoint.transform( feature->getSRS() ); feature->getGeometry()->push_back( featurePoint.vec3d() ); _featureNode->init(); return true; } } return false; }
int seed( osg::ArgumentParser& args ) { //Read the min level unsigned int minLevel = 0; while (args.read("--min-level", minLevel)); //Read the max level unsigned int maxLevel = 5; while (args.read("--max-level", maxLevel)); std::vector< Bounds > bounds; // restrict packaging to user-specified bounds. double xmin=DBL_MAX, ymin=DBL_MAX, xmax=DBL_MIN, ymax=DBL_MIN; while (args.read("--bounds", xmin, ymin, xmax, ymax )) { Bounds b; b.xMin() = xmin, b.yMin() = ymin, b.xMax() = xmax, b.yMax() = ymax; bounds.push_back( b ); } //Read the cache override directory std::string cachePath; while (args.read("--cache-path", cachePath)); //Read the cache type std::string cacheType; while (args.read("--cache-type", cacheType)); bool verbose = args.read("--verbose"); //Read in the earth file. osg::ref_ptr<osg::Node> node = osgDB::readNodeFiles( args ); if ( !node.valid() ) return usage( "Failed to read .earth file." ); MapNode* mapNode = MapNode::findMapNode( node.get() ); if ( !mapNode ) return usage( "Input file was not a .earth file" ); CacheSeed seeder; seeder.setMinLevel( minLevel ); seeder.setMaxLevel( maxLevel ); for (unsigned int i = 0; i < bounds.size(); i++) { GeoExtent extent(mapNode->getMapSRS(), bounds[i]); OE_DEBUG << "Adding extent " << extent.toString() << std::endl; seeder.addExtent( extent ); } if (verbose) { seeder.setProgressCallback(new ConsoleProgressCallback); } seeder.seed( mapNode->getMap() ); return 0; }
int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc,argv); // help? if ( arguments.read("--help") ) return usage(argv[0]); osgViewer::Viewer viewer(arguments); EarthManipulator* em = new EarthManipulator(); viewer.setCameraManipulator( em ); // load an earth file, and support all or our example command-line options // and earth file <external> tags osg::Node* earth = MapNodeHelper().load( arguments, &viewer ); MapNode* mapNode = MapNode::get(earth); if (!mapNode) return usage(argv[0]); // load the model file into the local coordinate frame, which will be // +X=east, +Y=north, +Z=up. osg::Node* model = osgDB::readNodeFile("cessna.osgt.1,-1,1.scale"); if ( !model ) return usage(argv[0]); osg::Group* root = new osg::Group(); root->addChild( earth ); App app; app.srs = mapNode->getMapSRS(); app.geo = new GeoTransform(); app.geo->setTerrain( mapNode->getTerrain() ); app.pat = new osg::PositionAttitudeTransform(); app.pat->addChild( model ); app.geo->addChild( app.pat ); root->addChild( app.geo ); viewer.setSceneData( root ); viewer.getCamera()->setNearFarRatio(0.00002); viewer.getCamera()->setSmallFeatureCullingPixelSize(-1.0f); ui::ControlCanvas::getOrCreate(&viewer)->addControl( makeUI(app) ); app.apply(); em->setTetherNode( app.geo ); osgEarth::Viewpoint vp; vp.setNode( app.geo ); vp.heading()->set( -45.0, Units::DEGREES ); vp.pitch()->set( -20.0, Units::DEGREES ); vp.range()->set( model->getBound().radius()*10.0, Units::METERS ); em->setViewpoint( vp ); return viewer.run(); }
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; }
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; }
int main(int argc, char** argv) { osg::Group* root = new osg::Group(); // try to load an earth file. osg::ArgumentParser arguments(&argc,argv); osgViewer::Viewer viewer(arguments); unsigned int numObjects = 200; while (arguments.read("--count", numObjects)) {} bool declutter = false; if (arguments.read("--declutter")) declutter = true; // initialize the viewer: viewer.setCameraManipulator( new EarthManipulator() ); // load an earth file and parse demo arguments osg::Node* node = MapNodeHelper().load(arguments, &viewer); if ( !node ) return usage(argv); // find the map node that we loaded. MapNode* mapNode = MapNode::findMapNode(node); if ( !mapNode ) return usage(argv); root->addChild( node ); // Make a group for 2D items, and activate the decluttering engine. Decluttering // will migitate overlap between elements that occupy the same screen real estate. osg::Group* labelGroup = new osg::Group(); if (declutter) { Decluttering::setEnabled( labelGroup->getOrCreateStateSet(), true ); } root->addChild( labelGroup ); // set up a style to use for placemarks: Style placeStyle; placeStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_RELATIVE_TO_TERRAIN; // A lat/long SRS for specifying points. const SpatialReference* geoSRS = mapNode->getMapSRS()->getGeographicSRS(); //-------------------------------------------------------------------- //Create a bunch of placemarks around Mt Rainer so we can actually get some elevation { osg::Image* pin = osgDB::readImageFile( "../data/placemark32.png" ); double centerLat = 46.840866; double centerLon = -121.769846; double height = 0.2; double width = 0.2; double minLat = centerLat - (height/2.0); double minLon = centerLon - (width/2.0); OE_NOTICE << "Placing " << numObjects << " placemarks" << std::endl; for (unsigned int i = 0; i < numObjects; i++) { double lat = minLat + height * (rand() * 1.0)/(RAND_MAX-1); double lon = minLon + width * (rand() * 1.0)/(RAND_MAX-1); PlaceNode* place = new PlaceNode(mapNode, GeoPoint(geoSRS, lon, lat), pin, "Placemark", placeStyle); //Enable occlusion culling. This will hide placemarks that are hidden behind terrain. //This makes use of the OcclusionCullingCallback in CullingUtils. place->setOcclusionCulling( true ); labelGroup->addChild( place ); } } viewer.setSceneData( root ); viewer.getCamera()->addCullCallback( new AutoClipPlaneCullCallback(mapNode) ); viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet())); return viewer.run(); }
int seed( osg::ArgumentParser& args ) { osgDB::Registry::instance()->getReaderWriterForExtension("png"); osgDB::Registry::instance()->getReaderWriterForExtension("jpg"); osgDB::Registry::instance()->getReaderWriterForExtension("tiff"); //Read the min level int minLevel = -1; while (args.read("--min-level", minLevel)); //Read the max level int maxLevel = -1; while (args.read("--max-level", maxLevel)); bool estimate = args.read("--estimate"); std::vector< Bounds > bounds; // restrict packaging to user-specified bounds. double xmin=DBL_MAX, ymin=DBL_MAX, xmax=DBL_MIN, ymax=DBL_MIN; while (args.read("--bounds", xmin, ymin, xmax, ymax )) { Bounds b; b.xMin() = xmin, b.yMin() = ymin, b.xMax() = xmax, b.yMax() = ymax; bounds.push_back( b ); } std::string tileList; while (args.read( "--tiles", tileList ) ); bool verbose = args.read("--verbose"); unsigned int batchSize = 0; args.read("--batchsize", batchSize); // Read the concurrency level unsigned int concurrency = 0; args.read("-c", concurrency); args.read("--concurrency", concurrency); int imageLayerIndex = -1; args.read("--image", imageLayerIndex); int elevationLayerIndex = -1; args.read("--elevation", elevationLayerIndex); //Read in the earth file. osg::ref_ptr<osg::Node> node = osgDB::readNodeFiles( args ); if ( !node.valid() ) return usage( "Failed to read .earth file." ); MapNode* mapNode = MapNode::findMapNode( node.get() ); if ( !mapNode ) return usage( "Input file was not a .earth file" ); // Read in an index shapefile std::string index; while (args.read("--index", index)) { //Open the feature source OGRFeatureOptions featureOpt; featureOpt.url() = index; osg::ref_ptr< FeatureSource > features = FeatureSourceFactory::create( featureOpt ); Status status = features->open(); if (status.isOK()) { osg::ref_ptr< FeatureCursor > cursor = features->createFeatureCursor(0L); while (cursor.valid() && cursor->hasMore()) { osg::ref_ptr< Feature > feature = cursor->nextFeature(); osgEarth::Bounds featureBounds = feature->getGeometry()->getBounds(); GeoExtent ext( feature->getSRS(), featureBounds ); ext = ext.transform( mapNode->getMapSRS() ); bounds.push_back( ext.bounds() ); } } else { OE_WARN << status.message() << "\n"; } } // If they requested to do an estimate then don't do the seed, just print out the estimated values. if (estimate) { CacheEstimator est; if ( minLevel >= 0 ) est.setMinLevel( minLevel ); if ( maxLevel >= 0 ) est.setMaxLevel( maxLevel ); est.setProfile( mapNode->getMap()->getProfile() ); for (unsigned int i = 0; i < bounds.size(); i++) { GeoExtent extent(mapNode->getMapSRS(), bounds[i]); OE_DEBUG << "Adding extent " << extent.toString() << std::endl; est.addExtent( extent ); } unsigned int numTiles = est.getNumTiles(); double size = est.getSizeInMB(); double time = est.getTotalTimeInSeconds(); std::cout << "Cache Estimation " << std::endl << "---------------- " << std::endl << "Total number of tiles: " << numTiles << std::endl << "Size on disk: " << osgEarth::prettyPrintSize( size ) << std::endl << "Total time: " << osgEarth::prettyPrintTime( time ) << std::endl; return 0; } osg::ref_ptr< TileVisitor > visitor; // If we are given a task file, load it up and create a new TileKeyListVisitor if (!tileList.empty()) { TaskList tasks( mapNode->getMap()->getProfile() ); tasks.load( tileList ); TileKeyListVisitor* v = new TileKeyListVisitor(); v->setKeys( tasks.getKeys() ); visitor = v; OE_DEBUG << "Read task list with " << tasks.getKeys().size() << " tasks" << std::endl; } // If we dont' have a visitor create one. if (!visitor.valid()) { if (args.read("--mt")) { // Create a multithreaded visitor MultithreadedTileVisitor* v = new MultithreadedTileVisitor(); if (concurrency > 0) { v->setNumThreads(concurrency); } visitor = v; } else if (args.read("--mp")) { // Create a multiprocess visitor MultiprocessTileVisitor* v = new MultiprocessTileVisitor(); if (concurrency > 0) { v->setNumProcesses(concurrency); } if (batchSize > 0) { v->setBatchSize(batchSize); } // Try to find the earth file std::string earthFile; for(int pos=1;pos<args.argc();++pos) { if (!args.isOption(pos)) { earthFile = args[ pos ]; break; } } v->setEarthFile( earthFile ); visitor = v; } else { // Create a single thread visitor visitor = new TileVisitor(); } } osg::ref_ptr< ProgressCallback > progress = new ConsoleProgressCallback(); if (verbose) { visitor->setProgressCallback( progress.get() ); } if ( minLevel >= 0 ) visitor->setMinLevel( minLevel ); if ( maxLevel >= 0 ) visitor->setMaxLevel( maxLevel ); for (unsigned int i = 0; i < bounds.size(); i++) { GeoExtent extent(mapNode->getMapSRS(), bounds[i]); OE_DEBUG << "Adding extent " << extent.toString() << std::endl; visitor->addExtent( extent ); } // Initialize the seeder CacheSeed seeder; seeder.setVisitor(visitor.get()); osgEarth::Map* map = mapNode->getMap(); // They want to seed an image layer if (imageLayerIndex >= 0) { osg::ref_ptr< ImageLayer > layer = map->getLayerAt<ImageLayer>( imageLayerIndex ); if (layer) { OE_NOTICE << "Seeding single layer " << layer->getName() << std::endl; osg::Timer_t start = osg::Timer::instance()->tick(); seeder.run(layer.get(), map); osg::Timer_t end = osg::Timer::instance()->tick(); if (verbose) { OE_NOTICE << "Completed seeding layer " << layer->getName() << " in " << prettyPrintTime( osg::Timer::instance()->delta_s( start, end ) ) << std::endl; } } else { std::cout << "Failed to find an image layer at index " << imageLayerIndex << std::endl; return 1; } } // They want to seed an elevation layer else if (elevationLayerIndex >= 0) { osg::ref_ptr< ElevationLayer > layer = map->getLayerAt<ElevationLayer>( elevationLayerIndex ); if (layer) { OE_NOTICE << "Seeding single layer " << layer->getName() << std::endl; osg::Timer_t start = osg::Timer::instance()->tick(); seeder.run(layer.get(), map); osg::Timer_t end = osg::Timer::instance()->tick(); if (verbose) { OE_NOTICE << "Completed seeding layer " << layer->getName() << " in " << prettyPrintTime( osg::Timer::instance()->delta_s( start, end ) ) << std::endl; } } else { std::cout << "Failed to find an elevation layer at index " << elevationLayerIndex << std::endl; return 1; } } // They want to seed the entire map else { TerrainLayerVector terrainLayers; map->getLayers(terrainLayers); // Seed all the map layers for (unsigned int i = 0; i < terrainLayers.size(); ++i) { osg::ref_ptr< TerrainLayer > layer = terrainLayers[i].get(); OE_NOTICE << "Seeding layer" << layer->getName() << std::endl; osg::Timer_t start = osg::Timer::instance()->tick(); seeder.run(layer.get(), map); osg::Timer_t end = osg::Timer::instance()->tick(); if (verbose) { OE_NOTICE << "Completed seeding layer " << layer->getName() << " in " << prettyPrintTime( osg::Timer::instance()->delta_s( start, end ) ) << std::endl; } } //for (unsigned int i = 0; i < map->getNumElevationLayers(); ++i) //{ // osg::ref_ptr< ElevationLayer > layer = map->getElevationLayerAt(i); // OE_NOTICE << "Seeding layer" << layer->getName() << std::endl; // osg::Timer_t start = osg::Timer::instance()->tick(); // seeder.run(layer.get(), map); // osg::Timer_t end = osg::Timer::instance()->tick(); // if (verbose) // { // OE_NOTICE << "Completed seeding layer " << layer->getName() << " in " << prettyPrintTime( osg::Timer::instance()->delta_s( start, end ) ) << std::endl; // } //} } return 0; }
int seed( osg::ArgumentParser& args ) { //Read the min level unsigned int minLevel = 0; while (args.read("--min-level", minLevel)); //Read the max level unsigned int maxLevel = 5; while (args.read("--max-level", maxLevel)); std::vector< Bounds > bounds; // restrict packaging to user-specified bounds. double xmin=DBL_MAX, ymin=DBL_MAX, xmax=DBL_MIN, ymax=DBL_MIN; while (args.read("--bounds", xmin, ymin, xmax, ymax )) { Bounds b; b.xMin() = xmin, b.yMin() = ymin, b.xMax() = xmax, b.yMax() = ymax; bounds.push_back( b ); } //Read the cache override directory std::string cachePath; while (args.read("--cache-path", cachePath)); //Read the cache type std::string cacheType; while (args.read("--cache-type", cacheType)); bool verbose = args.read("--verbose"); //Read in the earth file. osg::ref_ptr<osg::Node> node = osgDB::readNodeFiles( args ); if ( !node.valid() ) return usage( "Failed to read .earth file." ); MapNode* mapNode = MapNode::findMapNode( node.get() ); if ( !mapNode ) return usage( "Input file was not a .earth file" ); CacheSeed seeder; seeder.setMinLevel( minLevel ); seeder.setMaxLevel( maxLevel ); // Read in an index shapefile std::string index; while (args.read("--index", index)) { //Open the feature source OGRFeatureOptions featureOpt; featureOpt.url() = index; osg::ref_ptr< FeatureSource > features = FeatureSourceFactory::create( featureOpt ); features->initialize(); features->getFeatureProfile(); osg::ref_ptr< FeatureCursor > cursor = features->createFeatureCursor(); while (cursor.valid() && cursor->hasMore()) { osg::ref_ptr< Feature > feature = cursor->nextFeature(); osgEarth::Bounds featureBounds = feature->getGeometry()->getBounds(); GeoExtent ext( feature->getSRS(), featureBounds ); ext = ext.transform( mapNode->getMapSRS() ); bounds.push_back( ext.bounds() ); } } for (unsigned int i = 0; i < bounds.size(); i++) { GeoExtent extent(mapNode->getMapSRS(), bounds[i]); OE_DEBUG << "Adding extent " << extent.toString() << std::endl; seeder.addExtent( extent ); } if (verbose) { seeder.setProgressCallback(new ConsoleProgressCallback); } osg::Timer_t start = osg::Timer::instance()->tick(); seeder.seed( mapNode->getMap() ); osg::Timer_t end = osg::Timer::instance()->tick(); OE_NOTICE << "Completed seeding in " << prettyPrintTime( osg::Timer::instance()->delta_s( start, end ) ) << std::endl; return 0; }
osg::Group* addLights(osg::View* view, osg::Node* root, int lightNum) { MapNode* mapNode = MapNode::get(root); const SpatialReference* mapsrs = mapNode->getMapSRS(); const SpatialReference* geosrs = mapsrs->getGeographicSRS(); osg::Vec3d world; osg::Group* lights = new osg::Group(); // Add a directional light that simulates the sun - but skip this if a sky // was already added in the earth file. if (lightNum == 0) { Ephemeris e; DateTime dt(2016, 8, 10, 14.0); CelestialBody sun = e.getSunPosition(dt); world = sun.geocentric; osg::Light* sunLight = new osg::Light(lightNum++); world.normalize(); sunLight->setPosition(osg::Vec4d(world, 0.0)); sunLight->setAmbient(osg::Vec4(0.2, 0.2, 0.2, 1.0)); sunLight->setDiffuse(osg::Vec4(1.0, 1.0, 0.9, 1.0)); osg::LightSource* sunLS = new osg::LightSource(); sunLS->setLight(sunLight); lights->addChild( sunLS ); ShadowCaster* caster = osgEarth::findTopMostNodeOfType<ShadowCaster>(root); if (caster) { OE_INFO << "Found a shadow caster!\n"; caster->setLight(sunLight); } } #if 1 // A red spot light. A spot light has a real position in space // and points in a specific direciton. The Cutoff and Exponent // properties control the cone angle and sharpness, respectively { GeoPoint p(geosrs, -121, 34, 5000000., ALTMODE_ABSOLUTE); p.toWorld(world); osg::Light* spot = new osg::Light(lightNum++); spot->setPosition(worldToVec4(world)); spot->setAmbient(osg::Vec4(0,0.2,0,1)); spot->setDiffuse(osg::Vec4(1,0,0,1)); spot->setSpotCutoff(20.0f); spot->setSpotExponent(100.0f); // point straight down at the map: world.normalize(); spot->setDirection(-world); osg::LightSource* spotLS = new osg::LightSource(); spotLS->setLight(spot); lights->addChild( spotLS ); } // A green point light. A Point light lives at a real location in // space and lights equally in all directions. { GeoPoint p(geosrs, -45, -35, 1000000., ALTMODE_ABSOLUTE); p.toWorld(world); osg::Light* point = new osg::Light(lightNum++); point->setPosition(worldToVec4(world)); point->setAmbient(osg::Vec4(0,0,0,1)); point->setDiffuse(osg::Vec4(1.0, 1.0, 0.0,1)); osg::LightSource* pointLS = new osg::LightSource(); pointLS->setLight(point); lights->addChild( pointLS ); } #endif // Generate the necessary uniforms for the shaders. GenerateGL3LightingUniforms gen; lights->accept(gen); return lights; }
int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc,argv); // help? if ( arguments.read("--help") ) return usage(argv[0]); // create a viewer: osgViewer::Viewer viewer(arguments); // Tell the database pager to not modify the unref settings viewer.getDatabasePager()->setUnrefImageDataAfterApplyPolicy( false, false ); // install our default manipulator (do this before calling load) viewer.setCameraManipulator( new osgEarth::Util::EarthManipulator() ); // load an earth file, and support all or our example command-line options // and earth file <external> tags osg::Group* node = MapNodeHelper().load(arguments, &viewer, createUI()); if ( node ) { // Make sure we don't already have a sky. SkyNode* skyNode = osgEarth::findTopMostNodeOfType<SkyNode>(node); if (skyNode) { OE_WARN << LC << "Earth file already has a Sky. This example requires an " "earth file that does not use a sky already.\n"; return -1; } viewer.getCamera()->setNearFarRatio(0.00002); viewer.getCamera()->setSmallFeatureCullingPixelSize(-1.0f); MapNode* mapNode = MapNode::findMapNode( node ); // Create SilverLiningNode from SilverLiningOptions osgEarth::SilverLining::SilverLiningOptions slOptions; slOptions.user() = "my_user_name"; slOptions.licenseCode() = "my_license_code"; slOptions.cloudsMaxAltitude() = 100000; const char* ev_sl = ::getenv("SILVERLINING_PATH"); if ( ev_sl ) { slOptions.resourcePath() = osgDB::concatPaths( std::string(ev_sl), "Resources" ); } else { OE_WARN << LC << "No resource path! SilverLining might not initialize properly. " << "Consider setting the SILVERLINING_PATH environment variable." << std::endl; } // TODO: uncommenting the callback on the following line results in a crash when SeedClouds is called. s_settings.sky = new SilverLiningNode( mapNode->getMapSRS(), slOptions, new SLCallback() ); // insert the new sky above the map node. osgEarth::insertParent(s_settings.sky, mapNode); // use the topmost node. viewer.setSceneData(osgEarth::findTopOfGraph(node)); // connects the sky's light to the viewer. s_settings.sky->attach(&viewer); return viewer.run(); } else { return usage(argv[0]); } }
int main(int argc, char** argv) { osg::Group* root = new osg::Group(); // try to load an earth file. osg::ArgumentParser arguments(&argc,argv); osgViewer::Viewer viewer(arguments); viewer.setCameraManipulator( new EarthManipulator() ); // load an earth file and parse demo arguments osg::Node* node = MapNodeHelper().load(arguments, &viewer); if ( !node ) return usage(argv); root->addChild( node ); // find the map node that we loaded. MapNode* mapNode = MapNode::findMapNode(node); if ( !mapNode ) return usage(argv); // Group to hold all our annotation elements. osg::Group* annoGroup = new osg::Group(); root->addChild( annoGroup ); //A group for all the editors osg::Group* editorGroup = new osg::Group; root->addChild( editorGroup ); editorGroup->setNodeMask( 0 ); HBox* box = ControlCanvas::getOrCreate(&viewer)->addControl( new HBox() ); box->setChildSpacing( 5 ); //Add a toggle button to toggle editing CheckBoxControl* editCheckbox = new CheckBoxControl( false ); editCheckbox->addEventHandler( new ToggleNodeHandler( editorGroup ) ); box->addControl( editCheckbox ); LabelControl* labelControl = new LabelControl( "Edit Annotations" ); labelControl->setFontSize( 24.0f ); box->addControl( labelControl ); // Make a group for 2D items, and activate the decluttering engine. Decluttering // will migitate overlap between elements that occupy the same screen real estate. osg::Group* labelGroup = new osg::Group(); Decluttering::setEnabled( labelGroup->getOrCreateStateSet(), true ); annoGroup->addChild( labelGroup ); // Style our labels: Style labelStyle; labelStyle.getOrCreate<TextSymbol>()->alignment() = TextSymbol::ALIGN_CENTER_CENTER; labelStyle.getOrCreate<TextSymbol>()->fill()->color() = Color::Yellow; // A lat/long SRS for specifying points. const SpatialReference* geoSRS = mapNode->getMapSRS()->getGeographicSRS(); //-------------------------------------------------------------------- // A series of place nodes (an icon with a text label) { Style pin; pin.getOrCreate<IconSymbol>()->url()->setLiteral( "../data/placemark32.png" ); // bunch of pins: labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, -74.00, 40.71), "New York" , pin)); labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, -77.04, 38.85), "Washington, DC", pin)); labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS,-118.40, 33.93), "Los Angeles" , pin)); labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, -71.03, 42.37), "Boston" , pin)); labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS,-157.93, 21.35), "Honolulu" , pin)); labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, 139.75, 35.68), "Tokyo" , pin)); labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, -90.25, 29.98), "New Orleans" , pin)); labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, -80.28, 25.82), "Miami" , pin)); labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS,-117.17, 32.72), "San Diego" , pin)); // test with an LOD: osg::LOD* lod = new osg::LOD(); lod->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, 14.68, 50.0), "Prague", pin), 0.0, 1e6); labelGroup->addChild( lod ); // absolute altitude: labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, -87.65, 41.90, 1000, ALTMODE_ABSOLUTE), "Chicago" , pin)); } //-------------------------------------------------------------------- // a box that follows lines of latitude (rhumb line interpolation, the default) { Geometry* geom = new Polygon(); geom->push_back( osg::Vec3d(0, 40, 0) ); geom->push_back( osg::Vec3d(-60, 40, 0) ); geom->push_back( osg::Vec3d(-60, 60, 0) ); geom->push_back( osg::Vec3d(0, 60, 0) ); Style geomStyle; geomStyle.getOrCreate<LineSymbol>()->stroke()->color() = Color::Cyan; geomStyle.getOrCreate<LineSymbol>()->stroke()->width() = 5.0f; geomStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN; geomStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_GPU; FeatureNode* gnode = new FeatureNode(mapNode, new Feature(geom, geoSRS, geomStyle)); annoGroup->addChild( gnode ); labelGroup->addChild( new LabelNode(mapNode, GeoPoint(geoSRS,-30, 50), "Rhumb line polygon", labelStyle) ); } //-------------------------------------------------------------------- // another rhumb box that crosses the antimeridian { Geometry* geom = new Polygon(); geom->push_back( -160., -30. ); geom->push_back( 150., -20. ); geom->push_back( 160., -45. ); geom->push_back( -150., -40. ); Style geomStyle; geomStyle.getOrCreate<LineSymbol>()->stroke()->color() = Color::Lime; geomStyle.getOrCreate<LineSymbol>()->stroke()->width() = 3.0f; geomStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN; geomStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_GPU; FeatureNode* gnode = new FeatureNode(mapNode, new Feature(geom, geoSRS, geomStyle)); annoGroup->addChild( gnode ); labelGroup->addChild( new LabelNode(mapNode, GeoPoint(geoSRS, -175, -35), "Antimeridian polygon", labelStyle) ); } //-------------------------------------------------------------------- // A path using great-circle interpolation. { Geometry* path = new LineString(); path->push_back( osg::Vec3d(-74, 40.714, 0) ); // New York path->push_back( osg::Vec3d(139.75, 35.68, 0) ); // Tokyo Style pathStyle; pathStyle.getOrCreate<LineSymbol>()->stroke()->color() = Color::Red; pathStyle.getOrCreate<LineSymbol>()->stroke()->width() = 3.0f; pathStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN; pathStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_GPU; Feature* pathFeature = new Feature(path, geoSRS, pathStyle); pathFeature->geoInterp() = GEOINTERP_GREAT_CIRCLE; //OE_INFO << "Path extent = " << pathFeature->getExtent().toString() << std::endl; FeatureNode* pathNode = new FeatureNode(mapNode, pathFeature); annoGroup->addChild( pathNode ); labelGroup->addChild( new LabelNode(mapNode, GeoPoint(geoSRS,-170, 61.2), "Great circle path", labelStyle) ); } //-------------------------------------------------------------------- // Two circle segments around New Orleans. { Style circleStyle; circleStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Cyan, 0.5); circleStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN; circleStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_DRAPE; CircleNode* circle = new CircleNode( mapNode, GeoPoint(geoSRS, -90.25, 29.98, 1000., ALTMODE_RELATIVE), Distance(300, Units::KILOMETERS), circleStyle, Angle(-45.0, Units::DEGREES), Angle(45.0, Units::DEGREES), true); annoGroup->addChild( circle ); editorGroup->addChild( new CircleNodeEditor( circle ) ); } { Style circleStyle; circleStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Red, 0.5); circleStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN; circleStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_DRAPE; CircleNode* circle = new CircleNode( mapNode, GeoPoint(geoSRS, -90.25, 29.98, 1000., ALTMODE_RELATIVE), Distance(300, Units::KILOMETERS), circleStyle, Angle(45.0, Units::DEGREES), Angle(360.0 - 45.0, Units::DEGREES), true); annoGroup->addChild( circle ); editorGroup->addChild( new CircleNodeEditor( circle ) ); } //-------------------------------------------------------------------- // An extruded ellipse around Miami. { Style ellipseStyle; ellipseStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Orange, 0.75); ellipseStyle.getOrCreate<ExtrusionSymbol>()->height() = 250000.0; // meters MSL EllipseNode* ellipse = new EllipseNode( mapNode, GeoPoint(geoSRS, -80.28, 25.82, 0.0, ALTMODE_RELATIVE), Distance(250, Units::MILES), Distance(100, Units::MILES), Angle (0, Units::DEGREES), ellipseStyle, Angle(45.0, Units::DEGREES), Angle(360.0 - 45.0, Units::DEGREES), true); annoGroup->addChild( ellipse ); editorGroup->addChild( new EllipseNodeEditor( ellipse ) ); } { Style ellipseStyle; ellipseStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Blue, 0.75); ellipseStyle.getOrCreate<ExtrusionSymbol>()->height() = 250000.0; // meters MSL EllipseNode* ellipse = new EllipseNode( mapNode, GeoPoint(geoSRS, -80.28, 25.82, 0.0, ALTMODE_RELATIVE), Distance(250, Units::MILES), Distance(100, Units::MILES), Angle (0, Units::DEGREES), ellipseStyle, Angle(-40.0, Units::DEGREES), Angle(40.0, Units::DEGREES), true); annoGroup->addChild( ellipse ); editorGroup->addChild( new EllipseNodeEditor( ellipse ) ); } //-------------------------------------------------------------------- { // A rectangle around San Diego Style rectStyle; rectStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Green, 0.5); rectStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN; rectStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_DRAPE; RectangleNode* rect = new RectangleNode( mapNode, GeoPoint(geoSRS, -117.172, 32.721), Distance(300, Units::KILOMETERS ), Distance(600, Units::KILOMETERS ), rectStyle); annoGroup->addChild( rect ); editorGroup->addChild( new RectangleNodeEditor( rect ) ); } //-------------------------------------------------------------------- // An extruded polygon roughly the shape of Utah. Here we demonstrate the // FeatureNode, where you create a geographic geometry and use it as an // annotation. { Geometry* utah = new Polygon(); utah->push_back( -114.052, 37.0 ); utah->push_back( -109.054, 37.0 ); utah->push_back( -109.054, 41.0 ); utah->push_back( -111.040, 41.0 ); utah->push_back( -111.080, 42.059 ); utah->push_back( -114.080, 42.024 ); Style utahStyle; utahStyle.getOrCreate<ExtrusionSymbol>()->height() = 250000.0; // meters MSL utahStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::White, 0.8); Feature* utahFeature = new Feature(utah, geoSRS, utahStyle); FeatureNode* featureNode = new FeatureNode(mapNode, utahFeature); annoGroup->addChild( featureNode ); } //-------------------------------------------------------------------- // an image overlay. { ImageOverlay* imageOverlay = 0L; osg::Image* image = osgDB::readImageFile( "../data/USFLAG.TGA" ); if ( image ) { imageOverlay = new ImageOverlay(mapNode, image); imageOverlay->setBounds( Bounds( -100.0, 35.0, -90.0, 40.0) ); annoGroup->addChild( imageOverlay ); editorGroup->addChild( new ImageOverlayEditor( imageOverlay ) ); } } //-------------------------------------------------------------------- // install decoration. These change the appearance of an Annotation // based on some user action. // highlight annotation upon hover by default: DecorationInstaller highlightInstaller("hover", new HighlightDecoration()); annoGroup->accept( highlightInstaller ); // scale labels when hovering: DecorationInstaller scaleInstaller("hover", new ScaleDecoration(1.1f)); labelGroup->accept( scaleInstaller ); // install an event handler for picking and hovering. AnnotationEventCallback* cb = new AnnotationEventCallback(); cb->addHandler( new MyAnnoEventHandler() ); annoGroup->addEventCallback( cb ); //-------------------------------------------------------------------- // initialize the viewer: viewer.setSceneData( root ); viewer.getCamera()->addCullCallback( new AutoClipPlaneCullCallback(mapNode) ); viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet())); return viewer.run(); }
int main(int argc, char** argv) { osg::Group* root = new osg::Group(); // try to load an earth file. osg::ArgumentParser arguments(&argc,argv); osgViewer::Viewer viewer(arguments); viewer.setCameraManipulator( new EarthManipulator() ); // load an earth file and parse demo arguments osg::Node* node = MapNodeHelper().load(arguments, &viewer); if ( !node ) return usage(argv); root->addChild( node ); // find the map node that we loaded. MapNode* mapNode = MapNode::findMapNode(node); if ( !mapNode ) return usage(argv); // Group to hold all our annotation elements. osg::Group* annoGroup = new osg::Group(); root->addChild( annoGroup ); // Make a group for labels osg::Group* labelGroup = new osg::Group(); annoGroup->addChild( labelGroup ); osg::Group* editGroup = new osg::Group(); root->addChild( editGroup ); // Style our labels: Style labelStyle; labelStyle.getOrCreate<TextSymbol>()->alignment() = TextSymbol::ALIGN_CENTER_CENTER; labelStyle.getOrCreate<TextSymbol>()->fill()->color() = Color::Yellow; // A lat/long SRS for specifying points. const SpatialReference* geoSRS = mapNode->getMapSRS()->getGeographicSRS(); //-------------------------------------------------------------------- // A series of place nodes (an icon with a text label) { Style pm; pm.getOrCreate<IconSymbol>()->url()->setLiteral( "../data/placemark32.png" ); pm.getOrCreate<IconSymbol>()->declutter() = true; pm.getOrCreate<TextSymbol>()->halo() = Color("#5f5f5f"); // bunch of pins: labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, -74.00, 40.71), "New York" , pm)); labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, -77.04, 38.85), "Washington, DC", pm)); labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS,-118.40, 33.93), "Los Angeles" , pm)); labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, -71.03, 42.37), "Boston" , pm)); labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS,-157.93, 21.35), "Honolulu" , pm)); labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, 139.75, 35.68), "Tokyo" , pm)); labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, -90.25, 29.98), "New Orleans" , pm)); labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, -80.28, 25.82), "Miami" , pm)); labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS,-117.17, 32.72), "San Diego" , pm)); // test with an LOD: osg::LOD* lod = new osg::LOD(); lod->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, 14.68, 50.0), "Prague", pm), 0.0, 2e6); labelGroup->addChild( lod ); // absolute altitude: labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, -87.65, 41.90, 1000, ALTMODE_ABSOLUTE), "Chicago", pm)); } //-------------------------------------------------------------------- // a box that follows lines of latitude (rhumb line interpolation, the default) { Geometry* geom = new Polygon(); geom->push_back( osg::Vec3d(0, 40, 0) ); geom->push_back( osg::Vec3d(-60, 40, 0) ); geom->push_back( osg::Vec3d(-60, 60, 0) ); geom->push_back( osg::Vec3d(0, 60, 0) ); Feature* feature = new Feature(geom, geoSRS); feature->geoInterp() = GEOINTERP_RHUMB_LINE; Style geomStyle; geomStyle.getOrCreate<LineSymbol>()->stroke()->color() = Color::Cyan; geomStyle.getOrCreate<LineSymbol>()->stroke()->width() = 5.0f; geomStyle.getOrCreate<LineSymbol>()->tessellationSize() = 75000; geomStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN; geomStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_GPU; FeatureNode* fnode = new FeatureNode(mapNode, feature, geomStyle); annoGroup->addChild( fnode ); labelGroup->addChild( new LabelNode(mapNode, GeoPoint(geoSRS,-30, 50), "Rhumb line polygon", labelStyle) ); } //-------------------------------------------------------------------- // another rhumb box that crosses the antimeridian { Geometry* geom = new Polygon(); geom->push_back( -160., -30. ); geom->push_back( 150., -20. ); geom->push_back( 160., -45. ); geom->push_back( -150., -40. ); Style geomStyle; Feature* feature = new Feature(geom, geoSRS); feature->geoInterp() = GEOINTERP_RHUMB_LINE; geomStyle.getOrCreate<LineSymbol>()->stroke()->color() = Color::Lime; geomStyle.getOrCreate<LineSymbol>()->stroke()->width() = 3.0f; geomStyle.getOrCreate<LineSymbol>()->tessellationSize() = 75000; geomStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN; geomStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_GPU; FeatureNode* gnode = new FeatureNode(mapNode, feature, geomStyle); annoGroup->addChild( gnode ); labelGroup->addChild( new LabelNode(mapNode, GeoPoint(geoSRS, -175, -35), "Antimeridian polygon", labelStyle) ); } //-------------------------------------------------------------------- // A path using great-circle interpolation. // Keep a pointer to it so we can modify it later on. FeatureNode* pathNode = 0; { Geometry* path = new LineString(); path->push_back( osg::Vec3d(-74, 40.714, 0) ); // New York path->push_back( osg::Vec3d(139.75, 35.68, 0) ); // Tokyo Feature* pathFeature = new Feature(path, geoSRS); pathFeature->geoInterp() = GEOINTERP_GREAT_CIRCLE; Style pathStyle; pathStyle.getOrCreate<LineSymbol>()->stroke()->color() = Color::White; pathStyle.getOrCreate<LineSymbol>()->stroke()->width() = 1.0f; pathStyle.getOrCreate<LineSymbol>()->tessellationSize() = 75000; pathStyle.getOrCreate<PointSymbol>()->size() = 5; pathStyle.getOrCreate<PointSymbol>()->fill()->color() = Color::Red; pathStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN; pathStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_GPU; //OE_INFO << "Path extent = " << pathFeature->getExtent().toString() << std::endl; pathNode = new FeatureNode(mapNode, pathFeature, pathStyle); annoGroup->addChild( pathNode ); labelGroup->addChild( new LabelNode(mapNode, GeoPoint(geoSRS,-170, 61.2), "Great circle path", labelStyle) ); } //-------------------------------------------------------------------- // Two circle segments around New Orleans. { Style circleStyle; circleStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Cyan, 0.5); circleStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN; circleStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_DRAPE; CircleNode* circle = new CircleNode( mapNode, GeoPoint(geoSRS, -90.25, 29.98, 1000., ALTMODE_RELATIVE), Distance(300, Units::KILOMETERS), circleStyle, Angle(-45.0, Units::DEGREES), Angle(45.0, Units::DEGREES), true); annoGroup->addChild( circle ); editGroup->addChild( new CircleNodeEditor(circle) ); } { Style circleStyle; circleStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Red, 0.5); circleStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN; circleStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_DRAPE; CircleNode* circle = new CircleNode( mapNode, GeoPoint(geoSRS, -90.25, 29.98, 1000., ALTMODE_RELATIVE), Distance(300, Units::KILOMETERS), circleStyle, Angle(45.0, Units::DEGREES), Angle(360.0 - 45.0, Units::DEGREES), true); annoGroup->addChild( circle ); editGroup->addChild( new CircleNodeEditor(circle) ); } //-------------------------------------------------------------------- // An extruded ellipse around Miami. { Style ellipseStyle; ellipseStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Orange, 0.75); ellipseStyle.getOrCreate<ExtrusionSymbol>()->height() = 250000.0; // meters MSL EllipseNode* ellipse = new EllipseNode( mapNode, GeoPoint(geoSRS, -80.28, 25.82, 0.0, ALTMODE_RELATIVE), Distance(250, Units::MILES), Distance(100, Units::MILES), Angle (0, Units::DEGREES), ellipseStyle, Angle(45.0, Units::DEGREES), Angle(360.0 - 45.0, Units::DEGREES), true); annoGroup->addChild( ellipse ); editGroup->addChild( new EllipseNodeEditor(ellipse) ); } { Style ellipseStyle; ellipseStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Blue, 0.75); ellipseStyle.getOrCreate<ExtrusionSymbol>()->height() = 250000.0; // meters MSL EllipseNode* ellipse = new EllipseNode( mapNode, GeoPoint(geoSRS, -80.28, 25.82, 0.0, ALTMODE_RELATIVE), Distance(250, Units::MILES), Distance(100, Units::MILES), Angle (0, Units::DEGREES), ellipseStyle, Angle(-40.0, Units::DEGREES), Angle(40.0, Units::DEGREES), true); annoGroup->addChild( ellipse ); editGroup->addChild( new EllipseNodeEditor(ellipse) ); } //-------------------------------------------------------------------- { // A rectangle around San Diego Style rectStyle; rectStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Green, 0.5); rectStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN; rectStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_DRAPE; RectangleNode* rect = new RectangleNode( mapNode, GeoPoint(geoSRS, -117.172, 32.721), Distance(300, Units::KILOMETERS ), Distance(600, Units::KILOMETERS ), rectStyle); annoGroup->addChild( rect ); editGroup->addChild( new RectangleNodeEditor(rect) ); } //-------------------------------------------------------------------- // An extruded polygon roughly the shape of Utah. Here we demonstrate the // FeatureNode, where you create a geographic geometry and use it as an // annotation. { Geometry* utah = new Polygon(); utah->push_back( -114.052, 37.0 ); utah->push_back( -109.054, 37.0 ); utah->push_back( -109.054, 41.0 ); utah->push_back( -111.040, 41.0 ); utah->push_back( -111.080, 42.059 ); utah->push_back( -114.080, 42.024 ); Style utahStyle; utahStyle.getOrCreate<ExtrusionSymbol>()->height() = 250000.0; // meters MSL utahStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::White, 0.8); Feature* utahFeature = new Feature(utah, geoSRS); FeatureNode* featureNode = new FeatureNode(mapNode, utahFeature, utahStyle); annoGroup->addChild( featureNode ); } //-------------------------------------------------------------------- // an image overlay. { ImageOverlay* imageOverlay = 0L; osg::Image* image = osgDB::readImageFile( "../data/USFLAG.TGA" ); if ( image ) { imageOverlay = new ImageOverlay(mapNode, image); imageOverlay->setBounds( Bounds( -100.0, 35.0, -90.0, 40.0) ); annoGroup->addChild( imageOverlay ); editGroup->addChild( new ImageOverlayEditor(imageOverlay) ); } } //-------------------------------------------------------------------- // initialize the viewer: viewer.setSceneData( root ); viewer.getCamera()->setSmallFeatureCullingPixelSize(-1.0f); return viewer.run(); }