Referencing FAQ

Q: Why can’t I display a shapefile over a WMS layer?

This can happen when the axis definition (i.e. which way is X ?) differs between the coordinate reference system used by the shapefile and that used by the WMS layer. It can be fixed by requesting GeoTools to enforce longitude - latitude axis order by including this statement in your code prior to displaying layers…

Hints.putSystemDefault(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE);

If this doesn’t work you can try this more brutal, System wide approach…

System.setProperty("org.geotools.referencing.forceXY", "true");

See also:

Q: How to choose an EPSG Authority?

The referencing module does not do very much out of the box - it needs someone

to tell it what all the funny codes mean (such as “EPSG:4326”).

You need to choose a EPSG jar to have on your classpath; if you have several EPSG jars on your classpath you might end up with a conflict.

For most needs just use the gt-epsg-hsql plugin:

  • gt-epsg-hsql: will unpack an HSQL database containing the official EPSG database into a temp directory, a great solution for desktop applications.

There are several alternatives:

  • gt-epsg-wkt: uses an internal property file and is lightweight rather than official and correct. A great solution for applets

  • gt-epsg-postgres: uses the official EPSG database which you have to load into PostgreSQL yourself. A great solution for Java EE applications.

  • gt-epsg-access: directly use the official EPSG database as distributed. A great solution for windows users that need the latest official database.

Q: Are other authorities other than EPSG supported?

The main module includes definitions of AUTO and AUTO2 and several other OGC inspired ideas.

Q: What Jars does gt-referencing need?

As an example to use gt-epsg-hsql you will need:

C:\geotools\trunk\modules\plugin\epsg-hsql>mvn dependency:tree
...
------------------------------------------------------------------------
Building EPSG Authority Service using HSQL database
   task-segment: [dependency:tree]
------------------------------------------------------------------------
[dependency:tree]
org.geotools:gt2-epsg-hsql:jar:2.5-SNAPSHOT
+- junit:junit:jar:3.8.1:test
+- javax.media:jai_core:jar:1.1.3:provided
+- org.geotools:gt2-referencing:jar:2.5-SNAPSHOT:compile
|  +- java3d:vecmath:jar:1.3.1:compile
|  +- commons-pool:commons-pool:jar:1.3:compile
|  \- org.geotools:gt2-metadata:jar:2.5-SNAPSHOT:compile
|     +- org.geotools.api:geoapi:jar:2.2-SNAPSHOT:compile
|     +- javax.units:jsr108:jar:0.01:compile
|     \- edu.oswego:concurrent:jar:1.3.4:compile
+- org.geotools:gt2-sample-data:jar:2.5-SNAPSHOT:test
+- hsqldb:hsqldb:jar:1.8.0.7:compile
+- net.sourceforge.groboutils:groboutils-core:jar:5:test
\- commons-dbcp:commons-dbcp:jar:1.2.2:test
------------------------------------------------------------------------

Q: Bursa-Wolf Parameters Required?

GeoTools performs datum shift using Bursa-Wolf parameters at this time. If these cannot be determined from your CoordinateReferenceSystem we will be unable to sort out a transform.

Most of the time this does not matter as users work with their information in the same datum it was collected in.

  • A: Lenient

    A quick fix involves setting “lenient” to true when searching for a MathTransform.:

    MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
    

    This approach is good enough for display, but not recommended for editing or careful analysis work.

  • A: Match your PRJ file

    Usually this occurs when you have loaded a CoordinateReferenceSystem from a prj file included with your shapefile.

    To fix look up the complete definition in the EPSG database using the CRS utility class. The EPSG database contains more information than can be Expressed in your prj file.

  • A: Datum shift by Grid

    Finally in the rare case of a Datum shift backed by grids are only partially implemented. Reuben Schulz has implemented data shift backed by grids for NADCON with the following limitations:

    • Use of NADCON grids has not been integrated with DefaultCoordinateOperationFactory (so you would need to set it up by hand)

    • The general case of a Datum shift provided by a grid is not covered, for example Spanish Datum Changes ED50-ETRS89 will not work

Q: What does gt-referencing do?

