Exemple #1
0
TileBuilder::Job*
TileBuilder::createJob( const TileKey& key, Threading::MultiEvent& semaphore )
{
    Job* job = new Job( key, _map );

    // create the image layer tasks:
    for( ImageLayerVector::const_iterator i = job->_mapf.imageLayers().begin(); i != job->_mapf.imageLayers().end(); ++i )
    {
        ImageLayer* layer = i->get();

        if ( layer->getEnabled() && layer->isKeyValid(key) )
        {
            ParallelTask<BuildColorLayer>* j = new ParallelTask<BuildColorLayer>( &semaphore );
            j->init( key, layer, job->_mapf.getMapInfo(), _terrainOptions, job->_repo );
            j->setPriority( -(float)key.getLevelOfDetail() );
            job->_tasks.push_back( j );
        }
    }

    // If we have elevation layers, start an elevation job as well. Otherwise just create an
    // empty one while we're waiting for the images to load.
    if ( job->_mapf.elevationLayers().size() > 0 )
    {
        ParallelTask<BuildElevLayer>* ej = new ParallelTask<BuildElevLayer>( &semaphore );
        ej->init( key, job->_mapf, _terrainOptions, job->_repo );
        ej->setPriority( -(float)key.getLevelOfDetail() );
        job->_tasks.push_back( ej );
    }

    return job;
}
Exemple #2
0
bool
CacheSeed::cacheTile(const MapFrame& mapf, const TileKey& key ) const
{
    bool gotData = false;

    for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); i++ )
    {
        ImageLayer* layer = i->get();
        if ( layer->isKeyValid( key ) )
        {
            GeoImage image = layer->createImage( key );
            if ( image.valid() )
                gotData = true;
        }
    }

    if ( mapf.elevationLayers().size() > 0 )
    {
        osg::ref_ptr<osg::HeightField> hf;
        mapf.getHeightField( key, false, hf );
        if ( hf.valid() )
            gotData = true;
    }

    return gotData;
}
Exemple #3
0
void
TileBuilder::createTile(const TileKey&      key, 
                        bool                parallelize, 
                        osg::ref_ptr<Tile>& out_tile, 
                        bool&               out_hasRealData,
                        bool&               out_hasLodBlendedLayers )
{
    MapFrame mapf( _map, Map::MASKED_TERRAIN_LAYERS );

    SourceRepo repo;

    // init this to false, then search for real data. "Real data" is data corresponding
    // directly to the key, as opposed to fallback data, which is derived from a lower
    // LOD key.
    out_hasRealData = false;
    out_hasLodBlendedLayers = false;

    const MapInfo& mapInfo = mapf.getMapInfo();

    // If we need more than one layer, fetch them in parallel.
    // TODO: change the test based on isKeyValid total.
    if ( parallelize && (mapf.imageLayers().size() + mapf.elevationLayers().size() > 1) )
    {
        // count the valid layers.
        int jobCount = 0;

        for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i )
        {
            if ( i->get()->isKeyValid( key ) )
                ++jobCount;

            if ( i->get()->getImageLayerOptions().lodBlending() == true )
                out_hasLodBlendedLayers = true;
        }

        if ( mapf.elevationLayers().size() > 0 )
            ++jobCount;

        // A thread job monitoring event:
        Threading::MultiEvent semaphore( jobCount );

        // Start the image layer jobs:
        for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i )
        {
            ImageLayer* layer = i->get();
            if ( layer->isKeyValid(key) )
            {
                ParallelTask<BuildColorLayer>* j = new ParallelTask<BuildColorLayer>( &semaphore );
                j->init( key, layer, mapInfo, _terrainOptions, repo );
                j->setPriority( -(float)key.getLevelOfDetail() );
                _service->add( j );
            }
        }

        // If we have elevation layers, start an elevation job as well. Otherwise just create an
        // empty one while we're waiting for the images to load.
        if ( mapf.elevationLayers().size() > 0 )
        {
            ParallelTask<BuildElevLayer>* ej = new ParallelTask<BuildElevLayer>( &semaphore );
            ej->init( key, mapf, _terrainOptions, repo );
            ej->setPriority( -(float)key.getLevelOfDetail() );
            _service->add( ej );
        }
        else
        {
            BuildElevLayer build;
            build.init( key, mapf, _terrainOptions, repo );
            build.execute();
        }

        // Wait for all the jobs to finish.
        semaphore.wait();
    }
    
    // Fetch the image data serially:
    else
    {
        // gather all the image layers serially.
        for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i )
        {
            ImageLayer* layer = i->get();
            //if ( layer->isKeyValid(key) )  // Wrong. no guarantee key is in the same profile.

            if ( layer->getEnabled() )
            {
                BuildColorLayer build;
                build.init( key, layer, mapInfo, _terrainOptions, repo );
                build.execute();

                if ( layer->getImageLayerOptions().lodBlending() == true )
                    out_hasLodBlendedLayers = true;
            }
        }
        
        // make an elevation layer.
        BuildElevLayer build;
        build.init( key, mapf, _terrainOptions, repo );
        build.execute();
    }

    // Bail out now if there's no data to be had.
    if ( repo._colorLayers.size() == 0 && !repo._elevLayer.getHFLayer() )
    {
        return;
    }

    // OK we are making a tile, so if there's no heightfield yet, make an empty one.
    if ( !repo._elevLayer.getHFLayer() )
    {
        osg::HeightField* hf = HeightFieldUtils::createReferenceHeightField( key.getExtent(), 8, 8 );
        //osg::HeightField* hf = key.getProfile()->getVerticalSRS()->createReferenceHeightField( key.getExtent(), 8, 8 );
        osgTerrain::HeightFieldLayer* hfLayer = new osgTerrain::HeightFieldLayer( hf );
        hfLayer->setLocator( GeoLocator::createForKey(key, mapInfo) );
        repo._elevLayer = CustomElevLayer( hfLayer, true );
    }

    // Now, if there are any color layers that did not get built, create them with an empty
    // image so the shaders have something to draw.
    osg::ref_ptr<osg::Image> emptyImage;
    osgTerrain::Locator* locator = repo._elevLayer.getHFLayer()->getLocator();

    for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i )
    {
        ImageLayer* layer = i->get();

        if ( layer->getEnabled() && !layer->isKeyValid(key) )
        {
            if ( !emptyImage.valid() )
                emptyImage = ImageUtils::createEmptyImage();

            repo.add( CustomColorLayer(
                layer,
                emptyImage.get(),
                locator,
                key.getLevelOfDetail(),
                key,
                true ) );
        }
    }

    //osg::Vec3dArray* maskBounds = 0L;
    //osgEarth::MaskLayer* mask = mapf.getTerrainMaskLayer();
    //if (mask)
    //  maskBounds = mask->getOrCreateBoundary();

    // Ready to create the actual tile.
    AssembleTile assemble;
    assemble.init( key, mapInfo, _terrainOptions, repo, mapf.terrainMaskLayers() );
    assemble.execute();

    if (!out_hasRealData)
    {
        // Check the results and see if we have any real data.
        for( ColorLayersByUID::const_iterator i = repo._colorLayers.begin(); i != repo._colorLayers.end(); ++i )
        {
            if ( !i->second.isFallbackData() ) 
            {
                out_hasRealData = true;
                break;
            }
        }
    }

    if ( !out_hasRealData && !repo._elevLayer.isFallbackData() )
    {
        out_hasRealData = true;
    }

    out_tile = assemble._tile;
}
Exemple #4
0
void
TileBuilder::finalizeJob(TileBuilder::Job*   job, 
                         osg::ref_ptr<Tile>& out_tile,
                         bool&               out_hasRealData,
                         bool&               out_hasLodBlending)
{
    SourceRepo& repo = job->_repo;

    out_hasRealData = false;
    out_hasLodBlending = false;

    // Bail out now if there's no data to be had.
    if ( repo._colorLayers.size() == 0 && !repo._elevLayer.getHFLayer() )
    {
        return;
    }

    const TileKey& key = job->_key;
    const MapInfo& mapInfo = job->_mapf.getMapInfo();

    // OK we are making a tile, so if there's no heightfield yet, make an empty one.
    if ( !repo._elevLayer.getHFLayer() )
    {
        osg::HeightField* hf = HeightFieldUtils::createReferenceHeightField( key.getExtent(), 8, 8 );
        osgTerrain::HeightFieldLayer* hfLayer = new osgTerrain::HeightFieldLayer( hf );
        hfLayer->setLocator( GeoLocator::createForKey(key, mapInfo) );
        repo._elevLayer = CustomElevLayer( hfLayer, true );
    }

    // Now, if there are any color layers that did not get built, create them with an empty
    // image so the shaders have something to draw.
    osg::ref_ptr<osg::Image> emptyImage;
    osgTerrain::Locator* locator = repo._elevLayer.getHFLayer()->getLocator();

    for( ImageLayerVector::const_iterator i = job->_mapf.imageLayers().begin(); i != job->_mapf.imageLayers().end(); ++i )
    {
        ImageLayer* layer = i->get();

        if ( layer->getEnabled() )
        {
            if ( !layer->isKeyValid(key) )
            {
                if ( !emptyImage.valid() )
                    emptyImage = ImageUtils::createEmptyImage();

                repo.add( CustomColorLayer(
                    i->get(), emptyImage.get(),
                    locator,
                    key.getLevelOfDetail(),
                    key,
                    true ) );
            }

            if ( i->get()->getImageLayerOptions().lodBlending() == true )
                out_hasLodBlending = true;
        }
    }

    // Ready to create the actual tile.
    AssembleTile assemble;
    assemble.init( key, mapInfo, _terrainOptions, repo );
    assemble.execute();

    // Check the results and see if we have any real data.
    for( ColorLayersByUID::const_iterator i = repo._colorLayers.begin(); i != repo._colorLayers.end(); ++i )
    {
        if ( !i->second.isFallbackData() ) 
        {
            out_hasRealData = true;
            break;
        }
    }
    if ( !out_hasRealData && !repo._elevLayer.isFallbackData() )
    {
        out_hasRealData = true;
    }

    out_tile = assemble._tile;
}
Exemple #5
0
void
TileModelFactory::createTileModel(const TileKey&           key, 
                                  osg::ref_ptr<TileModel>& out_model,
                                  bool&                    out_hasRealData,
                                  bool&                    out_hasLodBlendedLayers )
{
    MapFrame mapf( _map, Map::MASKED_TERRAIN_LAYERS );
    
    const MapInfo& mapInfo = mapf.getMapInfo();

    osg::ref_ptr<TileModel> model = new TileModel();
    model->_tileKey = key;
    model->_tileLocator = GeoLocator::createForKey(key, mapInfo);

    // init this to false, then search for real data. "Real data" is data corresponding
    // directly to the key, as opposed to fallback data, which is derived from a lower
    // LOD key.
    out_hasRealData = false;
    out_hasLodBlendedLayers = false;
    
    // Fetch the image data and make color layers.
    for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i )
    {
        ImageLayer* layer = i->get();

        if ( layer->getEnabled() )
        {
            BuildColorData build;
            build.init( key, layer, mapInfo, _terrainOptions, model.get() );
            build.execute();

            if ( layer->getImageLayerOptions().lodBlending() == true )
            {
                out_hasLodBlendedLayers = true;
            }
        }
    }

    // make an elevation layer.
    BuildElevationData build;
    build.init( key, mapf, _terrainOptions, model.get(), _hfCache );
    build.execute();


    // Bail out now if there's no data to be had.
    if ( model->_colorData.size() == 0 && !model->_elevationData.getHFLayer() )
    {
        return;
    }

    // OK we are making a tile, so if there's no heightfield yet, make an empty one.
    if ( !model->_elevationData.getHFLayer() )
    {
        osg::HeightField* hf = HeightFieldUtils::createReferenceHeightField( key.getExtent(), 8, 8 );
        osgTerrain::HeightFieldLayer* hfLayer = new osgTerrain::HeightFieldLayer( hf );
        hfLayer->setLocator( GeoLocator::createForKey(key, mapInfo) );
        model->_elevationData = TileModel::ElevationData( hfLayer, true );
    }

    // Now, if there are any color layers that did not get built, create them with an empty
    // image so the shaders have something to draw.
    osg::ref_ptr<osg::Image> emptyImage;
    osgTerrain::Locator* locator = model->_elevationData.getHFLayer()->getLocator();

    for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i )
    {
        ImageLayer* layer = i->get();

        if ( layer->getEnabled() && !layer->isKeyValid(key) )
        {
            if ( !emptyImage.valid() )
                emptyImage = ImageUtils::createEmptyImage();

            model->_colorData[i->get()->getUID()] = TileModel::ColorData(
                layer,
                emptyImage.get(),
                locator,
                key.getLevelOfDetail(),
                key,
                true );
        }
    }

    // Ready to create the actual tile.
    //AssembleTile assemble;
    //assemble.init( key, mapInfo, _terrainOptions, model.get(), mapf.terrainMaskLayers() );
    //assemble.execute();

    // if we're using LOD blending, find and add the parent's state set.
    if ( out_hasLodBlendedLayers && key.getLevelOfDetail() > 0 && _liveTiles.valid() )
    {
        osg::ref_ptr<TileNode> parent;
        if ( _liveTiles->get( key.createParentKey(), parent ) )
        {
            model->_parentStateSet = parent->getPublicStateSet();
        }
    }

    if (!out_hasRealData)
    {
        // Check the results and see if we have any real data.
        for( TileModel::ColorDataByUID::const_iterator i = model->_colorData.begin(); i != model->_colorData.end(); ++i )
        {
            if ( !i->second.isFallbackData() ) 
            {
                out_hasRealData = true;
                break;
            }
        }
    }

    if ( !out_hasRealData && !model->_elevationData.isFallbackData() )
    {
        out_hasRealData = true;
    }

    out_model = model.release();
    //out_tile = assemble._node;
}
Exemple #6
0
osg::Node*
OSGTileFactory::createPopulatedTile(const MapFrame&  mapf, 
                                    Terrain*         terrain, 
                                    const TileKey&   key, 
                                    bool             wrapInPagedLOD, 
                                    bool             fallback, 
                                    bool&            validData )
{
    const MapInfo& mapInfo = mapf.getMapInfo();
    bool isPlateCarre = !mapInfo.isGeocentric() && mapInfo.isGeographicSRS();

    typedef std::vector<GeoImageData> GeoImageDataVector;
    GeoImageDataVector image_tiles;

    // Collect the image layers
    bool empty_map = mapf.imageLayers().size() == 0 && mapf.elevationLayers().size() == 0;

    // Create the images for the tile
    for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i )
    {
        ImageLayer* layer = i->get();
        GeoImageData imageData;

        // Only try to create images if the key is valid
        if ( layer->isKeyValid( key ) )
        {
            imageData._image = layer->createImage( key );
            imageData._layerUID = layer->getUID();
            imageData._imageTileKey = key;
        }

        // always push images, even it they are empty, so that the image_tiles vector is one-to-one
        // with the imageLayers() vector.
        image_tiles.push_back( imageData );
    }

    bool hasElevation = false;

    //Create the heightfield for the tile
    osg::ref_ptr<osg::HeightField> hf;
    if ( mapf.elevationLayers().size() > 0 )
    {
        mapf.getHeightField( key, false, hf, 0L, _terrainOptions.elevationInterpolation().value());     
    }

    //If we are on the first LOD and we couldn't get a heightfield tile, just create an empty one.  Otherwise you can run into the situation
    //where you could have an inset heightfield on one hemisphere and the whole other hemisphere won't show up.
    if ( mapInfo.isGeocentric() && key.getLevelOfDetail() <= 1 && !hf.valid())
    {
        hf = createEmptyHeightField( key );
    }
    hasElevation = hf.valid();

    //Determine if we've created any images
    unsigned int numValidImages = 0;
    for (unsigned int i = 0; i < image_tiles.size(); ++i)
    {
        if (image_tiles[i]._image.valid()) numValidImages++;
    }


    //If we couldn't create any imagery or heightfields, bail out
    if (!hf.valid() && (numValidImages == 0) && !empty_map)
    {
        OE_DEBUG << LC << "Could not create any imagery or heightfields for " << key.str() <<".  Not building tile" << std::endl;
        validData = false;

        //If we're not asked to fallback on previous LOD's and we have no data, return NULL
        if (!fallback)
        {
            return NULL;
        }
    }
    else
    {
        validData = true;
    }

    //Try to interpolate any missing image layers from parent tiles
    for (unsigned int i = 0; i < mapf.imageLayers().size(); i++ )
    {
        if (!image_tiles[i]._image.valid())
        {
            if (mapf.getImageLayerAt(i)->isKeyValid(key))
            {
                //If the key was valid and we have no image, then something possibly went wrong with the image creation such as a server being busy.
                createValidGeoImage(mapf.getImageLayerAt(i), key, image_tiles[i]._image, image_tiles[i]._imageTileKey);
            }

            //If we still couldn't create an image, either something is really wrong or the key wasn't valid, so just create a transparent placeholder image
            if (!image_tiles[i]._image.valid())
            {
                //If the image is not valid, create an empty texture as a placeholder
                image_tiles[i]._image = GeoImage(ImageUtils::createEmptyImage(), key.getExtent());
                image_tiles[i]._imageTileKey = key;
            }
        }
    }

    //Fill in missing heightfield information from parent tiles
    if (!hf.valid())
    {
        //We have no heightfield sources, 
        if ( mapf.elevationLayers().size() == 0 )
        {
            hf = createEmptyHeightField( key );
        }
        else
        {
            //Try to get a heightfield again, but this time fallback on parent tiles
            if ( mapf.getHeightField( key, true, hf, 0L, _terrainOptions.elevationInterpolation().value() ) )
            {
                hasElevation = true;
            }
            else
            {
                //We couldn't get any heightfield, so just create an empty one.
                hf = createEmptyHeightField( key );
            }
        }
    }


    // In a Plate Carre tesselation, scale the heightfield elevations from meters to degrees
    if ( isPlateCarre )
    {
        HeightFieldUtils::scaleHeightFieldToDegrees( hf.get() );
    }

    osg::ref_ptr<GeoLocator> locator = GeoLocator::createForKey( key, mapInfo );
    osgTerrain::HeightFieldLayer* hf_layer = new osgTerrain::HeightFieldLayer();
    hf_layer->setLocator( locator.get() );
    hf_layer->setHeightField( hf.get() );

    bool isStreaming = 
        _terrainOptions.loadingPolicy()->mode() == LoadingPolicy::MODE_SEQUENTIAL ||
        _terrainOptions.loadingPolicy()->mode() == LoadingPolicy::MODE_PREEMPTIVE;

    Tile* tile = terrain->createTile( key, locator.get() );
    tile->setTerrainTechnique( terrain->cloneTechnique() );
    tile->setVerticalScale( _terrainOptions.verticalScale().value() );
    //tile->setLocator( locator.get() );
    tile->setElevationLayer( hf_layer );
    //tile->setRequiresNormals( true );
    tile->setDataVariance(osg::Object::DYNAMIC);

#if 0
    //Attach an updatecallback to normalize the edges of TerrainTiles.
    if (hasElevation && _terrainOptions.normalizeEdges().get() )
    {
        tile->setUpdateCallback(new TerrainTileEdgeNormalizerUpdateCallback());
        tile->setDataVariance(osg::Object::DYNAMIC);
    }
#endif

    //Assign the terrain system to the TerrainTile.
    //It is very important the terrain system is set while the MapConfig's sourceMutex is locked.
    //This registers the terrain tile so that adding/removing layers are always in sync.  If you don't do this
    //you can end up with a situation where the database pager is waiting to merge a tile, then a layer is added, then
    //the tile is finally merged and is out of sync.

    double min_units_per_pixel = DBL_MAX;

#if 0
    // create contour layer:
    if (map->getContourTransferFunction() != NULL)
    {
        osgTerrain::ContourLayer* contourLayer(new osgTerrain::ContourLayer(map->getContourTransferFunction()));

        contourLayer->setMagFilter(_terrainOptions.getContourMagFilter().value());
        contourLayer->setMinFilter(_terrainOptions.getContourMinFilter().value());
        tile->setCustomColorLayer(layer,contourLayer); //TODO: need layerUID, not layer index here -GW
        ++layer;
    }
#endif

    for (unsigned int i = 0; i < image_tiles.size(); ++i)
    {
        if (image_tiles[i]._image.valid())
        {
            const GeoImage& geo_image = image_tiles[i]._image;

            double img_xmin, img_ymin, img_xmax, img_ymax;
            geo_image.getExtent().getBounds( img_xmin, img_ymin, img_xmax, img_ymax );

            //Specify a new locator for the color with the coordinates of the TileKey that was actually used to create the image
            osg::ref_ptr<GeoLocator> img_locator = key.getProfile()->getSRS()->createLocator( 
                img_xmin, img_ymin, img_xmax, img_ymax,
                isPlateCarre );

            if ( mapInfo.isGeocentric() )
                img_locator->setCoordinateSystemType( osgTerrain::Locator::GEOCENTRIC );

            tile->setCustomColorLayer( CustomColorLayer(
                mapf.getImageLayerAt(i),
                geo_image.getImage(),
                img_locator.get(),
                key.getLevelOfDetail(),
                key) );

            double upp = geo_image.getUnitsPerPixel();

            // Scale the units per pixel to degrees if the image is mercator (and the key is geo)
            if ( geo_image.getSRS()->isMercator() && key.getExtent().getSRS()->isGeographic() )
                upp *= 1.0f/111319.0f;

            min_units_per_pixel = osg::minimum(upp, min_units_per_pixel);
        }
    }

    osg::BoundingSphere bs = tile->getBound();
    double max_range = 1e10;
    double radius = bs.radius();

