コード例 #1
0
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;
}
コード例 #2
0
ファイル: TMS.cpp プロジェクト: Arlockff/osgearth
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;
}
コード例 #3
0
ファイル: FeatureSourceWFS.cpp プロジェクト: ifad-ts/osgearth
    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;
    }
コード例 #4
0
 // 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;
 }
コード例 #5
0
ファイル: TileService.cpp プロジェクト: APerennec/osgearth
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;
}
コード例 #6
0
    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;
    }
コード例 #7
0
ファイル: XmlUtils.cpp プロジェクト: JohnDr/osgearth
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;
}
コード例 #8
0
ファイル: TMS.cpp プロジェクト: Arlockff/osgearth
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 );    
}
コード例 #9
0
ファイル: WMS.cpp プロジェクト: rhabacker/osgearth
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;
}
コード例 #10
0
ファイル: ArcGIS.cpp プロジェクト: emminizer/osgearth
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 );    
}
コード例 #11
0
ファイル: MapService.cpp プロジェクト: caishanli/osgearth
bool
MapService::init( const URI& _uri, const osgDB::ReaderWriter::Options* options )
{
    uri = _uri;
    std::string sep = uri.full().find( "?" ) == std::string::npos ? "?" : "&";
    std::string json_url = uri.full() + sep + std::string("f=pjson");  // request the data in JSON format

    ReadResult r = URI(json_url).readString( options );
    if ( r.failed() )
        return setError( "Unable to read metadata from ArcGIS service" );

    Json::Value doc;
    Json::Reader reader;
//    if ( !reader.parse( response.getPartStream(0), doc ) )
    if ( !reader.parse( r.getString(), doc ) )
	{
        return setError( "Unable to parse metadata; invalid JSON" );
	}

    // Read the profile. We are using "fullExtent"; perhaps an option to use "initialExtent" instead?
	double xmin = 0.0;
	double ymin = 0.0; 
	double xmax = 0.0;
	double ymax = 0.0;
	int srs = 0;

    Json::Value fullExtentValue = doc["fullExtent"];
	Json::Value extentValue = doc["extent"];
	std::string srsValue;
	
	// added a case for "extent" which can be removed if we want to fall back on initialExtent if fullExtent fails
    if ( !fullExtentValue.empty() )
	{
		// if "fullExtent" exists .. use that
		xmin = doc["fullExtent"].get("xmin", 0).asDouble();
		ymin = doc["fullExtent"].get("ymin", 0).asDouble();
		xmax = doc["fullExtent"].get("xmax", 0).asDouble();
		ymax = doc["fullExtent"].get("ymax", 0).asDouble();
		srs = doc["fullExtent"].get("spatialReference", osgEarth::Json::Value::null).get("wkid", 0).asInt();

		srsValue = doc["fullExtent"].get("spatialReference", osgEarth::Json::Value::null).get("wkt", "null").asString();
	
		OE_DEBUG << LC << "fullExtent discovered: xmin: " << xmin << ", ymin: " << ymin << ", xmax: " << xmax << ", ymax: " << ymax << ", srs: " << srs << std::endl;
	}
	else if( !extentValue.empty() )
	{
		// else if "extent" exists .. use that
		xmin = doc["extent"].get("xmin", 0).asDouble();
		ymin = doc["extent"].get("ymin", 0).asDouble();
		xmax = doc["extent"].get("xmax", 0).asDouble();
		ymax = doc["extent"].get("ymax", 0).asDouble();
		srs = doc["extent"].get("spatialReference", osgEarth::Json::Value::null).get("wkid", 0).asInt();

		srsValue = doc["extent"].get("spatialReference", osgEarth::Json::Value::null).get("wkt", "null").asString();

		OE_DEBUG << LC << "extent discovered: xmin: " << xmin << ", ymin: " << ymin << ", xmax: " << xmax << ", ymax: " << ymax << ", srs: " << srs << std::endl;
	}
	else
	{
		// else "initialExtent" must exist ..
		xmin = doc["initialExtent"].get("xmin", 0).asDouble();
		ymin = doc["initialExtent"].get("ymin", 0).asDouble();
		xmax = doc["initialExtent"].get("xmax", 0).asDouble();
		ymax = doc["initialExtent"].get("ymax", 0).asDouble();
		srs = doc["initialExtent"].get("spatialReference", osgEarth::Json::Value::null).get("wkid", 0).asInt();

		srsValue = doc["initialExtent"].get("spatialReference", osgEarth::Json::Value::null).get("wkt", "null").asString();

		OE_DEBUG << LC << "initialExtent discovered: xmin: " << xmin << ", ymin: " << ymin << ", xmax: " << xmax << ", ymax: " << ymax << ", srs: " << srs << std::endl;
	}
    
    //Assumes the SRS is going to be an EPSG code
    std::stringstream ss;
    ss << "epsg:" << srs;
    
	// we can create a valid spatial reference from the WKT/proj4 string .. here just check if x/y/min/max values are set & correct
    if ( ! (xmax > xmin && ymax > ymin /*&& srs != 0*/ ) )
    {
        return setError( "Map service does not define a full extent" );
    }

    // Check that the layers list is not empty
    Json::Value j_layers = doc["layers"];
    if ( j_layers.empty() )
	{
        return setError( "Map service contains no layers" );
	}

	// not required to initialise a layer .. in any case this code does nothing
    for( unsigned int i=0; i<j_layers.size(); i++ )
    {
        Json::Value layer = j_layers[i];
        int id = i; // layer.get("id", -1).asInt();
        std::string name = layer["name"].asString();

        if ( id >= 0 && !name.empty() )
        {
            layers.push_back( MapServiceLayer( id, name ) );
        }
    }

    tiled = false;
    std::string format = "png";
    int tile_rows = 256;
    int tile_cols = 256;
    int min_level = 25;
    int max_level = 0;
    int num_tiles_wide = 1;
    int num_tiles_high = 1;

    // Read the tiling schema
    Json::Value j_tileinfo = doc["tileInfo"];
    if ( !j_tileinfo.empty() )
    {
        tiled = true;

     //   return setError( "Map service does not define a tiling schema" );

        // TODO: what do we do if the width <> height?
        tile_rows = j_tileinfo.get( "rows", 0 ).asInt();
        tile_cols = j_tileinfo.get( "cols", 0 ).asInt();
        if ( tile_rows <= 0 && tile_cols <= 0 )
		{
            return setError( "Map service tile size not specified" );
		}

        format = j_tileinfo.get( "format", "" ).asString();
        if ( format.empty() )
		{
            return setError( "Map service tile schema does not specify an image format" );
		}

        Json::Value j_levels = j_tileinfo["lods"];
        if ( j_levels.empty() )
		{
            return setError( "Map service tile schema contains no LODs" );
		}
        
        min_level = INT_MAX;
        max_level = 0;
        for( unsigned int i=0; i<j_levels.size(); i++ )
        {
            int level = j_levels[i].get( "level", -1 ).asInt();
            if ( level >= 0 && level < min_level )
			{
                min_level = level;
			}
            if ( level >= 0 && level > max_level )
			{
                max_level = level;
			}
        }

        if (j_levels.size() > 0)
        {
            int l = j_levels[0u].get("level", -1).asInt();
            double res = j_levels[0u].get("resolution", 0.0).asDouble();
            num_tiles_wide = (int)osg::round((xmax - xmin) / (res * tile_cols));
            num_tiles_high = (int)osg::round((ymax - ymin) / (res * tile_cols));

            //In case the first level specified isn't level 0, compute the number of tiles at level 0
            for (int i = 0; i < l; i++)
            {
                num_tiles_wide /= 2;
                num_tiles_high /= 2;
            }

            //profile.setNumTilesWideAtLod0(num_tiles_wide);
            //profile.setNumTilesHighAtLod0(num_tiles_high);
        }
    }

	std::string ssStr;
	ssStr = ss.str();

	osg::ref_ptr< SpatialReference > spatialReference;

	 // if srs is in a non integer form .. find out what form it's in & create ..
	if(srs == 0)
	{
		OE_DEBUG << LC << "srsString: " << srsValue << std::endl;

		// create spatial reference from WKT string
		spatialReference = SpatialReference::create( srsValue );
	}
	else
	{
		// create spatial reference from epsg string (WKID)
		spatialReference = SpatialReference::create( ssStr );
	}

	// if spatial reference is valid .. create a profile
	if( spatialReference.valid() )
	{
		// create profile from spatial reference
		if ( spatialReference->isGeographic() )
		{
			// If we have a geographic SRS, just use the geodetic profile
			profile = Registry::instance()->getGlobalGeodeticProfile();
		}
		else if ( spatialReference->isMercator() )
		{
			// If we have a mercator SRS, just use the mercator profile
			profile = Registry::instance()->getGlobalMercatorProfile();
		}
		else
		{
			//It's not geodetic or mercator, so try to use the full extent
			profile = Profile::create(
				spatialReference.get(),
				xmin, ymin, xmax, ymax,
				num_tiles_wide,
				num_tiles_high);
		}
	}
	else
	{
		return setError( "Map service Spatial Reference INVALID" );
	}

	if( !profile.valid() )
	{
		return setError( "Map service could not create a valid profile" );
	}

    // now we're good.
    tile_info = TileInfo( tile_rows, format, min_level, max_level, num_tiles_wide, num_tiles_high);
    is_valid = true;
    return is_valid;
}
コード例 #12
0
ファイル: BingTileSource.cpp プロジェクト: Sylla/osgearth
    /**
     * 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;
    }
コード例 #13
0
ファイル: SplatExtension.cpp プロジェクト: Geo12/osgearth
bool
SplatExtension::connect(MapNode* mapNode)
{
    if ( !mapNode )
    {
        OE_WARN << LC << "Illegal: MapNode cannot be null." << std::endl;
        return false;
    }

    OE_INFO << LC << "Connecting to MapNode.\n";

    if ( !_options.catalogURI().isSet() )
    {
        OE_WARN << LC << "Illegal: catalog URI is required" << std::endl;
        return false;
    }

    if ( !_options.legendURI().isSet() )
    {
        OE_WARN << LC << "Illegal: legend URI is required" << std::endl;
        return false;
    }

    if ( !_options.coverageLayerName().isSet() )
    {
        OE_WARN << LC << "Illegal: coverage layer name is required" << std::endl;
        return false;
    }

    // Locate the coverage layer in the map.
    const Map* map = mapNode->getMap();
    const ImageLayer* coverageLayer = map->getImageLayerByName( _options.coverageLayerName().get() );
    if ( !coverageLayer )
    {
        OE_WARN << LC << "Coverage layer \""
            << _options.coverageLayerName().get()
            << "\" not found in map."
            << std::endl;
        return false;
    }

    // Read in the catalog.
    osg::ref_ptr<SplatCatalog> catalog = new SplatCatalog();
    {
        ReadResult result = _options.catalogURI()->readString( _dbOptions.get() );
        if ( result.succeeded() )
        {
            Config conf;
            conf.setReferrer(_options.catalogURI()->full());

            std::string json = result.getString();
            conf.fromJSON( json );
            catalog->fromConfig( conf );

            OE_INFO << LC << "Catalog: " << catalog->getClasses().size() << " classes\n";
        }
        else
        {
            OE_WARN << LC
                << "Failed to read catalog from \""
                << _options.catalogURI()->full() << "\"\n";
            return false;
        }
    }

    // Read in the legend.
    osg::ref_ptr<SplatCoverageLegend> legend = new SplatCoverageLegend();
    {
        ReadResult result = _options.legendURI()->readString( _dbOptions.get() );
        if ( result.succeeded() )
        {
            Config conf;
            conf.setReferrer(_options.legendURI()->full());

            conf.fromJSON( result.getString() );
            legend->fromConfig( conf );

            OE_INFO << LC << "Legend: " << legend->getPredicates().size() << " mappings \n";
        }
        else
        {
            OE_WARN << LC
                << "Failed to read legend from \""
                << _options.legendURI()->full() << "\"\n";
            return false;
        }
    }

    // Terrain effect that implements splatting.
    _effect = new SplatTerrainEffect( catalog, legend, _dbOptions.get() );

    // set the coverage layer (mandatory)
    _effect->setCoverageLayer( coverageLayer );

    // set the render order (optional)
    if ( _options.drawAfterImageLayers() == true )
        _effect->setRenderOrder( 1.0f );

    // set the various rendering options.
    if ( _options.coverageWarp().isSet() )
        _effect->getCoverageWarpUniform()->set( _options.coverageWarp().get() );
    
    if ( _options.coverageBlur().isSet() )
        _effect->getCoverageBlurUniform()->set( _options.coverageBlur().get() );

    if ( _options.scaleLevelOffset().isSet() )
        _effect->getScaleLevelOffsetUniform()->set( (float)_options.scaleLevelOffset().get() );

    // add it to the terrain.
    mapNode->getTerrainEngine()->addEffect( _effect.get() );

    if ( ::getenv("OSGEARTH_SPLAT_MODELS") )
    {
    // TEMPORARY. This is just a quick hack to test the tile-based model splatter.
    // It finds any occurance of a model in the catalog and just installs that in
    // a single splatter. Doesn't support multiple models, classifications, or 
    // anything interesting quite yet.
    //const SplatClassVector& classes = catalog->getClasses();
    //for(SplatClassVector::const_iterator i = classes.begin(); i != classes.end(); ++i )
    //{
        osg::ref_ptr<osg::Node> model;
        //if ( i->_modelURI.isSet() )
        //{
            model = URI("../data/red_flag.osg").getNode(_dbOptions.get());
            //model = i->_modelURI->getNode(_dbOptions.get());
            if ( model.valid() )
            {
                if ( !_modelSplatter.valid() )
                {
                    _modelSplatter = new ModelSplatter();
                }

                _modelSplatter->setModel( model.get() );

                //if ( i->_modelCount.isSet() )
                //    _modelSplatter->setNumInstances( i->_modelCount.get() );

                //if ( i->_modelLevel.isSet() )
                //    _modelSplatter->setMinLOD( i->_modelLevel.get() );
            }
            else
            {
                OE_WARN << LC << "Can't load the tree!\n";
            }
    //    }
    }

    // Install the model splatter if we made one.
    if ( _modelSplatter.valid() )
    {
        mapNode->getTerrainEngine()->addTileNodeCallback( _modelSplatter.get() );
    }

    return true;
}
コード例 #14
0
    FeatureCursor* createFeatureCursor(const Symbology::Query& query, ProgressCallback* progress)
    {
        FeatureCursor* result = 0L;

        std::string url = createURL( query );

        // the URL wil lbe empty if it was invalid or outside the level bounds of the layer.
        if (url.empty())
            return 0L;

        OE_DEBUG << LC << url << std::endl;
        URI uri(url, _options.url()->context());

        // read the data:
        ReadResult r = uri.readString(_readOptions.get(), progress);

        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";
                else if (_options.format().value().compare("pbf") == 0) mimeType = "application/x-protobuf";
            }
            dataOK = getFeatures( buffer, *query.tileKey(), 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 (getFilters() && !getFilters()->empty() && !features.empty())
        {
            FilterContext cx;
            cx.setProfile(getFeatureProfile());
            cx.extent() = query.tileKey()->getExtent();

            for (FeatureFilterChain::const_iterator i = getFilters()->begin(); i != getFilters()->end(); ++i)
            {
                FeatureFilter* filter = i->get();
                cx = filter->push(features, cx);
            }
        }

        // If we have any features and we have an fid attribute, override the fid of the features
        if (_options.fidAttribute().isSet())
        {
            for (FeatureList::iterator itr = features.begin(); itr != features.end(); ++itr)
            {
                std::string attr = itr->get()->getString(_options.fidAttribute().get());                
                FeatureID fid = as<long>(attr, 0);
                itr->get()->setFID( fid );
            }
        }

        result = new FeatureListCursor(features);
        return result;
    }
コード例 #15
0
ファイル: TerrainLayer.cpp プロジェクト: caishanli/osgearth
CacheBin*
TerrainLayer::getCacheBin(const Profile* profile)
{
    if ( !_openCalled )
    {
        OE_WARN << LC << "Illegal- called getCacheBin() before layer is open.. did you call open()?\n";
        return 0L;
    }

    CacheSettings* cacheSettings = getCacheSettings();
    if (!cacheSettings)
        return 0L;

    if (cacheSettings->cachePolicy()->isCacheDisabled())
        return 0L;

    CacheBin* bin = cacheSettings->getCacheBin();
    if (!bin)
        return 0L;

    // does the metadata need initializing?
    std::string metaKey = getMetadataKey(profile);

    Threading::ScopedMutexLock lock(_mutex);

    CacheBinMetadataMap::iterator i = _cacheBinMetadata.find(metaKey);
    if (i == _cacheBinMetadata.end())
    {
        //std::string cacheId = _runtimeOptions->cacheId().get();

        // read the metadata record from the cache bin:
        ReadResult rr = bin->readString(metaKey, _readOptions.get());
            
        osg::ref_ptr<CacheBinMetadata> meta;
        bool metadataOK = false;

        if (rr.succeeded())
        {
            // Try to parse the metadata record:
            Config conf;
            conf.fromJSON(rr.getString());
            meta = new CacheBinMetadata(conf);

            if (meta->isOK())
            {
                metadataOK = true;

                // verify that the cache if compatible with the open tile source:
                if ( getTileSource() && getProfile() )
                {
                    //todo: check the profile too
                    if ( meta->_sourceDriver.get() != getTileSource()->getOptions().getDriver() )
                    {                     
                        OE_WARN << LC 
                            << "Layer \"" << getName() << "\" is requesting a \""
                            << getTileSource()->getOptions().getDriver() << "\" cache, but a \""
                            << meta->_sourceDriver.get() << "\" cache exists at the specified location. "
                            << "The cache will ignored for this layer.\n";

                        cacheSettings->cachePolicy() = CachePolicy::NO_CACHE;
                        return 0L;
                    }
                }   

                // if not, see if we're in cache-only mode and still need a profile:
                else if (cacheSettings->cachePolicy()->isCacheOnly() && !_profile.valid())
                {
                    // in cacheonly mode, create a profile from the first cache bin accessed
                    // (they SHOULD all be the same...)
                    setProfile( Profile::create(meta->_sourceProfile.get()) );
                    _tileSize = meta->_sourceTileSize.get();
                }

                bin->setMetadata(meta.get());
            }
            else
            {
                OE_WARN << LC << "Metadata appears to be corrupt.\n";
            }
        }

        if (!metadataOK)
        {
            // cache metadata does not exist, so try to create it.
            if ( getProfile() )
            {
                meta = new CacheBinMetadata();

                // no existing metadata; create some.
                meta->_cacheBinId      = _runtimeCacheId;
                meta->_sourceName      = this->getName();
                meta->_sourceTileSize  = getTileSize();
                meta->_sourceProfile   = getProfile()->toProfileOptions();
                meta->_cacheProfile    = profile->toProfileOptions();
                meta->_cacheCreateTime = DateTime().asTimeStamp();
                meta->_dataExtents     = getDataExtents();

                if (getTileSource())
                {
                    meta->_sourceDriver = getTileSource()->getOptions().getDriver();
                }

                // store it in the cache bin.
                std::string data = meta->getConfig().toJSON(false);
                osg::ref_ptr<StringObject> temp = new StringObject(data);
                bin->write(metaKey, temp.get(), _readOptions.get());                   

                bin->setMetadata(meta.get());
            }

            else if ( cacheSettings->cachePolicy()->isCacheOnly() )
            {
                disable(Stringify() <<
                    "Failed to open a cache for layer "
                    "because cache_only policy is in effect and bin [" << _runtimeCacheId << "] "
                    "could not be located.");

                return 0L;
            }

            else
            {
                OE_WARN << LC <<
                    "Failed to create cache bin [" << _runtimeCacheId << "] "
                    "because there is no valid profile."
                    << std::endl;

                cacheSettings->cachePolicy() = CachePolicy::NO_CACHE;
                return 0L;
            }
        }

        // If we loaded a profile from the cache metadata, apply the overrides:
        applyProfileOverrides();

        if (meta.valid())
        {
            _cacheBinMetadata[metaKey] = meta.get();
            OE_DEBUG << LC << "Established metadata for cache bin [" << _runtimeCacheId << "]" << std::endl;
        }
    }

    return bin;
}
コード例 #16
0
ファイル: SplatExtension.cpp プロジェクト: RollJack/osgearth
bool
SplatExtension::connect(MapNode* mapNode)
{
    if ( !mapNode )
    {
        OE_WARN << LC << "Illegal: MapNode cannot be null." << std::endl;
        return false;
    }

    OE_INFO << LC << "Connecting to MapNode.\n";

    if ( !_options.catalogURI().isSet() )
    {
        OE_WARN << LC << "Illegal: catalog URI is required" << std::endl;
        return false;
    }

    if ( !_options.legendURI().isSet() )
    {
        OE_WARN << LC << "Illegal: legend URI is required" << std::endl;
        return false;
    }

    if ( !_options.coverageLayerName().isSet() )
    {
        OE_WARN << LC << "Illegal: coverage layer name is required" << std::endl;
        return false;
    }

    // Locate the coverage layer in the map.
    const Map* map = mapNode->getMap();
    const ImageLayer* coverageLayer = map->getImageLayerByName( _options.coverageLayerName().get() );
    if ( !coverageLayer )
    {
        OE_WARN << LC << "Coverage layer \""
            << _options.coverageLayerName().get()
            << "\" not found in map."
            << std::endl;
        return false;
    }

    // Read in the catalog.
    osg::ref_ptr<SplatCatalog> catalog = new SplatCatalog();
    {
        ReadResult result = _options.catalogURI()->readString( _dbOptions.get() );
        if ( result.succeeded() )
        {
            Config conf;
            conf.setReferrer(_options.catalogURI()->full());

            std::string json = result.getString();
            conf.fromJSON( json );
            catalog->fromConfig( conf );

            OE_INFO << LC << "Catalog: " << catalog->getClasses().size() << " classes\n";
        }
        else
        {
            OE_WARN << LC
                << "Failed to read catalog from \""
                << _options.catalogURI()->full() << "\"\n";
            return false;
        }
    }

    // Read in the legend.
    osg::ref_ptr<SplatCoverageLegend> legend = new SplatCoverageLegend();
    {
        ReadResult result = _options.legendURI()->readString( _dbOptions.get() );
        if ( result.succeeded() )
        {
            Config conf;
            conf.setReferrer(_options.legendURI()->full());

            conf.fromJSON( result.getString() );
            legend->fromConfig( conf );

            OE_INFO << LC << "Legend: " << legend->getPredicates().size() << " mappings \n";
        }
        else
        {
            OE_WARN << LC
                << "Failed to read legend from \""
                << _options.legendURI()->full() << "\"\n";
            return false;
        }
    }

    // Install the splatter on the terrain engine.
    _effect = new SplatTerrainEffect( catalog, legend, _dbOptions.get() );

    // set the coverage layer (mandatory)
    _effect->setCoverageLayer( coverageLayer );

    // set the render order (optional)
    if ( _options.drawAfterImageLayers() == true )
        _effect->setRenderOrder( 1.0f );

    mapNode->getTerrainEngine()->addEffect( _effect.get() );

    return true;
}