|
osgEarth 2.1.1
|
#include <MapService.h>
Collaboration diagram for MapService:Public Member Functions | |
| MapService () | |
| bool | init (const std::string &url, const osgDB::ReaderWriter::Options *options=0L) |
| bool | isValid () const |
| bool | isTiled () const |
| const std::string & | getError () const |
| const Profile * | getProfile () const |
| const TileInfo & | getTileInfo () const |
Private Member Functions | |
| bool | setError (const std::string &) |
Private Attributes | |
| bool | is_valid |
| std::string | url |
| osg::ref_ptr< const Profile > | profile |
| std::string | error_msg |
| MapServiceLayerList | layers |
| bool | tiled |
| TileInfo | tile_info |
ESRI ArcGIS Server Map Service interface.
Definition at line 85 of file MapService.h.
| MapService::MapService | ( | ) |
Definition at line 101 of file MapService.cpp.
| const std::string & MapService::getError | ( | ) | const |
If isValid() returns false, this method will return the error message.
Definition at line 278 of file MapService.cpp.
{
return error_msg;
}
| const Profile * MapService::getProfile | ( | ) | const |
Gets the data profile associated with this map service.
Definition at line 119 of file MapService.cpp.
{
return profile.get();
}
| const TileInfo & MapService::getTileInfo | ( | ) | const |
Gets the tile information for this service.
Definition at line 124 of file MapService.cpp.
{
return tile_info;
}
| bool MapService::init | ( | const std::string & | url, |
| const osgDB::ReaderWriter::Options * | options = 0L |
||
| ) |
Initializes a map service interface and populates its metadata from the provided REST API URL (e.g.: http://server/ArcGIS/rest/services/MyMapService) Call isValid() to verify success.
Definition at line 129 of file MapService.cpp.
{
url = _url;
std::string sep = url.find( "?" ) == std::string::npos ? "?" : "&";
std::string json_url = url + sep + std::string("f=pjson"); // request the data in JSON format
HTTPResponse response = HTTPClient::get( json_url, options );
if ( !response.isOK() )
return setError( "Unable to read metadata from ArcGIS service" );
Json::Value doc;
Json::Reader reader;
if ( !reader.parse( response.getPartStream(0), doc ) )
return setError( "Unable to parse metadata; invalid JSON" );
// Read the profile. We are using "fullExtent"; perhaps an option to use "initialExtent" instead?
double xmin = doc["fullExtent"].get("xmin", 0).asDouble();
double ymin = doc["fullExtent"].get("ymin", 0).asDouble();
double xmax = doc["fullExtent"].get("xmax", 0).asDouble();
double ymax = doc["fullExtent"].get("ymax", 0).asDouble();
int srs = doc["fullExtent"].get("spatialReference", osgEarth::Json::Value::null).get("wkid", 0).asInt();
//Assumes the SRS is going to be an EPSG code
std::stringstream ss;
ss << "epsg:" << srs;
if ( ! (xmax > xmin && ymax > ymin && srs != 0 ) )
{
return setError( "Map service does not define a full extent" );
}
// Read the layers list
Json::Value j_layers = doc["layers"];
if ( j_layers.empty() )
return setError( "Map service contains no layers" );
for( unsigned int i=0; i<j_layers.size(); i++ )
{
Json::Value layer = j_layers[i];
int id = i; // layer.get("id", -1).asInt();
std::string name = layer["name"].asString();
if ( id >= 0 && !name.empty() )
{
layers.push_back( MapServiceLayer( id, name ) );
}
}
tiled = false;
std::string format = "png";
int tile_rows = 256;
int tile_cols = 256;
int min_level = 25;
int max_level = 0;
int num_tiles_wide = 1;
int num_tiles_high = 1;
// Read the tiling schema
Json::Value j_tileinfo = doc["tileInfo"];
if ( !j_tileinfo.empty() )
{
tiled = true;
// return setError( "Map service does not define a tiling schema" );
// TODO: what do we do if the width <> height?
tile_rows = j_tileinfo.get( "rows", 0 ).asInt();
tile_cols = j_tileinfo.get( "cols", 0 ).asInt();
if ( tile_rows <= 0 && tile_cols <= 0 )
return setError( "Map service tile size not specified" );
format = j_tileinfo.get( "format", "" ).asString();
if ( format.empty() )
return setError( "Map service tile schema does not specify an image format" );
Json::Value j_levels = j_tileinfo["lods"];
if ( j_levels.empty() )
return setError( "Map service tile schema contains no LODs" );
min_level = INT_MAX;
max_level = 0;
for( unsigned int i=0; i<j_levels.size(); i++ )
{
int level = j_levels[i].get( "level", -1 ).asInt();
if ( level >= 0 && level < min_level )
min_level = level;
if ( level >= 0 && level > max_level )
max_level = level;
}
if (j_levels.size() > 0)
{
int l = j_levels[0u].get("level", -1).asInt();
double res = j_levels[0u].get("resolution", 0.0).asDouble();
num_tiles_wide = (int)osg::round((xmax - xmin) / (res * tile_cols));
num_tiles_high = (int)osg::round((ymax - ymin) / (res * tile_cols));
//In case the first level specified isn't level 0, compute the number of tiles at level 0
for (int i = 0; i < l; i++)
{
num_tiles_wide /= 2;
num_tiles_high /= 2;
}
//profile.setNumTilesWideAtLod0(num_tiles_wide);
//profile.setNumTilesHighAtLod0(num_tiles_high);
}
}
std::string ssStr;
ssStr = ss.str();
osg::ref_ptr< SpatialReference > spatialReference = SpatialReference::create( ssStr );
if (spatialReference->isGeographic())
{
//If we have a geographic SRS, just use the geodetic profile
profile = Registry::instance()->getGlobalGeodeticProfile();
}
else if (spatialReference->isMercator())
{
//If we have a mercator SRS, just use the mercator profile
profile = Registry::instance()->getGlobalMercatorProfile();
}
else
{
//It's not geodetic or mercator, so try to use the full extent
profile = Profile::create(
spatialReference.get(),
xmin, ymin, xmax, ymax,
NULL,
num_tiles_wide,
num_tiles_high);
}
// now we're good.
tile_info = TileInfo( tile_rows, format, min_level, max_level, num_tiles_wide, num_tiles_high);
is_valid = true;
return is_valid;
}
Here is the call graph for this function:| bool MapService::isTiled | ( | ) | const |
Definition at line 114 of file MapService.cpp.
{
return tiled;
}
| bool MapService::isValid | ( | ) | const |
Returns true if the map service initialized succesfully.
Definition at line 109 of file MapService.cpp.
{
return is_valid;
}
| bool MapService::setError | ( | const std::string & | msg | ) | [private] |
Definition at line 272 of file MapService.cpp.
{
error_msg = msg;
return false;
}
Here is the caller graph for this function:std::string MapService::error_msg [private] |
Definition at line 123 of file MapService.h.
bool MapService::is_valid [private] |
Definition at line 120 of file MapService.h.
MapServiceLayerList MapService::layers [private] |
Definition at line 124 of file MapService.h.
osg::ref_ptr<const Profile> MapService::profile [private] |
Definition at line 122 of file MapService.h.
TileInfo MapService::tile_info [private] |
Definition at line 126 of file MapService.h.
bool MapService::tiled [private] |
Definition at line 125 of file MapService.h.
std::string MapService::url [private] |
Definition at line 121 of file MapService.h.
1.7.3