You will eventually care about this as it defines how 2D data actually means 3D data.

You can take a measurement (i.e. a coordinate) plus a coordinate reference system (the meaning) and figure out where a position on the earth is in 3D space.

It is easy to assume that Coordinates are recorded in double[] as repeating x/y values as is often done in CAD programs.

In a GIS application we can only wish they are X,Y. They are actually LAT/LONG or LONG/LAT or angle,angle,angle or something crazy like time.

Given two CoordinateReferenceSystems you can make a math transform from one to the other. So you could take angle/angle/angle and munch it into something you like for 3D or 2D display.

We will get into this again when you actually have some data - the CoordinateReferenceSystem will tells you what the data “means”.

Much like 3.0 and “three meters”. The first is a number, and the second one means a length.

Q: Can I just use Referencing without the rest of GeoTools?

Yes, you will need to use the metadata module, and one of the EPSG modules. Along with their dependencies such as units.

Q: I cannot find an EPSG Code?

You need to have at least one of the EPSG plugins at your CLASSPATH. To check which one are available and used, you could turn log level to FINE for org.geotools.referencing or org.geotools.referencing.factory. If none of the EPSG plugins at your CLASSPATH have a definition for your code, you could add your own definitions for that EPSG Code.

Q: How do I add my own EPSG Codes?

The gt-epsg-wkt plugin is intended to be used on its own and should not be combined with any of the other gt-epsg-h2 or gt-epsg-hsql plugins as they will end up in conflict.

If you want to add a few more definitions over and above those provided by the official database (i.e. gt-epsg-hsql or gt-epsg-h2) please use the following (taken from the uDig application):

URL url = new URL(url, "epsg.properties");
// application directory or user directory?
// where you are looking for epsg.properties
if ("file".equals(proposed.getProtocol())) {
    File file = new File(proposed.toURI());
    if (file.exists()) {
        epsg = file.toURI().toURL();
    }
}
// you may try several locations...
if (epsg != null) {
    Hints hints = new Hints(Hints.CRS_AUTHORITY_FACTORY, PropertyAuthorityFactory.class);
    ReferencingFactoryContainer referencingFactoryContainer =
               ReferencingFactoryContainer.instance(hints);

   PropertyAuthorityFactory factory = new PropertyAuthorityFactory(
                      referencingFactoryContainer, Citations.fromName("EPSG"), epsg);

   ReferencingFactoryFinder.addAuthorityFactory(factory);
   ReferencingFactoryFinder.scanForPlugins(); // hook everything up
}

Here is an example epsg.properties file used by uDig:

18001=PROJCS["Geoscience Australia Standard National Scale Lambert Projection",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1978",6378135,298.26],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",134.0],PARAMETER["latitude_of_origin",0.0],PARAMETER["standard_parallel_1",-18.0],PARAMETER["standard_parallel_2",-36.0],UNIT["Meter",1]]
41001=PROJCS["WGS84 / Simple Mercator",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],UNIT["Meter",1]]
42101=PROJCS["WGS 84 / LCC Canada",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-95.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",49.0],PARAMETER["standard_parallel_2",77.0],PARAMETER["false_northing",-8000000.0],UNIT["Meter",1]]
42102=PROJCS["BC_Albers",GEOGCS["GCS_North_American_1983",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Albers_Conic_Equal_Area"],PARAMETER["False_Easting",1000000],PARAMETER["Central_Meridian",-126],PARAMETER["Standard_Parallel_1",50],PARAMETER["Standard_Parallel_2",58.5],PARAMETER["Latitude_Of_Origin",45],UNIT["Meter",1]]
42103=PROJCS["WGS 84 / LCC USA",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1978",6378135,298.26]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-100.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",33.0],PARAMETER["standard_parallel_2",45.0],UNIT["Meter",1]]
42104=PROJCS["NAD83 / MTM zone 8 Québec",GEOGCS["GRS80",DATUM["GRS_1980",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-73.5],PARAMETER["scale_factor",0.9999],PARAMETER["false_easting",304800],UNIT["Meter",1]]
42105=PROJCS["WGS84 / Merc NorthAm",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",-96],UNIT["Meter",1]]
42106=PROJCS["WGS84 / Lambert Azim Mozambique",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Azimuthal_Equal_Area"],PARAMETER["latitude_of_origin",5],PARAMETER["central_meridian",20],UNIT["Meter",1]]
42301=PROJCS["NAD27 / Polar Stereographic / CM=-98",GEOGCS["NAD27",DATUM["North_American_Datum_1927",SPHEROID["Clarke 1866",6378206.4,294.978698213901],TOWGS84[-9,151,185]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Stereographic"],PARAMETER["latitude_of_origin",90],PARAMETER["central_meridian",-98.0],PARAMETER["scale_factor",0.9996],UNIT["Meter",1]]
42302=PROJCS["JapanOrtho.09 09",GEOGCS["Lon/Lat.Tokyo Datum",DATUM["Tokyo Datum",SPHEROID["anon",6377397.155,299.15281310608]],PRIMEM["Greenwich",0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",139.833333333333],PARAMETER["Latitude_of_Origin",36],PARAMETER["Scale_Factor",0.9999],UNIT["Meter",1]]
42303=PROJCS["NAD83 / Albers NorthAm",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Albers_conic_equal_area"],PARAMETER["central_meridian",-96.0],PARAMETER["latitude_of_origin",23],PARAMETER["standard_parallel_1",29.5],PARAMETER["standard_parallel_2",45.5],UNIT["Meter",1]]
42304=PROJCS["NAD83 / NRCan LCC Canada",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-95.0],PARAMETER["latitude_of_origin",49.0],PARAMETER["standard_parallel_1",49.0],PARAMETER["standard_parallel_2",77.0],UNIT["Meter",1]]
42305=PROJCS["France_II",GEOGCS["GCS_NTF_Paris",DATUM["Nouvelle_Triangulation_Francaise",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Paris",2.337229166666667],UNIT["degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["False_Easting",600000],PARAMETER["False_Northing",2200000],PARAMETER["Central_Meridian",0],PARAMETER["Standard_Parallel_1",45.898918964419],PARAMETER["Standard_Parallel_2",47.696014502038],PARAMETER["Latitude_Of_Origin",46.8],UNIT["Meter",1]]
42306=PROJCS["NAD83/QC_LCC",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-68.5],PARAMETER["latitude_of_origin",44],PARAMETER["standard_parallel_1",46],PARAMETER["standard_parallel_2",60],UNIT["Meter",1]]
42307=PROJCS["NAD83 / Texas Central - feet",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",31.8833333333333],PARAMETER["standard_parallel_2",30.1166666666667],PARAMETER["latitude_of_origin",29.6666666666667],PARAMETER["central_meridian",-100.333333333333],PARAMETER["false_easting",2296583.33333333333333],PARAMETER["false_northing",9842500],UNIT["US_Foot",0.30480060960121924]]
42308=PROJCS["NAD27 / California Albers",GEOGCS["NAD27",DATUM["North_American_Datum_1927",SPHEROID["Clarke 1866",6378206.4,294.978698213901],TOWGS84[-9,151,185]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Albers_conic_equal_area"],PARAMETER["central_meridian",-120.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",34],PARAMETER["standard_parallel_2",40.5],PARAMETER["false_northing",-4000000],UNIT["Meter",1]]
42309=PROJCS["NAD 83 / LCC Canada AVHRR-2",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-95.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",49.0],PARAMETER["standard_parallel_2",77.0],UNIT["Meter",1]]
42310=PROJCS["WGS84+GRS80 / Mercator",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],UNIT["Meter",1]]
42311=PROJCS["NAD83 / LCC Statcan",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-91.866667],PARAMETER["latitude_of_origin",63.390675],PARAMETER["standard_parallel_1",49],PARAMETER["standard_parallel_2",77],PARAMETER["false_easting",6200000],PARAMETER["false_northing",3000000],UNIT["Meter",1]]
45555=PROJCS["WRF_Lambert_Conformal_Conic 2",GEOGCS["GCS_North_American_1983",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.25722356300003]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943299]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",-97],PARAMETER["Standard_Parallel_1",33],PARAMETER["Standard_Parallel_2",60],PARAMETER["Latitude_Of_Origin",40.003338],UNIT["Meter",1],AUTHORITY["EPSG","45555"]]
45556=PROJCS["Albers Equal area",GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AUTHORITY["EPSG","4326"]], PROJECTION["Albers Equal Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -96.0], PARAMETER["latitude_of_origin", 37.5], PARAMETER["standard_parallel_1", 29.833333333333336], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["standard_parallel_2", 45.833333333333336], UNIT["m", 1.0], AUTHORITY["EPSG","45556"]]
54004=PROJCS["WGS84 / Simple Mercator", GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["WGS_1984", 6378137.0, 298.257223563]], PRIMEM["Greenwich", 0.0], UNIT["degree", 0.017453292519943295]], PROJECTION["Mercator_1SP_Google"], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["x", EAST], AXIS["y", NORTH], AUTHORITY["EPSG","54004"]]
100001=GEOGCS["NAD83 / NFIS Seconds",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Second",4.84813681109536e-06]]
100002=PROJCS["NAD83 / Austin",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",31.8833333333333],PARAMETER["standard_parallel_2",30.1166666666667],PARAMETER["latitude_of_origin",29.6666666666667],PARAMETER["central_meridian",-100.333333333333],PARAMETER["false_easting",2296583.333333],PARAMETER["false_northing",9842500.0000000],UNIT["Meter",1]]
100003=PROJCS["WGS84 / Google Mercator", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AUTHORITY["EPSG","4326"]], PROJECTION["Mercator (1SP)", AUTHORITY["EPSG","9804"]], PARAMETER["semi_major", 6378137.0], PARAMETER["semi_minor", 6378137.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AUTHORITY["EPSG","900913"]]
900913=PROJCS["WGS84 / Google Mercator", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AUTHORITY["EPSG","4326"]], PROJECTION["Mercator (1SP)", AUTHORITY["EPSG","9804"]], PARAMETER["semi_major", 6378137.0], PARAMETER["semi_minor", 6378137.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0],  AUTHORITY["EPSG","900913"]]
30031000=PROJCS["Monte Mario / Italy zone 1 - Peninsular Part/Accuracy 3-4m", GEOGCS["Monte Mario", DATUM["Monte Mario", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-104.1, -49.1, -9.9, 0.971, -2.917, 0.714, -11.68], AUTHORITY["EPSG","6265"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4265"]], PROJECTION["Transverse_Mercator"], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30031000"]]
30031001=PROJCS["Monte Mario / Italy zone 1 - Sardinia/Accuracy 3-4m", GEOGCS["Monte Mario", DATUM["Monte Mario", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-168.6,-34.0,38.6,-0.374,-0.679,-1.379,-9.48], AUTHORITY["EPSG","6265"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4265"]], PROJECTION["Transverse_Mercator"], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30031001"]]
30031002=PROJCS["Monte Mario / Italy zone 1 - Sicily/Accuracy 3-4m", GEOGCS["Monte Mario", DATUM["Monte Mario", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-50.2,-50.4,84.8,-0.690,-2.012,0.459,-28.08], AUTHORITY["EPSG","6265"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4265"]], PROJECTION["Transverse_Mercator"], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30031002"]]
30041000=PROJCS["Monte Mario / Italy zone 2 - Peninsular Part/Accuracy 3-4m", GEOGCS["Monte Mario", DATUM["Monte_Mario", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-104.1, -49.1, -9.9, 0.971, -2.917, 0.714, -11.68], AUTHORITY["EPSG","6265"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Lon", EAST], AXIS["Lat", NORTH], AUTHORITY["EPSG","4265"]], PROJECTION["Transverse_Mercator"], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 2520000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["x", EAST], AXIS["y", NORTH], AUTHORITY["EPSG","30041000"]] 
30041001=PROJCS["Monte Mario / Italy zone 2 - Sardinia/Accuracy 3-4m", GEOGCS["Monte Mario", DATUM["Monte_Mario", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-168.6,-34.0,38.6,-0.374,-0.679,-1.379,-9.48], AUTHORITY["EPSG","6265"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Lon", EAST], AXIS["Lat", NORTH], AUTHORITY["EPSG","4265"]], PROJECTION["Transverse_Mercator"], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 2520000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["x", EAST], AXIS["y", NORTH], AUTHORITY["EPSG","30041001"]] 
30041002=PROJCS["Monte Mario / Italy zone 2 - Sicily/Accuracy 3-4m", GEOGCS["Monte Mario", DATUM["Monte_Mario", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-50.2,-50.4,84.8,-0.690,-2.012,0.459,-28.08], AUTHORITY["EPSG","6265"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Lon", EAST], AXIS["Lat", NORTH], AUTHORITY["EPSG","4265"]], PROJECTION["Transverse_Mercator"], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 2520000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["x", EAST], AXIS["y", NORTH], AUTHORITY["EPSG","30041002"]]

Q: I cannot re-project my shapefile (missing “Bursa wolf parameters”)?

This error occurs when you try to re-project a shapefile with a custom coordinate reference system:

MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, moroccoCRS);

This problem often occurs when working with a custom coordinate reference system, if you look in your shapefile’s PRJ file you will see that the contents is normal “well known text”.

The “Bursa-Wolf parameters” define the relationship (and a transformation) between the spheroid being used by your shapefile and the normal WGS84 spheroid.

The opengis javadocs has some help for you here:

Your best bet is to look up the normal EPSG code for your area; and update your prj file to include the official definition.

Q: How do I Transform?

The MathTransform interface is used to transform (or “re-project”) one Position at a time.

You can also use the utility class JTS which has helper methods to transform a Geometry.

Q: How to Transform a Geometry?

You can use the JTS utility class to create a new geometry in the desired projection:

MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, false);
Geometry targetGeometry = JTS.transform( sourceGeometry, transform);

Q: How to Transform an Envelope?

For a referenced envelope you can transform directly:

        CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:4326");
        ReferencedEnvelope envelope = new ReferencedEnvelope(0, 10, 0, 20, sourceCRS);

        // Transform using 10 sample points around the envelope
        CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:23032");
        ReferencedEnvelope result = envelope.transform(targetCRS, true, 10);

For a JTS Envelope use the JTS utility class:

        CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:4326");
        CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:23032");

        Envelope envelope = new Envelope(0, 10, 0, 20);

        MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS);

        Envelope quick = JTS.transform(envelope, transform);

        // Sample 10 points around the envelope
        Envelope better = JTS.transform(envelope, null, transform, 10);

Q: How to Transform a GridCoverage?

You can use a resample operation to produce a GridCoverage in the desired projection.

Q: How do I extend the system with my own custom CRS?

If you wish to act as your own authority you can register an additional factory with the system.

This is often used by those working with a national standards body that maintains its own set of official codes.

You can use the gt-epsg-wkt plugin as an example of the following options:

  • Through a property file and programmatic registration of the factory

    You can create a file with your CRS in the WKT format, instantiate a PropertyAuthorityFactory with that CRS:

    1. Create a property file with your CRS definitions in Well-Known Text (WKT) format.

    2. Each line of the file should be someUniqueCodeValue = crsInWKT .

    3. Place that file as a resource available from your code at run time

    4. Create a org.geotools.referencing.factory.PropertyAuthorityFactory with a custom code for the authority such as “CUSTOM” and a URI to your file

    5. Register your factory with the ReferencingFactoryFinder.addAuthorityFactory(..) method

    After that, the desired CRS can be invoked as CUSTOM:someUniqueCodeValue so, for example, a CRS object can be created using the CRS.decode(..) method with the string nomenclature of authority-colon-code. The CRS’s defined in this way will also be taken into consideration by the rest of the referencing subsystem.

  • Through a property file and automatic registration of the factory

    A more sophisticated approach changes step 3 to create a new class which both extends PropertyAuthorityFactory and has a no argument constructor which calls the parent with the right URI argument. Such a class will be picked up automatically when the factory system is initialized so step 4 in the list above is no longer necessary.