osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarthUtil/WMS.cpp

Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines