Added by Rueben Schulz, last edited by jgarnett on Dec 30, 2008  (view change)

Labels:

Enter labels to add to this page:
Wait Image 
Looking for a label? Just start typing.

The following is a work in progress. It will be slowly finished as I procrastinate on my thesis writing.

This is a tutorial for new users of the Geotools referencing code. The code examples and most of the concepts refer to Geotools version 2.1 or greater. For Geotools 2.0 users, please see Coordinate Transformation Services for Geotools 2.0. Code for this tutorial can be found in CTSTutorial.java (not yet officially released).

The referencing implementation in geotools 2.1 uses GeoAPI interfaces modelled on the ISO-19111 specification. Most of the concepts are the same as the legacy geotools 2.0 implementation, based on the Open GIS Consortium's (OGC) Coordinate Transformation Services (OGC 01-009) specification, but coordinate systems are now known as coordinate reference systems (CRS).

The following areas of the legacy OGC 01-009 secification have no equivalent parts in ISO 19111, so were used to fill in the holes.

  • Well Know Text (WKT) format
  • MathTransform
  • Factories
  • Many classification names (figure 2)
  • Many parameter names (sections 10.1 to 10.6)

The GeoAPI referencing interfaces are implemented in the org.geotools.referencing.* package, which use the following GeoAPI sub-packages:

  • org.opengis.spatialschema.geometry.DirectPosition - a point to be transformed
  • org.opengis.parameter - parameters for projected CRS's or math transforms
  • org.opengis.referencing -
  • org.opengis.referencing.crs - Coordinate reference systems (coordinate systems with a datum).
  • org.opengis.referencing.cs - Coordinate systems and their axis.
  • org.opengis.referencing.datum - Geodetic datum (the relationship of a coordinate system to the earth).
  • org.opengis.referencing.operation - Coordinate operations (equations used to transform between any two coordinate reference systems).

This tutorial is split into four sections:

  1. GEOTOOLS:Background Information -
  2. GEOTOOLS:Coordinate Reference Systems - describe a coordinate reference system
  3. GEOTOOLS:MathTransforms - used to transform points
  4. GEOTOOLS:Uses of Referencing in GeoTools
  5. GEOTOOLS:Command line uses of GeoTools Referencing

Background Information

The referencing package provides objects used to describe coordinate reference systems (CRS's) and transformations. A CRS describes how a position is related to the surface of the earth (or another planet). A transformation provides mathematical formulae to convert positions from one CRS to another. For more information on these concepts see Introduction to Coordinate systems.

FactoryFinder

The org.geotools.referencing.FactoryFinder object contains static methods used to create factories. These factories are then used to create referencing objects. This approach allows multiple implementations of the factories to be discovered and used at runtime, and allows us to use GeoAPI referencing interfaces.

CRS

org.geotools.referencing.CRS is a utility class with some handy static methods. Its use is demonstrated in the transformUsingCRSUtility() method in the tutorial code.

Identified Objects

TODO

  • make the following information more presentable
  • mention authority codes

Many interfaces inherit from org.opengis.referencing.IdentifiedObject. This includes datums, crs's, math transforms, parameters, etc. Identified objects have a primary Identifier, alternate identifiers and aliases. This means that an identified object like a datum can have more than one name, allowing us to record all of the different, non-standard names people use for things. As another example, the Oblique Mercator projection has extra identifiers such as "Hotine_Oblique_Mercator" and "Hotine_Oblique_Mercator_Azimuth_Natural_Origin".

Identifiers can have Citations, which the person/organization that uses/defines the name. Examples of citations are the EPSG, ESRI, and OGC.

The above distinction between Identifiers and Aliases is confusing. Martin provided the following clarification in an email:

> I am confused about the difference between an alias returned from
> IdentifiedObject::getAlias() and an extra identifier returned from
> IdentifedObject::getIdentifiers(). Are aliases just less formal
> identifiers?

I'm a little bit confused too. The difference between alias and
identifier is not obvious to me neither, but ISO 19111 is done that way.

I was in the OGC meeting when the CRS working group voted for this alias
and identifier stuff, and listened the discussion between CRS members on
this topic. My understanding of their discussion is as below (but I'm
not completly sure to understand correctly):

   - Identifier said where to find more information about a Datum (or
     CRS, or CS, etc.). There is usually only one identifier by object.
     In the EPSG case, I believe that this is the EPSG number. The client
     can get a CRS with minimal information (for example from WKT). If he
     wants more information than what is provided in the WKT, he can use
     the identifier in order to find the missing informations. We should
     have only one identifier by IdentifiedObject in most cases. However,
     it is possible to specify more than one identifier because
     identifiers contains (indirectly) URL (through metadata Citation),
     and we way wants to specify mirrors.

   - Alias are names; they contain no URL or other contact informations.
     I don't think there is any specific rule for them (but we are better
     to always specify the scope). We can have as many alias as we want.


