예제 #1
0
파일: SLD.cpp 프로젝트: sourcepole/osgearth
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;
}
예제 #2
0
void 
KML_Placemark::build( xml_node<>* node, KMLContext& cx )
{
	Style masterStyle;

	std::string styleUrl = getValue(node, "styleurl");

	if (!styleUrl.empty())
	{	// process a "stylesheet" style
		const Style* ref_style = cx._sheet->getStyle( styleUrl, false );
		if (ref_style)
		{
			masterStyle = masterStyle.combineWith(*ref_style);
		}
	}

	xml_node<>* style = node->first_node("style", 0, false);
	if ( style )
	{	// process an "inline" style
		KML_Style kmlStyle;
		kmlStyle.scan(style, cx);
		masterStyle = masterStyle.combineWith(cx._activeStyle);
	}

    // parse the geometry. the placemark must have geometry to be valid. The 
    // geometry parse may optionally specify an altitude mode as well.
    KML_Geometry geometry;
    geometry.build(node, cx, masterStyle);

    Geometry* allGeom = geometry._geom.get();
    if ( allGeom )
    {
        GeometryIterator giter( allGeom, false );
        while( giter.hasMore() )
        {
            Geometry* geom = giter.next();
            Style style = masterStyle;

            AltitudeSymbol* alt = style.get<AltitudeSymbol>();
            
            if ( geom && geom->getTotalPointCount() > 0 )
            {
                // resolve the proper altitude mode for the anchor point
                AltitudeMode altMode = ALTMODE_RELATIVE;
                if (alt && 
                    !alt->clamping().isSetTo( alt->CLAMP_TO_TERRAIN ) &&
                    !alt->clamping().isSetTo( alt->CLAMP_RELATIVE_TO_TERRAIN ) )
                {
                    altMode = ALTMODE_ABSOLUTE;
                }

                GeoPoint position(cx._srs.get(), geom->getBounds().center(), altMode);

                bool isPoly = geom->getComponentType() == Geometry::TYPE_POLYGON;
                bool isPoint = geom->getComponentType() == Geometry::TYPE_POINTSET;

                // check for symbols.
                ModelSymbol*    model = style.get<ModelSymbol>();
                IconSymbol*     icon  = style.get<IconSymbol>();
                TextSymbol*     text  = style.get<TextSymbol>();

                // the annotation name:
                std::string name = getValue(node, "name");

                AnnotationNode* featureNode = 0L;
                AnnotationNode* iconNode    = 0L;
                AnnotationNode* modelNode   = 0L;

                // one coordinate? It's a place marker or a label.
                if ( (model || icon || text) && geom->getTotalPointCount() == 1 )
                {
                    // load up the default icon if there we don't have one.
                    if ( !model && !icon )
                    {
                        icon = cx._options->defaultIconSymbol().get();
                        if ( icon )
                            style.add( icon );
                    }

                    // if there's a model, render that - models do NOT get labels.
                    if ( model )
                    {
                        ModelNode* node = new ModelNode( cx._mapNode, style, cx._dbOptions );
                        node->setPosition( position );

                        // model scale:
                        if ( cx._options->modelScale() != 1.0f )
                        {
                            float s = *cx._options->modelScale();
                            node->setScale( osg::Vec3f(s,s,s) );
                        }

                        // model local tangent plane rotation:
                        if ( !cx._options->modelRotation()->zeroRotation() )
                        {
                            node->setLocalRotation( *cx._options->modelRotation() );
                        }

                        modelNode = node;
                    }

                    // is there a label?
                    else if ( !name.empty() )
                    {
                        if ( !text && cx._options->defaultTextSymbol().valid() )
                        {
                            text = cx._options->defaultTextSymbol().get();
                            style.addSymbol( text );

                        }
                        else
                        {
                            text = style.getOrCreate<TextSymbol>();
                            text->encoding() = TextSymbol::ENCODING_UTF8;
                        }
                        text->content()->setLiteral( name );
                    }

                    // is there an icon?
                    if ( icon )
                    {
                        iconNode = new PlaceNode( cx._mapNode, position, style, cx._dbOptions );
                    }

                    else if ( !model && text && !name.empty() )
                    {
                        // note: models do not get labels.
                        iconNode = new LabelNode( cx._mapNode, position, style );
                    }
                }

                // multiple coords? feature:
                if ( geom->getTotalPointCount() > 1 )
                {
                    ExtrusionSymbol* extruded = style.get<ExtrusionSymbol>();

                    // Remove symbols that we have already processed so the geometry
                    // compiler doesn't get confused.
                    if ( model )
                        style.removeSymbol( model );
                    if ( icon )
                        style.removeSymbol( icon );
                    if ( text )
                        style.removeSymbol( text );

                    Feature* feature = new Feature(geom, cx._srs.get(), style);
                    featureNode = new FeatureNode( cx._mapNode, feature );
                }


                // assemble the results:
                if ( (iconNode || modelNode) && featureNode )
                {
                    osg::Group* group = new osg::Group();
                    group->addChild( featureNode );
                    if ( iconNode )
                        group->addChild( iconNode );
                    if ( modelNode )
                        group->addChild( modelNode );

                    cx._groupStack.top()->addChild( group );

                    if ( iconNode && cx._options->declutter() == true )
                    {
                        Decluttering::setEnabled( iconNode->getOrCreateStateSet(), true );
                    }

                    if ( iconNode )
                        KML_Feature::build( node, cx, iconNode );
                    if ( modelNode )
                        KML_Feature::build( node, cx, modelNode );
                    if ( featureNode )
                        KML_Feature::build( node, cx, featureNode );
                }

                else
                {
                    if ( iconNode )
                    {
                        if ( cx._options->iconAndLabelGroup().valid() )
                        {
                            cx._options->iconAndLabelGroup()->addChild( iconNode );
                        }
                        else
                        {
                            cx._groupStack.top()->addChild( iconNode );
                            if ( cx._options->declutter() == true )
                            {
                                Decluttering::setEnabled( iconNode->getOrCreateStateSet(), true );
                            }
                        }
                        KML_Feature::build( node, cx, iconNode );
                    }
                    if ( modelNode )
                    {
                        cx._groupStack.top()->addChild( modelNode );
                        KML_Feature::build( node, cx, modelNode );
                    }
                    if ( featureNode )
                    {
                        cx._groupStack.top()->addChild( featureNode );
                        KML_Feature::build( node, cx, featureNode );
                    }
                }
            }
        }
    }
}
예제 #3
0
void 
KML_Placemark::build( const Config& conf, KMLContext& cx )
{
    Style style;
    if ( conf.hasValue("styleurl") )
    {
        // process a "stylesheet" style
        const Style* ref_style = cx._sheet->getStyle( conf.value("styleurl"), false );
        if ( ref_style )
            style = *ref_style;
    }
    else if ( conf.hasChild("style") )
    {
        // process an "inline" style
        KML_Style kmlStyle;
        kmlStyle.scan( conf.child("style"), cx );
        style = cx._activeStyle;
    }

    // parse the geometry. the placemark must have geometry to be valid. The 
    // geometry parse may optionally specify an altitude mode as well.
    KML_Geometry geometry;
    geometry.build(conf, cx, style);

    // KML's default altitude mode is clampToGround.
    AltitudeMode altMode = ALTMODE_RELATIVE;

    AltitudeSymbol* altSym = style.get<AltitudeSymbol>();
    if ( !altSym )
    {
        altSym = style.getOrCreate<AltitudeSymbol>();
        altSym->clamping() = AltitudeSymbol::CLAMP_RELATIVE_TO_TERRAIN;
    }
    else if ( !altSym->clamping().isSetTo(AltitudeSymbol::CLAMP_RELATIVE_TO_TERRAIN) )
    {
        altMode = ALTMODE_ABSOLUTE;
    }
    
    if ( geometry._geom.valid() && geometry._geom->getTotalPointCount() > 0 )
    {
        Geometry* geom = geometry._geom.get();

        GeoPoint position(cx._srs.get(), geom->getBounds().center(), altMode);

        bool isPoly = geom->getComponentType() == Geometry::TYPE_POLYGON;
        bool isPoint = geom->getComponentType() == Geometry::TYPE_POINTSET;

        // read in the Marker if there is one.
        URI                      markerURI;
        osg::ref_ptr<osg::Image> markerImage;
        osg::ref_ptr<osg::Node>  markerModel;

        MarkerSymbol* marker = style.get<MarkerSymbol>();

        if ( marker && marker->url().isSet() )
        {
            if ( marker->isModel() == false )
            {
                markerImage = marker->getImage( *cx._options->iconMaxSize() );
            }
            else
            {
                markerURI = URI( marker->url()->eval(), marker->url()->uriContext() );
                markerModel = markerURI.getNode();

                // We can't leave the marker symbol in the style, or the GeometryCompiler will
                // think we want to do Point-model substitution. So remove it. A bit of a hack
                if ( marker )
                    style.removeSymbol(marker);
            }
        }

        std::string text = conf.hasValue("name") ? conf.value("name") : "";

        AnnotationNode* fNode = 0L;
        AnnotationNode* pNode = 0L;

        // place a 3D model:
        if ( markerModel.valid() )
        {
            LocalGeometryNode* lg = new LocalGeometryNode(cx._mapNode, markerModel.get(), style, false);
            lg->setPosition( position );
            if ( marker )
            {
                if ( marker->scale().isSet() )
                {
                    float scale = marker->scale()->eval();
                    lg->setScale( osg::Vec3f(scale,scale,scale) );
                }
                if ( marker->orientation().isSet() )
                {
                   // lg->setRotation( );
                }
            }

            fNode = lg;
            //Feature* feature = new Feature(geometry._geom.get(), cx._srs.get(), style);
            //fNode = new FeatureNode( cx._mapNode, feature, false );
        }

        // Place node (icon + text) or Label node (text only)
        else if ( marker || geometry._geom->getTotalPointCount() == 1 )
        {
            if ( !markerImage.valid() )
            {
                markerImage = cx._options->defaultIconImage().get();
                if ( !markerImage.valid() )
                {
                    markerImage = cx._options->defaultIconURI()->getImage();
                }
            }
            
            if ( !style.get<TextSymbol>() && cx._options->defaultTextSymbol().valid() )
            {
                style.addSymbol( cx._options->defaultTextSymbol().get() );
            }

            if ( markerImage.valid() )
                pNode = new PlaceNode( cx._mapNode, position, markerImage.get(), text, style );
            else
                pNode = new LabelNode( cx._mapNode, position, text, style );
        }

        if ( geometry._geom->getTotalPointCount() > 1 )
        {
            const ExtrusionSymbol* ex = style.get<ExtrusionSymbol>();
            const AltitudeSymbol* alt = style.get<AltitudeSymbol>();    

            if ( style.get<MarkerSymbol>() )
                style.removeSymbol(style.get<MarkerSymbol>());

            bool draped =
                isPoly   && 
                ex == 0L && 
                (alt == 0L || alt->clamping() == AltitudeSymbol::CLAMP_TO_TERRAIN);

            // Make a feature node; drape if we're not extruding.
            GeometryCompilerOptions options;
            options.clustering() = false;            
            Feature* feature = new Feature(geometry._geom.get(), cx._srs.get(), style);
            fNode = new FeatureNode( cx._mapNode, feature, draped, options );

            if ( !ex )
            {
                fNode->getOrCreateStateSet()->setMode(GL_LIGHTING, 0);
            }
        }
        
        if ( pNode && fNode )
        {
            osg::Group* group = new osg::Group();
            group->addChild( fNode );
            group->addChild( pNode );
            cx._groupStack.top()->addChild( group );
            if ( cx._options->declutter() == true )
                Decluttering::setEnabled( pNode->getOrCreateStateSet(), true );
            KML_Feature::build( conf, cx, pNode );
            KML_Feature::build( conf, cx, fNode );
        }

        else if ( pNode )
        {
            if ( cx._options->iconAndLabelGroup().valid() )
            {
                cx._options->iconAndLabelGroup()->addChild( pNode );
            }
            else
            {
                cx._groupStack.top()->addChild( pNode );
                if ( cx._options->declutter() == true )
                    Decluttering::setEnabled( pNode->getOrCreateStateSet(), true );
            }
            KML_Feature::build( conf, cx, pNode );
        }

        else if ( fNode )
        {
            cx._groupStack.top()->addChild( fNode );
            KML_Feature::build( conf, cx, fNode );
        }
    }
}