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 <osgEarthUtil/WMS> 00021 #include <osgEarth/XmlUtils> 00022 #include <osgEarth/HTTPClient> 00023 00024 #include <osgDB/FileNameUtils> 00025 #include <osgDB/FileUtils> 00026 00027 using namespace osgEarth; 00028 using namespace osgEarth::Util; 00029 using namespace std; 00030 00031 static 00032 WMSLayer* getLayerByName(const string &name, WMSLayer::LayerList& layers) 00033 { 00034 for (WMSLayer::LayerList::iterator i = layers.begin(); i != layers.end(); ++i) 00035 { 00036 if (osgDB::equalCaseInsensitive(i->get()->getName(),name)) return i->get(); 00037 WMSLayer *l = getLayerByName(name, i->get()->getLayers()); 00038 if (l) return l; 00039 } 00040 return 0; 00041 } 00042 00043 WMSStyle::WMSStyle() 00044 { 00045 } 00046 00047 WMSStyle::WMSStyle(const std::string& name, const std::string &title) 00048 { 00049 _name = name; 00050 _title = title; 00051 } 00052 00053 WMSLayer::WMSLayer(): 00054 _minLon(0), 00055 _minLat(0), 00056 _maxLon(0), 00057 _maxLat(0), 00058 _minX(0), 00059 _minY(0), 00060 _maxX(0), 00061 _maxY(0), 00062 _parentLayer(0) 00063 { 00064 } 00065 00066 void WMSLayer::getLatLonExtents(double &minLon, double &minLat, double &maxLon, double &maxLat) 00067 { 00068 minLon = _minLon; 00069 minLat= _minLat; 00070 maxLon = _maxLon; 00071 maxLat = _maxLat; 00072 } 00073 00074 void WMSLayer::setLatLonExtents(double minLon, double minLat, double maxLon, double maxLat) 00075 { 00076 _minLon = minLon; 00077 _minLat = minLat; 00078 _maxLon = maxLon; 00079 _maxLat = maxLat; 00080 } 00081 00082 void WMSLayer::getExtents(double &minX, double &minY, double &maxX, double &maxY) 00083 { 00084 minX = _minX; 00085 minY = _minY; 00086 maxX = _maxX; 00087 maxY = _maxY; 00088 } 00089 00090 void WMSLayer::setExtents(double minX, double minY, double maxX, double maxY) 00091 { 00092 _minX = minX; 00093 _minY = minY; 00094 _maxX = maxX; 00095 _maxY = maxY; 00096 } 00097 00098 00099 WMSCapabilities::WMSCapabilities() 00100 { 00101 } 00102 00103 std::string WMSCapabilities::suggestExtension() 00104 { 00105 //Default to png 00106 std::string ext = "png"; 00107 00108 //Find the first format that we have an osg ReaderWriter for 00109 for (unsigned int i = 0; i < _formats.size(); ++i) 00110 { 00111 std::string format = _formats[i]; 00112 //Strip off the "image/" 00113 if ((format.length() > 6) && (format.compare(0,6,"image/") == 0)) 00114 { 00115 format = format.substr(6); 00116 //See if we have a ReaderWriter for the extension 00117 osgDB::ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension( format ); 00118 if (rw) 00119 { 00120 ext = format; 00121 OE_DEBUG << "suggestExtension found ReaderWriter for " << ext << std::endl; 00122 break; 00123 } 00124 } 00125 } 00126 return ext; 00127 } 00128 00129 WMSLayer* 00130 WMSCapabilities::getLayerByName(const std::string &name) 00131 { 00132 return ::getLayerByName(name, _layers); 00133 } 00134 00135 WMSCapabilities* 00136 WMSCapabilitiesReader::read( const std::string &location, const osgDB::ReaderWriter::Options* options ) 00137 { 00138 WMSCapabilities *caps = NULL; 00139 if ( osgDB::containsServerAddress( location ) ) 00140 { 00141 HTTPResponse response = HTTPClient::get( location, options ); 00142 if ( response.isOK() && response.getNumParts() > 0 ) 00143 { 00144 caps = read( response.getPartStream( 0 ) ); 00145 } 00146 } 00147 else 00148 { 00149 if ((osgDB::fileExists(location)) && (osgDB::fileType(location) == osgDB::REGULAR_FILE)) 00150 { 00151 std::ifstream in( location.c_str() ); 00152 caps = read( in ); 00153 } 00154 } 00155 return caps; 00156 } 00157 00158 #define ATTR_VERSION "version" 00159 #define ELEM_CAPABILITY "capability" 00160 #define ELEM_REQUEST "request" 00161 #define ELEM_ABSTRACT "abstract" 00162 #define ELEM_GETMAP "getmap" 00163 #define ELEM_FORMAT "format" 00164 #define ELEM_LAYER "layer" 00165 #define ELEM_NAME "name" 00166 #define ELEM_TITLE "title" 00167 #define ELEM_STYLE "style" 00168 #define ELEM_SRS "srs" 00169 #define ELEM_CRS "crs" 00170 #define ELEM_LATLONBOUNDINGBOX "latlonboundingbox" 00171 #define ELEM_BOUNDINGBOX "boundingbox" 00172 #define ATTR_MINX "minx" 00173 #define ATTR_MINY "miny" 00174 #define ATTR_MAXX "maxx" 00175 #define ATTR_MAXY "maxy" 00176 00177 00178 00179 static void 00180 readLayers(XmlElement* e, WMSLayer* parentLayer, WMSLayer::LayerList& layers) 00181 { 00182 XmlNodeList layerNodes = e->getSubElements( ELEM_LAYER ); 00183 for( XmlNodeList::const_iterator i = layerNodes.begin(); i != layerNodes.end(); i++ ) 00184 { 00185 XmlElement* e_layer = static_cast<XmlElement*>( i->get() ); 00186 00187 WMSLayer *layer = new WMSLayer; 00188 layer->setName( e_layer->getSubElementText( ELEM_NAME ) ); 00189 layer->setTitle( e_layer->getSubElementText( ELEM_TITLE ) ); 00190 layer->setAbstract( e_layer->getSubElementText( ELEM_ABSTRACT ) ); 00191 00192 //Read all the supported styles 00193 XmlNodeList styles = e_layer->getSubElements( ELEM_STYLE ); 00194 for( XmlNodeList::const_iterator styleitr = styles.begin(); styleitr != styles.end(); styleitr++ ) 00195 { 00196 XmlElement* e_style = static_cast<XmlElement*>( styleitr->get() ); 00197 string name = e_style->getSubElementText( ELEM_NAME ); 00198 string title = e_style->getSubElementText( ELEM_TITLE ); 00199 layer->getStyles().push_back(WMSStyle(name,title)); 00200 } 00201 00202 //Read all the supported SRS's 00203 XmlNodeList spatialReferences = e_layer->getSubElements( ELEM_SRS ); 00204 for (XmlNodeList::const_iterator srsitr = spatialReferences.begin(); srsitr != spatialReferences.end(); ++srsitr) 00205 { 00206 string srs = static_cast<XmlElement*>( srsitr->get() )->getText(); 00207 layer->getSpatialReferences().push_back(srs); 00208 } 00209 00210 //Read all the supported CRS's 00211 spatialReferences = e_layer->getSubElements( ELEM_CRS ); 00212 for (XmlNodeList::const_iterator srsitr = spatialReferences.begin(); srsitr != spatialReferences.end(); ++srsitr) 00213 { 00214 string crs = static_cast<XmlElement*>( srsitr->get() )->getText(); 00215 layer->getSpatialReferences().push_back(crs); 00216 } 00217 00218 osg::ref_ptr<XmlElement> e_bb = e_layer->getSubElement( ELEM_LATLONBOUNDINGBOX ); 00219 if (e_bb.valid()) 00220 { 00221 double minX, minY, maxX, maxY; 00222 minX = as<double>(e_bb->getAttr( ATTR_MINX ), 0); 00223 minY = as<double>(e_bb->getAttr( ATTR_MINY ), 0); 00224 maxX = as<double>(e_bb->getAttr( ATTR_MAXX ), 0); 00225 maxY = as<double>(e_bb->getAttr( ATTR_MAXY ), 0); 00226 layer->setLatLonExtents(minX, minY, maxX, maxY); 00227 } 00228 00229 e_bb = e_layer->getSubElement( ELEM_BOUNDINGBOX ); 00230 if (e_bb.valid()) 00231 { 00232 double minX, minY, maxX, maxY; 00233 minX = as<double>(e_bb->getAttr( ATTR_MINX ), 0); 00234 minY = as<double>(e_bb->getAttr( ATTR_MINY ), 0); 00235 maxX = as<double>(e_bb->getAttr( ATTR_MAXX ), 0); 00236 maxY = as<double>(e_bb->getAttr( ATTR_MAXY ), 0); 00237 layer->setExtents(minX, minY, maxX, maxY); 00238 } 00239 00240 //Add the layer to the list and set its parent layer 00241 layers.push_back(layer); 00242 layer->setParentLayer( parentLayer ); 00243 00244 //Read any other layers that are in the layer node 00245 readLayers( e_layer, layer, layer->getLayers()); 00246 } 00247 } 00248 00249 00250 00251 00252 WMSCapabilities* 00253 WMSCapabilitiesReader::read(std::istream &in) 00254 { 00255 osg::ref_ptr<WMSCapabilities> capabilities = new WMSCapabilities; 00256 00257 osg::ref_ptr<XmlDocument> doc = XmlDocument::load( in ); 00258 if (!doc.valid() || doc->getChildren().empty()) 00259 { 00260 OE_NOTICE << "Failed to load Capabilities " << std::endl; 00261 return 0; 00262 } 00263 00264 //Get the Capabilities version 00265 osg::ref_ptr<XmlElement> e_root = static_cast<XmlElement*>(doc->getChildren()[0].get()); 00266 capabilities->setVersion( e_root->getAttr(ATTR_VERSION ) ); 00267 00268 osg::ref_ptr<XmlElement> e_capability = e_root->getSubElement( ELEM_CAPABILITY ); 00269 if (!e_capability.valid()) 00270 { 00271 OE_NOTICE << "Could not find Capability element" << std::endl; 00272 return 0; 00273 } 00274 00275 //Get the supported formats 00276 osg::ref_ptr<XmlElement> e_request = e_capability->getSubElement( ELEM_REQUEST ); 00277 if (e_request.valid()) 00278 { 00279 osg::ref_ptr<XmlElement> e_getMap = e_request->getSubElement( ELEM_GETMAP ); 00280 if ( e_getMap.valid() ) 00281 { 00282 //Read all the formats 00283 XmlNodeList formats = e_getMap->getSubElements( ELEM_FORMAT ); 00284 for( XmlNodeList::const_iterator i = formats.begin(); i != formats.end(); i++ ) 00285 { 00286 string format = trim(static_cast<XmlElement*>( i->get() )->getText()); 00287 capabilities->getFormats().push_back(format); 00288 } 00289 } 00290 } 00291 00292 //Try to read the layers 00293 readLayers( e_capability.get(), 0, capabilities->getLayers()); 00294 00295 return capabilities.release(); 00296 }