void FeatureModelGraph::redraw() { removeChildren( 0, getNumChildren() ); osg::Node* node = 0; // if there's a display schema in place, set up for quadtree paging. if ( _options.layout().isSet() || _useTiledSource ) { node = setupPaging(); } else { FeatureLevel defaultLevel( 0.0f, FLT_MAX ); //Remove all current children node = buildLevel( defaultLevel, GeoExtent::INVALID, 0 ); } float minRange = -FLT_MAX; if ( _options.minRange().isSet() ) minRange = std::max(minRange, *_options.minRange()); if ( _options.layout().isSet() && _options.layout()->minRange().isSet() ) minRange = std::max(minRange, *_options.layout()->minRange()); float maxRange = FLT_MAX; if ( _options.maxRange().isSet() ) maxRange = std::min(maxRange, *_options.maxRange()); if ( _options.layout().isSet() && _options.layout()->maxRange().isSet() ) maxRange = std::min(maxRange, *_options.layout()->maxRange()); //If they've specified a min/max range, setup an LOD if ( minRange != -FLT_MAX || maxRange != FLT_MAX ) { ElevationLOD *lod = new ElevationLOD(_session->getMapInfo().getSRS(), minRange, maxRange ); lod->addChild( node ); node = lod; } addChild( node ); _session->getFeatureSource()->sync( _revision ); _dirty = false; }
void FeatureModelGraph::redraw() { // clear it out removeChildren( 0, getNumChildren() ); // zero out any decorators _clampable = 0L; _drapeable = 0L; _overlayPlaceholder = new osg::Group(); _overlayInstalled = _overlayPlaceholder; osg::Node* node = 0; // if there's a display schema in place, set up for quadtree paging. if ( _options.layout().isSet() || _useTiledSource ) { node = setupPaging(); } else { FeatureLevel defaultLevel( 0.0f, FLT_MAX ); //Remove all current children node = buildLevel( defaultLevel, GeoExtent::INVALID, 0 ); } float minRange = -FLT_MAX; if ( _options.minRange().isSet() ) minRange = std::max(minRange, *_options.minRange()); if ( _options.layout().isSet() && _options.layout()->minRange().isSet() ) minRange = std::max(minRange, *_options.layout()->minRange()); float maxRange = FLT_MAX; if ( _options.maxRange().isSet() ) maxRange = std::min(maxRange, *_options.maxRange()); if ( _options.layout().isSet() && _options.layout()->maxRange().isSet() ) maxRange = std::min(maxRange, *_options.layout()->maxRange()); //If they've specified a min/max range, setup an LOD if ( minRange != -FLT_MAX || maxRange != FLT_MAX ) { // todo: revisit this, make sure this is still right. ElevationLOD *lod = new ElevationLOD(_session->getMapInfo().getSRS(), minRange, maxRange ); lod->addChild( node ); node = lod; } // If we want fading, install fading. if ( _options.fading().isSet() ) { FadeEffect* fader = new FadeEffect(); fader->setFadeDuration( *_options.fading()->duration() ); fader->setMaxRange( *_options.fading()->maxRange() ); fader->setAttenuationDistance( *_options.fading()->attenuationDistance() ); fader->addChild( node ); node = fader; } // overlay placeholder. this will make it easier to // replace with a clamper/draper later if necessary { _overlayInstalled->addChild( node ); node = _overlayInstalled; } addChild( node ); _session->getFeatureSource()->sync( _revision ); _dirty = false; }
/** * Builds geometry for feature data at a particular level, and constrained by an extent. * The extent is either (a) expressed in "extent" literally, as is the case in a non-tiled * data source, or (b) expressed implicitly by a TileKey, which is the case for a tiled * data source. */ osg::Group* FeatureModelGraph::buildLevel( const FeatureLevel& level, const GeoExtent& extent, const TileKey* key ) { // set up for feature indexing if appropriate: osg::ref_ptr<osg::Group> group; FeatureSourceIndexNode* index = 0L; if ( _session->getFeatureSource() && _options.featureIndexing().isSet() ) { index = new FeatureSourceIndexNode( _session->getFeatureSource(), *_options.featureIndexing() ); group = index; } else { group = new osg::Group(); } // form the baseline query, which does a spatial query based on the working extent. Query query; if ( extent.isValid() ) query.bounds() = extent.bounds(); // add a tile key to the query if there is one, to support TFS-style queries if ( key ) query.tileKey() = *key; // does the level have a style name set? if ( level.styleName().isSet() ) { osg::Node* node = 0L; const Style* style = _session->styles()->getStyle( *level.styleName(), false ); if ( style ) { // found a specific style to use. node = createStyleGroup( *style, query, index ); if ( node ) group->addChild( node ); } else { const StyleSelector* selector = _session->styles()->getSelector( *level.styleName() ); if ( selector ) { buildStyleGroups( selector, query, index, group.get() ); } } } else { Style defaultStyle; if ( _session->styles()->selectors().size() == 0 ) { // attempt to glean the style from the feature source name: defaultStyle = *_session->styles()->getStyle( *_session->getFeatureSource()->getFeatureSourceOptions().name() ); } osg::Node* node = build( defaultStyle, query, extent, index ); if ( node ) group->addChild( node ); } if ( group->getNumChildren() > 0 ) { // account for a min-range here. Do not address the max-range here; that happens // above when generating paged LOD nodes, etc. float minRange = level.minRange(); if ( minRange > 0.0f ) { ElevationLOD* lod = new ElevationLOD( _session->getMapSRS() ); lod->setMinElevation( minRange ); lod->addChild( group.get() ); group = lod; } // install a cluster culler. if ( _session->getMapInfo().isGeocentric() && _options.clusterCulling() == true ) { const FeatureProfile* featureProfile = _session->getFeatureSource()->getFeatureProfile(); const GeoExtent& ccExtent = extent.isValid() ? extent : featureProfile->getExtent(); if ( ccExtent.isValid() ) { // if the extent is more than 90 degrees, bail GeoExtent geodeticExtent = ccExtent.transform( ccExtent.getSRS()->getGeographicSRS() ); if ( geodeticExtent.width() < 90.0 && geodeticExtent.height() < 90.0 ) { // get the geocentric tile center: osg::Vec3d tileCenter; ccExtent.getCentroid( tileCenter.x(), tileCenter.y() ); osg::Vec3d centerECEF; ccExtent.getSRS()->transform( tileCenter, _session->getMapSRS()->getECEF(), centerECEF ); //ccExtent.getSRS()->transformToECEF( tileCenter, centerECEF ); osg::NodeCallback* ccc = ClusterCullingFactory::create2( group.get(), centerECEF ); if ( ccc ) group->addCullCallback( ccc ); } } } // if indexing is enabled, build the index now. if ( index ) index->reindex(); return group.release(); } else { return 0L; } }
void FeatureModelGraph::redraw() { removeChildren( 0, getNumChildren() ); // initialize the clamping node first, since we need it in order // to build the default level _clamper = new ClampableNode(0L, false); osg::Node* node = 0; // if there's a display schema in place, set up for quadtree paging. if ( _options.layout().isSet() || _useTiledSource ) { node = setupPaging(); } else { FeatureLevel defaultLevel( 0.0f, FLT_MAX ); //Remove all current children node = buildLevel( defaultLevel, GeoExtent::INVALID, 0 ); } float minRange = -FLT_MAX; if ( _options.minRange().isSet() ) minRange = std::max(minRange, *_options.minRange()); if ( _options.layout().isSet() && _options.layout()->minRange().isSet() ) minRange = std::max(minRange, *_options.layout()->minRange()); float maxRange = FLT_MAX; if ( _options.maxRange().isSet() ) maxRange = std::min(maxRange, *_options.maxRange()); if ( _options.layout().isSet() && _options.layout()->maxRange().isSet() ) maxRange = std::min(maxRange, *_options.layout()->maxRange()); //If they've specified a min/max range, setup an LOD if ( minRange != -FLT_MAX || maxRange != FLT_MAX ) { ElevationLOD *lod = new ElevationLOD(_session->getMapInfo().getSRS(), minRange, maxRange ); lod->addChild( node ); node = lod; } // If we want fading, install fading. if ( _options.fading().isSet() ) { FadeEffect* fader = new FadeEffect(); fader->setFadeDuration( *_options.fading()->duration() ); fader->setMaxRange( *_options.fading()->maxRange() ); fader->setAttenuationDistance( *_options.fading()->attenuationDistance() ); fader->addChild( node ); node = fader; } // clamper. TODO: figure out if we can optionally include this { _clamper->addChild( node ); node = _clamper; } addChild( node ); _session->getFeatureSource()->sync( _revision ); _dirty = false; }