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/WFS> 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 00032 00033 00034 00035 WFSCapabilities::WFSCapabilities() 00036 { 00037 } 00038 00039 WFSFeatureType* 00040 WFSCapabilities::getFeatureTypeByName(const std::string& name) 00041 { 00042 for (FeatureTypeList::iterator itr = _featureTypes.begin(); itr != _featureTypes.end(); ++itr) 00043 { 00044 if (osgDB::equalCaseInsensitive(itr->get()->getName(),name)) return itr->get(); 00045 } 00046 return NULL; 00047 } 00048 00049 #define ATTR_VERSION "version" 00050 #define ELEM_CAPABILITY "capability" 00051 #define ELEM_SERVICE "service" 00052 #define ELEM_REQUEST "request" 00053 #define ELEM_ABSTRACT "abstract" 00054 #define ELEM_TILED "tiled" 00055 #define ELEM_MAXLEVEL "maxlevel" 00056 #define ELEM_FIRSTLEVEL "firstlevel" 00057 #define ELEM_FORMAT "format" 00058 #define ELEM_NAME "name" 00059 #define ELEM_TITLE "title" 00060 #define ELEM_SRS "srs" 00061 #define ELEM_FEATURETYPELIST "featuretypelist" 00062 #define ELEM_FEATURETYPE "featuretype" 00063 #define ELEM_LATLONGBOUNDINGBOX "latlongboundingbox" 00064 #define ATTR_MINX "minx" 00065 #define ATTR_MINY "miny" 00066 #define ATTR_MAXX "maxx" 00067 #define ATTR_MAXY "maxy" 00068 00069 /**************************************************************************************/ 00070 WFSFeatureType::WFSFeatureType() 00071 { 00072 } 00073 /**************************************************************************************/ 00074 00075 WFSCapabilities* 00076 WFSCapabilitiesReader::read( const std::string &location, const osgDB::ReaderWriter::Options *options ) 00077 { 00078 WFSCapabilities *caps = NULL; 00079 if ( osgDB::containsServerAddress( location ) ) 00080 { 00081 HTTPResponse response = HTTPClient::get( location, options ); 00082 if ( response.isOK() && response.getNumParts() > 0 ) 00083 { 00084 caps = read( response.getPartStream( 0 ) ); 00085 } 00086 } 00087 else 00088 { 00089 if ((osgDB::fileExists(location)) && (osgDB::fileType(location) == osgDB::REGULAR_FILE)) 00090 { 00091 std::ifstream in( location.c_str() ); 00092 caps = read( in ); 00093 } 00094 } 00095 return caps; 00096 } 00097 00098 WFSCapabilities* 00099 WFSCapabilitiesReader::read(std::istream &in) 00100 { 00101 osg::ref_ptr<WFSCapabilities> capabilities = new WFSCapabilities; 00102 00103 osg::ref_ptr<XmlDocument> doc = XmlDocument::load( in ); 00104 if (!doc.valid() || doc->getChildren().empty()) 00105 { 00106 OE_NOTICE << "Failed to load Capabilities " << std::endl; 00107 return 0; 00108 } 00109 00110 //Get the Capabilities version 00111 osg::ref_ptr<XmlElement> e_root = static_cast<XmlElement*>(doc->getChildren()[0].get()); 00112 capabilities->setVersion( e_root->getAttr(ATTR_VERSION ) ); 00113 00114 osg::ref_ptr<XmlElement> e_service = e_root->getSubElement( ELEM_SERVICE ); 00115 if (!e_service.valid()) 00116 { 00117 OE_NOTICE << "Could not find Service element" << std::endl; 00118 return 0; 00119 } 00120 00121 00122 //Read the parameters from the Service block 00123 capabilities->setName( e_service->getSubElementText(ELEM_NAME ) ); 00124 capabilities->setAbstract( e_service->getSubElementText( ELEM_ABSTRACT ) ); 00125 capabilities->setTitle( e_service->getSubElementText( ELEM_TITLE ) ); 00126 00127 //Read all the feature types 00128 osg::ref_ptr<XmlElement> e_feature_types = e_root->getSubElement( ELEM_FEATURETYPELIST ); 00129 if (e_feature_types.valid()) 00130 { 00131 XmlNodeList featureTypes = e_feature_types->getSubElements( ELEM_FEATURETYPE ); 00132 for( XmlNodeList::const_iterator itr = featureTypes.begin(); itr != featureTypes.end(); itr++ ) 00133 { 00134 XmlElement* e_featureType = static_cast<XmlElement*>( itr->get() ); 00135 WFSFeatureType* featureType = new WFSFeatureType(); 00136 featureType->setName( e_featureType->getSubElementText( ELEM_NAME ) ); 00137 featureType->setTitle( e_featureType->getSubElementText( ELEM_TITLE ) ); 00138 featureType->setAbstract( e_featureType->getSubElementText( ELEM_ABSTRACT ) ); 00139 00140 //NOTE: TILED and MAXLEVEL aren't part of the WFS spec, these are enhancements to our server for tiled WFS access 00141 std::string tiledStr = e_featureType->getSubElementText(ELEM_TILED); 00142 if (tiledStr.compare("") != 0) 00143 { 00144 featureType->setTiled( as<bool>(tiledStr, false) ); 00145 } 00146 00147 std::string maxLevelStr = e_featureType->getSubElementText(ELEM_MAXLEVEL); 00148 if (maxLevelStr.compare("") != 0) 00149 { 00150 featureType->setMaxLevel( as<int>(maxLevelStr, -1)); 00151 } 00152 00153 std::string firstLevelStr = e_featureType->getSubElementText(ELEM_FIRSTLEVEL); 00154 if (firstLevelStr.compare("") != 0) 00155 { 00156 featureType->setFirstLevel( as<int>(firstLevelStr, 0)); 00157 } 00158 00159 osg::ref_ptr<XmlElement> e_bb = e_featureType->getSubElement( ELEM_LATLONGBOUNDINGBOX ); 00160 if (e_bb.valid()) 00161 { 00162 double minX, minY, maxX, maxY; 00163 minX = as<double>(e_bb->getAttr( ATTR_MINX ), 0); 00164 minY = as<double>(e_bb->getAttr( ATTR_MINY ), 0); 00165 maxX = as<double>(e_bb->getAttr( ATTR_MAXX ), 0); 00166 maxY = as<double>(e_bb->getAttr( ATTR_MAXY ), 0); 00167 featureType->setExtent( GeoExtent(SpatialReference::create( "epsg:4326"), minX, minY, maxX, maxY)); 00168 } 00169 00170 capabilities->getFeatureTypes().push_back( featureType ); 00171 } 00172 } 00173 00174 00175 return capabilities.release(); 00176 }