void GeodeticGraticuleOptions::addLevel( float maxRange, float minRange, unsigned subFactor, const Style& lineStyle, const Style& textStyle ) { Level level; level._maxRange = maxRange; level._minRange = minRange; level._subdivisionFactor = subFactor; if ( !lineStyle.empty() ) level._lineStyle = lineStyle; if ( !textStyle.empty() ) level._textStyle = textStyle; _levels.push_back(level); }
Style Style::combineWith( const Style& rhs ) const { // start by deep-cloning this style. Style newStyle(*this); newStyle.copySymbols(rhs); if ( !this->empty() && !rhs.empty() ) newStyle.setName( _name + std::string(":") + rhs.getName() ); else if ( !this->empty() && rhs.empty() ) newStyle.setName( _name ); else if ( this->empty() && !rhs.empty() ) newStyle.setName( rhs.getName() ); else newStyle.setName( _name ); return newStyle; }
Feature::Feature( Geometry* geom, const Style& style, FeatureID fid ) : _geom ( geom ), _fid ( fid ) { if ( !style.empty() ) _style = style; }
void GeodeticGraticule::addLevel(float maxRange, float minRange, unsigned subdivFactor, const Style& style) { if ( _autoLevels ) { _autoLevels = false; _levels.clear(); } // the "-2" here is because normal tile paging gives you one subdivision already, // so we only need to account for > 1 subdivision factor. unsigned cellsPerTile = subdivFactor <= 2u ? 1u : 1u << (subdivFactor-2u); Level level; level._maxRange = maxRange; level._minRange = minRange; _profile->getNumTiles( _levels.size(), level._tilesX, level._tilesY ); level._cellsPerTileX = std::max(1u, cellsPerTile); level._cellsPerTileY = std::max(1u, cellsPerTile); if ( !style.empty() ) { level._style = style; } else { level._style = _levels.size() > 0 ? _levels[_levels.size()-1]._style : _defaultLineStyle; } _levels.push_back( level ); }
Feature::Feature( Geometry* geom, const SpatialReference* srs, const Style& style, FeatureID fid ) : _geom ( geom ), _srs ( srs ), _fid ( fid ) { if ( !style.empty() ) _style = style; dirty(); }
Style Style::combineWith( const Style& rhs ) const { // start by deep-cloning this style. Config conf = getConfig( false ); Style newStyle( conf ); // next, merge in the symbology from the other style. newStyle.mergeConfig( rhs.getConfig(false) ); if ( !this->empty() && !rhs.empty() ) newStyle.setName( _name + std::string(":") + rhs.getName() ); else if ( !this->empty() && rhs.empty() ) newStyle.setName( _name ); else if ( this->empty() && !rhs.empty() ) newStyle.setName( rhs.getName() ); else newStyle.setName( _name ); return newStyle; }
FeatureNode::FeatureNode(Feature* feature, const Style& in_style, const GeometryCompilerOptions& options, StyleSheet* styleSheet) : AnnotationNode(), _options ( options ), _needsRebuild ( true ), _styleSheet ( styleSheet ), _clampDirty (false), _index ( 0 ) { _features.push_back( feature ); Style style = in_style; if (style.empty() && feature->style().isSet()) { style = *feature->style(); } setStyle( style ); }
FeatureNode::FeatureNode(MapNode* mapNode, Feature* feature, const Style& in_style, const GeometryCompilerOptions& options, StyleSheet* styleSheet) : AnnotationNode(), _options ( options ), _needsRebuild ( true ), _styleSheet ( styleSheet ) { _features.push_back( feature ); FeatureNode::setMapNode( mapNode ); Style style = in_style; if (style.empty() && feature->style().isSet()) { style = *feature->style(); } setStyle( style ); }
/** * Querys the feature source; * Visits each feature and uses the Style Expression to resolve its style class; * Sorts the features into bins based on style class; * Compiles each bin into a separate style group; * Adds the resulting style groups to the provided parent. */ void FeatureModelGraph::queryAndSortIntoStyleGroups(const Query& query, const StringExpression& styleExpr, FeatureSourceIndex* index, osg::Group* parent) { // the profile of the features const FeatureProfile* featureProfile = _session->getFeatureSource()->getFeatureProfile(); // get the extent of the full set of feature data: const GeoExtent& extent = featureProfile->getExtent(); // query the feature source: osg::ref_ptr<FeatureCursor> cursor = _session->getFeatureSource()->createFeatureCursor( query ); if ( !cursor.valid() ) return; // establish the working bounds and a context: Bounds bounds = query.bounds().isSet() ? *query.bounds() : extent.bounds(); FilterContext context( _session.get(), featureProfile, GeoExtent(featureProfile->getSRS(), bounds), index ); StringExpression styleExprCopy( styleExpr ); // visit each feature and run the expression to sort it into a bin. std::map<std::string, FeatureList> styleBins; while( cursor->hasMore() ) { osg::ref_ptr<Feature> feature = cursor->nextFeature(); if ( feature.valid() ) { const std::string& styleString = feature->eval( styleExprCopy, &context ); styleBins[styleString].push_back( feature.get() ); } } // next create a style group per bin. for( std::map<std::string,FeatureList>::iterator i = styleBins.begin(); i != styleBins.end(); ++i ) { const std::string& styleString = i->first; FeatureList& workingSet = i->second; // resolve the style: Style combinedStyle; // if the style string begins with an open bracket, it's an inline style definition. if ( styleString.length() > 0 && styleString.at(0) == '{' ) { Config conf( "style", styleString ); conf.setReferrer( styleExpr.uriContext().referrer() ); conf.set( "type", "text/css" ); combinedStyle = Style(conf); } // otherwise, look up the style in the stylesheet. Do NOT fall back on a default // style in this case: for style expressions, the user must be explicity about // default styling; this is because there is no other way to exclude unwanted // features. else { const Style* selectedStyle = _session->styles()->getStyle(styleString, false); if ( selectedStyle ) combinedStyle = *selectedStyle; } // if there is a valid style, create the node and add it. (Otherwise we will skip // the feature.) if ( !combinedStyle.empty() ) { osg::Group* styleGroup = createStyleGroup(combinedStyle, workingSet, context); if ( styleGroup ) parent->addChild( styleGroup ); } } }