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 "EarthFileSerializer" 00020 00021 using namespace osgEarth; 00022 00023 MapNode* 00024 EarthFileSerializer2::deserialize( const Config& conf, const std::string& referenceURI ) const 00025 { 00026 MapOptions mapOptions( conf.child( "options" ) ); 00027 00028 //Set the reference URI of the cache config. 00029 if (mapOptions.cache().isSet()) 00030 { 00031 mapOptions.cache()->setReferenceURI(referenceURI); 00032 } 00033 00034 // the reference URI allows osgEarth to resolve relative paths within the configuration 00035 mapOptions.referenceURI() = referenceURI; 00036 00037 // manually extract the "type" from the main tag: 00038 const std::string& csVal = conf.value("type"); 00039 mapOptions.coordSysType() = 00040 csVal == "cube" ? MapOptions::CSTYPE_GEOCENTRIC_CUBE : 00041 csVal == "projected" || csVal == "flat" ? MapOptions::CSTYPE_PROJECTED : 00042 MapOptions::CSTYPE_GEOCENTRIC; 00043 00044 // legacy: check for name/type in top-level attrs: 00045 if ( conf.hasValue( "name" ) || conf.hasValue( "type" ) ) 00046 { 00047 Config legacy; 00048 if ( conf.hasValue("name") ) legacy.add( "name", conf.value("name") ); 00049 if ( conf.hasValue("type") ) legacy.add( "type", conf.value("type") ); 00050 mapOptions.mergeConfig( legacy ); 00051 } 00052 00053 Map* map = new Map( mapOptions ); 00054 00055 // Yes, MapOptions and MapNodeOptions share the same Config node. Weird but true. 00056 MapNodeOptions mapNodeOptions( conf.child( "options" ) ); 00057 00058 // Read the layers in LAST (otherwise they will not benefit from the cache/profile configuration) 00059 00060 // Image layers: 00061 ConfigSet images = conf.children( "image" ); 00062 for( ConfigSet::const_iterator i = images.begin(); i != images.end(); i++ ) 00063 { 00064 Config layerDriverConf = *i; 00065 layerDriverConf.add( "default_tile_size", "256" ); 00066 00067 ImageLayerOptions layerOpt( layerDriverConf ); 00068 layerOpt.name() = layerDriverConf.value("name"); 00069 //layerOpt.driver() = TileSourceOptions( layerDriverConf ); 00070 00071 map->addImageLayer( new ImageLayer(layerOpt) ); 00072 } 00073 00074 // Elevation layers: 00075 for( int k=0; k<2; ++k ) 00076 { 00077 std::string tagName = k == 0 ? "elevation" : "heightfield"; // support both :) 00078 00079 ConfigSet heightfields = conf.children( tagName ); 00080 for( ConfigSet::const_iterator i = heightfields.begin(); i != heightfields.end(); i++ ) 00081 { 00082 Config layerDriverConf = *i; 00083 layerDriverConf.add( "default_tile_size", "16" ); 00084 00085 ElevationLayerOptions layerOpt( layerDriverConf ); 00086 layerOpt.name() = layerDriverConf.value( "name" ); 00087 //layerOpt.driver() = TileSourceOptions( layerDriverConf ); 00088 00089 map->addElevationLayer( new ElevationLayer(layerOpt) ); 00090 } 00091 } 00092 00093 // Model layers: 00094 ConfigSet models = conf.children( "model" ); 00095 for( ConfigSet::const_iterator i = models.begin(); i != models.end(); i++ ) 00096 { 00097 const Config& layerDriverConf = *i; 00098 00099 ModelLayerOptions layerOpt( layerDriverConf ); 00100 layerOpt.name() = layerDriverConf.value( "name" ); 00101 layerOpt.driver() = ModelSourceOptions( layerDriverConf ); 00102 00103 map->addModelLayer( new ModelLayer(layerOpt) ); 00104 //map->addModelLayer( new ModelLayer( layerDriverConf.value("name"), ModelSourceOptions(*i) ) ); 00105 } 00106 00107 // Overlay layers (just an alias for Model Layer with overlay=true) 00108 ConfigSet overlays = conf.children( "overlay" ); 00109 for( ConfigSet::const_iterator i = overlays.begin(); i != overlays.end(); i++ ) 00110 { 00111 Config layerDriverConf = *i; 00112 if ( !layerDriverConf.hasValue("driver") ) 00113 layerDriverConf.attr("driver") = "feature_geom"; 00114 //const Config& layerDriverConf = *i; 00115 00116 ModelLayerOptions layerOpt( layerDriverConf ); 00117 layerOpt.name() = layerDriverConf.value( "name" ); 00118 layerOpt.driver() = ModelSourceOptions( layerDriverConf ); 00119 layerOpt.overlay() = true; // forced on when "overlay" specified 00120 00121 map->addModelLayer( new ModelLayer(layerOpt) ); 00122 } 00123 00124 // Mask layer: 00125 ConfigSet masks = conf.children( "mask" ); 00126 for( ConfigSet::const_iterator i = masks.begin(); i != masks.end(); i++ ) 00127 { 00128 Config maskLayerConf = *i; 00129 00130 MaskLayerOptions options(maskLayerConf); 00131 options.name() = maskLayerConf.value( "name" ); 00132 options.driver() = MaskSourceOptions(options); 00133 00134 map->addTerrainMaskLayer( new MaskLayer(options) ); 00135 } 00136 00137 00138 //Add any addition paths specified in the options/osg_file_paths element to the file path. Useful for pointing osgEarth at resource folders. 00139 Config osg_file_paths = conf.child( "options" ).child("osg_file_paths"); 00140 ConfigSet urls = osg_file_paths.children("url"); 00141 for (ConfigSet::const_iterator i = urls.begin(); i != urls.end(); i++) 00142 { 00143 std::string path = osgEarth::getFullPath( referenceURI, (*i).value()); 00144 OE_DEBUG << "Adding OSG file path " << path << std::endl; 00145 osgDB::Registry::instance()->getDataFilePathList().push_back( path ); 00146 } 00147 00148 00149 00150 00151 MapNode* mapNode = new MapNode( map, mapNodeOptions ); 00152 00153 // External configs: 00154 Config ext = conf.child( "external" ); 00155 if ( !ext.empty() ) 00156 { 00157 mapNode->externalConfig() = ext; 00158 } 00159 00160 return mapNode; 00161 } 00162 00163 00164 Config 00165 EarthFileSerializer2::serialize( MapNode* input ) const 00166 { 00167 Config mapConf("map"); 00168 mapConf.attr("version") = "2"; 00169 00170 if ( !input || !input->getMap() ) 00171 return mapConf; 00172 00173 Map* map = input->getMap(); 00174 MapFrame mapf( map, Map::ENTIRE_MODEL ); 00175 00176 // the map and node options: 00177 Config optionsConf = map->getMapOptions().getConfig(); 00178 optionsConf.merge( input->getMapNodeOptions().getConfig() ); 00179 mapConf.add( "options", optionsConf ); 00180 00181 // the layers 00182 for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i ) 00183 { 00184 ImageLayer* layer = i->get(); 00185 Config layerConf = layer->getImageLayerOptions().getConfig(); 00186 layerConf.attr("name") = layer->getName(); 00187 layerConf.attr("driver") = layer->getImageLayerOptions().driver()->getDriver(); 00188 mapConf.add( "image", layerConf ); 00189 } 00190 00191 for( ElevationLayerVector::const_iterator i = mapf.elevationLayers().begin(); i != mapf.elevationLayers().end(); ++i ) 00192 { 00193 ElevationLayer* layer = i->get(); 00194 Config layerConf = layer->getElevationLayerOptions().getConfig(); 00195 layerConf.attr("name") = layer->getName(); 00196 layerConf.attr("driver") = layer->getElevationLayerOptions().driver()->getDriver(); 00197 mapConf.add( "elevation", layerConf ); 00198 } 00199 00200 for( ModelLayerVector::const_iterator i = mapf.modelLayers().begin(); i != mapf.modelLayers().end(); ++i ) 00201 { 00202 ModelLayer* layer = i->get(); 00203 Config layerConf = layer->getModelLayerOptions().getConfig(); //layer->getDriverConfig(); 00204 layerConf.attr("name") = layer->getName(); 00205 //layerConf.attr("driver") = layer->getDriverConfig().value("driver"); 00206 layerConf.attr("driver") = layer->getModelLayerOptions().driver()->getDriver(); 00207 mapConf.add( "model", layerConf ); 00208 } 00209 00210 Config ext = input->externalConfig(); 00211 if ( !ext.empty() ) 00212 { 00213 ext.key() = "external"; 00214 mapConf.addChild( ext ); 00215 } 00216 00217 return mapConf; 00218 }