#if 1
    double min_range = radius * _terrainOptions.minTileRangeFactor().get();
    //osg::LOD::RangeMode mode = osg::LOD::DISTANCE_FROM_EYE_POINT;
#else
    double width = key.getExtent().width();	
    if (min_units_per_pixel == DBL_MAX) min_units_per_pixel = width/256.0;
    double min_range = (width / min_units_per_pixel) * _terrainOptions.getMinTileRangeFactor(); 
    //osg::LOD::RangeMode mode = osg::LOD::PIXEL_SIZE_ON_SCREEN;
#endif


    // a skirt hides cracks when transitioning between LODs:
    hf->setSkirtHeight(radius * _terrainOptions.heightFieldSkirtRatio().get() );

    // for now, cluster culling does not work for CUBE rendering
    //bool isCube = mapInfo.isCube(); //map->getMapOptions().coordSysType() == MapOptions::CSTYPE_GEOCENTRIC_CUBE;
    if ( mapInfo.isGeocentric() && !mapInfo.isCube() )
    {
        //TODO:  Work on cluster culling computation for cube faces
        osg::ClusterCullingCallback* ccc = createClusterCullingCallback(tile, locator->getEllipsoidModel() );
        tile->setCullCallback( ccc );
    }

    // Wait until now, when the tile is fully baked, to assign the terrain to the tile.
    // Placeholder tiles might try to locate this tile as an ancestor, and access its layers
    // and locators...so they must be intact before making this tile available via setTerrain.
    //
    // If there's already a placeholder tile registered, this will be ignored. If there isn't,
    // this will register the new tile.
    tile->attachToTerrain( terrain );
    //tile->setTerrain( terrain );
    //terrain->registerTile( tile );

    if ( isStreaming && key.getLevelOfDetail() > 0 )
    {
        static_cast<StreamingTile*>(tile)->setHasElevationHint( hasElevation );
    }

    osg::Node* result = 0L;

    if (wrapInPagedLOD)
    {
        // create a PLOD so we can keep subdividing:
        osg::PagedLOD* plod = new osg::PagedLOD();
        plod->setCenter( bs.center() );
        plod->addChild( tile, min_range, max_range );

        std::string filename = createURI( _engineId, key ); //map->getId(), key );

        //Only add the next tile if it hasn't been blacklisted
        bool isBlacklisted = osgEarth::Registry::instance()->isBlacklisted( filename );
        if (!isBlacklisted && key.getLevelOfDetail() < (unsigned int)getTerrainOptions().maxLOD().value() && validData )
        {
            plod->setFileName( 1, filename  );
            plod->setRange( 1, 0.0, min_range );
        }
        else
        {
            plod->setRange( 0, 0, FLT_MAX );
        }

#if USE_FILELOCATIONCALLBACK
        osgDB::Options* options = new osgDB::Options;
        options->setFileLocationCallback( new FileLocationCallback() );
        plod->setDatabaseOptions( options );
#endif
        result = plod;

        if ( isStreaming )
            result->addCullCallback( new PopulateStreamingTileDataCallback( _cull_thread_mapf ) );
    }
    else
    {
        result = tile;
    }

    return result;
}
Exemple #7
0
bool
MapFrame::isCached( const osgEarth::TileKey& key ) const
{
    const Profile* mapProfile = getProfile();

    //Check the imagery layers
    for( ImageLayerVector::const_iterator i = imageLayers().begin(); i != imageLayers().end(); i++ )
    {
        ImageLayer* layer = i->get();
        osg::ref_ptr< Cache > cache = layer->getCache();

        if ( !cache.valid() || !layer->getProfile() ) 
            return false;

        std::vector< TileKey > keys;

        if ( mapProfile->isEquivalentTo( layer->getProfile() ) )
        {
            keys.push_back( key );
        }
        else
        {
            layer->getProfile()->getIntersectingTiles( key, keys );
        }

        for (unsigned int j = 0; j < keys.size(); ++j)
        {
            if ( layer->isKeyValid( keys[j] ) )
            {
                if ( !cache->isCached( keys[j], layer->getCacheSpec() ) )
                {
                    return false;
                }
            }
        }
    }

    for( ElevationLayerVector::const_iterator i = elevationLayers().begin(); i != elevationLayers().end(); ++i )
    {
        ElevationLayer* layer = i->get();
        osg::ref_ptr< Cache > cache = layer->getCache();

        if ( !cache.valid() || !layer->getProfile() )
            return false;

        std::vector<TileKey> keys;

        if ( mapProfile->isEquivalentTo( layer->getProfile() ) )
        {
            keys.push_back( key );
        }
        else
        {
            layer->getProfile()->getIntersectingTiles( key, keys );
        }

        for (unsigned int j = 0; j < keys.size(); ++j)
        {
            if ( layer->isKeyValid( keys[j] ) )
            {
                if ( !cache->isCached( keys[j], layer->getCacheSpec() ) )
                {
                    return false;
                }
            }
        }
    }
    return true;
}