TerraLib and TerraView Wiki Page

This is an old revision of the document!


The Spatial Reference System (SRS) Module

This module is based on the specifications: ISO 19111 – Geographic information – Spatial Referencing by Coordinates and OGC - Implementation Specification: Coordinate Transformation Services and at providing the mechanisms to represent a coordinate that describes a position on or near the Earth's surface and are referenced to a model of the Earth. Coordinates are referenced to a Coordinate Reference System (CRS). A Coordinate Reference System is a Coordinate System (CS) – an abstract mathematical concept without any relationship to a physical object – that is referenced through a Datum to the Earth or some other object such as a vessel.

The SRS module offers this concepts, as classes of the namespace te::srs: including:SpatialReferenceSystem, GeographicCoordinateSystem,ProjectedCoordinateSystem, GeographicCoordinateSystem, Ellipsoid and Datum. Check the DOxygen documentation of this module, where these and other classes are documented in details.

SRS Representation

In practice, users can describe an SRS in different ways, such as:

The class SpatialReferenceSystemMananger is responsible for handling the Spatial Reference in TerraLib applications. The manager is a singleton, i.e., there is only one instance of this class per application. By default the SRS Manager is initialized in TerraLib from the srs.json file, that can be founded in the subdirectory share/terralib/json of your local codebase folder.

The snippet code bellow exemplifies how to manipulate the Manager. Note that the names from this module are in the namespace te::srs.

{
  int nsrs = te::srs::SpatialReferenceSystemManager::getInstance().size();
  std::cout << "There are " << nsrs << " available in the SRS Manager.\n";
 
  std::cout << "Searching for an SRS named \"WGS 84\": \n";
  std::pair<std::string,int> myid = te::srs::SpatialReferenceSystemManager::getInstance().getIdFromName("WGS 84");
  std::cout << "WGS 84 => " << myid.second << " from " << myid.first << " authority." << std::endl;
 
  std::cout << "Searching for an SRS with the ID \"EPSG:4326\": \n";
  std::string myname = te::srs::SpatialReferenceSystemManager::getInstance().getName(4326);
  std::cout << "EPSG:4326 => " << myname << std::endl;
}

Coordinate Transformation

TerraLib uses the PROJ.4 library to implement coordinate transformations. The access and call to PROJ.4 is encapsulated in the class Converter, that will be responsible by transforming coordinates from a source SRS Id to a target SRS ID, both represented by an unique integer identifier or SRID. The SRID should exist in the SRSManager described above.

The code snippet below shows how an application can request a Converter to convert some coordinates.

{
  // ...
  // requesting a pointer to a converter
  std::auto_ptr<te::srs::Converter> converter(new te::srs::Converter());
 
  converter->setSourceSRS(4326);      // the SRS id for geographic coordinates over a WGS84 datum
  converter->setTargetSRS(31985);     // the SRS id for projected coordinates of UTM / WGS84 datum, Zone 17 South
 
  // Converting a single coordinate
  double llX = -45.5;
  double llY = -23.0;
 
  double xyX;
  double xyY;
 
  converter->convert(llX,llY,xyX,xyY);
  converter->invert(xyX,xyY,llX,llY);
 
  // Converting a list of coordinates
  double* xs = new double[3];
  double* ys = new double[3];
 
  xs[0] = -45.5;
  xs[1] = -45.6;
  xs[2] = -45.7;
 
  ys[0] = -23.0;
  ys[1] = -23.1;
  ys[2] = -23.2;
 
  converter->convert(xs,ys,3,1);
// ...
}

Coordinate conversion is implicitly done by the geometry module when implementing the transform method, as illustrated in the code snippet below.

{
  // ...
  // Converting a geometry
  te::gm::Geometry* geom = new te::gm::Point(-45.0,-23.0,4326);
  geom->asText(std::cout);
 
  std::cout << std::endl;
 
  geom->transform(31985);
  geom->asText(std::cout);
 
  delete geom;
  // ...
}

The code snippet below shows how an application can add an SRS Id, Authority code. This automatically makes the SRSID recognizable by the Converter.

{
  // ...
  // Adding a new SRS ID with your PROJ4 and WKT description
  // 
  SpatialReferenceSystemManager::getInstance().add("SIRGAS 2000 / UTM zone 25S",
                                           "PROJCS[\"SIRGAS 2000 / UTM zone 25S\",GEOGCS[\"SIRGAS 2000\",DATUM[\"Sistema_de_Referencia_Geocentrico_para_America_del_Sur_2000\",SPHEROID[\"GRS 1980\",6378137,298.257222101],TOWGS84[0,0,0,0,0,0,0]],PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.01745329251994328]],PROJECTION[\"Transverse_Mercator\"],PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"central_meridian\",-33],PARAMETER[\"scale_factor\",0.9996],PARAMETER[\"false_easting\",500000],PARAMETER[\"false_northing\",10000000],AXIS[\"Easting\",EAST],AXIS[\"Northing\",NORTH],UNIT[\"metre\",1]]",
                                           "+proj=utm +zone=25 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs",
                                           31985);
  converter->setSourceSRID(31985);
  converter->setTargetSRID(4326);
 
  xyX = 500000 * 0.001;   // meter to kilometer
  xyY = 10000000 * 0.001; // meter to kilometer
 
	converter->convert(xyX,xyY,llX,llY);
  // ...
}

Module Dependencies