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 00020 #include <osgEarth/ModelSource> 00021 #include <osgEarth/Registry> 00022 #include <osgEarth/Map> 00023 #include <osgEarthFeatures/FeatureModelSource> 00024 #include <osgEarthFeatures/FeatureSource> 00025 #include <osgEarthFeatures/TransformFilter> 00026 #include <osgEarthFeatures/BuildGeometryFilter> 00027 #include <osg/Notify> 00028 #include <osg/MatrixTransform> 00029 #include <osgDB/FileNameUtils> 00030 #include <osgEarthSymbology/Style> 00031 #include <osgEarthFeatures/BuildTextOperator> 00032 00033 #include "FeatureLabelModelOptions" 00034 00035 using namespace osgEarth; 00036 using namespace osgEarth::Features; 00037 using namespace osgEarth::Symbology; 00038 using namespace osgEarth::Drivers; 00039 00040 namespace 00041 { 00042 class LabelNodeFactory : public FeatureNodeFactory 00043 { 00044 protected: 00045 const FeatureLabelModelOptions _options; 00046 00047 public: 00048 LabelNodeFactory(const FeatureLabelModelOptions& options) 00049 : _options(options) { } 00050 00051 //override 00052 bool createOrUpdateNode( 00053 FeatureCursor* cursor, 00054 const Style& style, 00055 const FilterContext& context, 00056 osg::ref_ptr<osg::Node>& node ) 00057 { 00058 const MapInfo& mi = context.getSession()->getMapInfo(); 00059 00060 // A processing context to use with the filters: 00061 FilterContext cx = context; 00062 00063 // Make a working copy of the features: 00064 FeatureList featureList; 00065 cursor->fill( featureList ); 00066 //for (FeatureList::const_iterator it = features.begin(); it != features.end(); ++it) 00067 // featureList.push_back(osg::clone((*it).get(),osg::CopyOp::DEEP_COPY_ALL)); 00068 00069 // Transform them into the map's SRS: 00070 TransformFilter xform( mi.getProfile()->getSRS(), mi.isGeocentric() ); 00071 xform.setLocalizeCoordinates( true ); 00072 xform.setMatrix( osg::Matrixd::translate( 0, 0, *_options.heightOffset() ) ); 00073 //xform.setHeightOffset( *_options.heightOffset() ); 00074 cx = xform.push( featureList, cx ); 00075 00076 // Make some labels 00077 osg::ref_ptr<const TextSymbol> textSymbol = style.getSymbol<TextSymbol>(); 00078 //Use a default symbol if we have no text symbol 00079 if (!textSymbol) textSymbol = new TextSymbol(); 00080 osg::Node* labels = NULL; 00081 if (textSymbol.valid()) 00082 { 00083 BuildTextOperator textOperator; 00084 labels = textOperator(featureList, textSymbol.get(), cx); 00085 } 00086 00087 osg::Node* result = labels; 00088 00089 // If the context specifies a reference frame, apply it to the resulting model. 00090 if ( cx.hasReferenceFrame() ) 00091 { 00092 osg::MatrixTransform* delocalizer = new osg::MatrixTransform( cx.inverseReferenceFrame() ); 00093 delocalizer->addChild( labels ); 00094 result = delocalizer; 00095 } 00096 00097 // Apply an LOD if required: 00098 if ( _options.minRange().isSet() || _options.maxRange().isSet() ) 00099 { 00100 osg::LOD* lod = new osg::LOD(); 00101 lod->addChild( result, *_options.minRange(), *_options.maxRange() ); 00102 result = lod; 00103 } 00104 00105 node = result; 00106 return true; 00107 } 00108 }; 00109 00110 //------------------------------------------------------------------------ 00111 00112 class FeatureLabelModelSource : public FeatureModelSource 00113 { 00114 public: 00115 FeatureLabelModelSource( const ModelSourceOptions& options ) : FeatureModelSource( options ), 00116 _options( options ) { } 00117 00118 //override 00119 void initialize( const std::string& referenceURI, const osgEarth::Map* map ) 00120 { 00121 FeatureModelSource::initialize( referenceURI, map ); 00122 } 00123 00124 //override 00125 FeatureNodeFactory* createFeatureNodeFactory() 00126 { 00127 return new LabelNodeFactory( _options ); 00128 } 00129 00130 protected: 00131 int _sourceId; 00132 ModelSourceOptions _options; 00133 }; 00134 } 00135 00136 //------------------------------------------------------------------------ 00137 00138 class FeatureLabelModelSourceDriver : public ModelSourceDriver 00139 { 00140 public: 00141 FeatureLabelModelSourceDriver() 00142 { 00143 supportsExtension( "osgearth_model_feature_label", "osgEarth feature label plugin" ); 00144 } 00145 00146 virtual const char* className() 00147 { 00148 return "osgEarth Feature Label Model Plugin"; 00149 } 00150 00151 virtual ReadResult readObject(const std::string& file_name, const Options* options) const 00152 { 00153 if ( !acceptsExtension(osgDB::getLowerCaseFileExtension( file_name ))) 00154 return ReadResult::FILE_NOT_HANDLED; 00155 00156 return new FeatureLabelModelSource( getModelSourceOptions(options) ); 00157 } 00158 }; 00159 00160 REGISTER_OSGPLUGIN(osgearth_model_feature_label, FeatureLabelModelSourceDriver)