bool TileMapServiceReader::read( const Config& conf, TileMapEntryList& tileMaps) { const Config* TileMapServiceConf = conf.find("tilemapservice"); if (!TileMapServiceConf) { OE_NOTICE << "Couldn't find root TileMapService element" << std::endl; return false; } const Config* TileMapsConf = TileMapServiceConf->find("tilemaps"); if (TileMapsConf) { const ConfigSet& TileMaps = TileMapsConf->children("tilemap"); if (TileMaps.size() == 0) { return false; } for (ConfigSet::const_iterator itr = TileMaps.begin(); itr != TileMaps.end(); ++itr) { std::string href = itr->value("href"); std::string title = itr->value("title"); std::string profile = itr->value("profile"); std::string srs = itr->value("srs"); tileMaps.push_back( TileMapEntry( title, href, srs, profile ) ); } return true; } return false; }
Biome::Biome(const Config& conf) { conf.getIfSet( "name", _name ); conf.getIfSet( "catalog", _catalogURI ); // only supports lat long for now const SpatialReference* srs = SpatialReference::create("wgs84"); const Config& extentsConf = conf.child("regions"); for(ConfigSet::const_iterator i = extentsConf.children().begin(); i != extentsConf.children().end(); ++i) { double xmin = i->value("xmin", -DBL_MAX); double xmax = i->value("xmax", DBL_MAX); double ymin = i->value("ymin", -DBL_MAX); double ymax = i->value("ymax", DBL_MAX); double zmin = i->value("zmin", -DBL_MAX); double zmax = i->value("zmax", DBL_MAX); _regions.push_back( Region() ); _regions.back().extent = GeoExtent(srs, xmin, ymin, xmax, ymax); _regions.back().zmin = zmin; _regions.back().zmax = zmax; } }
void KML_Model::parseStyle(const Config& conf, KMLContext& cx, Style& style) { ModelSymbol* model = 0L; std::string url = KMLUtils::parseLink(conf); if ( !url.empty() ) { if ( !model ) model = style.getOrCreate<ModelSymbol>(); model->url()->setLiteral( url ); model->url()->setURIContext( URIContext(conf.referrer()) ); } Config scale = conf.child("scale"); if (!scale.empty()) { if ( !model ) model = style.getOrCreate<ModelSymbol>(); //TODO: Support XYZ scale instead of single value model->scale() = scale.value("x", 1.0); } Config orientation = conf.child("orientation"); if (!orientation.empty()) { if ( !model ) model = style.getOrCreate<ModelSymbol>(); double h = orientation.value("heading", 0); if ( !osg::equivalent(h, 0.0) ) model->heading() = NumericExpression( h ); double p = orientation.value("tilt", 0); if ( !osg::equivalent(p, 0.0) ) model->pitch() = NumericExpression( p ); double r = orientation.value("roll", 0); if ( !osg::equivalent(r, 0.0) ) model->roll() = NumericExpression( r ); } // Read and store file path aliases from a KML ResourceMap. Config resource_map = conf.child("resourcemap"); if ( !resource_map.empty() ) { const ConfigSet aliases = resource_map.children("alias"); for( ConfigSet::const_iterator i = aliases.begin(); i != aliases.end(); ++i ) { std::string source = i->value("sourcehref"); std::string target = i->value("targethref"); if ( !source.empty() || !target.empty() ) { if ( !model ) model = style.getOrCreate<ModelSymbol>(); model->uriAliasMap()->insert( source, target ); } } } KML_Geometry::parseStyle(conf, cx, style); }
const EglConfigImpl* EglDisplayImpl::GetConfig(EGLConfig cfg) const { for (ConfigSet::const_iterator i = configs_.begin(); i != configs_.end(); ++i) { if (i->GetKey() == cfg) { return &*i; } } return NULL; }
const Config& Config::child( const std::string& childName ) const { for( ConfigSet::const_iterator i = _children.begin(); i != _children.end(); i++ ) { if ( i->key() == childName ) return *i; } return emptyConfig(); }
const Config* Config::child_ptr( const std::string& childName ) const { for( ConfigSet::const_iterator i = _children.begin(); i != _children.end(); i++ ) { if ( i->key() == childName ) return &(*i); } return 0L; }
bool EglDisplayImpl::IsValidConfig(EGLConfig config) const { for (ConfigSet::const_iterator i = configs_.begin(); i != configs_.end(); ++i) { if (config == i->GetKey()) { return true; } } return false; }
void ShaderOptions::fromConfig(const Config& conf) { _code = conf.value(); _samplers.clear(); ConfigSet s = conf.children("sampler"); for (ConfigSet::const_iterator i = s.begin(); i != s.end(); ++i) { _samplers.push_back(Sampler()); _samplers.back()._name = i->value("name"); const Config* urlarray = i->find("array"); if (urlarray) { ConfigSet uris = urlarray->children("url"); for (ConfigSet::const_iterator j = uris.begin(); j != uris.end(); ++j) { URI uri(j->value(), URIContext(conf.referrer())); _samplers.back()._uris.push_back(uri); } } else { optional<URI> uri; i->get("url", uri); if (uri.isSet()) _samplers.back()._uris.push_back(uri.get()); } } s = conf.children("uniform"); for (ConfigSet::const_iterator i = s.begin(); i != s.end(); ++i) { _uniforms.push_back(Uniform()); _uniforms.back()._name = i->value("name"); i->get("value", _uniforms.back()._value); } }
void Config::merge( const Config& rhs ) { // remove any matching keys first; this will allow the addition of multi-key values for( ConfigSet::const_iterator c = rhs._children.begin(); c != rhs._children.end(); ++c ) remove( c->key() ); // add in the new values. for( ConfigSet::const_iterator c = rhs._children.begin(); c != rhs._children.end(); ++c ) add( *c ); }
TerrainLayer::CacheBinMetadata::CacheBinMetadata(const Config& conf) { _valid = !conf.empty(); conf.getIfSet("cachebin_id", _cacheBinId); conf.getIfSet("source_name", _sourceName); conf.getIfSet("source_driver", _sourceDriver); conf.getIfSet("source_tile_size", _sourceTileSize); conf.getObjIfSet("source_profile", _sourceProfile); conf.getObjIfSet("cache_profile", _cacheProfile); conf.getIfSet("cache_create_time", _cacheCreateTime); const Config* extentsRoot = conf.child_ptr("extents"); if ( extentsRoot ) { const ConfigSet& extents = extentsRoot->children(); for (ConfigSet::const_iterator i = extents.begin(); i != extents.end(); ++i) { std::string srsString; double xmin, ymin, xmax, ymax; optional<unsigned> minLevel, maxLevel; srsString = i->value("srs"); xmin = i->value("xmin", 0.0f); ymin = i->value("ymin", 0.0f); xmax = i->value("xmax", 0.0f); ymax = i->value("ymax", 0.0f); i->getIfSet("minlevel", minLevel); i->getIfSet("maxlevel", maxLevel); const SpatialReference* srs = SpatialReference::get(srsString); DataExtent e( GeoExtent(srs, xmin, ymin, xmax, ymax) ); if (minLevel.isSet()) e.minLevel() = minLevel.get(); if (maxLevel.isSet()) e.maxLevel() = maxLevel.get(); _dataExtents.push_back(e); } } // check for validity. This will reject older caches that don't have // sufficient attribution. if (_valid) { if (!conf.hasValue("source_tile_size") || !conf.hasChild("source_profile") || !conf.hasChild("cache_profile")) { _valid = false; } } }
Config Config::operator - ( const Config& rhs ) const { Config result( *this ); for( ConfigSet::const_iterator i = rhs.children().begin(); i != rhs.children().end(); ++i ) { result.remove( i->key() ); } return result; }
Config Config::child( const std::string& childName ) const { for( ConfigSet::const_iterator i = _children.begin(); i != _children.end(); i++ ) { if ( i->key() == childName ) return *i; } Config emptyConf; emptyConf.setReferrer( _referrer ); return emptyConf; }
void ZoneOptions::fromConfig(const Config& conf) { conf.getIfSet("name", _name); const Config* boundaries = conf.child_ptr("boundaries"); if ( boundaries ) { for(ConfigSet::const_iterator i = boundaries->children().begin(); i != boundaries->children().end(); ++i) { _boundaries.push_back(osg::BoundingBox( i->value("xmin", -FLT_MAX), i->value("ymin", -FLT_MAX), i->value("zmin", -FLT_MAX), i->value("xmax", FLT_MAX), i->value("ymax", FLT_MAX), i->value("zmax", FLT_MAX))); } } conf.getObjIfSet( "surface", _surface ); conf.getObjIfSet( "land_cover", _landCover ); }
XmlElement::XmlElement( const Config& conf ) { name = conf.key(); for( Properties::const_iterator i = conf.attrs().begin(); i != conf.attrs().end(); i++ ) attrs[i->first] = i->second; for( ConfigSet::const_iterator j = conf.children().begin(); j != conf.children().end(); j++ ) { if (!j->children().empty()) { children.push_back( new XmlElement( *j ) ); } else { addSubElement(j->key(), j->attrs(), j->value()); } } }
const Config* Config::find( const std::string& key, bool checkMe ) const { if ( checkMe && key == this->key() ) return this; for( ConfigSet::const_iterator c = _children.begin(); c != _children.end(); ++c ) if ( key == c->key() ) return &(*c); for( ConfigSet::const_iterator c = _children.begin(); c != _children.end(); ++c ) { const Config* r = c->find(key, false); if ( r ) return r; } return 0L; }
void ChromeMetricsBackend::end(const std::string& name, const Config& args) { osg::Timer_t now = osg::Timer::instance()->tick(); OpenThreads::ScopedLock< OpenThreads::Mutex > lk(_mutex); if (_firstEvent) { _firstEvent = false; } else { _metricsFile << "," << std::endl; } _metricsFile << "{" << "\"cat\": \"" << "" << "\"," << "\"pid\": \"" << 0 << "\"," << "\"tid\": \"" << osgEarth::Threading::getCurrentThreadId() << "\"," << "\"ts\": \"" << std::setprecision(9) << osg::Timer::instance()->delta_u(_startTime, now) << "\"," << "\"ph\": \"E\"," << "\"name\": \"" << name << "\""; if (!args.empty()) { _metricsFile << "," << std::endl << " \"args\": {"; bool first = true; for( ConfigSet::const_iterator i = args.children().begin(); i != args.children().end(); ++i ) { if (first) { first = !first; } else { _metricsFile << "," << std::endl; } _metricsFile << "\"" << i->key() << "\" : \"" << i->value() << "\""; } _metricsFile << "}"; } _metricsFile << "}"; }
void SplatCoverageLegend::fromConfig(const Config& conf) { conf.get("name", _name); conf.get("source", _source); ConfigSet predicatesConf = conf.child("mappings").children(); for(ConfigSet::const_iterator i = predicatesConf.begin(); i != predicatesConf.end(); ++i) { osg::ref_ptr<CoverageValuePredicate> p = new CoverageValuePredicate(); i->get( "name", p->_description ); i->get( "value", p->_exactValue ); i->get( "class", p->_mappedClassName ); if ( p->_mappedClassName.isSet() ) { _predicates.push_back( p.get() ); } } }
XmlElement::XmlElement( const Config& conf ) { name = conf.key(); if ( !conf.value().empty() ) { children.push_back( new XmlText(conf.value()) ); } for( ConfigSet::const_iterator j = conf.children().begin(); j != conf.children().end(); j++ ) { if ( j->isSimple() ) { attrs[j->key()] = j->value(); } else if ( j->children().size() > 0 ) { children.push_back( new XmlElement(*j) ); } } }
osg::Node* EarthFileSerializer2::deserialize( const Config& conf, const std::string& referrer ) const { // First, pre-load any extension DLLs. preloadExtensionLibs(conf); preloadExtensionLibs(conf.child("extensions")); preloadExtensionLibs(conf.child("external")); MapOptions mapOptions( conf.child( "options" ) ); // legacy: check for name/type in top-level attrs: if ( conf.hasValue( "name" ) || conf.hasValue( "type" ) ) { Config legacy; if ( conf.hasValue("name") ) legacy.add( "name", conf.value("name") ); if ( conf.hasValue("type") ) legacy.add( "type", conf.value("type") ); mapOptions.mergeConfig( legacy ); } osg::ref_ptr< Map > map = new Map( mapOptions ); // Start a batch update of the map: map->beginUpdate(); // Read all the elevation layers in FIRST so other layers can access them for things like clamping. // TODO: revisit this since we should really be listening for elevation data changes and // re-clamping based on that.. for(ConfigSet::const_iterator i = conf.children().begin(); i != conf.children().end(); ++i) { // for backwards compatibility: if (i->key() == "heightfield") { Config temp = *i; temp.key() = "elevation"; addLayer(temp, map); } else if ( i->key() == "elevation" ) // || i->key() == "heightfield" ) { addLayer(*i, map); } } Config externalConfig; std::vector<osg::ref_ptr<Extension> > extensions; // Read the layers in LAST (otherwise they will not benefit from the cache/profile configuration) for(ConfigSet::const_iterator i = conf.children().begin(); i != conf.children().end(); ++i) { if (i->key() == "options" || i->key() == "name" || i->key() == "type" || i->key() == "version") { // nop - handled earlier } #if 0 else if ( i->key() == "image" ) { addImageLayer( *i, map ); } else */if ( i->key() == "model" ) { addModelLayer( *i, map ); } else if ( i->key() == "mask" ) { addMaskLayer( *i, map ); } #endif else if ( i->key() == "external" || i->key() == "extensions" ) { externalConfig = *i; for(ConfigSet::const_iterator e = i->children().begin(); e != i->children().end(); ++e) { Extension* extension = loadExtension(*e); if (extension) extensions.push_back(extension); //addExtension( *e, mapNode.get() ); } } else if ( !isReservedWord(i->key()) ) // plugins/extensions. { // try to add as a plugin Layer first: bool addedLayer = addLayer(*i, map); // failing that, try to load as an extension: if ( !addedLayer ) { Extension* extension = loadExtension(*i); if (extension) extensions.push_back(extension); } } } // Complete the batch update of the map map->endUpdate(); // If any errors occurred, report them now. reportErrors(map); // Yes, MapOptions and MapNodeOptions share the same Config node. Weird but true. MapNodeOptions mapNodeOptions( conf.child("options") ); // Create a map node. osg::ref_ptr<MapNode> mapNode = new MapNode( map, mapNodeOptions ); // Apply the external conf if there is one. if (!externalConfig.empty()) { mapNode->externalConfig() = externalConfig; } // Install the extensions for (unsigned i = 0; i < extensions.size(); ++i) { mapNode->addExtension(extensions[i].get()); } // return the topmost parent of the mapnode. It's possible that // an extension added parents! osg::Node* top = mapNode.release(); while( top->getNumParents() > 0 ) top = top->getParent(0); return top; }
void StyleSheet::mergeConfig( const Config& conf ) { // read in any resource library references ConfigSet libraries = conf.children( "library" ); for( ConfigSet::iterator i = libraries.begin(); i != libraries.end(); ++i ) { std::string name = i->value("name"); if ( name.empty() ) { OE_WARN << LC << "Resource library missing required 'name' attribute" << std::endl; continue; } URI uri( i->value("url"), i->uriContext() ); if ( uri.empty() ) { OE_WARN << LC << "Resource library missing required 'url' element" << std::endl; continue; } osg::ref_ptr<ResourceLibrary> reslib = ResourceLibrary::create( uri ); if ( !reslib.valid() ) { OE_WARN << LC << "Resource library creation failed" << std::endl; continue; } addResourceLibrary( name, reslib.get() ); } // read any style class definitions. either "class" or "selector" is allowed ConfigSet selectors = conf.children( "selector" ); if ( selectors.empty() ) selectors = conf.children( "class" ); for( ConfigSet::iterator i = selectors.begin(); i != selectors.end(); ++i ) { _selectors.push_back( StyleSelector( *i ) ); } // read in the actual styles ConfigSet styles = conf.children( "style" ); for( ConfigSet::iterator i = styles.begin(); i != styles.end(); ++i ) { const Config& styleConf = *i; if ( styleConf.value("type") == "text/css" ) { // read the inline data: std::string cssString = styleConf.value(); // if there's a URL, read the CSS from the URL: if ( styleConf.hasValue("url") ) { URI uri( styleConf.value("url"), styleConf.uriContext() ); HTTPClient::readString( uri.full(), cssString ); } // a CSS style definition can actually contain multiple styles. Read them // and create one style for each in the catalog. std::stringstream buf( cssString ); Config css = CssUtils::readConfig( buf ); css.setURIContext( styleConf.uriContext( ) ); const ConfigSet children = css.children(); for(ConfigSet::const_iterator j = children.begin(); j != children.end(); ++j ) { Style style( styleConf ); if ( SLDReader::readStyleFromCSSParams( *j, style ) ) _styles[ j->key() ] = style; } } else { Style style( styleConf ); _styles[ style.getName() ] = style; } } }
void StyleSheet::mergeConfig( const Config& conf ) { _uriContext = URIContext( conf.referrer() ); // read in any resource library references ConfigSet libraries = conf.children( "library" ); for( ConfigSet::iterator i = libraries.begin(); i != libraries.end(); ++i ) { std::string name = i->value("name"); if ( name.empty() ) { OE_WARN << LC << "Resource library missing required 'name' attribute" << std::endl; continue; } URI uri( i->value("url"), i->referrer() ); if ( uri.empty() ) { OE_WARN << LC << "Resource library missing required 'url' element" << std::endl; continue; } _resLibs[name] = ResourceLibraryEntry(uri, (osgEarth::Symbology::ResourceLibrary*)0L); //addResourceLibrary( name, reslib.get() ); } // read in any scripts ConfigSet scripts = conf.children( "script" ); for( ConfigSet::iterator i = scripts.begin(); i != scripts.end(); ++i ) { // get the script code std::string code = i->value(); // name is optional and unused at the moment std::string name = i->value("name"); std::string lang = i->value("language"); if ( lang.empty() ) { // default to javascript lang = "javascript"; } _script = new Script(code, lang, name); } // read any style class definitions. either "class" or "selector" is allowed ConfigSet selectors = conf.children( "selector" ); if ( selectors.empty() ) selectors = conf.children( "class" ); for( ConfigSet::iterator i = selectors.begin(); i != selectors.end(); ++i ) { _selectors.push_back( StyleSelector( *i ) ); } // read in the actual styles ConfigSet styles = conf.children( "style" ); for( ConfigSet::iterator i = styles.begin(); i != styles.end(); ++i ) { const Config& styleConf = *i; if ( styleConf.value("type") == "text/css" ) { // read the inline data: std::string cssString = styleConf.value(); // if there's a URL, read the CSS from the URL: if ( styleConf.hasValue("url") ) { URI uri( styleConf.value("url"), styleConf.referrer() ); cssString = uri.readString().getString(); } // a CSS style definition can actually contain multiple styles. Read them // and create one style for each in the catalog. std::stringstream buf( cssString ); Config css = CssUtils::readConfig( buf ); css.setReferrer( styleConf.referrer() ); const ConfigSet children = css.children(); for(ConfigSet::const_iterator j = children.begin(); j != children.end(); ++j ) { Style style( styleConf ); if ( SLDReader::readStyleFromCSSParams( *j, style ) ) _styles[ j->key() ] = style; } } else { Style style( styleConf ); _styles[ style.getName() ] = style; } } }
MapNode* EarthFileSerializer2::deserialize( const Config& conf, const std::string& referrer ) const { // First, pre-load any extension DLLs. preloadExtensionLibs(conf); MapOptions mapOptions( conf.child( "options" ) ); // legacy: check for name/type in top-level attrs: if ( conf.hasValue( "name" ) || conf.hasValue( "type" ) ) { Config legacy; if ( conf.hasValue("name") ) legacy.add( "name", conf.value("name") ); if ( conf.hasValue("type") ) legacy.add( "type", conf.value("type") ); mapOptions.mergeConfig( legacy ); } Map* map = new Map( mapOptions ); // Yes, MapOptions and MapNodeOptions share the same Config node. Weird but true. MapNodeOptions mapNodeOptions( conf.child( "options" ) ); // Read the layers in LAST (otherwise they will not benefit from the cache/profile configuration) // Image layers: ConfigSet images = conf.children( "image" ); for( ConfigSet::const_iterator i = images.begin(); i != images.end(); i++ ) { Config layerDriverConf = *i; ImageLayerOptions layerOpt( layerDriverConf ); layerOpt.name() = layerDriverConf.value("name"); map->addImageLayer( new ImageLayer(layerOpt) ); } // Elevation layers: for( int k=0; k<2; ++k ) { std::string tagName = k == 0 ? "elevation" : "heightfield"; // support both :) ConfigSet heightfields = conf.children( tagName ); for( ConfigSet::const_iterator i = heightfields.begin(); i != heightfields.end(); i++ ) { Config layerDriverConf = *i; ElevationLayerOptions layerOpt( layerDriverConf ); layerOpt.name() = layerDriverConf.value( "name" ); map->addElevationLayer( new ElevationLayer(layerOpt) ); } } // Model layers: ConfigSet models = conf.children( "model" ); for( ConfigSet::const_iterator i = models.begin(); i != models.end(); i++ ) { const Config& layerDriverConf = *i; ModelLayerOptions layerOpt( layerDriverConf ); layerOpt.name() = layerDriverConf.value( "name" ); layerOpt.driver() = ModelSourceOptions( layerDriverConf ); map->addModelLayer( new ModelLayer(layerOpt) ); } // Mask layer: ConfigSet masks = conf.children( "mask" ); for( ConfigSet::const_iterator i = masks.begin(); i != masks.end(); i++ ) { Config maskLayerConf = *i; MaskLayerOptions options(maskLayerConf); options.name() = maskLayerConf.value( "name" ); options.driver() = MaskSourceOptions(options); map->addTerrainMaskLayer( new MaskLayer(options) ); } //Add any addition paths specified in the options/osg_file_paths element to the file path. Useful for pointing osgEarth at resource folders. Config osg_file_paths = conf.child( "options" ).child("osg_file_paths"); ConfigSet urls = osg_file_paths.children("url"); for (ConfigSet::const_iterator i = urls.begin(); i != urls.end(); i++) { std::string path = osgEarth::getFullPath( referrer, (*i).value()); OE_DEBUG << "Adding OSG file path " << path << std::endl; osgDB::Registry::instance()->getDataFilePathList().push_back( path ); } osg::ref_ptr<MapNode> mapNode = new MapNode( map, mapNodeOptions ); // External configs. Support both "external" and "extensions" tags. Config ext = conf.child( "external" ); if ( ext.empty() ) ext = conf.child( "extensions" ); if ( !ext.empty() ) { // save the configuration in case we need to write it back out later mapNode->externalConfig() = ext; // locate and install any registered extensions. ConfigSet extensions = ext.children(); for(ConfigSet::const_iterator i = extensions.begin(); i != extensions.end(); ++i) { Extension* extension = Extension::create( i->key(), *i ); if ( extension ) { mapNode->addExtension( extension ); } else { OE_DEBUG << LC << "Failed to load an extension for \"" << i->key() << "\"\n"; } } } return mapNode.release(); }
/** * 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; }
osg::Node* EarthFileSerializer2::deserialize( const Config& conf, const std::string& referrer ) const { // First, pre-load any extension DLLs. preloadExtensionLibs(conf); preloadExtensionLibs(conf.child("extensions")); preloadExtensionLibs(conf.child("external")); MapOptions mapOptions( conf.child( "options" ) ); // legacy: check for name/type in top-level attrs: if ( conf.hasValue( "name" ) || conf.hasValue( "type" ) ) { Config legacy; if ( conf.hasValue("name") ) legacy.add( "name", conf.value("name") ); if ( conf.hasValue("type") ) legacy.add( "type", conf.value("type") ); mapOptions.mergeConfig( legacy ); } Map* map = new Map( mapOptions ); // Yes, MapOptions and MapNodeOptions share the same Config node. Weird but true. MapNodeOptions mapNodeOptions( conf.child( "options" ) ); // Create a map node. osg::ref_ptr<MapNode> mapNode = new MapNode( map, mapNodeOptions ); // Read all the elevation layers in FIRST so other layers can access them for things like clamping. for(ConfigSet::const_iterator i = conf.children().begin(); i != conf.children().end(); ++i) { if ( i->key() == "elevation" || i->key() == "heightfield" ) { addElevationLayer( *i, map ); } } // Read the layers in LAST (otherwise they will not benefit from the cache/profile configuration) for(ConfigSet::const_iterator i = conf.children().begin(); i != conf.children().end(); ++i) { if (i->key() == "options" || i->key() == "name" || i->key() == "type" || i->key() == "version") { // nop - handled earlier } else if ( i->key() == "image" ) { addImageLayer( *i, map ); } else if ( i->key() == "model" ) { addModelLayer( *i, map ); } else if ( i->key() == "mask" ) { addMaskLayer( *i, map ); } else if ( i->key() == "external" || i->key() == "extensions" ) { mapNode->externalConfig() = *i; for(ConfigSet::const_iterator e = i->children().begin(); e != i->children().end(); ++e) { addExtension( *e, mapNode.get() ); } } else if ( !isReservedWord(i->key()) ) // plugins/extensions. { addExtension( *i, mapNode.get() ); } } // return the topmost parent of the mapnode. It's possible that // an extension added parents! osg::Node* top = mapNode.release(); while( top->getNumParents() > 0 ) top = top->getParent(0); return top; }