FeatureSource* FeatureSourceFactory::create( const FeatureSourceOptions& options ) { FeatureSource* featureSource = 0L; if ( !options.getDriver().empty() ) { std::string driverExt = std::string(".osgearth_feature_") + options.getDriver(); osg::ref_ptr<osgDB::Options> rwopts = Registry::instance()->cloneOrCreateOptions(); rwopts->setPluginData( FEATURE_SOURCE_OPTIONS_TAG, (void*)&options ); featureSource = dynamic_cast<FeatureSource*>( osgDB::readObjectFile( driverExt, rwopts.get() ) ); if ( featureSource ) { if ( options.name().isSet() ) featureSource->setName( *options.name() ); else featureSource->setName( options.getDriver() ); } else { OE_WARN << LC << "FAILED to load feature driver \"" << options.getDriver() << "\"" << std::endl; } } else { OE_WARN << LC << "ILLEGAL null feature driver name" << std::endl; } return featureSource; }
FeatureSource* FeatureSourceFactory::create( const DriverOptions* driverOptions ) { FeatureSource* featureSource = 0L; if ( driverOptions ) { std::string driverExt = std::string(".osgearth_feature_") + driverOptions->driver(); featureSource = dynamic_cast<FeatureSource*>( osgDB::readObjectFile( driverExt, driverOptions ) ); if ( featureSource ) { featureSource->setName( driverOptions->name() ); } else { OE_NOTICE << "WARNING: Failed to load feature driver for " << driverExt << std::endl; } } else { OE_NOTICE << "ERROR: null driver options to FeatureSourceFactory" << std::endl; } return featureSource; }
FeatureGroupNode* FeatureLayer::createFeatureGroupNode(const TerrainTile* tile,ProgressBase* p) { if(!tile) return NULL; FeatureSource* fs = getFeatureSource(); if(!fs) return NULL; if(tile->getTileKey().level()<getMinLevel() || tile->getTileKey().level()>getMaxLevel()) return NULL; const SpatialProperty* sp = tile->getSP(); const SpatialProperty* local_sp = getSP(); if(!sp || !sp->getSrs() || !local_sp || !local_sp->getSrs()) return NULL; osg::ref_ptr<FeatureCursor> fc; if(sp->getSrs()->isEquivalentTo(local_sp->getSrs())) { const GeoExtent* q_ex = sp->getGeoExtent(); fc = fs->createFeatureCursor(*sp); } else { osg::ref_ptr<GeoExtent> q_ex = new GeoExtent(sp->getGeoExtent()); osg::ref_ptr<SpatialProperty> sp2 = new SpatialProperty(q_ex.get(), ((SpatialProperty*)local_sp)->getSrs()); sp->getSrs()->transformExtent(local_sp->getSrs(), q_ex->xMin(),q_ex->yMin(),q_ex->xMax(),q_ex->yMax()); sp2->setGeoExtent(q_ex.get()); fc = fs->createFeatureCursor(*sp2); } if(!fc.valid()) return NULL; FeatureGroupNode* g = new FeatureGroupNode; while(fc->hasNext()) { osg::ref_ptr<Feature> f = fc->next(); osg::Node* n = createNode(tile,f.get()); if(n) { FeatureNode* fn = new FeatureNode(); fn->setFeature(f); fn->setParentLayer(this); fn->addChild(n); g->addFeatureNode(fn); } } return g; }
const FeatureProfile* FeatureSource::getFeatureProfile() const { if ( !_featureProfile.valid() ) { FeatureSource* nonConstThis = const_cast<FeatureSource*>(this); ScopedLock<Mutex> doubleCheckLock( nonConstThis->_createMutex ); { if ( !_featureProfile.valid() ) { // caching pattern nonConstThis->_featureProfile = nonConstThis->createFeatureProfile(); } } } return _featureProfile.get(); }
const Status& FeatureMaskLayer::open() { if (options().featureSource().isSet()) { FeatureSource* fs = FeatureSourceFactory::create(options().featureSource().get()); if (fs) { fs->setReadOptions(getReadOptions()); fs->open(); setFeatureSource(fs); } else { setStatus(Status(Status::ConfigurationError, "Cannot create feature source")); } } return MaskLayer::open(); }
const Status& FeatureModelLayer::open() { OE_TEST << LC << "open" << std::endl; if (options().featureSource().isSet()) { FeatureSource* fs = FeatureSourceFactory::create(options().featureSource().get()); if (fs) { fs->setReadOptions(getReadOptions()); fs->open(); setFeatureSource(fs); } else { setStatus(Status(Status::ConfigurationError, "Cannot create feature source")); } } return VisibleLayer::open(); }
osg::Group* FeatureModelGraph::build(const Style& defaultStyle, const Query& baseQuery, const GeoExtent& workingExtent, FeatureSourceIndex* index) { osg::ref_ptr<osg::Group> group = new osg::Group(); FeatureSource* source = _session->getFeatureSource(); // case: each feature has an embedded style. if ( source->hasEmbeddedStyles() ) { const FeatureProfile* featureProfile = source->getFeatureProfile(); // each feature has its own style, so use that and ignore the style catalog. osg::ref_ptr<FeatureCursor> cursor = source->createFeatureCursor( baseQuery ); while( cursor.valid() && cursor->hasMore() ) { Feature* feature = cursor->nextFeature(); if ( feature ) { FeatureList list; list.push_back( feature ); osg::ref_ptr<FeatureCursor> cursor = new FeatureListCursor(list); FilterContext context( _session.get(), featureProfile, workingExtent, index ); // note: gridding is not supported for embedded styles. osg::ref_ptr<osg::Node> node; // Get the Group that parents all features of this particular style. Note, this // might be NULL if the factory does not support style groups. osg::Group* styleGroup = _factory->getOrCreateStyleGroup(*feature->style(), _session.get()); if ( styleGroup ) { if ( !group->containsNode( styleGroup ) ) group->addChild( styleGroup ); } if ( _factory->createOrUpdateNode( cursor.get(), *feature->style(), context, node ) ) { if ( node.valid() ) { if ( styleGroup ) styleGroup->addChild( node.get() ); else group->addChild( node.get() ); } } } } } // case: features are externally styled. else { const StyleSheet* styles = _session->styles(); // if the stylesheet has selectors, use them to sort the features into style groups. Then create // a create a node for each style group. if ( styles->selectors().size() > 0 ) { for( StyleSelectorList::const_iterator i = styles->selectors().begin(); i != styles->selectors().end(); ++i ) { // pull the selected style... const StyleSelector& sel = *i; // if the selector uses an expression to select the style name, then we must perform the // query and then SORT the features into style groups. if ( sel.styleExpression().isSet() ) { // merge the selector's query into the existing query Query combinedQuery = baseQuery.combineWith( *sel.query() ); // query, sort, and add each style group to th parent: queryAndSortIntoStyleGroups( combinedQuery, *sel.styleExpression(), index, group ); } // otherwise, all feature returned by this query will have the same style: else { // combine the selection style with the incoming base style: Style selectedStyle = *styles->getStyle( sel.getSelectedStyleName() ); Style combinedStyle = defaultStyle.combineWith( selectedStyle ); // .. and merge it's query into the existing query Query combinedQuery = baseQuery.combineWith( *sel.query() ); // then create the node. osg::Group* styleGroup = createStyleGroup( combinedStyle, combinedQuery, index ); if ( styleGroup && !group->containsNode(styleGroup) ) group->addChild( styleGroup ); } } } // if no selectors are present, render all the features with a single style. else { Style combinedStyle = defaultStyle; // if there's no base style defined, choose a "default" style from the stylesheet. if ( defaultStyle.empty() ) combinedStyle = *styles->getDefaultStyle(); osg::Group* styleGroup = createStyleGroup( combinedStyle, baseQuery, index ); if ( styleGroup && !group->containsNode(styleGroup) ) group->addChild( styleGroup ); } } return group->getNumChildren() > 0 ? group.release() : 0L; }