Ejemplo n.º 1
0
/**
 * Builds a collection of style groups by processing a StyleSelector.
 */
void
FeatureModelGraph::buildStyleGroups(const StyleSelector* selector,
                                    const Query&         baseQuery,
                                    FeatureSourceIndex*  index,
                                    osg::Group*          parent)
{
    // 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 ( selector->styleExpression().isSet() )
    {
        // merge the selector's query into the existing query
        Query combinedQuery = baseQuery.combineWith( *selector->query() );

        // query, sort, and add each style group to the parent:
        queryAndSortIntoStyleGroups( combinedQuery, *selector->styleExpression(), index, parent );
    }

    // otherwise, all feature returned by this query will have the same style:
    else
    {
        // combine the selection style with the incoming base style:
        const Style* selectedStyle = _session->styles()->getStyle(selector->getSelectedStyleName());
        Style style;
        if ( selectedStyle )
            style = *selectedStyle;

        // .. and merge it's query into the existing query
        Query combinedQuery = baseQuery.combineWith( *selector->query() );

        // then create the node.
        osg::Node* node = createStyleGroup( style, combinedQuery, index );
        if ( node && !parent->containsNode(node) )
            parent->addChild( node );
    }
}
Ejemplo n.º 2
0
osg::Group*
FeatureModelGraph::build( const FeatureLevel& level, const GeoExtent& extent, const TileKey* key )
{
    osg::ref_ptr<osg::Group> 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;

    // now, go through any level-based selectors.
    const StyleSelectorVector& levelSelectors = level.selectors();
    
    // if there are none, just build once with the default style and query.
    if ( levelSelectors.size() == 0 )
    {
        osg::Node* node = build( Style(), query, extent );
        if ( node )
            group->addChild( node );
    }

    else
    {
        for( StyleSelectorVector::const_iterator i = levelSelectors.begin(); i != levelSelectors.end(); ++i )
        {
            const StyleSelector& selector = *i;

            // fetch the selector's style:
            Style selectorStyle;
            _styles.getStyle( selector.getSelectedStyleName(), selectorStyle );

            // combine the selector's query, if it has one:
            Query selectorQuery = 
                selector.query().isSet() ? query.combineWith( *selector.query() ) : query;

            osg::Node* node = build( selectorStyle, selectorQuery, extent );
            if ( node )
                group->addChild( node );
        }
    }

    if ( group->getNumChildren() > 0 )
    {
        // account for a min-range here.
        if ( level.minRange() > 0.0f )
        {
            osg::LOD* lod = new osg::LOD();
            lod->addChild( group.get(), level.minRange(), FLT_MAX );
            group = lod;
        }

        if ( _session->getMapInfo().isGeocentric() && _options.clusterCulling() == true )
        {
            const GeoExtent& ccExtent = extent.isValid() ? extent : _source->getFeatureProfile()->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()->transformToECEF( tileCenter, centerECEF );

                    osg::NodeCallback* ccc = ClusterCullerFactory::create( group.get(), centerECEF );
                    if ( ccc )
                        group->addCullCallback( ccc );
                }
            }
        }

        return group.release();
    }

    else
    {
        return 0L;
    }
}