osgEarth 2.1.1
Public Member Functions | Protected Attributes

osgEarth::Features::GeometryCompiler Class Reference

Collaboration diagram for osgEarth::Features::GeometryCompiler:

List of all members.

Public Member Functions

 GeometryCompiler ()
 GeometryCompiler (const GeometryCompilerOptions &options)
const GeometryCompilerOptionsoptions () const
GeometryCompilerOptionsoptions ()
osg::Node * compile (FeatureCursor *input, const Style &style, const FilterContext &context)
osg::Node * compile (Feature *input, const Style &style, const FilterContext &context)
osg::Node * compile (FeatureList &mungeableInput, const Style &style, const FilterContext &context)

Protected Attributes

GeometryCompilerOptions _options

Detailed Description

Compiles a collection of features against a style.

Definition at line 88 of file GeometryCompiler.


Constructor & Destructor Documentation

GeometryCompiler::GeometryCompiler ( )

Constructs a new geometry compiler with default options.

Definition at line 91 of file GeometryCompiler.cpp.

{
    //nop
}
GeometryCompiler::GeometryCompiler ( const GeometryCompilerOptions options)

Constructs a new compiler with preconfigured options.

Definition at line 96 of file GeometryCompiler.cpp.

                                                                           :
_options( options )
{
    //nop
}

Member Function Documentation

osg::Node * GeometryCompiler::compile ( FeatureCursor input,
const Style style,
const FilterContext context 
)

Compiles a collection of features into an OSG scene graph.

Definition at line 123 of file GeometryCompiler.cpp.

{
    if ( !context.profile() ) {
        OE_WARN << LC << "Valid feature profile required" << std::endl;
        return 0L;
    }

    //if ( style.empty() ) {
    //    OE_WARN << LC << "Non-empty style required" << std::endl;
    //    return 0L;
    //}

    // start by making a working copy of the feature set
    FeatureList workingSet;
    cursor->fill( workingSet );

    return compile(workingSet, style, context);
}

Here is the call graph for this function:

Here is the caller graph for this function:

osg::Node * GeometryCompiler::compile ( FeatureList mungeableInput,
const Style style,
const FilterContext context 
)

Definition at line 146 of file GeometryCompiler.cpp.

{
#ifdef PROFILING
    osg::Timer_t p_start = osg::Timer::instance()->tick();
    unsigned p_features = workingSet.size();
#endif

    osg::ref_ptr<osg::Group> resultGroup = new osg::Group();

    // create a filter context that will track feature data through the process
    FilterContext sharedCX = context;
    if ( !sharedCX.extent().isSet() )
        sharedCX.extent() = sharedCX.profile()->getExtent();

    // only localize coordinates if the map is geocentric AND the extent is
    // less than 180 degrees.
    const MapInfo& mi = sharedCX.getSession()->getMapInfo();
    GeoExtent workingExtent = sharedCX.extent()->transform( sharedCX.profile()->getSRS()->getGeographicSRS() );
    bool localize = mi.isGeocentric() && workingExtent.width() < 180.0;

    // go through the Style and figure out which filters to use.
    const MarkerSymbol*    marker    = style.get<MarkerSymbol>();
    const PointSymbol*     point     = style.get<PointSymbol>();
    const LineSymbol*      line      = style.get<LineSymbol>();
    const PolygonSymbol*   polygon   = style.get<PolygonSymbol>();
    const ExtrusionSymbol* extrusion = style.get<ExtrusionSymbol>();
    const AltitudeSymbol*  altitude  = style.get<AltitudeSymbol>();
    const TextSymbol*      text      = style.get<TextSymbol>();

    // if the style was empty, use some defaults based on the geometry type of the
    // first feature.
    if ( style.empty() && workingSet.size() > 0 )
    {
        Feature* first = workingSet.begin()->get();
        Geometry* geom = first->getGeometry();
        if ( geom )
        {
            switch( geom->getComponentType() )
            {
            case Geometry::TYPE_LINESTRING:
            case Geometry::TYPE_RING:
                line = s_defaultLineSymbol.get(); break;
            case Geometry::TYPE_POINTSET:
                point = s_defaultPointSymbol.get(); break;
            case Geometry::TYPE_POLYGON:
                polygon = s_defaultPolygonSymbol.get(); break;
            }
        }
    }

    if (_options.resampleMode().isSet())
    {
        ResampleFilter resample;
        resample.resampleMode() = *_options.resampleMode();        
        if (_options.resampleMaxLength().isSet())
        {
            resample.maxLength() = *_options.resampleMaxLength();
        }                   
        sharedCX = resample.push( workingSet, sharedCX );        
    }    
    
    bool altRequired =
        altitude && (
            altitude->clamping() != AltitudeSymbol::CLAMP_NONE ||
            altitude->verticalOffset().isSet() ||
            altitude->verticalScale().isSet() );

    // model substitution
    if ( marker )
    {
        // use a separate filter context since we'll be munging the data
        FilterContext markerCX = sharedCX;

        if ( marker->placement() == MarkerSymbol::PLACEMENT_RANDOM   ||
             marker->placement() == MarkerSymbol::PLACEMENT_INTERVAL )
        {
            ScatterFilter scatter;
            scatter.setDensity( *marker->density() );
            scatter.setRandom( marker->placement() == MarkerSymbol::PLACEMENT_RANDOM );
            scatter.setRandomSeed( *marker->randomSeed() );
            markerCX = scatter.push( workingSet, markerCX );
        }
        else if ( marker->placement() == MarkerSymbol::PLACEMENT_CENTROID )
        {
            CentroidFilter centroid;
            centroid.push( workingSet, markerCX );
        }

        if ( altRequired )
        {
            AltitudeFilter clamp;
            clamp.setPropertiesFromStyle( style );
            markerCX = clamp.push( workingSet, markerCX );

            // don't set this; we changed the input data.
            //altRequired = false;
        }

        SubstituteModelFilter sub( style );
        if ( marker->scale().isSet() )
        {
            //Turn on GL_NORMALIZE so lighting works properly
            resultGroup->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON );
            //sub.setModelMatrix( osg::Matrixd::scale( *marker->scale() ) );
        }

        sub.setClustering( *_options.clustering() );
        if ( _options.featureName().isSet() )
            sub.setFeatureNameExpr( *_options.featureName() );

        osg::Node* node = sub.push( workingSet, markerCX );
        if ( node )
        {
            resultGroup->addChild( node );
        }
    }

    // extruded geometry
    if ( extrusion )
    {
        if ( altRequired )
        {
            AltitudeFilter clamp;
            clamp.setPropertiesFromStyle( style );
            sharedCX = clamp.push( workingSet, sharedCX );
            altRequired = false;
        }

        ExtrudeGeometryFilter extrude;
        extrude.setStyle( style );

        // apply per-feature naming if requested.
        if ( _options.featureName().isSet() )
            extrude.setFeatureNameExpr( *_options.featureName() );

        osg::Node* node = extrude.push( workingSet, sharedCX );
        if ( node )
        {
            resultGroup->addChild( node );
        }
    }

    // simple geometry
    else if ( point || line || polygon )
    {
        if ( altRequired )
        {
            AltitudeFilter clamp;
            clamp.setPropertiesFromStyle( style );
            sharedCX = clamp.push( workingSet, sharedCX );
            altRequired = false;
        }

        BuildGeometryFilter filter( style );
        if ( _options.maxGranularity().isSet() )
            filter.maxGranularity() = *_options.maxGranularity();
        if ( _options.geoInterp().isSet() )
            filter.geoInterp() = *_options.geoInterp();
        if ( _options.mergeGeometry().isSet() )
            filter.mergeGeometry() = *_options.mergeGeometry();
        if ( _options.featureName().isSet() )
            filter.featureName() = *_options.featureName();

        osg::Node* node = filter.push( workingSet, sharedCX );
        if ( node )
        {
            resultGroup->addChild( node );
        }
    }

    if ( text )
    {
        if ( altRequired )
        {
            AltitudeFilter clamp;
            clamp.setPropertiesFromStyle( style );
            sharedCX = clamp.push( workingSet, sharedCX );
            altRequired = false;
        }

        BuildTextFilter filter( style );
        osg::Node* node = filter.push( workingSet, sharedCX );
        if ( node )
        {
            resultGroup->addChild( node );
        }
    }

    resultGroup->getOrCreateStateSet()->setMode( GL_BLEND, 1 );

    //osgDB::writeNodeFile( *(resultGroup.get()), "out.osg" );

#ifdef PROFILING
    osg::Timer_t p_end = osg::Timer::instance()->tick();
    OE_INFO << LC
        << "features = " << p_features <<
        << " ,time = " << osg::Timer::instance()->delta_s(p_start, p_end) << " s." << std::endl;
#endif

    return resultGroup.release();
}

Here is the call graph for this function:

osg::Node * GeometryCompiler::compile ( Feature input,
const Style style,
const FilterContext context 
)

Definition at line 103 of file GeometryCompiler.cpp.

{
    if ( !context.profile() ) {
        OE_WARN << LC << "Valid feature profile required" << std::endl;
        return 0L;
    }

    //if ( style.empty() ) {
    //    OE_WARN << LC << "Non-empty style required" << std::endl;
    //    return 0L;
    //}

    FeatureList workingSet;
    workingSet.push_back(feature);
    return compile(workingSet, style, context);
}

Here is the call graph for this function:

const GeometryCompilerOptions& osgEarth::Features::GeometryCompiler::options ( ) const [inline]

Access the options read-only

Definition at line 99 of file GeometryCompiler.

{ return _options; }
GeometryCompilerOptions& osgEarth::Features::GeometryCompiler::options ( ) [inline]

Access the options for editing.

Definition at line 102 of file GeometryCompiler.

{ return _options; }

Member Data Documentation

Definition at line 123 of file GeometryCompiler.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines