Пример #1
0
void
KML_Geometry::parseStyle( const Config& conf, KMLContext& cx, Style& style )
{
    _extrude = conf.value("extrude") == "1";
    _tessellate = conf.value("tessellate") == "1";

    std::string am = conf.value("altitudemode");

    // clampToGround is the default. We will be draping the geometry UNLESS tessellate is
    // set to true.
    if ( (am.empty() || am == "clampToGround") && _tessellate )
    {
        AltitudeSymbol* af = style.getOrCreate<AltitudeSymbol>();
        af->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN;
        _extrude = false;
    }

    // "relativeToGround" means the coordinates' Z values are relative to the Z of the
    // terrain at that point. NOTE: GE flattens rooftops in this mode when extrude=1,
    // which seems wrong..
    else if ( am == "relativeToGround" )
    {
        AltitudeSymbol* af = style.getOrCreate<AltitudeSymbol>();
        af->clamping() = AltitudeSymbol::CLAMP_RELATIVE_TO_TERRAIN;
    }

    // "absolute" means to treat the Z values as-is
    else if ( am == "absolute" )
    {
        AltitudeSymbol* af = style.getOrCreate<AltitudeSymbol>();
        af->clamping() = AltitudeSymbol::CLAMP_ABSOLUTE;
    }

    if ( _extrude )
    {
        ExtrusionSymbol* es = style.getOrCreate<ExtrusionSymbol>();
        es->flatten() = false;
    }
}
Пример #2
0
void
KML_Geometry::parseStyle( xml_node<>* node, KMLContext& cx, Style& style )
{
    _extrude = getValue(node, "extrude") == "1";
    _tessellate = getValue(node, "tessellate") == "1";

    std::string am = getValue(node, "altitudemode");
    if ( am.empty() )
        am = "clampToGround"; // default.

    bool isPoly = _geom.valid() && _geom->getComponentType() == Geometry::TYPE_POLYGON;
    bool isLine = _geom.valid() && _geom->getComponentType() == Geometry::TYPE_LINESTRING;

    // Resolve the correct altitude symbol. CLAMP_TO_TERRAIN is the default, but the
    // technique will depend on the geometry's type and setup.
    AltitudeSymbol* alt = style.getOrCreate<AltitudeSymbol>();
    alt->clamping() = alt->CLAMP_TO_TERRAIN;


    // Compute some info about the geometry

    // Are all of the elevations zero?
    bool zeroElev = true;
    // Are all of the the elevations the same?
    bool sameElev = true;

    double maxElevation = -DBL_MAX;

    //if ( isPoly ) //compute maxElevation also for line strings for extrusion height
    {
        bool first = true;
        double e = 0.0;
        ConstGeometryIterator gi( _geom.get(), false );
        while(gi.hasMore() )
        {
            const Geometry* g = gi.next();
            for( Geometry::const_iterator ji = g->begin(); ji != g->end(); ++ji )
            {
                if ( !osg::equivalent(ji->z(), 0.0) )
                    zeroElev = false;

                if (first)
                {
                    first = false;
                    e = ji->z();
                }
                else
                {
                    if (!osg::equivalent(e, ji->z()))
                    {
                        sameElev = false;
                    }
                }

                if (ji->z() > maxElevation) maxElevation = ji->z();
            }
        }
    }

    // clamp to ground mode:
    if ( am == "clampToGround" )
    {
        if ( _extrude )
        {
            alt->technique() = alt->TECHNIQUE_MAP;
        }
        else if ( isPoly )
        {
            alt->technique() = alt->TECHNIQUE_DRAPE;
        }
        else if ( isLine)
        {
            alt->technique() = alt->TECHNIQUE_DRAPE; // or could be GPU.
        }
        else // line or point
        {
            alt->technique() = alt->TECHNIQUE_SCENE;
        }

        // extrusion is not compatible with clampToGround.
        _extrude = false;
    }

    // "relativeToGround" means the coordinates' Z values are relative to the Z of the
    // terrain at that point. NOTE: GE flattens rooftops in this mode when extrude=1,
    // which seems wrong..
    else if ( am == "relativeToGround" )
    {
        alt->clamping() = alt->CLAMP_RELATIVE_TO_TERRAIN;

        if (isPoly)
        {
            // If all of the verts have the same elevation then assume that it should be clamped at the centroid and not per vertex.
            if (sameElev)
            {
                alt->binding() = AltitudeSymbol::BINDING_CENTROID;
            }

            if ( _extrude )
            {
                alt->technique() = alt->TECHNIQUE_MAP;
            }
            else
            {
                alt->technique() = alt->TECHNIQUE_SCENE;

                if ( zeroElev )
                {
                    alt->clamping()  = alt->CLAMP_TO_TERRAIN;
                    alt->technique() = alt->TECHNIQUE_DRAPE;
                }
            }
        }
    }

    // "absolute" means to treat the Z values as-is
    else if ( am == "absolute" )
    {
        alt->clamping() = AltitudeSymbol::CLAMP_NONE;
    }

    if ( _extrude )
    {
        ExtrusionSymbol* es = style.getOrCreate<ExtrusionSymbol>();
        es->flatten() = false;
        if (*alt->clamping() == AltitudeSymbol::CLAMP_NONE)
        {
            // Set the height to the max elevation + the approx depth of the mariana trench so that it will extend low enough to be always go to the surface of the earth.
            // This lets us avoid clamping absolute absolute extruded polygons completely.
            es->height() = -(maxElevation + 11100.0);
        }
    }
    else
    {
        // remove polystyle since it doesn't apply to non-extruded lines and points
        if ( !isPoly )
        {
            style.remove<PolygonSymbol>();
        }
    }
}
Пример #3
0
bool
SLDReader::readStyleFromCSSParams( const Config& conf, Style& sc )
{
    sc.setName( conf.key() );

    LineSymbol*      line      = 0L;
    PolygonSymbol*   polygon   = 0L;
    PointSymbol*     point     = 0L;
    TextSymbol*      text      = 0L;
    ExtrusionSymbol* extrusion = 0L;
    MarkerSymbol*    marker     = 0L;
    AltitudeSymbol*  altitude  = 0L;

    for(Properties::const_iterator p = conf.attrs().begin(); p != conf.attrs().end(); p++ )
    {
        if ( p->first == CSS_STROKE )
        {
            if (!line) line = sc.getOrCreateSymbol<LineSymbol>();
            line->stroke()->color() = htmlColorToVec4f( p->second );
        }
        else if ( p->first == CSS_STROKE_OPACITY )
        {
            if (!line) line = sc.getOrCreateSymbol<LineSymbol>();
            line->stroke()->color().a() = as<float>( p->second, 1.0f );
        }
        else if ( p->first == CSS_STROKE_WIDTH )
        {
            if (!line) line = sc.getOrCreateSymbol<LineSymbol>();
            line->stroke()->width() = as<float>( p->second, 1.0f );
        }
        else if ( p->first == CSS_STROKE_LINECAP )
        {
            if (!line) line = sc.getOrCreateSymbol<LineSymbol>();
            parseLineCap( p->second, line->stroke()->lineCap() );
        }
        else if ( p->first == CSS_FILL )
        {
            if (!polygon) polygon = sc.getOrCreateSymbol<PolygonSymbol>();
            polygon->fill()->color() = htmlColorToVec4f( p->second );

            if ( !point ) point = sc.getOrCreateSymbol<PointSymbol>();
            point->fill()->color() = htmlColorToVec4f( p->second );

            if ( !text ) text = new TextSymbol();
            text->fill()->color() = htmlColorToVec4f( p->second );
        }
        else if ( p->first == CSS_FILL_OPACITY )
        {
            if (!polygon) polygon = sc.getOrCreateSymbol<PolygonSymbol>();
            polygon->fill()->color().a() = as<float>( p->second, 1.0f );

            if (!polygon) polygon = sc.getOrCreateSymbol<PolygonSymbol>();
            point->fill()->color().a() = as<float>( p->second, 1.0f );

            if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
            text->fill()->color().a() = as<float>( p->second, 1.0f );
        }
        else if (p->first == CSS_POINT_SIZE)
        {
            if ( !point ) point = sc.getOrCreateSymbol<PointSymbol>();
            point->size() = as<float>(p->second, 1.0f);
        }
        else if (p->first == CSS_TEXT_SIZE)
        {
            if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
            text->size() = as<float>(p->second, 32.0f);
        }
        else if (p->first == CSS_TEXT_FONT)
        {
            if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
            text->font() = p->second;
        }
        else if (p->first == CSS_TEXT_HALO)
        {
            if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
            text->halo()->color() = htmlColorToVec4f( p->second );
        }
        //else if (p->first == CSS_TEXT_ATTRIBUTE)
        //{
        //    if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
        //    text->attribute() = p->second;
        //}
        else if (p->first == CSS_TEXT_ROTATE_TO_SCREEN)
        {
            if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
            if (p->second == "true") text->rotateToScreen() = true;
            else if (p->second == "false") text->rotateToScreen() = false;
        }
        else if (p->first == CSS_TEXT_SIZE_MODE)
        {
            if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
            if (p->second == "screen") text->sizeMode() = TextSymbol::SIZEMODE_SCREEN;
            else if (p->second == "object") text->sizeMode() = TextSymbol::SIZEMODE_OBJECT;
        }
        else if (p->first == CSS_TEXT_REMOVE_DUPLICATE_LABELS)
        {
            if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
            if (p->second == "true") text->removeDuplicateLabels() = true;
            else if (p->second == "false") text->removeDuplicateLabels() = false;
        } 
        else if (p->first == CSS_TEXT_LINE_ORIENTATION)
        {
            if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
            if (p->second == "parallel") text->lineOrientation() = TextSymbol::LINEORIENTATION_PARALLEL;
            else if (p->second == "horizontal") text->lineOrientation() = TextSymbol::LINEORIENTATION_HORIZONTAL;
            else if (p->second == "perpendicular") text->lineOrientation() = TextSymbol::LINEORIENTATION_PERPENDICULAR;
        }
        else if (p->first == CSS_TEXT_LINE_PLACEMENT)
        {
            if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
            if (p->second == "centroid") text->linePlacement() = TextSymbol::LINEPLACEMENT_CENTROID;
            else if (p->second == "along-line") text->linePlacement() = TextSymbol::LINEPLACEMENT_ALONG_LINE;
        }
        else if (p->first == "text-content")
        {
            if (!text) text = sc.getOrCreate<TextSymbol>();
            text->content() = StringExpression( p->second );
        }
        else if (p->first == "text-priority")
        {
            if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
            text->priority() = NumericExpression( p->second );
        }
        else if (p->first == "text-provider")
        {
            if (!text) text = sc.getOrCreate<TextSymbol>();
            text->provider() = p->second;
        }

        //else if (p->first == CSS_TEXT_CONTENT)
        //{
        //    if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
        //    text->content() = p->second;
        //}
        //else if (p->first == CSS_TEXT_CONTENT_ATTRIBUTE_DELIMITER)
        //{
        //    if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
        //    text->contentAttributeDelimiter() = p->second;
        //}

        else if (p->first == "marker")
        {
            if (!marker) marker = sc.getOrCreateSymbol<MarkerSymbol>();
            marker->url() = p->second;
        }
        else if (p->first == "marker-placement")
        {
            if (!marker) marker = sc.getOrCreateSymbol<MarkerSymbol>();
            if      (p->second == "centroid") marker->placement() = MarkerSymbol::PLACEMENT_CENTROID;
            else if (p->second == "interval") marker->placement() = MarkerSymbol::PLACEMENT_INTERVAL;
            else if (p->second == "random"  ) marker->placement() = MarkerSymbol::PLACEMENT_RANDOM;
        }
        else if (p->first == "marker-density")
        {
            if (!marker) marker = sc.getOrCreateSymbol<MarkerSymbol>();
            marker->density() = as<float>(p->second, 1.0f);
        }
        else if (p->first == "marker-random-seed")
        {
            if (!marker) marker = sc.getOrCreateSymbol<MarkerSymbol>();
            marker->randomSeed() = as<unsigned>(p->second, 0);
        }
        else if (p->first == "marker-scale")
        {
            if (!marker) marker = sc.getOrCreateSymbol<MarkerSymbol>();
            marker->scale() = stringToVec3f(p->second, osg::Vec3f(1,1,1));
        }

        else if (p->first == "extrusion-height")
        {
            if (!extrusion) extrusion = sc.getOrCreateSymbol<ExtrusionSymbol>();
            extrusion->heightExpression() = NumericExpression(p->second);
        }
        else if (p->first == "extrusion-flatten")
        {
            if (!extrusion) extrusion = sc.getOrCreateSymbol<ExtrusionSymbol>();
            extrusion->flatten() = as<bool>(p->second, true);
        }
                
        else if (p->first == "altitude-clamping")
        {
            if (!altitude) altitude = sc.getOrCreateSymbol<AltitudeSymbol>();
            if      (p->second == "none"    ) altitude->clamping() = AltitudeSymbol::CLAMP_NONE;
            else if (p->second == "terrain" ) altitude->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN;
            else if (p->second == "relative") altitude->clamping() = AltitudeSymbol::CLAMP_RELATIVE_TO_TERRAIN;
        }
        else if (p->first == "altitude-offset")
        {
            if (!altitude) altitude = sc.getOrCreateSymbol<AltitudeSymbol>();
            altitude->verticalOffset() = as<float>( p->second, 0.0f );
        }
    }

#if 0
    if (line)
        sc.addSymbol(line);
    if (polygon)
        sc.addSymbol(polygon);
    if (point)
        sc.addSymbol(point);
    if (text)
        sc.addSymbol(text);
    if (extrusion)
        sc.addSymbol(extrusion);
    if (marker)
        sc.addSymbol(marker);
    if (altitude)
        sc.addSymbol(altitude);
#endif

    return true;
}
Пример #4
0
/**
 * This code example effectively duplicates the "boston.earth" sample,
 * demonstrating how to create a 3D city model in osgEarth.
 *
 * Run this from the tests folder.
 */
