osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarthDrivers/tms/ReaderWriterTMS.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 <osgEarth/TileSource>
00021 #include <osgEarth/TMS>
00022 #include <osgEarth/FileUtils>
00023 #include <osgEarth/ImageUtils>
00024 #include <osgEarth/HTTPClient>
00025 
00026 #include <osg/Notify>
00027 #include <osgDB/FileNameUtils>
00028 #include <osgDB/FileUtils>
00029 #include <osgDB/Registry>
00030 #include <osgDB/ReadFile>
00031 #include <osgDB/WriteFile>
00032 
00033 #include <sstream>
00034 #include <iomanip>
00035 #include <string.h>
00036 
00037 #include "TMSOptions"
00038 
00039 using namespace osgEarth;
00040 using namespace osgEarth::Drivers;
00041 
00042 #define LC "[TMS driver] "
00043 
00044 
00045 class TMSSource : public TileSource
00046 {
00047 public:
00048     TMSSource(const TileSourceOptions& options) : TileSource(options), _options(options)
00049     {
00050         _invertY = _options.tmsType() == "google";
00051     }
00052 
00053 
00054     void initialize( const std::string& referenceURI, const Profile* overrideProfile)
00055     {
00056         const Profile* result = NULL;
00057 
00058         URI tmsURI = _options.url().value();
00059         if ( tmsURI.empty() )
00060         {
00061             OE_WARN << LC << "Fail: TMS driver requires a valid \"url\" property" << std::endl;
00062             return;
00063         }
00064 
00065         //Find the full path to the URL
00066         //If we have a relative path and the map file contains a server address, just concat the server path and the url together
00067         if (osgEarth::isRelativePath(tmsURI.full()) && osgDB::containsServerAddress(referenceURI))
00068         {
00069             tmsURI = URI( osgDB::getFilePath(referenceURI) + std::string("/") + tmsURI.full() );
00070         }
00071 
00072         //If the path doesn't contain a server address, get the full path to the file.
00073         if (!osgDB::containsServerAddress(tmsURI.full()))
00074         {
00075             tmsURI = URI( tmsURI.full(), referenceURI );
00076             //tmsPath = osgEarth::getFullPath(referenceURI, tmsURI);
00077         }
00078 
00079                 // Attempt to read the tile map parameters from a TMS TileMap XML tile on the server:
00080         _tileMap = TileMapReaderWriter::read( tmsURI.full(), 0L ); //getOptions() );
00081 
00082 
00083                 //Take the override profile if one is given
00084                 if (overrideProfile)
00085                 {
00086                     OE_INFO << LC << "Using override profile " << overrideProfile->toString() << std::endl;                             
00087                         result = overrideProfile;
00088                         _tileMap = TileMap::create( 
00089                 _options.url()->full(),
00090                 overrideProfile, 
00091                 _options.format().value(),
00092                 _options.tileSize().value(), 
00093                 _options.tileSize().value() );
00094                 }
00095                 else
00096                 {
00097                 if (_tileMap.valid())
00098                         {
00099                                 result = _tileMap->createProfile();
00100                         }
00101                         else
00102                         {
00103                 OE_WARN << LC << "Error reading TMS TileMap, and no overrides set (url=" << tmsURI.full() << ")" << std::endl;          
00104                             return;
00105                         }
00106                 }
00107 
00108         //Automatically set the min and max level of the TileMap
00109         if (_tileMap.valid() && _tileMap->getTileSets().size() > 0)
00110         {
00111           OE_INFO << LC << "TileMap min/max " << _tileMap->getMinLevel() << ", " << _tileMap->getMaxLevel() << std::endl;
00112           if (_tileMap->getDataExtents().size() > 0)
00113           {
00114               for (DataExtentList::iterator itr = _tileMap->getDataExtents().begin(); itr != _tileMap->getDataExtents().end(); ++itr)
00115               {
00116                   this->getDataExtents().push_back(*itr);
00117               }
00118           }
00119           else
00120           {
00121               //Push back a single area that encompasses the whole profile going up to the max level
00122               this->getDataExtents().push_back(DataExtent(result->getExtent(), 0, _tileMap->getMaxLevel()));
00123           }
00124         }
00125 
00126                 setProfile( result );
00127     }
00128 
00129 
00130     osg::Image* createImage(const osgEarth::TileKey& key,
00131                             ProgressCallback* progress)
00132     {
00133         if (_tileMap.valid() && key.getLevelOfDetail() <= getMaxDataLevel() )
00134         {
00135             std::string image_url = _tileMap->getURL( key, _invertY );
00136                 
00137             //OE_NOTICE << "TMSSource: Key=" << key.str() << ", URL=" << image_url << std::endl;
00138 
00139             
00140             osg::ref_ptr<osg::Image> image;
00141             
00142             if (!image_url.empty())
00143             {
00144                 HTTPClient::readImageFile( image_url, image, 0L, progress ); //getOptions(), progress );
00145             }
00146 
00147             if (!image.valid())
00148             {
00149                 if (image_url.empty() || !_tileMap->intersectsKey(key))
00150                 {
00151                     //We couldn't read the image from the URL or the cache, so check to see if the given key is less than the max level
00152                     //of the tilemap and create a transparent image.
00153                     if (key.getLevelOfDetail() <= _tileMap->getMaxLevel())
00154                     {
00155                         OE_INFO << LC << "Returning empty image " << std::endl;
00156                         return ImageUtils::createEmptyImage();
00157                     }
00158                 }
00159             }
00160             return image.release();
00161         }
00162         return 0;
00163     }
00164 
00165     virtual int getPixelsPerTile() const
00166     {
00167         return _tileMap->getFormat().getWidth();
00168     }
00169 
00170     virtual std::string getExtension()  const 
00171     {
00172         return _tileMap->getFormat().getExtension();
00173     }
00174 
00175 private:
00176 
00177     osg::ref_ptr<TileMap> _tileMap;
00178     bool _invertY;
00179     const TMSOptions _options;
00180 };
00181 
00182 
00183 
00184 
00185 class ReaderWriterTMS : public TileSourceDriver
00186 {
00187 private:
00188     typedef std::map< std::string,osg::ref_ptr<TileMap> > TileMapCache;
00189     TileMapCache _tileMapCache;
00190 
00191 public:
00192     ReaderWriterTMS()
00193     {
00194         supportsExtension( "osgearth_tms", "Tile Map Service" );
00195     }
00196 
00197     virtual const char* className()
00198     {
00199         return "Tile Map Service ReaderWriter";
00200     }
00201 
00202     virtual ReadResult readObject(const std::string& file_name, const Options* options) const
00203     {
00204         if ( !acceptsExtension(osgDB::getLowerCaseFileExtension( file_name )))
00205             return ReadResult::FILE_NOT_HANDLED;
00206 
00207         return new TMSSource( getTileSourceOptions(options) );
00208     }
00209 };
00210 
00211 REGISTER_OSGPLUGIN(osgearth_tms, ReaderWriterTMS)
00212 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines