|
osgEarth 2.1.1
|
Inheritance diagram for WMSSource:
Collaboration diagram for WMSSource:Public Member Functions | |
| WMSSource (const TileSourceOptions &options) | |
| void | initialize (const std::string &referenceURI, const Profile *overrideProfile) |
| bool | isDynamic () const |
| osgDB::ReaderWriter * | fetchTileAndReader (const TileKey &key, const std::string &extraAttrs, ProgressCallback *progress, HTTPResponse &out_response) |
| osg::Image * | createImage (const TileKey &key, ProgressCallback *progress) |
| osg::Image * | createImage3D (const TileKey &key, ProgressCallback *progress) |
| osg::Image * | createImageSequence (const TileKey &key, ProgressCallback *progress) |
| osg::HeightField * | createHeightField (const TileKey &key, ProgressCallback *progress) |
| std::string | createURI (const TileKey &key) const |
| virtual int | getPixelsPerTile () const |
| virtual std::string | getExtension () const |
Private Attributes | |
| const WMSOptions | _options |
| std::string | _formatToUse |
| std::string | _srsToUse |
| osg::ref_ptr< TileService > | _tileService |
| osg::ref_ptr< const Profile > | _profile |
| std::string | _prototype |
| std::vector< std::string > | _timesVec |
Definition at line 61 of file ReaderWriterWMS.cpp.
| WMSSource::WMSSource | ( | const TileSourceOptions & | options | ) | [inline] |
Definition at line 64 of file ReaderWriterWMS.cpp.
: TileSource( options ), _options(options) { if ( _options.times().isSet() ) { StringTokenizer( *_options.times(), _timesVec, ",", "", false, true ); OE_INFO << LC << "WMS-T: found " << _timesVec.size() << " times." << std::endl; } // localize it since we might override them: _formatToUse = _options.format().value(); _srsToUse = _options.srs().value(); }
| osg::HeightField* WMSSource::createHeightField | ( | const TileKey & | key, |
| ProgressCallback * | progress | ||
| ) | [inline, virtual] |
override
Reimplemented from osgEarth::TileSource.
Definition at line 455 of file ReaderWriterWMS.cpp.
{
osg::Image* image = createImage(key, progress);
if (!image)
{
OE_INFO << "[osgEarth::WMS] Failed to read heightfield from " << createURI(key) << std::endl;
}
float scaleFactor = 1;
//Scale the heightfield to meters
if ( _options.elevationUnit() == "ft")
{
scaleFactor = 0.3048;
}
ImageToHeightFieldConverter conv;
return conv.convert( image, scaleFactor );
}
Here is the call graph for this function:| osg::Image* WMSSource::createImage | ( | const TileKey & | key, |
| ProgressCallback * | progress | ||
| ) | [inline, virtual] |
override
Implements osgEarth::TileSource.
Definition at line 324 of file ReaderWriterWMS.cpp.
{
osg::ref_ptr<osg::Image> image;
if ( _timesVec.size() > 1 )
{
image = createImageSequence( key, progress );
}
else
{
std::string extras;
if ( _timesVec.size() == 1 )
extras = "TIME=" + _timesVec[0];
HTTPResponse response;
osgDB::ReaderWriter* reader = fetchTileAndReader( key, extras, progress, response );
if ( reader )
{
osgDB::ReaderWriter::ReadResult readResult = reader->readImage( response.getPartStream( 0 ), 0L ); //getOptions() );
if ( readResult.error() ) {
OE_WARN << "WMS: image read failed for " << createURI(key) << std::endl;
}
else {
image = readResult.getImage();
}
}
}
return image.release();
}
Here is the call graph for this function:| osg::Image* WMSSource::createImage3D | ( | const TileKey & | key, |
| ProgressCallback * | progress | ||
| ) | [inline] |
creates a 3D image from timestamped data.
Definition at line 356 of file ReaderWriterWMS.cpp.
{
osg::ref_ptr<osg::Image> image;
for( unsigned int r=0; r<_timesVec.size(); ++r )
{
std::string extraAttrs = "TIME=" + _timesVec[r];
HTTPResponse response;
osgDB::ReaderWriter* reader = fetchTileAndReader( key, extraAttrs, progress, response );
if ( reader )
{
osgDB::ReaderWriter::ReadResult readResult = reader->readImage( response.getPartStream( 0 ), 0L ); //getOptions() );
if ( readResult.error() ) {
OE_WARN << "WMS: image read failed for " << createURI(key) << std::endl;
}
else
{
osg::ref_ptr<osg::Image> timeImage = readResult.getImage();
if ( !image.valid() )
{
image = new osg::Image();
image->allocateImage(
timeImage->s(), timeImage->t(), _timesVec.size(),
timeImage->getPixelFormat(),
timeImage->getDataType(),
timeImage->getPacking() );
image->setInternalTextureFormat( timeImage->getInternalTextureFormat() );
}
memcpy(
image->data(0,0,r),
timeImage->data(),
osg::minimum(image->getImageSizeInBytes(), timeImage->getImageSizeInBytes()) );
}
}
}
return image.release();
}
Here is the call graph for this function:| osg::Image* WMSSource::createImageSequence | ( | const TileKey & | key, |
| ProgressCallback * | progress | ||
| ) | [inline] |
creates a 3D image from timestamped data. creates a 3D image from timestamped data.
Definition at line 422 of file ReaderWriterWMS.cpp.
{
osg::ImageSequence* seq = new SyncImageSequence(); //osg::ImageSequence();
seq->setLoopingMode( osg::ImageStream::LOOPING );
seq->setLength( _options.secondsPerFrame().value() * (double)_timesVec.size() );
seq->play();
for( unsigned int r=0; r<_timesVec.size(); ++r )
{
std::string extraAttrs = "TIME=" + _timesVec[r];
HTTPResponse response;
osgDB::ReaderWriter* reader = fetchTileAndReader( key, extraAttrs, progress, response );
if ( reader )
{
osgDB::ReaderWriter::ReadResult readResult = reader->readImage( response.getPartStream( 0 ), 0L ); //getOptions() );
if ( !readResult.error() )
{
seq->addImage( readResult.getImage() );
}
else
{
OE_WARN << "WMS: image read failed for " << createURI(key) << std::endl;
}
}
}
return seq;
}
Here is the call graph for this function:| std::string WMSSource::createURI | ( | const TileKey & | key | ) | const [inline] |
Definition at line 477 of file ReaderWriterWMS.cpp.
{
double minx, miny, maxx, maxy;
key.getExtent().getBounds( minx, miny, maxx, maxy);
char buf[2048];
sprintf(buf, _prototype.c_str(), minx, miny, maxx, maxy);
std::string uri(buf);
// url-ize the uri before returning it
if ( osgDB::containsServerAddress( uri ) )
uri = replaceIn(uri, " ", "%20");
return uri;
}
Here is the call graph for this function:| osgDB::ReaderWriter* WMSSource::fetchTileAndReader | ( | const TileKey & | key, |
| const std::string & | extraAttrs, | ||
| ProgressCallback * | progress, | ||
| HTTPResponse & | out_response | ||
| ) | [inline] |
Definition at line 269 of file ReaderWriterWMS.cpp.
{
osgDB::ReaderWriter* result = 0L;
std::string uri = createURI(key);
if ( !extraAttrs.empty() )
{
std::string delim = uri.find("?") == std::string::npos ? "?" : "&";
uri = uri + delim + extraAttrs;
}
out_response = HTTPClient::get( uri, 0L, progress ); //getOptions(), progress );
if ( out_response.isOK() )
{
const std::string& mt = out_response.getMimeType();
if ( mt == "application/vnd.ogc.se_xml" || mt == "text/xml" )
{
// an XML result means there was a WMS service exception:
Config se;
if ( se.loadXML( out_response.getPartStream(0) ) )
{
Config ex = se.child("serviceexceptionreport").child("serviceexception");
if ( !ex.empty() ) {
OE_NOTICE << "WMS Service Exception: " << ex.value() << std::endl;
}
else {
OE_NOTICE << "WMS Response: " << se.toString() << std::endl;
}
}
else {
OE_NOTICE << "WMS: unknown error." << std::endl;
}
}
else
{
// really ought to use mime-type support here -GW
std::string typeExt = mt.substr( mt.find_last_of("/")+1 );
result = osgDB::Registry::instance()->getReaderWriterForExtension( typeExt );
if ( !result ) {
OE_NOTICE << "WMS: no reader registered; URI=" << createURI(key) << std::endl;
}
}
}
return result;
}
Here is the call graph for this function:| virtual std::string WMSSource::getExtension | ( | ) | const [inline, virtual] |
Gets the preferred extension for this TileSource
Reimplemented from osgEarth::TileSource.
Definition at line 499 of file ReaderWriterWMS.cpp.
{
return _formatToUse;
}
| virtual int WMSSource::getPixelsPerTile | ( | ) | const [inline, virtual] |
Gets the number of pixels per tile for this TileSource.
Reimplemented from osgEarth::TileSource.
Definition at line 494 of file ReaderWriterWMS.cpp.
| void WMSSource::initialize | ( | const std::string & | referenceURI, |
| const Profile * | overrideProfile | ||
| ) | [inline, virtual] |
override
Implements osgEarth::TileSource.
Definition at line 78 of file ReaderWriterWMS.cpp.
{
osg::ref_ptr<const Profile> result;
char sep = _options.url()->full().find_first_of('?') == std::string::npos? '?' : '&';
URI capUrl = _options.capabilitiesUrl().value();
if ( capUrl.empty() )
{
capUrl = URI(
_options.url()->full() +
sep +
"SERVICE=WMS" +
"&VERSION=" + _options.wmsVersion().value() +
"&REQUEST=GetCapabilities" );
}
//Try to read the WMS capabilities
osg::ref_ptr<WMSCapabilities> capabilities = WMSCapabilitiesReader::read( capUrl.full(), 0L ); //getOptions() );
if ( !capabilities.valid() )
{
OE_WARN << "[osgEarth::WMS] Unable to read WMS GetCapabilities." << std::endl;
//return;
}
else
{
OE_INFO << "[osgEarth::WMS] Got capabilities from " << capUrl.full() << std::endl;
}
if ( _formatToUse.empty() && capabilities.valid() )
{
_formatToUse = capabilities->suggestExtension();
OE_NOTICE << "[osgEarth::WMS] No format specified, capabilities suggested extension " << _formatToUse << std::endl;
}
if ( _formatToUse.empty() )
_formatToUse = "png";
if ( _srsToUse.empty() )
_srsToUse = "EPSG:4326";
std::string wmsFormatToUse = _options.wmsFormat().value();
//Initialize the WMS request prototype
std::stringstream buf;
// first the mandatory keys:
buf
<< std::fixed << _options.url()->full() << sep
<< "SERVICE=WMS"
<< "&VERSION=" << _options.wmsVersion().value()
<< "&REQUEST=GetMap"
<< "&LAYERS=" << _options.layers().value()
<< "&FORMAT=" << ( wmsFormatToUse.empty() ? std::string("image/") + _formatToUse : wmsFormatToUse )
<< "&STYLES=" << _options.style().value()
<< "&SRS=" << _srsToUse
<< "&WIDTH="<< _options.tileSize().value()
<< "&HEIGHT="<< _options.tileSize().value()
<< "&BBOX=%lf,%lf,%lf,%lf";
// then the optional keys:
if ( _options.transparent().isSet() )
buf << "&TRANSPARENT=" << (_options.transparent() == true ? "TRUE" : "FALSE");
_prototype = "";
_prototype = buf.str();
osg::ref_ptr<SpatialReference> wms_srs = SpatialReference::create( _srsToUse );
// check for spherical mercator:
if ( wms_srs.valid() && wms_srs->isEquivalentTo( osgEarth::Registry::instance()->getGlobalMercatorProfile()->getSRS() ) )
{
result = osgEarth::Registry::instance()->getGlobalMercatorProfile();
}
else if (wms_srs.valid() && wms_srs->isEquivalentTo( osgEarth::Registry::instance()->getGlobalGeodeticProfile()->getSRS()))
{
result = osgEarth::Registry::instance()->getGlobalGeodeticProfile();
}
// Next, try to glean the extents from the layer list
if ( capabilities.valid() )
{
//TODO: "layers" mights be a comma-separated list. need to loop through and
//combine the extents?? yes
WMSLayer* layer = capabilities->getLayerByName( _options.layers().value() );
if ( layer )
{
double minx, miny, maxx, maxy;
minx = miny = maxx = maxy = 0;
//Check to see if the profile is equivalent to global-geodetic
if (wms_srs->isGeographic())
{
//Try to get the lat lon extents if they are provided
layer->getLatLonExtents(minx, miny, maxx, maxy);
//If we still don't have any extents, just default to global geodetic.
if (!result.valid() && minx == 0 && miny == 0 && maxx == 0 && maxy == 0)
{
result = osgEarth::Registry::instance()->getGlobalGeodeticProfile();
}
}
if (minx == 0 && miny == 0 && maxx == 0 && maxy == 0)
{
layer->getExtents(minx, miny, maxx, maxy);
}
if (!result.valid())
{
result = Profile::create( _srsToUse, minx, miny, maxx, maxy );
}
//Add the layer extents to the list of valid areas
if (minx != 0 || maxx != 0 || miny != 0 || maxy != 0)
{
GeoExtent extent( result->getSRS(), minx, miny, maxx, maxy);
getDataExtents().push_back( DataExtent(extent, 0, INT_MAX) );
}
}
}
// Last resort: create a global extent profile (only valid for global maps)
if ( !result.valid() && wms_srs->isGeographic())
{
result = osgEarth::Registry::instance()->getGlobalGeodeticProfile();
}
// JPL uses an experimental interface called TileService -- ping to see if that's what
// we are trying to read:
URI tsUrl = _options.tileServiceUrl().value();
if ( tsUrl.empty() )
{
tsUrl = URI(
_options.url()->full() + sep + std::string("request=GetTileService") );
}
OE_INFO << "[osgEarth::WMS] Testing for JPL/TileService at " << tsUrl.full() << std::endl;
_tileService = TileServiceReader::read(tsUrl.full(), 0L); //getOptions());
if (_tileService.valid())
{
OE_INFO << "[osgEarth::WMS] Found JPL/TileService spec" << std::endl;
TileService::TilePatternList patterns;
_tileService->getMatchingPatterns(
_options.layers().value(),
_formatToUse,
_options.style().value(),
_srsToUse,
_options.tileSize().value(),
_options.tileSize().value(),
patterns );
if (patterns.size() > 0)
{
result = _tileService->createProfile( patterns );
_prototype = _options.url()->full() + sep + patterns[0].getPrototype();
}
}
else
{
OE_INFO << "[osgEarth::WMS] No JPL/TileService spec found; assuming standard WMS" << std::endl;
}
//Use the override profile if one is passed in.
if (overrideProfile)
{
result = overrideProfile;
}
//TODO: won't need this for OSG 2.9+, b/c of mime-type support
_prototype = _prototype + std::string("&.") + _formatToUse;
// populate the data metadata:
// TODO
setProfile( result.get() );
}
Here is the call graph for this function:| bool WMSSource::isDynamic | ( | ) | const [inline, virtual] |
Whether this TileSource produces tiles whose data can change after it's been created.
Reimplemented from osgEarth::TileSource.
Definition at line 260 of file ReaderWriterWMS.cpp.
{
// return TRUE if we are reading WMS-T.
return _timesVec.size() > 1;
}
std::string WMSSource::_formatToUse [private] |
Definition at line 506 of file ReaderWriterWMS.cpp.
const WMSOptions WMSSource::_options [private] |
Reimplemented from osgEarth::TileSource.
Definition at line 505 of file ReaderWriterWMS.cpp.
osg::ref_ptr<const Profile> WMSSource::_profile [private] |
Reimplemented from osgEarth::TileSource.
Definition at line 509 of file ReaderWriterWMS.cpp.
std::string WMSSource::_prototype [private] |
Definition at line 510 of file ReaderWriterWMS.cpp.
std::string WMSSource::_srsToUse [private] |
Definition at line 507 of file ReaderWriterWMS.cpp.
osg::ref_ptr<TileService> WMSSource::_tileService [private] |
Definition at line 508 of file ReaderWriterWMS.cpp.
std::vector<std::string> WMSSource::_timesVec [private] |
Definition at line 511 of file ReaderWriterWMS.cpp.
1.7.3