Example #1
0
bool
Bounds::contains(const Bounds& rhs) const
{
    return 
        isValid() && rhs.isValid() && 
        xMin() <= rhs.xMin() && xMax() >= rhs.xMax() &&
        yMin() <= rhs.yMin() && yMax() >= rhs.yMax();
}
Example #2
0
bool
CubeSpatialReference::transformExtentToMBR(const SpatialReference* to_srs,
                                           double&                 in_out_xmin,
                                           double&                 in_out_ymin,
                                           double&                 in_out_xmax,
                                           double&                 in_out_ymax ) const
{
    // input bounds:
    Bounds inBounds(in_out_xmin, in_out_ymin, in_out_xmax, in_out_ymax);

    Bounds outBounds;

    // for each CUBE face, find the intersection of the input bounds and that face.
    for (int face = 0; face < 6; ++face)
    {
        Bounds faceBounds( (double)(face), 0.0, (double)(face+1), 1.0);

        Bounds intersection = faceBounds.intersectionWith(inBounds);

        // if they intersect (with a non-zero area; abutting doesn't count in this case)
        // transform the intersection and include in the result.
        if (intersection.isValid() && intersection.area2d() > 0.0)
        {
            double
                xmin = intersection.xMin(), ymin = intersection.yMin(),
                xmax = intersection.xMax(), ymax = intersection.yMax();

            if (transformInFaceExtentToMBR(to_srs, face, xmin, ymin, xmax, ymax))
            {
                outBounds.expandBy(Bounds(xmin, ymin, xmax, ymax));
            }
        }
    }

    if (outBounds.valid())
    {
        in_out_xmin = outBounds.xMin();
        in_out_ymin = outBounds.yMin();
        in_out_xmax = outBounds.xMax();
        in_out_ymax = outBounds.yMax();
        return true;
    }
    else
    {
        return false;
    }
}
Example #3
0
osg::Vec3d
Geometry::localize()
{
    osg::Vec3d offset;

    Bounds bounds = getBounds();
    if ( bounds.isValid() )
    {      
        osg::Vec2d center = bounds.center2d();
        offset.set( center.x(), center.y(), 0 );

        GeometryIterator i( this );
        while( i.hasMore() )
        {
            Geometry* part = i.next();
            for( Geometry::iterator j = part->begin(); j != part->end(); ++j )
            {
                *j = *j - offset;
            }
        }
    }

    return offset;
}
Example #4
0
/** Packages an image layer as a TMS folder. */
int
makeTMS( osg::ArgumentParser& args )
{
    // see if the user wants to override the type extension (imagery only)
    std::string extension;
    args.read( "--ext", extension );

    // verbosity?
    bool verbose = !args.read( "--quiet" );

    // find a .earth file on the command line
    std::string earthFile = findArgumentWithExtension( args, ".earth" );
    /*   if ( earthFile.empty() )
           return usage( "Missing required .earth file" );
           */
    // folder to which to write the TMS archive.
    std::string rootFolder;
    if( !args.read( "--out", rootFolder ) )
        rootFolder = Stringify() << earthFile << ".tms_repo";

    // whether to overwrite existing tile files
    bool overwrite = false;
    if( args.read( "--overwrite" ) )
        overwrite = true;

    // write out an earth file
    std::string outEarth;
    args.read( "--out-earth", outEarth );

    std::string dbOptions;
    args.read( "--db-options", dbOptions );
    std::string::size_type n = 0;
    while( (n = dbOptions.find( '"', n )) != dbOptions.npos )
    {
        dbOptions.erase( n, 1 );
    }

    osg::ref_ptr<osgDB::Options> options = new osgDB::Options( dbOptions );


    std::vector< Bounds > bounds;
    // restrict packaging to user-specified bounds.    
    double xmin = DBL_MAX, ymin = DBL_MAX, xmax = DBL_MIN, ymax = DBL_MIN;
    while( args.read( "--bounds", xmin, ymin, xmax, ymax ) )
    {
        Bounds b;
        b.xMin() = xmin, b.yMin() = ymin, b.xMax() = xmax, b.yMax() = ymax;
        bounds.push_back( b );
    }

    // max level to which to generate
    unsigned maxLevel = ~0;
    args.read( "--max-level", maxLevel );

    // whether to keep 'empty' tiles
    bool keepEmpties = args.read( "--keep-empties" );

    bool continueSingleColor = args.read( "--continue-single-color" );

    // max level to which to generate
    unsigned elevationPixelDepth = 32;
    args.read( "--elevation-pixel-depth", elevationPixelDepth );

    // load up the map
    osg::ref_ptr<MapNode> mapNode = MapNode::load( args );
    if( !mapNode.valid() )
        return usage( "Failed to load a valid .earth file" );

    // create a folder for the output
    osgDB::makeDirectory( rootFolder );
    if( !osgDB::fileExists( rootFolder ) )
        return usage( "Failed to create root output folder" );

    Map* map = mapNode->getMap();

    // fire up a packager:
    TMSPackager packager( map->getProfile(), options );

    packager.setVerbose( verbose );
    packager.setOverwrite( overwrite );
    packager.setKeepEmptyImageTiles( keepEmpties );
    packager.setSubdivideSingleColorImageTiles( continueSingleColor );
    packager.setElevationPixelDepth( elevationPixelDepth );

    if( maxLevel != ~0 )
        packager.setMaxLevel( maxLevel );

    if( bounds.size() > 0 )
    {
        for( unsigned int i = 0; i < bounds.size(); ++i )
        {
            Bounds b = bounds[i];
            if( b.isValid() )
                packager.addExtent( GeoExtent( map->getProfile()->getSRS(), b ) );
        }
    }


    // new map for an output earth file if necessary.
    osg::ref_ptr<Map> outMap = 0L;
    if( !outEarth.empty() )
    {
        // copy the options from the source map first
        outMap = new Map( map->getInitialMapOptions() );
    }

    // establish the output path of the earth file, if applicable:
    std::string outEarthFile = osgDB::concatPaths( rootFolder, osgDB::getSimpleFileName( outEarth ) );

    // package any image layers that are enabled:
    ImageLayerVector imageLayers;
    map->getImageLayers( imageLayers );

    unsigned counter = 0;

    for( ImageLayerVector::iterator i = imageLayers.begin(); i != imageLayers.end(); ++i, ++counter )
    {
        ImageLayer* layer = i->get();
        if( layer->getImageLayerOptions().enabled() == true )
        {
            std::string layerFolder = toLegalFileName( layer->getName() );
            if( layerFolder.empty() )
                layerFolder = Stringify() << "image_layer_" << counter;

            if( verbose )
            {
                OE_NOTICE << LC << "Packaging image layer \"" << layerFolder << "\"" << std::endl;
            }

            osg::ref_ptr< ConsoleProgressCallback > progress = new ConsoleProgressCallback();
            std::string layerRoot = osgDB::concatPaths( rootFolder, layerFolder );
            TMSPackager::Result r = packager.package( layer, layerRoot, progress, extension );
            if( r.ok )
            {
                // save to the output map if requested:
                if( outMap.valid() )
                {
                    // new TMS driver info:
                    TMSOptions tms;
                    tms.url() = URI(
                        osgDB::concatPaths( layerFolder, "tms.xml" ),
                        outEarthFile );

                    ImageLayerOptions layerOptions( layer->getName(), tms );
                    layerOptions.mergeConfig( layer->getInitialOptions().getConfig( true ) );
                    layerOptions.cachePolicy() = CachePolicy::NO_CACHE;

                    outMap->addImageLayer( new ImageLayer( layerOptions ) );
                }
            }
            else
            {
                OE_WARN << LC << r.message << std::endl;
            }
        }
        else if( verbose )
        {
            OE_NOTICE << LC << "Skipping disabled layer \"" << layer->getName() << "\"" << std::endl;
        }
    }

    // package any elevation layers that are enabled:
    counter = 0;
    ElevationLayerVector elevationLayers;
    map->getElevationLayers( elevationLayers );

    for( ElevationLayerVector::iterator i = elevationLayers.begin(); i != elevationLayers.end(); ++i, ++counter )
    {
        ElevationLayer* layer = i->get();
        if( layer->getElevationLayerOptions().enabled() == true )
        {
            std::string layerFolder = toLegalFileName( layer->getName() );
            if( layerFolder.empty() )
                layerFolder = Stringify() << "elevation_layer_" << counter;

            if( verbose )
            {
                OE_NOTICE << LC << "Packaging elevation layer \"" << layerFolder << "\"" << std::endl;
            }

            std::string layerRoot = osgDB::concatPaths( rootFolder, layerFolder );
            TMSPackager::Result r = packager.package( layer, layerRoot );

            if( r.ok )
            {
                // save to the output map if requested:
                if( outMap.valid() )
                {
                    // new TMS driver info:
                    TMSOptions tms;
                    tms.url() = URI(
                        osgDB::concatPaths( layerFolder, "tms.xml" ),
                        outEarthFile );

                    ElevationLayerOptions layerOptions( layer->getName(), tms );
                    layerOptions.mergeConfig( layer->getInitialOptions().getConfig( true ) );
                    layerOptions.cachePolicy() = CachePolicy::NO_CACHE;

                    outMap->addElevationLayer( new ElevationLayer( layerOptions ) );
                }
            }
            else
            {
                OE_WARN << LC << r.message << std::endl;
            }
        }
        else if( verbose )
        {
            OE_NOTICE << LC << "Skipping disabled layer \"" << layer->getName() << "\"" << std::endl;
        }
    }

    // Finally, write an earth file if requested:
    if( outMap.valid() )
    {
        MapNodeOptions outNodeOptions = mapNode->getMapNodeOptions();
        osg::ref_ptr<MapNode> outMapNode = new MapNode( outMap.get(), outNodeOptions );
        if( !osgDB::writeNodeFile( *outMapNode.get(), outEarthFile ) )
        {
            OE_WARN << LC << "Error writing earth file to \"" << outEarthFile << "\"" << std::endl;
        }
        else if( verbose )
        {
            OE_NOTICE << LC << "Wrote earth file to \"" << outEarthFile << "\"" << std::endl;
        }
    }

    return 0;
}
FilterContext
CropFilter::push( FeatureList& input, FilterContext& context )
{
    if ( !context.extent().isSet() )
    {
        OE_WARN << LC << "Extent is not set (and is required)" << std::endl;
        return context;
    }

    const GeoExtent& extent = *context.extent();

    GeoExtent newExtent( extent.getSRS() );

    if ( _method == METHOD_CENTROID )
    {
        for( FeatureList::iterator i = input.begin(); i != input.end();  )
        {
            bool keepFeature = false;

            Feature* feature = i->get();
            Geometry* featureGeom = feature->getGeometry();

            if ( featureGeom && featureGeom->isValid() )
            {
                Bounds bounds = featureGeom->getBounds();
                if ( bounds.isValid() )
                {
                    osg::Vec3d centroid = bounds.center();
                    if ( extent.contains( centroid.x(), centroid.y() ) )
                    {
                        keepFeature = true;
                        newExtent.expandToInclude( bounds.xMin(), bounds.yMin() );
                    }
                }
            }

            if ( keepFeature )
                ++i;
            else
                i = input.erase( i );
        }
    }

    else // METHOD_CROPPING (requires GEOS)
    {
#ifdef OSGEARTH_HAVE_GEOS

        // create the intersection polygon:
        osg::ref_ptr<Symbology::Polygon> poly;
        
        for( FeatureList::iterator i = input.begin(); i != input.end();  )
        {
            bool keepFeature = false;

            Feature* feature = i->get();

            Symbology::Geometry* featureGeom = feature->getGeometry();
            if ( featureGeom && featureGeom->isValid() )
            {
                // test for trivial acceptance:
                const Bounds bounds = featureGeom->getBounds();
                if ( !bounds.isValid() )
                {
                    //nop
                }

                else if ( extent.contains( bounds ) )
                {
                    keepFeature = true;
                    newExtent.expandToInclude( bounds );
                }

                // then move on to the cropping operation:
                else
                {
                    if ( !poly.valid() )
                    {
                        poly = new Symbology::Polygon();
                        poly->push_back( osg::Vec3d( extent.xMin(), extent.yMin(), 0 ));
                        poly->push_back( osg::Vec3d( extent.xMax(), extent.yMin(), 0 ));
                        poly->push_back( osg::Vec3d( extent.xMax(), extent.yMax(), 0 ));
                        poly->push_back( osg::Vec3d( extent.xMin(), extent.yMax(), 0 ));
                    }

                    osg::ref_ptr<Geometry> croppedGeometry;
                    if ( featureGeom->crop( poly.get(), croppedGeometry ) )
                    {
                        if ( croppedGeometry->isValid() )
                        {
                            feature->setGeometry( croppedGeometry.get() );
                            keepFeature = true;
                            newExtent.expandToInclude( croppedGeometry->getBounds() );
                        }
                    }
                }
            }

            if ( keepFeature )
                ++i;
            else
                i = input.erase( i );
        }  

#else // OSGEARTH_HAVE_GEOS

        OE_WARN << "CropFilter - METHOD_CROPPING not available - please compile osgEarth with GEOS" << std::endl;
        return context;

#endif
    }

    FilterContext newContext = context;
    newContext.extent() = newExtent;

    return newContext;
}
Example #6
0
int main(int argc, char** argv)
{
    osg::ArgumentParser arguments(&argc,argv);

    if (argc < 2)
    {
        return usage("");
    }
    
    //The first level
    unsigned int firstLevel = 0;
    while (arguments.read("--first-level", firstLevel));

    //The max level
    unsigned int maxLevel = 6;
    while (arguments.read("--max-level", maxLevel));

    unsigned int maxFeatures = 300;
    while (arguments.read("--max-features", maxFeatures));    

    //The destination directory
    std::string destination = "out";
    while (arguments.read("--out", destination));

    //The name of the layer
    std::string layer = "layer";
    while (arguments.read("--layer", layer));

    //The description of the layer
    std::string description = "";
    while (arguments.read("--description", description));

    std::string queryExpression = "";
    while (arguments.read("--expression", queryExpression));

    std::string queryOrderBy = "";
    while (arguments.read("--order-by", queryOrderBy));

    CropFilter::Method cropMethod = CropFilter::METHOD_CENTROID;
    if (arguments.read("--crop"))
    {
        cropMethod = CropFilter::METHOD_CROPPING;
    }

    std::string destSRS;
    while(arguments.read("--dest-srs", destSRS));

    // Custom bounding box
    Bounds bounds;
    double xmin=DBL_MAX, ymin=DBL_MAX, xmax=DBL_MIN, ymax=DBL_MIN;
    while (arguments.read("--bounds", xmin, ymin, xmax, ymax ))
    {
        bounds.xMin() = xmin;
        bounds.yMin() = ymin;
        bounds.xMax() = xmax;
        bounds.yMax() = ymax;
    }
    
    std::string filename;

    //Get the first argument that is not an option
    for(int pos=1;pos<arguments.argc();++pos)
    {
        if (!arguments.isOption(pos))
        {
            filename  = arguments[ pos ];
            break;
        }
    }

    if (filename.empty())
    {
        return usage( "Please provide a filename" );
    }

    //Open the feature source
    OGRFeatureOptions featureOpt;
    featureOpt.url() = filename;

    osg::ref_ptr< FeatureSource > features = FeatureSourceFactory::create( featureOpt );
    if (!features.valid())
    {
        OE_NOTICE << "Failed to open " << filename << std::endl;
        return 1;
    }

    features->initialize();
    const FeatureProfile* profile = features->getFeatureProfile();
    if (!profile)
    {
        OE_NOTICE << "Failed to create a valid profile for " << filename << std::endl;
        return 1;
    }

    std::string method = cropMethod == CropFilter::METHOD_CENTROID ? "Centroid" : "Cropping";

    OE_NOTICE << "Processing " << filename << std::endl
              << "  FirstLevel=" << firstLevel << std::endl
              << "  MaxLevel=" << maxLevel << std::endl
              << "  MaxFeatures=" << maxFeatures << std::endl
              << "  Destination=" << destination << std::endl
              << "  Layer=" << layer << std::endl
              << "  Description=" << description << std::endl
              << "  Expression=" << queryExpression << std::endl
              << "  OrderBy=" << queryOrderBy << std::endl
              << "  Method= " << method << std::endl
              << "  DestSRS= " << destSRS << std::endl
              << std::endl;


    Query query;
    if (!queryExpression.empty())
    {
        query.expression() = queryExpression;
    }

    if (!queryOrderBy.empty())
    {
        query.orderby() = queryOrderBy;
    }    

    osg::Timer_t startTime = osg::Timer::instance()->tick();
    //buildTFS( features.get(), firstLevel, maxLevel, maxFeatures, destination, layer, description, query, cropMethod);
    TFSPackager packager;
    packager.setFirstLevel( firstLevel );
    packager.setMaxLevel( maxLevel );
    packager.setMaxFeatures( maxFeatures );
    packager.setQuery( query );
    packager.setMethod( cropMethod );    
    packager.setDestSRS( destSRS );
    if (bounds.isValid())
    {
        packager.setLod0Extent(GeoExtent(osgEarth::SpatialReference::create( destSRS ), bounds));
    }
    packager.package( features, destination, layer, description );
    osg::Timer_t endTime = osg::Timer::instance()->tick();
    OE_NOTICE << "Completed in " << osg::Timer::instance()->delta_s( startTime, endTime ) << " s " << std::endl;

    return 0;
}