osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarthSymbology/SLD.cpp

Go to the documentation of this file.
00001 /* -*-c++-*- */
00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00003  * Copyright 2008-2010 Pelican Mapping
00004  * http://osgearth.org
00005  *
00006  * osgEarth is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU Lesser General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018  */
00019 #include <osgEarthSymbology/SLD>
00020 #include <osgEarthSymbology/CssUtils>
00021 #include <osgEarthSymbology/Style>
00022 #include <osgEarthSymbology/Expression>
00023 #include <osgEarth/XmlUtils>
00024 #include <stack>
00025 #include <algorithm>
00026 
00027 using namespace osgEarth;
00028 using namespace osgEarth::Symbology;
00029 
00030 #define CSS_STROKE          "stroke"
00031 #define CSS_STROKE_WIDTH    "stroke-width"
00032 #define CSS_STROKE_OPACITY  "stroke-opacity"
00033 #define CSS_STROKE_LINECAP  "stroke-linecap"
00034 
00035 #define CSS_FILL           "fill"
00036 #define CSS_FILL_OPACITY   "fill-opacity"
00037 
00038 #define CSS_POINT_SIZE     "point-size"
00039 
00040 #define CSS_TEXT_FONT             "text-font"
00041 #define CSS_TEXT_SIZE             "text-size"
00042 #define CSS_TEXT_HALO             "text-halo"
00043 #define CSS_TEXT_ATTRIBUTE        "text-attribute"
00044 #define CSS_TEXT_ROTATE_TO_SCREEN "text-rotate-to-screen"
00045 #define CSS_TEXT_SIZE_MODE        "text-size-mode"
00046 #define CSS_TEXT_REMOVE_DUPLICATE_LABELS "text-remove-duplicate-labels"
00047 #define CSS_TEXT_LINE_ORIENTATION "text-line-orientation"
00048 #define CSS_TEXT_LINE_PLACEMENT   "text-line-placement"
00049 #define CSS_TEXT_CONTENT          "text-content"
00050 #define CSS_TEXT_CONTENT_ATTRIBUTE_DELIMITER "text-content-attribute-delimiter"
00051 
00052 
00053 static void
00054 parseLineCap( const std::string& value, optional<Stroke::LineCapStyle>& cap )
00055 {
00056     if ( value == "butt" ) cap = Stroke::LINECAP_BUTT;
00057     if ( value == "round" ) cap = Stroke::LINECAP_ROUND;
00058     if ( value == "square" ) cap = Stroke::LINECAP_SQUARE;
00059 }
00060 
00061 bool
00062 SLDReader::readStyleFromCSSParams( const Config& conf, Style& sc )
00063 {
00064     sc.setName( conf.key() );
00065 
00066     LineSymbol*      line      = 0L;
00067     PolygonSymbol*   polygon   = 0L;
00068     PointSymbol*     point     = 0L;
00069     TextSymbol*      text      = 0L;
00070     ExtrusionSymbol* extrusion = 0L;
00071     MarkerSymbol*    marker    = 0L;
00072     AltitudeSymbol*  altitude  = 0L;
00073     SkinSymbol*      skin      = 0L;
00074 
00075     for(Properties::const_iterator p = conf.attrs().begin(); p != conf.attrs().end(); p++ )
00076     {
00077         // ..... LineSymbol .....
00078 
00079         if ( p->first == CSS_STROKE )
00080         {
00081             if (!line) line = sc.getOrCreateSymbol<LineSymbol>();
00082             line->stroke()->color() = htmlColorToVec4f( p->second );
00083         }
00084         else if ( p->first == CSS_STROKE_OPACITY )
00085         {
00086             if (!line) line = sc.getOrCreateSymbol<LineSymbol>();
00087             line->stroke()->color().a() = as<float>( p->second, 1.0f );
00088         }
00089         else if ( p->first == CSS_STROKE_WIDTH )
00090         {
00091             if (!line) line = sc.getOrCreateSymbol<LineSymbol>();
00092             line->stroke()->width() = as<float>( p->second, 1.0f );
00093         }
00094         else if ( p->first == CSS_STROKE_LINECAP )
00095         {
00096             if (!line) line = sc.getOrCreateSymbol<LineSymbol>();
00097             parseLineCap( p->second, line->stroke()->lineCap() );
00098         }
00099 
00100         // ..... PolygonSymbol .....
00101 
00102         else if ( p->first == CSS_FILL )
00103         {
00104             if (!polygon) polygon = sc.getOrCreateSymbol<PolygonSymbol>();
00105             polygon->fill()->color() = htmlColorToVec4f( p->second );
00106 
00107             if ( !point ) point = sc.getOrCreateSymbol<PointSymbol>();
00108             point->fill()->color() = htmlColorToVec4f( p->second );
00109 
00110             if ( !text ) text = new TextSymbol();
00111             text->fill()->color() = htmlColorToVec4f( p->second );
00112         }
00113         else if ( p->first == CSS_FILL_OPACITY )
00114         {
00115             if (!polygon) polygon = sc.getOrCreateSymbol<PolygonSymbol>();
00116             polygon->fill()->color().a() = as<float>( p->second, 1.0f );
00117 
00118             if ( !point ) point = sc.getOrCreateSymbol<PointSymbol>();
00119             point->fill()->color().a() = as<float>( p->second, 1.0f );
00120 
00121             if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
00122             text->fill()->color().a() = as<float>( p->second, 1.0f );
00123         }
00124 
00125         // ..... PointSymbol .....
00126 
00127         else if (p->first == CSS_POINT_SIZE)
00128         {
00129             if ( !point ) point = sc.getOrCreateSymbol<PointSymbol>();
00130             point->size() = as<float>(p->second, 1.0f);
00131         }
00132 
00133         // ..... TextSymbol .....
00134 
00135         else if (p->first == CSS_TEXT_SIZE)
00136         {
00137             if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
00138             text->size() = as<float>(p->second, 32.0f);
00139         }
00140         else if (p->first == CSS_TEXT_FONT)
00141         {
00142             if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
00143             text->font() = p->second;
00144         }
00145         else if (p->first == CSS_TEXT_HALO)
00146         {
00147             if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
00148             text->halo()->color() = htmlColorToVec4f( p->second );
00149         }
00150         //else if (p->first == CSS_TEXT_ATTRIBUTE)
00151         //{
00152         //    if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
00153         //    text->attribute() = p->second;
00154         //}
00155         else if (p->first == CSS_TEXT_ROTATE_TO_SCREEN)
00156         {
00157             if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
00158             if (p->second == "true") text->rotateToScreen() = true;
00159             else if (p->second == "false") text->rotateToScreen() = false;
00160         }
00161         else if (p->first == CSS_TEXT_SIZE_MODE)
00162         {
00163             if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
00164             if (p->second == "screen") text->sizeMode() = TextSymbol::SIZEMODE_SCREEN;
00165             else if (p->second == "object") text->sizeMode() = TextSymbol::SIZEMODE_OBJECT;
00166         }
00167         else if (p->first == CSS_TEXT_REMOVE_DUPLICATE_LABELS)
00168         {
00169             if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
00170             if (p->second == "true") text->removeDuplicateLabels() = true;
00171             else if (p->second == "false") text->removeDuplicateLabels() = false;
00172         } 
00173         else if (p->first == CSS_TEXT_LINE_ORIENTATION)
00174         {
00175             if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
00176             if (p->second == "parallel") text->lineOrientation() = TextSymbol::LINEORIENTATION_PARALLEL;
00177             else if (p->second == "horizontal") text->lineOrientation() = TextSymbol::LINEORIENTATION_HORIZONTAL;
00178             else if (p->second == "perpendicular") text->lineOrientation() = TextSymbol::LINEORIENTATION_PERPENDICULAR;
00179         }
00180         else if (p->first == CSS_TEXT_LINE_PLACEMENT)
00181         {
00182             if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
00183             if (p->second == "centroid") text->linePlacement() = TextSymbol::LINEPLACEMENT_CENTROID;
00184             else if (p->second == "along-line") text->linePlacement() = TextSymbol::LINEPLACEMENT_ALONG_LINE;
00185         }
00186         else if (p->first == "text-content")
00187         {
00188             if (!text) text = sc.getOrCreate<TextSymbol>();
00189             text->content() = StringExpression( p->second );
00190         }
00191         else if (p->first == "text-priority")
00192         {
00193             if (!text) text = sc.getOrCreateSymbol<TextSymbol>();
00194             text->priority() = NumericExpression( p->second );
00195         }
00196         else if (p->first == "text-provider")
00197         {
00198             if (!text) text = sc.getOrCreate<TextSymbol>();
00199             text->provider() = p->second;
00200         }
00201 
00202         // ..... MarkerSymbol .....
00203 
00204         else if (p->first == "marker")
00205         {
00206             if (!marker) marker = sc.getOrCreate<MarkerSymbol>();            
00207             marker->url() = p->second;
00208             marker->url()->setURIContext( conf.uriContext() );
00209         }
00210         else if (p->first == "marker-placement")
00211         {
00212             if (!marker) marker = sc.getOrCreate<MarkerSymbol>();
00213             if      (p->second == "vertex")   marker->placement() = MarkerSymbol::PLACEMENT_VERTEX;
00214             else if (p->second == "interval") marker->placement() = MarkerSymbol::PLACEMENT_INTERVAL;
00215             else if (p->second == "random"  ) marker->placement() = MarkerSymbol::PLACEMENT_RANDOM;
00216             else if (p->second == "centroid") marker->placement() = MarkerSymbol::PLACEMENT_CENTROID;
00217         }
00218         else if (p->first == "marker-density")
00219         {
00220             if (!marker) marker = sc.getOrCreateSymbol<MarkerSymbol>();
00221             marker->density() = as<float>(p->second, 1.0f);
00222         }
00223         else if (p->first == "marker-random-seed")
00224         {
00225             if (!marker) marker = sc.getOrCreateSymbol<MarkerSymbol>();
00226             marker->randomSeed() = as<unsigned>(p->second, 0);
00227         }
00228         else if (p->first == "marker-scale")
00229         {
00230             if (!marker) marker = sc.getOrCreateSymbol<MarkerSymbol>();
00231             marker->scale() = NumericExpression(p->second);
00232         }
00233 
00234         // ..... ExtrusionSymbol .....
00235                 
00236         else if (p->first == "extrusion-height")
00237         {
00238             if (!extrusion) extrusion = sc.getOrCreate<ExtrusionSymbol>();
00239             extrusion->heightExpression() = NumericExpression(p->second);
00240         }
00241         else if (p->first == "extrusion-flatten")
00242         {
00243             if (!extrusion) extrusion = sc.getOrCreate<ExtrusionSymbol>();
00244             extrusion->flatten() = as<bool>(p->second, true);
00245         }
00246         else if (p->first == "extrusion-wall-style")
00247         {
00248             if (!extrusion) extrusion = sc.getOrCreate<ExtrusionSymbol>();
00249             extrusion->wallStyleName() = p->second;
00250         }
00251         else if (p->first == "extrusion-roof-style")
00252         {
00253             if (!extrusion) extrusion = sc.getOrCreate<ExtrusionSymbol>();
00254             extrusion->roofStyleName() = p->second;
00255         }
00256 
00257         // ..... AltitideSymbol .....
00258                 
00259         else if (p->first == "altitude-clamping")
00260         {
00261             if (!altitude) altitude = sc.getOrCreateSymbol<AltitudeSymbol>();
00262             if      (p->second == "none"    ) altitude->clamping() = AltitudeSymbol::CLAMP_NONE;
00263             else if (p->second == "terrain" ) altitude->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN;
00264             else if (p->second == "absolute") altitude->clamping() = AltitudeSymbol::CLAMP_ABSOLUTE;
00265             else if (p->second == "relative") altitude->clamping() = AltitudeSymbol::CLAMP_RELATIVE_TO_TERRAIN;
00266         }
00267         else if (p->first == "altitude-resolution")
00268         {
00269             if (!altitude) altitude = sc.getOrCreate<AltitudeSymbol>();
00270             altitude->clampingResolution() = as<float>( p->second, 0.0f );
00271         }
00272         else if (p->first == "altitude-offset")
00273         {
00274             if (!altitude) altitude = sc.getOrCreate<AltitudeSymbol>();
00275             altitude->verticalOffset() = NumericExpression( p->second );
00276         }
00277         else if (p->first == "altitude-scale")
00278         {
00279             if (!altitude) altitude = sc.getOrCreate<AltitudeSymbol>();
00280             altitude->verticalScale() = NumericExpression( p->second );
00281         }
00282 
00283         // ..... SkinSymbol .....
00284 
00285         else if (p->first == "skin-library")
00286         {
00287             if (!skin) skin = sc.getOrCreate<SkinSymbol>();
00288             if ( !p->second.empty() ) skin->libraryName() = p->second;
00289         }
00290         else if (p->first == "skin-tags")
00291         {
00292             if (!skin) skin = sc.getOrCreate<SkinSymbol>();
00293             skin->addTags( p->second );
00294         }
00295         else if (p->first == "skin-tiled")
00296         {
00297             if (!skin) skin = sc.getOrCreate<SkinSymbol>();
00298             skin->isTiled() = as<bool>( p->second, false );
00299         }
00300         else if (p->first == "skin-object-height")
00301         {
00302             if (!skin) skin = sc.getOrCreate<SkinSymbol>();
00303             skin->objectHeight() = as<float>( p->second, 0.0f );
00304         }
00305         else if (p->first == "skin-min-object-height")
00306         {
00307             if (!skin) skin = sc.getOrCreate<SkinSymbol>();
00308             skin->minObjectHeight() = as<float>( p->second, 0.0f );
00309         }
00310         else if (p->first == "skin-max-object-height")
00311         {
00312             if (!skin) skin = sc.getOrCreate<SkinSymbol>();
00313             skin->maxObjectHeight() = as<float>( p->second, 0.0f );
00314         }
00315         else if (p->first == "skin-random-seed")
00316         {
00317             if (!skin) skin = sc.getOrCreate<SkinSymbol>();
00318             skin->randomSeed() = as<unsigned>( p->second, 0u );
00319         }
00320 
00321     }
00322 
00323     return true;
00324 }
00325 
00326 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines