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; }
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; }