We have provided a couple of helpers classes to making use the rich functionality of the referencing module a little bit easier. Personally if I ever have to tread outside the safey of these classes I get worried.
Before you Start
The most sane way to deal with the definition of CoordinateReferenceSystem is not to. Instead make use of a CoordinateReferenceSystem authority that can understand a simple String - and provide you with the complete definition.
To hook this up simply make sure you have one of the Referencing Plugins on your classpath, EPSG WKT Plugin is probably the least trouble although EPSG HSQL Plugin comes with a reputation for accuracy.
CRS Utility Class
We have set up a utility class for the referencing module that allows you to quickly accomplish the most common referencing tasks.
For more information please check out the javadocs:
Defining a CoordinateReferenceSystem
This is easily the most common use for the CRS class:
import org.geotools.referencing.CRS; CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:4326");
The example above assumes you have gt-epsg-hsql jar on your classpath. Depending on the jars you have on your classpath a range of coordinate reference system authorities will be available to you.
Using the "OGC URN" syntax:
CoordinateReferenceSystem sourceCRS = CRS.decode("urn:ogc:def:ellipsoid:EPSG:6.0:7001");
Using the WMS AUTO2 syntax (which requires you pass in your current "position":
CoordinateReferenceSystem sourceCRS = CRS.decode("AUTO2:42001,"+lat+","+lon);
Produce CoordinateReferenceSystem from Text
String wkt = "GEOGCS[" + "\"WGS 84\"," + " DATUM[" + " \"WGS_1984\"," + " SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]]," + " TOWGS84[0,0,0,0,0,0,0]," + " AUTHORITY[\"EPSG\",\"6326\"]]," + " PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]]," + " UNIT[\"DMSH\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9108\"]]," + " AXIS[\"Lat\",NORTH]," + " AXIS[\"Long\",EAST]," + " AUTHORITY[\"EPSG\",\"4326\"]]"; CoordinateReferenceSystem crs = CRS.parseWKT(wkt);
Searching for a CoordinateReferenceSystem
You can actually search based on any metadata, not just name, the way you do it is you construct an example of what you are looking for - and than ask for the best match.
This functionality is especially useful when you have produced a CoordinateReferenceSystem by parsing WKT and you would like to find the "official" code for it.
String wkt = "GEOGCS[\"ED50\",\n" + " DATUM[\"European Datum 1950\",\n" + " SPHEROID[\"International 1924\", 6378388.0, 297.0]],\n" + "PRIMEM[\"Greenwich\", 0.0],\n" + "UNIT[\"degree\", 0.017453292519943295]]"; CoordinateReferenceSystem example = CRS.parseWKT(wkt); String code = CRS.lookupIdentifier( example, true ); // should be "EPSG:4230" CoordinateReferenceSystem crs = CRS.decode( code );
In the above example the projected is named "ED50", which is not the official name.
Finding a Math Transform
Here is a quick sample use of the CRS class:
import org.geotools.referencing.CRS; CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:4326"); CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:23032"); MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
When using a CoordinateReferenceSystem that has been parsed from WKT you will often need
to "relax" the accuracy by setting the flag lenient to true when peforming your findMathTransform. The official CoordinateReferenceSystem definitions provided by the EPSG database have extra metadata (describing how to do Datum shifts for example), beyond what can be provided using WKT.
import org.geotools.referencing.CRS; String wkt = "PROJCS[\"NAD83 / BC Albers\","+ "GEOGCS[\"NAD83\", "+ " DATUM[\"North_American_Datum_1983\", "+ " SPHEROID[\"GRS 1980\", 6378137.0, 298.257222101, AUTHORITY[\"EPSG\",\"7019\"]], "+ " TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], "+ " AUTHORITY[\"EPSG\",\"6269\"]], "+ " PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], "+ " UNIT[\"degree\", 0.017453292519943295], "+ " AXIS[\"Lon\", EAST], "+ " AXIS[\"Lat\", NORTH], "+ " AUTHORITY[\"EPSG\",\"4269\"]], "+ "PROJECTION[\"Albers_Conic_Equal_Area\"], "+ "PARAMETER[\"central_meridian\", -126.0], "+ "PARAMETER[\"latitude_of_origin\", 45.0], "+ "PARAMETER[\"standard_parallel_1\", 50.0], "+ "PARAMETER[\"false_easting\", 1000000.0], "+ "PARAMETER[\"false_northing\", 0.0], "+ "PARAMETER[\"standard_parallel_2\", 58.5], "+ "UNIT[\"m\", 1.0], "+ "AXIS[\"x\", EAST], "+ "AXIS[\"y\", NORTH], "+ "AUTHORITY[\"EPSG\","3005"]]"; CoordinateReferenceSystem example = CRS.parseWKT(wkt); CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326"); MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, false);
Reprojecting a JTS Geometry
A MathTransform (as generated above) can be used by bashing away at the interface and feeding it {{DirectPosition}}s one at a time - or you could break out the JTS utility class.
import org.geotools.geometry.jts.JTS;
Geometry targetGeometry = JTS.transform( sourceGeometry, transform);
Reprojecting a ISO Geometry
CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:23032");
Geometry target = geometry.transform( targetCRS );