int
main(int argc, char** argv)
{
    osg::ArgumentParser arguments(&argc,argv);

    // create the map.
    Map* map = new Map();

    // add a TMS imagery layer:
    TMSOptions imagery;
    imagery.url() = "http://readymap.org/readymap/tiles/1.0.0/22/";
    map->addImageLayer( new ImageLayer("ReadyMap imagery", imagery) );

    // create a feature source to load the building footprint shapefile.
    OGRFeatureOptions feature_opt;
    feature_opt.name() = "buildings";
    feature_opt.url() = "../data/boston_buildings_utm19.shp";
    feature_opt.buildSpatialIndex() = true;
    
    // a style for the building data:
    Style buildingStyle;
    buildingStyle.setName( "default" );

    ExtrusionSymbol* extrusion = buildingStyle.getOrCreate<ExtrusionSymbol>();
    extrusion->heightExpression() = NumericExpression( "3.5 * max( [story_ht_], 1 )" );
    extrusion->flatten() = true;
    extrusion->wallStyleName() = "building-wall";
    extrusion->roofStyleName() = "building-roof";

    // a style for the wall textures:
    Style wallStyle;
    wallStyle.setName( "building-wall" );
    SkinSymbol* wallSkin = wallStyle.getOrCreate<SkinSymbol>();
    wallSkin->libraryName() = "us_resources";
    wallSkin->addTag( "building" );
    wallSkin->randomSeed() = 1;

    // a style for the rooftop textures:
    Style roofStyle;
    roofStyle.setName( "building-roof" );
    SkinSymbol* roofSkin = roofStyle.getOrCreate<SkinSymbol>();
    roofSkin->libraryName() = "us_resources";
    roofSkin->addTag( "rooftop" );
    roofSkin->randomSeed() = 1;
    roofSkin->isTiled() = true;

    // assemble a stylesheet and add our styles to it:
    StyleSheet* styleSheet = new StyleSheet();
    styleSheet->addStyle( buildingStyle );
    styleSheet->addStyle( wallStyle );
    styleSheet->addStyle( roofStyle );
    
    // load a resource library that contains the building textures.
    ResourceLibrary* reslib = new ResourceLibrary( "us_resources", "../data/resources/textures_us/catalog.xml" );
    styleSheet->addResourceLibrary( reslib );

    // set up a paging layout for incremental loading.
    FeatureDisplayLayout layout;
    layout.tileSizeFactor() = 45.0;
    layout.addLevel( FeatureLevel(0.0f, 20000.0f) );

    // create a model layer that will render the buildings according to our style sheet.
    FeatureGeomModelOptions fgm_opt;
    fgm_opt.featureOptions() = feature_opt;
    fgm_opt.styles() = styleSheet;
    fgm_opt.layout() = layout;

    map->addModelLayer( new ModelLayer( "buildings", fgm_opt ) );


    // initialize a viewer:
    osgViewer::Viewer viewer(arguments);
    EarthManipulator* manip = new EarthManipulator();
    viewer.setCameraManipulator( manip );

    // make the map scene graph:
    osg::Group* root = new osg::Group();
    viewer.setSceneData( root );

    MapNode* mapNode = new MapNode( map );
    root->addChild( mapNode );
    
    // Process cmdline args
    MapNodeHelper helper;
    helper.configureView( &viewer );
    helper.parse(mapNode, arguments, &viewer, root, new LabelControl("City Demo"));

    // zoom to a good startup position
    manip->setViewpoint( Viewpoint(-71.0763, 42.34425, 0, 24.261, -21.6, 3450.0), 5.0 );

    viewer.getDatabasePager()->setDoPreCompile( true );
    viewer.getCamera()->addCullCallback( new AutoClipPlaneCullCallback(mapNode) );

    return viewer.run();
}