osgEarth 2.1.1
|
Public Member Functions | |
GeometryCompiler () | |
GeometryCompiler (const GeometryCompilerOptions &options) | |
const GeometryCompilerOptions & | options () const |
GeometryCompilerOptions & | options () |
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 |
Compiles a collection of features against a style.
Definition at line 88 of file GeometryCompiler.
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 }
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); }
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(); }
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); }
const GeometryCompilerOptions& osgEarth::Features::GeometryCompiler::options | ( | ) | const [inline] |
GeometryCompilerOptions& osgEarth::Features::GeometryCompiler::options | ( | ) | [inline] |
Access the options for editing.
Definition at line 102 of file GeometryCompiler.
{ return _options; }
Definition at line 123 of file GeometryCompiler.