osgEarth 2.1.1
Public Member Functions | Private Member Functions | Private Attributes

MapService Class Reference

#include <MapService.h>

Collaboration diagram for MapService:

List of all members.

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 ProfilegetProfile () const
const TileInfogetTileInfo () const

Private Member Functions

bool setError (const std::string &)

Private Attributes

bool is_valid
std::string url
osg::ref_ptr< const Profileprofile
std::string error_msg
MapServiceLayerList layers
bool tiled
TileInfo tile_info

Detailed Description

ESRI ArcGIS Server Map Service interface.

Definition at line 85 of file MapService.h.


Constructor & Destructor Documentation

MapService::MapService ( )

Definition at line 101 of file MapService.cpp.

                       :
is_valid( false ),
tiled( false )
{
    //NOP
}

Member Function Documentation

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:


Member Data Documentation

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.

Definition at line 124 of file MapService.h.

osg::ref_ptr<const Profile> MapService::profile [private]

Definition at line 122 of file MapService.h.

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.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines