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 <osgEarthFeatures/FeatureDisplayLayout> 00020 #include <limits> 00021 00022 using namespace osgEarth; 00023 using namespace osgEarth::Features; 00024 using namespace osgEarth::Symbology; 00025 00026 //------------------------------------------------------------------------ 00027 00028 FeatureLevel::FeatureLevel( const Config& conf ) : 00029 _minRange( 0.0f ), 00030 _maxRange( FLT_MAX ) 00031 { 00032 fromConfig( conf ); 00033 } 00034 00035 FeatureLevel::FeatureLevel( float minRange, float maxRange ) : 00036 _minRange( minRange ), 00037 _maxRange( maxRange ) 00038 { 00039 //nop 00040 } 00041 00042 FeatureLevel::FeatureLevel( float minRange, float maxRange, const StyleSelector& oneSelector ) : 00043 _minRange( minRange ), 00044 _maxRange( maxRange ) 00045 { 00046 _selectors.push_back( oneSelector ); 00047 } 00048 00049 void 00050 FeatureLevel::fromConfig( const Config& conf ) 00051 { 00052 if ( conf.hasValue( "min_range" ) ) 00053 _minRange = conf.value( "min_range", 0.0f ); 00054 if ( conf.hasValue( "max_range" ) ) 00055 _maxRange = conf.value( "max_range", FLT_MAX ); 00056 00057 conf.getIfSet( "lod", _lod ); 00058 00059 const ConfigSet selectorsConf = conf.children( "selector" ); 00060 for( ConfigSet::const_iterator i = selectorsConf.begin(); i != selectorsConf.end(); ++i ) 00061 { 00062 _selectors.push_back( StyleSelector(*i) ); 00063 } 00064 } 00065 00066 Config 00067 FeatureLevel::getConfig() const 00068 { 00069 Config conf( "level" ); 00070 conf.add( "min_range", toString(_minRange) ); 00071 conf.add( "max_range", toString(_maxRange) ); 00072 conf.addIfSet( "lod", _lod ); 00073 00074 for( StyleSelectorVector::const_iterator i = _selectors.begin(); i != _selectors.end(); ++i ) 00075 { 00076 conf.addChild( (*i).getConfig() ); 00077 } 00078 00079 return conf; 00080 } 00081 00082 //------------------------------------------------------------------------ 00083 00084 FeatureDisplayLayout::FeatureDisplayLayout( const Config& conf ) : 00085 _tileSizeFactor( 15.0f ), 00086 _cropFeatures( false ) 00087 { 00088 fromConfig( conf ); 00089 } 00090 00091 void 00092 FeatureDisplayLayout::fromConfig( const Config& conf ) 00093 { 00094 conf.getIfSet( "tile_size_factor", _tileSizeFactor ); 00095 conf.getIfSet( "crop_features", _cropFeatures ); 00096 ConfigSet children = conf.children( "level" ); 00097 for( ConfigSet::const_iterator i = children.begin(); i != children.end(); ++i ) 00098 addLevel( FeatureLevel( *i ) ); 00099 } 00100 00101 Config 00102 FeatureDisplayLayout::getConfig() const 00103 { 00104 Config conf( "layout" ); 00105 conf.addIfSet( "tile_size_factor", _tileSizeFactor ); 00106 conf.addIfSet( "crop_features", _cropFeatures ); 00107 for( Levels::const_iterator i = _levels.begin(); i != _levels.end(); ++i ) 00108 conf.add( i->second.getConfig() ); 00109 return conf; 00110 } 00111 00112 void 00113 FeatureDisplayLayout::addLevel( const FeatureLevel& level ) 00114 { 00115 _levels.insert( std::make_pair( -level.maxRange(), level ) ); 00116 } 00117 00118 unsigned 00119 FeatureDisplayLayout::getNumLevels() const 00120 { 00121 return _levels.size(); 00122 } 00123 00124 const FeatureLevel* 00125 FeatureDisplayLayout::getLevel( unsigned n ) const 00126 { 00127 unsigned i = 0; 00128 for( Levels::const_iterator k = _levels.begin(); k != _levels.end(); ++k ) 00129 { 00130 if ( n == i++ ) 00131 return &(k->second); 00132 } 00133 return 0L; 00134 } 00135 00136 float 00137 FeatureDisplayLayout::getMaxRange() const 00138 { 00139 return _levels.size() > 0 ? _levels.begin()->second.maxRange() : 0.0f; 00140 } 00141 00142 unsigned 00143 FeatureDisplayLayout::chooseLOD( const FeatureLevel& level, double fullExtentRadius ) const 00144 { 00145 double radius = fullExtentRadius; 00146 unsigned lod = 1; 00147 for( ; lod < 20; ++lod ) 00148 { 00149 radius *= 0.5; 00150 float lodMaxRange = radius * _tileSizeFactor.value(); 00151 00152 if ( level.maxRange() >= lodMaxRange ) 00153 break; 00154 } 00155 return lod-1; 00156 }