So the key points is that even if we can specify an arbitrary amount of
identifiers, extra identifiers should be mirrors of the first one (in my
understanding). What we wants for GEOT-409 is really alias.



> Also, are EPSG codes always guaranteed to be in the first Identifier
> returned from IdentifedObject::getIdentifiers(). This seems to be the
> case for CRS's created with the WKT parser, but I assume this does not
> always need to hold true and a user should check all identifiers.

There is no garantee that EPSG code would be the first identifier.
Actually, in my understansing, it would be a mistake to have both an
EPSG identifier and an other identifier except a mirror. If the
IdentifiedObject definition come from ESRI, ESRI and eventual mirrors
should be the only identifier (again in my understanding).

I realize that this is a somewhat dark corner in Geotools
implementation. If my memory serve me right, Geotools takes the first
org.geotools.referencing.Identifier as identifier, and take all of them
as alias (since Geotools implementation of identifier in CRS implements
both Identifier and GenericName interfaces). I'm not sure what is the
best approach here, and we should probably revisit which identifier to
choose for MathTransforms in Geotools (maybe it would be okay to keep
all of them?)

<documentation from unreleased ISO 19111
revision draft at end of email - need to incorporate this information>

The following code can be used to get information from an identified object.

An error occurred: http://svn.geotools.org/geotools/trunk/gt/demo/referencing/src/main/java/org/geotools/demo/referencing/CTSTutorial.java. The system administrator has been notified.

Coordinate Reference Systems

Parameters used in projected crs's can be found in Coordinate Transformation Parameters.

There are many ways to create CoordinateReferenceSystem objects in Geotools.

Pre-made static objects

Many classes in the org.geotools.referencing package have convenient, pre-made static objects, which make it easy to reference commonly used instances. Some of these are shown in the following example.

An error occurred: http://svn.geotools.org/geotools/trunk/gt/demo/referencing/src/main/java/org/geotools/demo/referencing/CTSTutorial.java. The system administrator has been notified.

Creating from WKT

An easy way to create an arbitrary coordinate reference system is to use a Well Known Text (WKT) description. This is shown in the following example.

An error occurred: http://svn.geotools.org/geotools/trunk/gt/demo/referencing/src/main/java/org/geotools/demo/referencing/CTSTutorial.java. The system administrator has been notified.

For more WKT examples, see the test scripts in http://svn.geotools.org/geotools/trunk/gt/module/referencing/test/org/geotools/referencing/test-data/. New WKT strings can usually be made by copying these and changing a few parameters.

Creating from XML

Not yet implemented.

Creating from an Authority Factory (EPSG database)

If you have access to an EPSG Geodesy Parameters database (http://www.epsg.org) you can create coordinate reference systems and other objects from EPSG authority codes.

There are a few different EPSG authority factories in geotools that do roughly the same thing:

  • gt2-epsg-access.jar is backed by the official EPSG MS Access database (only works on MS Windows).
  • gt2-epsg-hsql.jar provides an embeded hsql database created from the EPSG SQL scripts. This contains the same information as the MS Arcess database.
  • other factories allow the EPSG information to be in an external database (postgresql, mysql, oracle)
  • gt2-epsg-wkt.jar is a simple properties file with WKT descriptions for EPSG defined CRS codes. This file does not derive directly from the official EPSG database, so its should be used with caution. It provides a very simple method of creating a new authority factory and named objects.

The specific authority factory returned by getCRSAuthorityFactory() is dependent on the different factories on your classpath (ie WKT or Access or HSQL) and the hints you provide. By default the "better" authority factory should be used if more than one is available.

The creation of a WGS84 coordinate system is shown in the following example.

An error occurred: http://svn.geotools.org/geotools/trunk/gt/demo/referencing/src/main/java/org/geotools/demo/referencing/CTSTutorial.java. The system administrator has been notified.

Creating by hand

The following example creates a geographic coordinate system with a NAD 27 datum. Since this datum name is in DatumAliasesTable.txt, all of the known datum aliases will be automatically added to the datum (aliases names are used by the CoordinateOperationFactory to determine if two datums are the same).

An error occurred: http://svn.geotools.org/geotools/trunk/gt/demo/referencing/src/main/java/org/geotools/demo/referencing/CTSTutorial.java. The system administrator has been notified.

The next example creates a projected coordinate system using an UTM Zone 10N map projection and a WGS84 datum. The use of the FactoryGroup() below is more convienient than using the CRSFactory.createProjectedCRS(Map, OperationMethod, GeographicCRS, MathTransform, CartesianCS) method (which requires you to interact with multiple factories).

An error occurred: http://svn.geotools.org/geotools/trunk/gt/demo/referencing/src/main/java/org/geotools/demo/referencing/CTSTutorial.java. The system administrator has been notified.

For another example of creating CoordinateReferenceSystem objects by hand see the createCRSByHand3() method in the tutorial.

Axis order

TODO - a CRS may describe coordinates in (x,y) or (y,x). You need to check the CS description to know which it is.

See the "Axis units and orientation" section of Package org.geotools.referencing.operation.projection Description

Math Transforms and their parameters (and operation methods)

TODO:

  • describe the higher level stuff (operations, conversions, transformations have metadata )
    **empirically derived parameters (Transformation)
    **The parameters describing coordinate conversions are defined rather than empirically derived (Conversion)

Math transforms can be used to transform coordinates from one CRS to another. Some common transformation methods include:

  • Map projections - equations used to convert from a roundish surface to a flat one. The results of these transforms are usually exact, however the Transverse Mercator equations are an approximation and not valid when far away from the central meridian. Currently geotools implements 8 different map projections and their variants. See individual projection class javadocs for more information.
  • Datum shifts - there are many datum shifting methods and they usually involve imperically derived parameters and have some measure of error in the resulting calculation. Some of these methods are:
    • Molodenski
    • Bursa Wolf (a.k.a Position Vector 7-param)
    • NADCON
  • Geographic to geocentric - converting from a point on the surface of an ellipsoid to a geocentric x,y,z. This is an exact calculation.
  • Affine

Math transform parameters in geotools no longer depend on Java JAI (as in geotools 2.0) and instead implement org.opengis.parameter. See Coordinate Transformation Parameters for an outdated listing of some of the transforms and their parameters.

CoordinateOperationFactory

The following code snippet creates a math transform between a NAD 27 geographic CRS and a UTM Zone 10N projected CRS.

An error occurred: http://svn.geotools.org/geotools/trunk/gt/demo/referencing/src/main/java/org/geotools/demo/referencing/CTSTutorial.java. The system administrator has been notified.

The resulting transformation is a concatenation of the following transforms:

  • Affine - to switch axis order from (latitude,longitude) to (longitude,latitude)
  • Molodenski - to preform a datum shift between NAD27 and WGS84, using the NAD 27 CRS BursaWolfParameters parameters
  • Transverse Mercator - to convert from geographic to projected UTM coordinates

MathTransformFactory

Math transforms may also be created by hand, as shown in the following example.

An error occurred: http://svn.geotools.org/geotools/trunk/gt/demo/referencing/src/main/java/org/geotools/demo/referencing/CTSTutorial.java. The system administrator has been notified.

OperationAuthorityFactory

TODO:

  • new to geotools 2.2

Uses of Referencing in GeoTools

Referencing is not an island, entire of itself; it is a piece of GeoTools. There are many places where it is used throughout the library.

Data Access

Vector data (through the DataStore interface) and raster data (through the grid coverage exchange interface) may have information about the CRS of the data.

Data Re-projection

There is also support for re-projecting data from their source CRS to a target CRS.

Two demos to do this:

Also see

 trans = org.geotools.referencing.CRS.transform(
                sourceCoordRefSys, targetCoordRefSys, true);
newGeom = org.geotools.jts.JTS.transform(oldGeom, trans);

The boolean lets the transform ignore the datum shift which turns out to
{{be critical if you don't have each datum perfectly defined. }}

Renderes

The j2d renderer allows the CRS's of datasets and the renderer to be specified and changed. This allows you to project different datasets to the same CRS. The transformation is done on the rendered geometries, so this does not affect the datasets.

Command line uses of GeoTools Referencing

Geotools can be used to produce WKT for CRS's in the EPSG database as shown in the following example.

$ java -classpath
referencing-2.2.x.jar:epsg-hsql-2.2.x.jar:geoapi-2.0.jar:hsqldb-1.8.0.1.jar:vecmath-1.3.jar:units-0.01.jar \
org.geotools.referencing.factory.epsg.DefaultFactory EPSG:31467
EPSG version:    6.7
Database engine: HSQL Database Engine version 1.8.0
Database URL:    jdbc:hsqldb:file:/tmp/Geotools/Databases/HSQL/EPSG

_______________________________________________________________________________

PROJCS["DHDN / Gauss-Kruger zone 3",
  GEOGCS["DHDN",
    DATUM["Deutsches Hauptdreiecksnetz",
      SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]],
      TOWGS84[598.1, 73.7, 418.2, 0.202, 0.045, -2.455, 1.3819742018555456],
      AUTHORITY["EPSG","6314"]],
    PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]],
    UNIT["degree", 0.017453292519943295],
    AXIS["Geodetic latitude", NORTH],
    AXIS["Geodetic longitude", EAST],
    AUTHORITY["EPSG","4314"]],
  PROJECTION["Transverse Mercator", AUTHORITY["EPSG","9807"]],
  PARAMETER["central_meridian", 9.0],
  PARAMETER["latitude_of_origin", 0.0],
  PARAMETER["scale_factor", 1.0],
  PARAMETER["false_easting", 3500000.0],
  PARAMETER["false_northing", 0.0],
  UNIT["m", 1.0],
  AXIS["Northing", NORTH],
  AXIS["Easting", EAST],
  AUTHORITY["EPSG","31467"]]

DefaultMathTransformFactory (mentoned in Coordinate Transformation Parameters) is also useful from the command line.