osg::HeightField* TileSource::createHeightField(const TileKey& key, HeightFieldOperation* prepOp, ProgressCallback* progress ) { if ( _status != STATUS_OK ) return 0L; // Try to get it from the memcache first: if (_memCache.valid()) { ReadResult r = _memCache->getOrCreateDefaultBin()->readObject( key.str() ); if ( r.succeeded() ) return r.release<osg::HeightField>(); } osg::ref_ptr<osg::HeightField> newHF = createHeightField( key, progress ); if ( prepOp ) (*prepOp)( newHF ); if ( newHF.valid() && _memCache.valid() ) { _memCache->getOrCreateDefaultBin()->write( key.str(), newHF.get() ); } //TODO: why not just newHF.release()? -gw return newHF.valid() ? new osg::HeightField( *newHF.get() ) : 0L; }
ReadResult HTTPClient::doReadString(const std::string& location, const osgDB::Options* options, ProgressCallback* callback ) { initialize(); ReadResult result; HTTPResponse response = this->doGet( location, options, callback ); if ( response.isOK() ) { result = ReadResult( new StringObject(response.getPartAsString(0)), response.getHeadersAsConfig()); } else { result = ReadResult( response.isCancelled() ? ReadResult::RESULT_CANCELED : response.getCode() == HTTPResponse::NOT_FOUND ? ReadResult::RESULT_NOT_FOUND : response.getCode() == HTTPResponse::SERVER_ERROR ? ReadResult::RESULT_SERVER_ERROR : ReadResult::RESULT_UNKNOWN_ERROR ); //If we have an error but it's recoverable, like a server error or timeout then set the callback to retry. if (HTTPClient::isRecoverable( result.code() ) ) { if (callback) { OE_DEBUG << "Error in HTTPClient for " << location << " but it's recoverable" << std::endl; callback->setNeedsRetry( true ); } } } return result; }
virtual ReadResult readShader(const std::string& file, const osgDB::ReaderWriter::Options* options) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string fileName = osgDB::findDataFile( file, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; osgDB::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary); if(!istream) return ReadResult::FILE_NOT_HANDLED; ReadResult rr = readShader(istream, options); if(rr.validShader()) { osg::Shader* shader = rr.getShader(); shader->setFileName(file); if (shader->getType() == osg::Shader::UNDEFINED) { // set type based on filename extension, where possible if (ext == "frag") shader->setType(osg::Shader::FRAGMENT); if (ext == "vert") shader->setType(osg::Shader::VERTEX); if (ext == "geom") shader->setType(osg::Shader::GEOMETRY); if (ext == "tctrl") shader->setType(osg::Shader::TESSCONTROL); if (ext == "teval") shader->setType(osg::Shader::TESSEVALUATION); if (ext == "compute") shader->setType(osg::Shader::COMPUTE); } } return rr; }
osg::Node* ModelResource::createNodeFromURI( const URI& uri, const osgDB::Options* dbOptions ) const { osg::Node* node = 0L; ReadResult r = uri.readNode( dbOptions ); if ( r.succeeded() ) { node = r.releaseNode(); OE_INFO << LC << "Loaded " << uri.base() << "(from " << (r.isFromCache()? "cache" : "source") << ")" << std::endl; osgUtil::Optimizer o; o.optimize( node, o.DEFAULT_OPTIMIZATIONS | o.INDEX_MESH | o.VERTEX_PRETRANSFORM | o.VERTEX_POSTTRANSFORM ); } else // failing that, fall back on the old encoding format.. { StringVector tok; StringTokenizer( *uri, tok, "()" ); if (tok.size() >= 2) { node = createNodeFromURI( URI(tok[1]), dbOptions ); } } return node; }
virtual ReadResult readNode(const std::string &file, const Options *options) const { ReadResult result = openArchive(file, osgDB::Archive::READ); if (!result.validArchive()) return result; // copy the incoming options if possible so that plugin options can be applied to files // inside the archive osg::ref_ptr<osgDB::ReaderWriter::Options> local_options = options ? new osgDB::ReaderWriter::Options(*options) : new osgDB::ReaderWriter::Options; local_options->setDatabasePath(file); ReadResult result_2 = result.getArchive()->readNode(result.getArchive()->getMasterFileName(), local_options.get()); if (!options || (options->getObjectCacheHint() & osgDB::ReaderWriter::Options::CACHE_ARCHIVES)) { // register the archive so that it is cached for future use. osgDB::Registry::instance()->addToArchiveCache(file, result.getArchive()); } return result_2; }
TileMap* TileMapReaderWriter::read( const std::string& location, const osgDB::ReaderWriter::Options* options ) { TileMap* tileMap = NULL; ReadResult r = URI(location).readString(); if ( r.failed() ) { OE_DEBUG << LC << "Failed to read TMS tile map file from " << location << std::endl; return 0L; } // Read tile map into a Config: Config conf; std::stringstream buf( r.getString() ); conf.fromXML( buf ); // parse that into a tile map: tileMap = TileMapReaderWriter::read( conf ); if (tileMap) { tileMap->setFilename( location ); // record the timestamp (if there is one) in the tilemap. It's not a persistent field // but will help with things like per-session caching. tileMap->setTimeStamp( r.lastModifiedTime() ); } return tileMap; }
osg::Node* IconResource::createNodeFromURI( const URI& uri, const osgDB::Options* dbOptions ) const { osg::Node* node = 0L; ReadResult r = uri.readImage( dbOptions ); if ( r.succeeded() ) { OE_INFO << LC << "Loaded " << uri.base() << "(from " << (r.isFromCache()? "cache" : "source") << ")" << std::endl; if ( r.getImage() ) { node = buildIconModel( r.releaseImage() ); } } else // failing that, fall back on the old encoding format.. { StringVector tok; StringTokenizer( *uri, tok, "()" ); if (tok.size() >= 2) return createNodeFromURI( URI(tok[1]), dbOptions ); } return node; }
TileMap* TileMapReaderWriter::read( const std::string& location, const osgDB::ReaderWriter::Options* options ) { TileMap* tileMap = NULL; ReadResult r = URI(location).readString(); if ( r.failed() ) { OE_WARN << LC << "Failed to read TMS tile map file from " << location << std::endl; return 0L; } // Read tile map into a Config: Config conf; std::stringstream buf( r.getString() ); conf.fromXML( buf ); // parse that into a tile map: tileMap = TileMapReaderWriter::read( conf ); if (tileMap) { tileMap->setFilename( location ); } return tileMap; }
osg::Image* TileSource::createImage(const TileKey& key, ImageOperation* prepOp, ProgressCallback* progress ) { if ( _status != STATUS_OK ) return 0L; // Try to get it from the memcache fist if (_memCache.valid()) { ReadResult r = _memCache->getOrCreateDefaultBin()->readImage( key.str() ); if ( r.succeeded() ) return r.releaseImage(); } osg::ref_ptr<osg::Image> newImage = createImage(key, progress); if ( prepOp ) (*prepOp)( newImage ); if ( newImage.valid() && _memCache.valid() ) { // cache it to the memory cache. _memCache->getOrCreateDefaultBin()->write( key.str(), newImage.get() ); } return newImage.release(); }
osg::ref_ptr<osg::Image> SkinResource::createImage( const osgDB::Options* dbOptions ) const { if (getStatus().isError()) return 0L; ReadResult result; if (_readOptions.isSet()) { osg::ref_ptr<osgDB::Options> ro = Registry::cloneOrCreateOptions(dbOptions); ro->setOptionString(Stringify() << _readOptions.get() << " " << ro->getOptionString()); result = _imageURI->readImage(ro.get()); } else { result = _imageURI->readImage(dbOptions); } if (result.failed()) { Threading::ScopedMutexLock lock(_mutex); if (_status.isOK()) _status = Status::Error(Status::ServiceUnavailable, "Failed to load resource image\n"); } return result.releaseImage(); }
ReadResult HTTPClient::doReadNode(const std::string& location, const osgDB::Options* options, ProgressCallback* callback) { initialize(); ReadResult result; HTTPResponse response = this->doGet(location, options, callback); if (response.isOK()) { osgDB::ReaderWriter* reader = getReader(location, response); if (!reader) { OE_WARN << LC << "Can't find an OSG plugin to read "<<location<<std::endl; result = ReadResult(ReadResult::RESULT_NO_READER); } else { osgDB::ReaderWriter::ReadResult rr = reader->readNode(response.getPartStream(0), options); if ( rr.validNode() ) { result = ReadResult(rr.takeNode(), response.getHeadersAsConfig()); } else { if ( !rr.message().empty() ) { OE_WARN << LC << "HTTP error: " << rr.message() << std::endl; } OE_WARN << LC << reader->className() << " failed to read node from " << location << std::endl; result = ReadResult(ReadResult::RESULT_READER_ERROR); } } } else { result = ReadResult( response.isCancelled() ? ReadResult::RESULT_CANCELED : response.getCode() == HTTPResponse::NOT_FOUND ? ReadResult::RESULT_NOT_FOUND : response.getCode() == HTTPResponse::SERVER_ERROR ? ReadResult::RESULT_SERVER_ERROR : ReadResult::RESULT_UNKNOWN_ERROR ); //If we have an error but it's recoverable, like a server error or timeout then set the callback to retry. if (HTTPClient::isRecoverable( result.code() ) ) { if (callback) { OE_DEBUG << "Error in HTTPClient for " << location << " but it's recoverable" << std::endl; callback->setNeedsRetry( true ); } } } return result; }
FeatureCursor* createFeatureCursor( const Symbology::Query& query ) { FeatureCursor* result = 0L; std::string url = createURL( query ); // check the blacklist: if ( Registry::instance()->isBlacklisted(url) ) return 0L; OE_DEBUG << LC << url << std::endl; URI uri(url); // read the data: ReadResult r = uri.readString( _dbOptions.get() ); const std::string& buffer = r.getString(); const Config& meta = r.metadata(); bool dataOK = false; FeatureList features; if ( !buffer.empty() ) { // Get the mime-type from the metadata record if possible const std::string& mimeType = r.metadata().value( IOMetadata::CONTENT_TYPE ); dataOK = getFeatures( buffer, mimeType, features ); } if ( dataOK ) { OE_DEBUG << LC << "Read " << features.size() << " features" << std::endl; } //If we have any filters, process them here before the cursor is created if (!_options.filters().empty()) { // preprocess the features using the filter list: if ( features.size() > 0 ) { FilterContext cx; cx.setProfile( getFeatureProfile() ); for( FeatureFilterList::const_iterator i = _options.filters().begin(); i != _options.filters().end(); ++i ) { FeatureFilter* filter = i->get(); cx = filter->push( features, cx ); } } } //result = new FeatureListCursor(features); result = dataOK ? new FeatureListCursor( features ) : 0L; if ( !result ) Registry::instance()->blacklist( url ); return result; }
// read the WKT geometry from a URL, then parse into a Geometry. Symbology::Geometry* parseGeometryUrl( const std::string& geomUrl, const osgDB::Options* dbOptions ) { ReadResult r = URI(geomUrl).readString( dbOptions ); if ( r.succeeded() ) { Config conf( "geometry", r.getString() ); return parseGeometry( conf ); } return 0L; }
ReadResult HTTPClient::doReadString(const HTTPRequest& request, const osgDB::Options* options, ProgressCallback* callback ) { initialize(); ReadResult result; HTTPResponse response = this->doGet( request, options, callback ); if ( response.isOK() ) { result = ReadResult( new StringObject(response.getPartAsString(0)) ); } else if ( response.getCode() >= 400 && response.getCode() < 500 && response.getCode() != 404 ) { // for request errors, return an error result with the part data intact // so the user can parse it as needed. We only do this for readString. result = ReadResult( ReadResult::RESULT_SERVER_ERROR, new StringObject(response.getPartAsString(0)) ); } else { result = ReadResult( response.isCancelled() ? ReadResult::RESULT_CANCELED : response.getCode() == HTTPResponse::NOT_FOUND ? ReadResult::RESULT_NOT_FOUND : response.getCode() == HTTPResponse::SERVER_ERROR ? ReadResult::RESULT_SERVER_ERROR : response.getCode() == HTTPResponse::NOT_MODIFIED ? ReadResult::RESULT_NOT_MODIFIED : ReadResult::RESULT_UNKNOWN_ERROR ); //If we have an error but it's recoverable, like a server error or timeout then set the callback to retry. if (HTTPClient::isRecoverable( result.code() ) ) { if (callback) { if ( s_HTTP_DEBUG ) { OE_NOTICE << LC << "Error in HTTPClient for " << request.getURL() << " but it's recoverable" << std::endl; } callback->setNeedsRetry( true ); } } } // encode headers result.setMetadata( response.getHeadersAsConfig() ); // last-modified (file time) result.setLastModifiedTime( getCurlFileTime(_curl_handle) ); return result; }
ReadResult HTTPClient::doReadString(const std::string& location, const osgDB::Options* options, ProgressCallback* callback ) { initialize(); ReadResult result; HTTPResponse response = this->doGet( location, options, callback ); if ( response.isOK() ) { result = ReadResult( new StringObject(response.getPartAsString(0)), response.getHeadersAsConfig()); } else if ( response.getCode() >= 400 && response.getCode() < 500 && response.getCode() != 404 ) { // for request errors, return an error result with the part data intact // so the user can parse it as needed. We only do this for readString. result = ReadResult( ReadResult::RESULT_SERVER_ERROR, new StringObject(response.getPartAsString(0)), response.getHeadersAsConfig() ); } else { result = ReadResult( response.isCancelled() ? ReadResult::RESULT_CANCELED : response.getCode() == HTTPResponse::NOT_FOUND ? ReadResult::RESULT_NOT_FOUND : response.getCode() == HTTPResponse::SERVER_ERROR ? ReadResult::RESULT_SERVER_ERROR : ReadResult::RESULT_UNKNOWN_ERROR ); //If we have an error but it's recoverable, like a server error or timeout then set the callback to retry. if (HTTPClient::isRecoverable( result.code() ) ) { if (callback) { OE_DEBUG << "Error in HTTPClient for " << location << " but it's recoverable" << std::endl; callback->setNeedsRetry( true ); } } } // last-modified (file time) TimeStamp filetime = 0; if ( CURLE_OK == curl_easy_getinfo(_curl_handle, CURLINFO_FILETIME, &filetime) ) { result.setLastModifiedTime( filetime ); } return result; }
bool ReaderWriterCURL::fileExists(const std::string& filename, const osgDB::Options* options) const { if (osgDB::containsServerAddress(filename)) { OSG_NOTICE<<"Checking if file exists using curl plugin: "<<filename<<std::endl; ReadResult result = readFile(OBJECT,filename,options); return result.status()==osgDB::ReaderWriter::ReadResult::FILE_LOADED; } else { return ReaderWriter::fileExists(filename, options); } }
TileService* TileServiceReader::read( const std::string &location, const osgDB::ReaderWriter::Options* options ) { TileService *tileService = NULL; ReadResult r = URI(location).readString( options ); if ( r.succeeded() ) { std::istringstream buf( r.getString() ); tileService = read( buf ); } return tileService; }
virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string fileName = osgDB::findDataFile( file, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; osgDB::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary); if(!istream) return ReadResult::ERROR_IN_READING_FILE; ReadResult rr = readJPGStream(istream); if(rr.validImage()) rr.getImage()->setFileName(file); return rr; }
FeatureCursor* createFeatureCursor( const Symbology::Query& query ) { FeatureCursor* result = 0L; std::string url = createURL( query ); if (url.empty()) return 0; // check the blacklist: if ( Registry::instance()->isBlacklisted(url) ) return 0L; OE_DEBUG << LC << url << std::endl; URI uri(url); // read the data: ReadResult r = uri.readString( _dbOptions.get() ); const std::string& buffer = r.getString(); const Config& meta = r.metadata(); bool dataOK = false; FeatureList features; if ( !buffer.empty() ) { // Get the mime-type from the metadata record if possible std::string mimeType = r.metadata().value( IOMetadata::CONTENT_TYPE ); //If the mimetype is empty then try to set it from the format specification if (mimeType.empty()) { if (_options.format().value() == "json") mimeType = "json"; else if (_options.format().value().compare("gml") == 0) mimeType = "text/xml"; } dataOK = getFeatures( buffer, mimeType, features ); } if ( dataOK ) { OE_DEBUG << LC << "Read " << features.size() << " features" << std::endl; } //result = new FeatureListCursor(features); result = dataOK ? new FeatureListCursor( features ) : 0L; if ( !result ) Registry::instance()->blacklist( url ); return result; }
osg::ref_ptr<osg::Image> SkinResource::createImage( const osgDB::Options* dbOptions ) const { ReadResult result; if (_readOptions.isSet()) { osg::ref_ptr<osgDB::Options> ro = dbOptions ? osg::clone(dbOptions) : new osgDB::Options(); ro->setOptionString(Stringify() << _readOptions.get() << " " << ro->getOptionString()); result = _imageURI->readImage(ro.get()); } else { result = _imageURI->readImage(dbOptions); } return result.releaseImage(); }
ReadResult LevelDBCacheBin::readString(const std::string& key) { ReadResult r = readObject(key); if ( r.succeeded() ) { if ( r.get<StringObject>() ) return r; else return ReadResult(); } else { return r; } }
MapNode* MapNode::load(osg::ArgumentParser& args) { for( int i=1; i<args.argc(); ++i ) { if ( args[i] && endsWith(args[i], ".earth") ) { ReadResult r = URI(args[i]).readNode(); if ( r.succeeded() ) { return r.release<MapNode>(); } } } return 0L; }
XmlDocument* XmlDocument::load( const URI& uri, const osgDB::Options* dbOptions ) { XmlDocument* result = 0L; ReadResult r = uri.readString( dbOptions ); if ( r.succeeded() ) { std::stringstream buf( r.getString() ); result = load( buf ); if ( result ) result->_sourceURI = uri; } return result; }
virtual ReadResult readObject (const std::string &file, const osgDB::ReaderWriter::Options* options) const { ReadResult rr = readImage(file, options); if (!rr.validImage()) return rr; bool use_core_video = true; if (options && !options->getPluginStringData("disableCoreVideo").empty()) use_core_video = false; osg::ref_ptr<OSXAVFoundationVideo> video = dynamic_cast<OSXAVFoundationVideo*>(rr.getImage()); if (!video || !use_core_video) return rr; osg::ref_ptr<OSXAVFoundationCoreVideoTexture> texture = new OSXAVFoundationCoreVideoTexture(video); return texture.release(); }
bool TileMapServiceReader::read( const std::string &location, const osgDB::ReaderWriter::Options* options, TileMapEntryList& tileMaps ) { ReadResult r = URI(location).readString(); if ( r.failed() ) { OE_WARN << LC << "Failed to read TileMapServices from " << location << std::endl; return 0L; } // Read tile map into a Config: Config conf; std::stringstream buf( r.getString() ); conf.fromXML( buf ); // parse that into a tile map: return read( conf, tileMaps ); }
MapNode* MapNode::load(osg::ArgumentParser& args, const MapNodeOptions& defaults) { for( int i=1; i<args.argc(); ++i ) { if ( args[i] && endsWith(args[i], ".earth") ) { osg::ref_ptr<osgDB::Options> dbo = new osgDB::Options(); std::string optionsJSON = defaults.getConfig().toJSON(); dbo->setPluginStringData( "osgEarth.defaultOptions", optionsJSON ); ReadResult r = URI(args[i]).readNode( dbo.get() ); if ( r.succeeded() ) { return r.release<MapNode>(); } } } return 0L; }
osg::Node* ModelResource::createNodeFromURI( const URI& uri, const osgDB::Options* dbOptions ) const { osg::Node* node = 0L; ReadResult r = uri.getNode( dbOptions ); if ( r.succeeded() ) { node = r.releaseNode(); } else // failing that, fall back on the old encoding format.. { StringVector tok; StringTokenizer( *uri, tok, "()" ); if (tok.size() >= 2) return createNodeFromURI( URI(tok[1]), dbOptions ); } return node; }
WMSCapabilities* WMSCapabilitiesReader::read( const std::string &location, const osgDB::ReaderWriter::Options* options ) { WMSCapabilities *caps = NULL; if ( osgDB::containsServerAddress( location ) ) { ReadResult rr = URI(location).readString( options ); if ( rr.succeeded() ) { std::istringstream in( rr.getString() ); caps = read( in ); } } else { if ((osgDB::fileExists(location)) && (osgDB::fileType(location) == osgDB::REGULAR_FILE)) { std::ifstream in( location.c_str() ); caps = read( in ); } } return caps; }
bool ServiceReader::read( const URI& location, const osgDB::Options* options, RESTResponse& response ) { response.setServiceURL( location.full() ); std::string serviceLocation = location.full() + "?f=json&pretty=true"; ReadResult r = URI(serviceLocation, location.context()).readString(); if ( r.failed() ) { OE_WARN << "Failed to read ArcGIS Services tile map file from " << serviceLocation << std::endl; return false; } // Read tile map into a Config: Config conf; std::stringstream buf( r.getString() ); if (!conf.fromJSON( buf.str() )) { return false; } return read( conf, response ); }
osg::Node* ModelResource::createNodeFromURI( const URI& uri, const osgDB::Options* dbOptions ) const { osg::ref_ptr< osgDB::Options > options = dbOptions ? new osgDB::Options( *dbOptions ) : 0; // Explicitly cache images so that models that share images will only load one copy. options->setObjectCacheHint( osgDB::Options::CACHE_IMAGES ); osg::Node* node = 0L; ReadResult r = uri.readNode( options.get() ); if ( r.succeeded() ) { node = r.releaseNode(); OE_INFO << LC << "Loaded " << uri.base() << "(from " << (r.isFromCache()? "cache" : "source") << ")" << std::endl; osgUtil::Optimizer o; o.optimize( node, o.DEFAULT_OPTIMIZATIONS | o.INDEX_MESH | o.VERTEX_PRETRANSFORM | o.VERTEX_POSTTRANSFORM ); } else // failing that, fall back on the old encoding format.. { StringVector tok; StringTokenizer( *uri, tok, "()" ); if (tok.size() >= 2) { node = createNodeFromURI( URI(tok[1]), options.get() ); } } return node; }