osgEarth 2.1.1
|
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 "KML_Placemark" 00020 #include "KML_Geometry" 00021 #include "KML_Style" 00022 #include <osgEarthUtil/Annotation> 00023 00024 using namespace osgEarth::Features; 00025 using namespace osgEarth::Util::Annotation; 00026 00027 void 00028 KML_Placemark::build( const Config& conf, KMLContext& cx ) 00029 { 00030 Style style; 00031 if ( conf.hasValue("styleurl") ) 00032 { 00033 // process a "stylesheet" style 00034 const Style* ref_style = cx._sheet->getStyle( conf.value("styleurl"), false ); 00035 if ( ref_style ) 00036 style = *ref_style; 00037 } 00038 else if ( conf.hasChild("style") ) 00039 { 00040 // process an "inline" style 00041 KML_Style kmlStyle; 00042 kmlStyle.scan( conf.child("style"), cx ); 00043 style = cx._activeStyle; 00044 } 00045 00046 URI iconURI; 00047 MarkerSymbol* marker = style.get<MarkerSymbol>(); 00048 if ( marker && marker->url().isSet() ) 00049 { 00050 iconURI = URI( marker->url()->expr(), marker->url()->uriContext() ); 00051 } 00052 00053 std::string text = 00054 conf.hasValue("name") ? conf.value("name") : 00055 conf.hasValue("description") ? conf.value("description") : 00056 "Unnamed"; 00057 00058 // read in the geometry: 00059 bool isPoly = false; 00060 bool isPoint = false; 00061 osg::Vec3d position; 00062 KML_Geometry geometry; 00063 geometry.build(conf, cx, style); 00064 if ( geometry._geom.valid() && geometry._geom->getTotalPointCount() > 0 ) 00065 { 00066 Geometry* geom = geometry._geom.get(); 00067 position = geom->getBounds().center(); 00068 isPoly = geom->getComponentType() == Geometry::TYPE_POLYGON; 00069 isPoint = geom->getComponentType() == Geometry::TYPE_POINTSET; 00070 } 00071 00072 FeatureNode* fNode = 0L; 00073 PlacemarkNode* pNode = 0L; 00074 00075 // if we have a non-single-point geometry, render it. 00076 if ( geometry._geom.valid() && geometry._geom->getTotalPointCount() > 1 ) 00077 { 00078 const ExtrusionSymbol* ex = style.get<ExtrusionSymbol>(); 00079 const AltitudeSymbol* alt = style.get<AltitudeSymbol>(); 00080 00081 bool draped = 00082 (ex == 0L && alt == 0L && isPoly) || 00083 (ex == 0L && alt != 0L && alt->clamping() == AltitudeSymbol::CLAMP_TO_TERRAIN); 00084 00085 // Make a feautre node; drape if we're not extruding. 00086 fNode = new FeatureNode( cx._mapNode, new Feature(geometry._geom.get()), draped ); 00087 fNode->setStyle( style ); 00088 00089 if ( draped ) 00090 fNode->getOrCreateStateSet()->setMode(GL_LIGHTING, 1); 00091 } 00092 00093 if ( isPoint ) 00094 { 00095 osg::Image* image = iconURI.readImage(); 00096 if ( !image ) 00097 { 00098 image = cx._options->defaultIconImage().get(); 00099 if ( !image ) 00100 { 00101 image = cx._options->defaultIconURI()->readImage(); 00102 } 00103 } 00104 00105 // apply the default text symbol for labeling, if necessary: 00106 if ( !style.get<TextSymbol>() && cx._options->defaultTextSymbol().valid() ) 00107 { 00108 style.addSymbol( cx._options->defaultTextSymbol().get() ); 00109 } 00110 00111 pNode = new PlacemarkNode( cx._mapNode, position, image, text, style ); 00112 } 00113 00114 if ( fNode && pNode ) 00115 { 00116 osg::Group* group = new osg::Group(); 00117 group->addChild( fNode ); 00118 group->addChild( pNode ); 00119 cx._groupStack.top()->addChild( group ); 00120 KML_Feature::build( conf, cx, group ); 00121 } 00122 else if ( pNode ) 00123 { 00124 cx._groupStack.top()->addChild( pNode ); 00125 KML_Feature::build( conf, cx, pNode ); 00126 } 00127 else if ( fNode ) 00128 { 00129 cx._groupStack.top()->addChild( fNode ); 00130 KML_Feature::build( conf, cx, fNode ); 00131 } 00132 }