Frequently Asked Questions

This page brings together the individual faq pages for each module. This allows you to search for an answer even if you are not sure exactly what module is responsible.

Please direct any comments or suggestions about this page to the GeoTools user list.

GeoTools FAQ

Q: What is GeoTools ?

GeoTools is a free, open source Java geospatial toolkit for working with both vector and raster data. It is made up of a large number of modules that allow you to:

  • access GIS data in many file formats and spatial databases

  • work with an extensive range of map projections

  • filter and analyze data in terms of spatial and non-spatial attributes

  • compose and display maps with complex styling

  • create and analyze graphs and networks

GeoTools implements specifications of the Open Geospatial Consortium including:

  • Simple Features

  • GridCoverage

  • Styled Layer Descriptor

  • Filter Encoding

GeoTools can be readily extended by adding new modules, either for custom applications or as contributions to the library.

Q: How do I search the archives of the GeoTools mailing lists?

Go to this page.

Q: What are the features of the GeoTools Library?

That is a hard question to answer as GeoTools is a general purpose geospatial library.

Here is a sample of some of the great features in the library today:

  • Supports OGC Grid Coverage implementation

  • Coordinate reference system and transformation support

  • Symbology using OGC Styled Layer Descriptor (SLD) specification

  • Attribute and spatial filters using OGC Filter Encoding specification

  • Supports graphs and networks

  • Java Topology Suite (JTS) - with support for the OGC Simple Features Specification - used as the geometry model for vector features.

  • A stateless, low memory renderer, particularly useful in server-side environments

  • Powerful “schema assisted” parsing technology using XML Schema to bind to GML content

  • Interact with OGC web services with both Web Map Server and Web Feature Server support

  • Open plug-in system allowing you to teach the library additional formats

  • Plug-ins for the ImageIO-EXT project allowing GeoTools to read additional raster formats from GDAL

Q: Okay what data formats does GeoTools support?

GeoTools supports additional formats through the use of plug-ins. You can control the formats supported by your application by only including the plug-ins you require.

  • arcgrid

  • db2

  • raster formats

    • geotiff

    • grassraster

    • image - world plus image files using common image formats such as JPEG, TIFF, GIF and PNG

    • imageio-ext-gdal (allows access to additional GDAL formats thanks to the ImageIO project)

    • imagemoasaic

    • imagepyramid

    • JP2K

  • Database gt-jdbc-ng `` support

    • db2

    • geopackage

    • hana

    • h2

    • mysql

    • oracle

    • postgis

    • sqlserver

    • teradata

  • property - simple text file format often used for testing

  • shapefile

Perhaps one of the unsupported modules or plugins may have what you need. These modules are supplied by the community and do not yet meet the quality expected by the library:

There are also some “unsupported” formats that are either popular or under development:

  • dfx

  • geojson

  • wfs

The current authoritative list of plugins is of course the source code:

GeoTools versions

Q. How are GeoTools versions organized?

Like many open source projects, GeoTools has a development version and one or more stable versions active at any given time. By active, we mean that the project developers are working on new features, improvements and bug fixes.

The development version is the main branch in the GitHub repository (https://github.com/geotools/geotools). This is the ‘bleeding edge’ code where the latest features are being worked on. Eventually this code will become the next stable branch.

Stable versions are a branch in the GitHub repository. As an example, the 14.x stable branch can be found at https://github.com/geotools/geotools/tree/14.x. Stable versions do not get new features, but do get bug fixes and sometimes other minor improvements.

Formal releases are a tag in the GitHub repository. For example, GeoTools 14.0 can be found at https://github.com/geotools/geotools/releases/tag/14.0. Similarly, the 13.1 release can be found at https://github.com/geotools/geotools/releases/tag/13.1.

Commencing with GeoTools version 8, a major.minor.patch numbering system applies.

major

An increment of the major identifier (e.g. from version 8.x.y to 9.0.0) indicates substantial changes that can break binary compatibility with previous versions.

minor

An increment in the minor identifier (e.g. from version 8.0.y to 8.1.y) indicates new features and/or improvements that do not break binary compatibility with the previous version.

patch

An increment in the patch identifier (e.g. from version 8.0.0 to 8.0.1) indicates fixes and minor tweaks since the previous version.

Q. What is a SNAPSHOT version and how do I use it?

A snapshot is the GeoTools code that the developers are actively working on.

Usually there will be three active snapshots:

  • one associated with the stable branch (e.g GeoTools 23-SNAPSHOT);

  • a second associated with the maintenance branch (e.g. 22-SNAPSHOT);

  • and a third for main branch (e.g. 24-SNAPSHOT).

At times there will also be snapshot releases for an earlier branch that is having a bug fixe applied (e.g. GeoTools 19-SNAPSHOT).

New snapshot jars are built nightly and deployed to a repository separate from the one used for formal releases. If you are using Maven as your build tool you can work with a snapshot release by adding the following to your pom.xml :

<repository>
    <id>osgeo-snapshot</id>
    <name>OSGeo Snapshot Repository</name>
    <url>https://repo.osgeo.org/repository/snapshot/</url>
    <snapshots><enabled>true</enabled></snapshots>
    <releases><enabled>false</enabled></releases>
</repository>

You can now build your project against a snapshot release by setting it as the your version property as shown here:

<properties>
    <geotools.version>24-SNAPSHOT</geotools.version>
</properties>

This is a great approach when to use when actively testing a fix in your application.

Common License Questions

Q: What license does GeoTools use?

All GeoTools modules are released under the GNU Lesser General Public License (LGPL). GeoTools can be used for commercial applications, any changes made to GeoTools need to be made available to your customers.

An easy way to do this is to contribute the changes back to the GeoTools project (but this is not required).

Q: Can I use GeoTools in my Commercial Project?

Yes. This is one of the reasons we chose the LGPL license. You can build a Commercial application which uses GeoTools as a library and re-distribute your application under any license you choose. Your users will get a license to your application under the terms of your license and a license to the GeoTools library under the terms of the LGPL. You only need to give your users some way to get the source code of the GeoTools library, most easily by pointing your users to the servers of the GeoTools project.

However, if you choose to modify the GeoTools library itself, then you have to publish the source code to those changes to the users of your application.

The easiest way to do that will be to submit those changes back to the GeoTools project so the changes can be incorporated into the core source code.

Q: Can I use GeoTools in my GPL Project?

Yes. This is one of the reasons we chose the LGPL license. You can build a free software application which uses GeoTools as a library and re-distribute your application under the GPL license. Your users will get a license to your application under the terms of the GPL and a license to the GeoTools library under the terms of the LGPL. You only need to give your users some way to get the source code of the GeoTools library, either by pointing your users to the servers of the GeoTools project or by giving them the GeoTools code in the same way you give them the code to your GPL application.

However, if you choose to modify the GeoTools library itself, then you have to publish the source code to those changes to your users.

The easiest way to do that will be to submit those changes back to the GeoTools project so the changes can be incorporated into the core source code.

Note

You can also incorporate GeoTools code directly into your GPL application. Legally, the latter amounts to re-licensing GeoTools under the GPL, which is specifically allowed by the LGPL. This re-licensing is one-way, and requires specific actions - see the LGPL.

Q: What restrictions are there on my use of GeoTools?

None. You can read, run, copy, or do anything else you want to do with the GeoTools code. This is one of the four core freedoms of free software which we grant you under the LGPL: the freedom to use the software for any purpose you choose.

The only restrictions of the LGPL come when you are re-distributing GeoTools, that is when you are passing it on to someone else either on its own or as part of a larger product, such as when you share it or sell it.

Q: What restrictions are there on my re-distribution of GeoTools?

Technically, you have to provide everyone who receives a copy of GeoTools from you with some way to get the source code to the library. In practice, pointing those users to the GeoTools project itself is considered an adequate solution.

However, if you are re-distributing a modified version of GeoTools then you need to provide users with access to the modified code. This means that you must give your users some way to get the modified code such as by publishing it yourself. An alternative way to provide your users with the modifications would be to work with us to get your changes integrated into the GeoTools library– -you could then use the new library directly. The best way to do this would be to open a change request on our issue tracker and add to that request a code patch containing your changes.

Q: What should I do if I am still unsure what I am allowed to do?

You can clarify any questions you have by sending us questions to the user mailing list:

Q: Why can’t I find module X in the GeoTools distribution or javadocs?

If you’re working with a recent GeoTools release then chances are the module that you’re looking for is an unsupported module. These modules not part of the standard GeoTools distribution but are available from the GIT repository in the modules/unsupported folder. If you are using Maven as your build tool you can include a dependency for an unsupported module as you would any other GeoTools module.

Q: What is an unsupported module?

Unsupported modules are those found in the modules/unsupported folder of each GeoTools version in the GIT repository. They are not part of the standard GeoTools distribution but are still available for use via Subversion, Maven and manual download.

A module can be unsupported for one or more of the following reasons:

  • It is under development and has not yet met all of the criteria for usability, test coverage, documentation etc to be included in the general GeoTools distribution.

  • It lacks a module maintainer.

  • It has been superseded by another module and dropped from the general distribution, but still has enough useful bits or active users to make it worth keeping (at least for a while).

Unsupported modules are a mixed bag: some are reliable and regularly used while others are in various states of development or decay. The best way to find out the status of any particular module is to look in the user list archives and then, if you want to check further, post a question to the list.

OpenGIS FAQ

Q: What is “GeoAPI”?

The GeoAPI Implementation Specification was a Java standard (Interfaces and Classes) provided by the Open Geospatial Consortium for interoperability between Java projects and libraries.

This was similar to the SFSQL specification implemented by PostGIS, SQLServer and others for database interoperability when working with GIS information.

Q: Does GeoTools implement “GeoAPI”?

No we do not.

GeoTools worked on a pre-release of these interfaces in the hopes of collaborating with other projects. In GeoTools 2.7 these interfaces were folded back into the GeoTools gt-opengis module due to lack of collaboration opportunities and funding.

In GeoTools 30.0 we responded to a request from the Open GIS Consortium to drop the use of the org.opengis package left over from the pre-release of GeoAPI.

  • We have refactored all such content into org.geotools.api packages.

  • There is no remaining references to org.opengis packages in the GeoTools code base.

Please see update instructions for instructions on how to udpate, including a script to refactor your code base.

JTS FAQ

Q: What is the relationship between JTS and GeoTools?

We make use of the Java Topology Suite to represent “Simple” Geometry, and the OpenGIS interfaces to represent everything else. We have been forced to define an API module of our own in a few cases, like data access, where something “standard” is not available.

You will be using JTS a lot as it literally is the “shape” of GeoTools. It captures shapes using constructs like Coordinate Point Polygon and LineString

  • Do keep in mind that JTS is pure topology and the Geometry objects are pure shapes with no meaning. For the meaning, placing that shape on the earth, you will need to consult a CoordinateReferenceSystem .

  • JTS topological operations work in a two dimensional Cartesian plane. With this in mind three dimensional shapes can be represented, but not calculated with.

  • JTS focuses on linear topology, you will need to represent curves as a LineString with many little segments.

With those notes it may sound like JTS is limited; it is instead focused on the task at hand - Geographic Information Systems. While 3D and curves may be common in CAD systems we will need a lot of funding and raw science to make it work for GIS. Some of that work is happening in GeoTools with ISO Geometry.

Q: What Geometry Specifications?

JTS is an implementation of the OGC Simple Features for SQL Specification (i.e. SFSQL). It covers 2D constructs like Point, Line and Polygon. JTS is willing to carry a 3rd point around but does not use it for calculations - making it a 2.5D solution for Cartesian space.

Specification

Supports

Implementation

Simple Features for SQL

2.5D, linear

Java Topology Suite

ISO Geometry

3D, curves

OpenGIS ISO Geometry interfaces

GeoTools makes a point of working with both implementations, but frankly the ISO Geometry implementations are not ready yet.

Metadata FAQ

Q: Utility Classes?

GeoTools also includes utility classes used to support the implementation of GeoTools.

For the most part these classes are considered internal, as an example to iron out differences between Java versions.

Q: Where are the Interfaces for Metadata?

The interfaces are in the gt-api module.

If you don’t have access to the ISO documentation (who does?) just reading the javadocs is a great place to start.

Q: Why did you implement this class it is in Java 6?

If you are running Java 6 feel free to use Java 6 facilities.

Some of the utility classes are just here to get the job done in Java 1.4 - they have nothing to do with spatial anything. You will find examples of checked collections (yes I know that is available in Java 5); an implementation of an object cache (there is a JSR for that); and so on …

Q: Why are these utility classes in the Metadata Module?

Because metadata is the “lowest” implementation jar in our software stack; needed by everyone else. These classes really are not interesting enough to separate out into their own module.

Q: Why does gt-metadata contain all this factory stuff?

The gt-metadata module introduces some of the “glue code” needed used to hook up GeoTools to services provided by your project. You will find pages here covering logging and JNDI integration.

For a more detailed discussion of how to integrate GeoTools into your application please review the advanced section on integration.

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.

Coverage FAQ

Q: Relationship with ISO Coverage?

Within GeoTools, the coverage module exists below the main module (where Feature is defined) and therefore a GeoTools GridCoverage is not a feature.

This is in opposition to the ISO Coverage model (where Coverage extends Feature) provided by ISO 19123 specification.

GeoTools ‘Coverage’ objects emerged from an earlier specification published by the Open Geospatial Consortium (OGC) called “Grid Coverage Services Implementation” (OGC 01-004).

Q: How is raster data supported?

The design of the coverage modules follows closely the design of image handling in Java. Java provides three major subsystems in their Java media APIs which are used and extended in GeoTools.

Image I/O system

To access files with image content. This provides code to access many standard image formats.

Java Advanced Imaging (JAI) system

which provides a powerful approach for performing operations on images. Not only does JAI provide efficient code for performing lots of operations, but it creates a system through which a user can create chains of operations which can be applied repeatedly to an image or applied to a whole slew of images.

JAI Image I/O system

Combines the two other systems by treating image access as one of the JAI operations allowing for differed access and enabling the treatment of file access as a standard step in an operation chain. The module also provides access to additional file formats.

When combined, these subsystems provide immense power to the GeoTools coverage module but this dependency does require that programmers who wish to use and extend the module must learn to use these other Java modules.

To get the most out of the gt-coverage module developers should be familiar with the underlying mathematical ideas. Knowledge of ideas such as an Affine Transforms (for rotating and scaling) is required to work effectively with the coverage module. Affines are explained any computer graphics textbooks, and on many web sites, if you need a refresher.

Q: How to make raster data work in a NetBeans based application?

Reportedly, the NetBeans class loader breaks ImageIO plugin mechanism which is used to locate image format readers, image input and output streams, and the like. To work around it, run the following line of code, only once, before any raster access:

IIORegistry.getDefaultInstance().registerApplicationClasspathSpis();

Main FAQ

Q: What is gt-main responsible for?

The gt-main module defines the following API:

  • org.geotools.jts for integrating with the JTS Topology Suite representing geometry.

  • org.geotools.api.data which defines a datastore api to read and write spatial content

In addition gt-main modules includes the default implementations for the feature model, filter support, and style data structures. These default implementations are not intended to be used directly, and are accessed through the plug-in system. Implementation access is provided by CommonFactoryFinder and DataStoreFinder rather than creating new instances.

Q: How do I make a FeatureType?

Use FeatureTypeBuilde to define a feature type:

SimpleFeatureTypeBuilder b = new SimpleFeatureTypeBuilder();

//set the name
b.setName( "Flag" );

//add some properties
b.add( "name", String.class );
b.add( "classification", Integer.class );
b.add( "height", Double.class );

//add a geometry property
b.setCRS( DefaultGeographicCRS.WSG84 ); // set crs first
b.add( "location", Point.class ); // then add geometry

//build the type
final SimpleFeatureType FLAG = b.buildFeatureType();

You may also see Test cases using the DataUtilities createType method (which processes a text string and calls SimpleFeatureType builder):

SimpleFeatureType lineType = DataUtilities.createType("LINE", "centerline:LineString,name:\"\",id:0");

Q: How do I modify a FeatureType?

You cannot modify a feature type directly as it is considered immutable and not subject to change.

You can however use a FeatureTypeBuilder to create a modified copy:

SimpleFeatureType lineType = DataUtilities.createType("LINE", "geom:LineString,name:\"\",id:0");
SimpleFeatureTypeBuilder b = new SimpleFeatureTypeBuilder();
b.init( lineType );
b.setName("POINT");
b.add(0, "geom", Point.class );
SimpleFeatureType pointType = b.buildFeatureType();

Q: How to get FeatureCollection to work with a ‘for each’ loop?

Feature collection is a wrapper around a live data stream; as such we need to be sure to close the iterator after we are finished with it:

        try (SimpleFeatureIterator iterator = featureCollection.features()) {
            while (iterator.hasNext()) {
                SimpleFeature feature = iterator.next();
                // process feature
            }
        }

This requirement prevents us implementing Collection (and being compatible with ‘for each’ syntax. I am afraid this is a fundamental limitation of Java and not something that can or should be addressed in a future release.

JDBC FAQ

Q: How to access a database from Java Enterprise Edition?

Depending on your application container (and organizational polices) you may be restricted to only using database connection pools under control of your administrator.

Your administrator will register the database connection pool with the application server and configure your application with the Java Naming and Directory Interface (JNDI) reference.

To use GeoTools with a JNDI name:

Map map = new HashMap();
map.put( "dbtype", "postgis");
map.put( "jndiReferenceName", "java:comp/env/jdbc/geotools");

DataStore store =  DataStoreFinder.getDataStore(map);

The specific dbtype marks the plugin you will use to communicate with the database.

CQL FAQ

Q: What is CQL used for?

The CQL utility class has static methods to parse an input String into either a Filter or an Expression.

Here is the most common use for the CQL class - asking for Features:

        Filter filter = CQL.toFilter("population >= 10000000");

The CQL utility class produced is a Filter; you can create Filters by hand (using a FilterFactory but this is much easier.

Q: What version of CQL is implemented?

The input string defining the query predicate that CQL accepts has to respond to the grammar of the OGC Common Query Language, defined in the Catalog Service for Web, v2.0.1, from the OGC.

We’ve added a couple extensions and fixes to that grammar in order to fix a bug in the definition of temporal expressions and to leverage its use in the GeoTools library.

Q: Can I just try CQL out?

If you’re developing with GeoTools, you can easily try out the CQL parser by depending on the gt-cql jar and running the CQL class as a normal Java application.

It will present a prompt on the console (standard input) from where you can input CQL strings and will get back the corresponding Filter in XML encoding.:

Expression Tester ("quit" to finish)
>attr > 10
<?xml version="1.0" encoding="UTF-8"?>
<ogc:PropertyIsGreaterThan xmlns="http://www.opengis.net/ogc"
                           xmlns:ogc="http://www.opengis.net/ogc"
                           xmlns:gml="http://www.opengis.net/gml">
  <ogc:PropertyName>attr</ogc:PropertyName>
  <ogc:Literal>10</ogc:Literal>
</ogc:PropertyIsGreaterThan>

>quit
Bye!

Q: What does ECQL offer?

The ECQL class offers an extension of the basic CQL language, it is backward compatible so the following still works:

        Filter filter = ECQL.toFilter("POPULTATION >= 1000");

The ECQL has a syntax more flexible and nearest to the natural language. By example, ECQL allows to use an expression in the left hand of comparison as is showed in the following example

        Filter filter = ECQL.toFilter("1000 <= population");

XML FAQ

Q: What parser does GeoTools use?

We have a range of tools to help you with parsing and encoding XML. As a general purpose library GeoTools does not have the luxury of choosing a parser to work with.

The following parsers are based on W3C APIs (SAX, DOM, and XML Transform). You can choose the most appropriate solution for the system you want to use GeoTools in.

Technology

SAX

DOM

Encode

Support

Notes

SAX

sax

dom

Filter GML SLD

Hard to trace through, parse not easily extended

DOM

dom

Filter GML SLD

Forgiving and easy to trace through and debug, memory limitation for GIS data

Transform

XML

Filter GML2 SLD

Easy to trace through and debug, difficult to configure for specific data

JABX

sax

dom

XML

n/a

Fast but not suitable for dynamic data, precompiled

Pull

sax

dom

n/a

Should combine the ease of DOM with the streaming performance of XDO and GTXML

XDO

sax

dom

XML

Filter GML SLD WMS WFS1.0 XSD

Proof of concept of schema assisted parsing allowing streaming into Java Objects. Code is fast and well tested but is hard to trace through

GTXML

sax

dom

XML

Filter GML SLD WMS WFS1.0 WFS1.1 WPS XSD

Schema assisted parsing backed by Eclipse XSD to represent schema.

Easier to trace through but still not straight forward

Allows streaming for large GIS data volumes.

The XDO and GTXML solutions are configuration based. You set up a configuration matching the data you wish to work with and the technology will make use of any XML schema available to assist in parsing or encoding your content correctly.

The JAXB library from Java is a little different in that you start from an XML schema and generate a parser or encoder class for use. This solution performs well but cannot be used for dynamic content such as GML.

Q: What is SAX?

SAX is a W3C technology from the early days of XML. SAX Parsers work using callbacks, they pass control between several hard coded implementations. For basic use you create your own SAX Parser (say responding to a new Geometry being parsed) and pass control off to the GeoTools implementations and wait for it to call you.

  • Allows streaming for large content.

  • Rather tricky to set up

  • Reuse of a SAX parser is possible, but is very tricky to reuse

As a result SAX parsers are rather “brittle” and difficult to maintain are currently hard coded to pass control between themselves, making support for new specifications tricky.

Example: while parsing a Filter control will be need to be handed over to a Geometry parser if the expression contains a literal Geometry.

The later Schema Assisted parsers are an attempt to let mere mortals create a tree of handlers on the fly (they use the schema document to do a bunch of the grunt work) that is hard coded for the SAX Parsers.

Q: What is DOM?

The W3C Document Object Model (DOM) is most popularly used to represent the the contents of a web page as a series of Nodes. These notes form a tree structure and can be used to represent the contents of an XML document in memory.

As a result the GeoTools DOM parsers are functions that can wander through an in memory DOM doing their best to extract content.

Delegation is hard coded in much the same way as with the SAX parsers.

  • accessible easy to understand technology

  • very nice for quick examples

  • obvious how to use the parser

  • solution does not scale to large content as steaming not available

  • can only handle direct use of GML

  • additional coding is always required to parse your own content

Q: What is XML Transform?

Traditional XML generation, traverse your data structure and call methods to generate as you go.

  • very fast, so fast we use it for GeoServer even though it is hard to maintain

  • scalable (does not load features into memory)

  • not open ended

  • need to carefully provide hints before use

  • may revisit data several times (for bounding box and then content)

Q: Schema Assisted -did you make that up?

Yes we did.

This idea of “Schema Assisted” parsers is a GeoTools specific piece of technology. Then general idea is to makes use of XML Schema information to minimize the amount of code you need to write.

A parser is supplied a configuration of bindings; each binding maps an XML elements or XML attributes to Java class.

While this sounds similar to other XML parsing technologies we do have a couple of key differences:

  • taking special care to pay attention to the schema at runtime (so we can parse new documents using the “best” binding available rather than fail)

  • Ensure that data is not loaded into memory; allowing us to “stream” the XML document through an application.

  • We are on our third generation schema assisted parser.

Q: XDO?

XML Data Objects (XDO) is the third generation of our schema assisted parser idea (where the SAX bindings are referenced by the XMLSchema rather then directly hard coded). This is fast scalable solution that supports reading and writing.

  • fast and proven solution for geospatial data

  • ability to handle MASSIVE content like FeatureCollections

  • how to create new bindings is not obvious

Q: GTXML?

GeoTools XML (GTXML) is the fourth generation schema assisted parser, using the XML Schema data structure (rather then hard coding) to figure out what binding to call. The XSD is used to hold our representation of the schema at runtime.

  • schema aware allowing use of new content without additional coding

  • code generator for making custom bindings

  • streaming content for MASSIVE content like feature collections

  • support for content generation

  • hard to debug and trace through the parsing or encoding process

  • code generator available to jump start the development of bindings

  • examples how how to use Eclipse Modeling Objects (EMF) based bindings to work directly from the schema

Q: Why doesn’t GeoTools use JAXB?

JAXB is a set of Java technologies (now included as part of Java 6) that are able to generate a parser form an XML schema.

A couple of groups have used JAXB have bind things such as OGC Filter. In general works well; however it does have trouble responding to content that is negotiated dynamically … such as GML.

Q: For WFS why does Parser return a Map?

This shows up as the following error:

  • ClassCastException java.util.HashMap cannot be cast to FeatureCollection

To understand this error please remember that the GML returned by a WFS GetFeatures request is a normal XML file, with a reference to an XML schema at the top.

For a WFS GetFeature response the schema reference is usually a DescribeFeatureType call that returns an XML Schema.

If this schema is incorrectly configured (common with MapServer) or cannot be reached (common with restricted environments) our parser will give up guessing what is a Feature and just return the values in a HashMap .

Note

If you are using the GML utility class it will perform a bit of analysis and create an ad-hoc FeatureType in order to return you Features.

  • looking at the HashMaps returned

  • building a feature type that matches that kind of contents

  • building features that match that FeatureType

This is similar to the approach taken by OGR; OGR figures out where the “geometry” is; and then goes up two levels and assumes those things are features.

Both of these approaches are strictly a work around for a common problem of misconfigured WFS servers.

Here is how to review the configuration of your WFS Server:

  1. If you are having a problem with a HashMap being returned when you expect a Feature, you should check GetCapabilities responses for remote server e.g. with browser:

    http://{URL}?SERVICE=WFS&VERSION=1.1.0&REQUEST=GetCapabilities
    
  2. After that, ensure that <ows:Operation> elements contain URLs that actually work

  3. In particular check that DescribeFeatureType responds with the expected XML Schema

Q: I am in a restricted environment, how to configure SchemaLocator?

You can configure the Parser with a SchemaLocator (we use this internally to force the parser to a copy of the GML schema included in the GeoTools jars; rather than force the Parser to download the GML schema each time).

  1. To customize how XML Schemas are located in a restricted environment (such as web portal for multiple WFS services that require authorization, or require the use of an HTTP proxy for schema requests).

  2. Create custom SchemaLocator we start with configuration like so:

    GMLConfiguration configuration = new GMLConfiguration() {
        public void configureContext(final MutablePicoContainer container) {
            super.configureContext(container);
            String username = "geotools user";
            String password = "support osgeo";
            Boolean useProxy = true;
            XSDSchemaLocator locator = new CachingSchemaLocator(username, password, useProxy);
            QName key = new QName("mycustom", "schemaLocator");
            container.registerComponentInstance(key, locator);
        }
    };
    
  3. In the above code, CachingSchemaLocator is a custom XSDSchemaLocator:

    public class CachingSchemaLocator implements XSDSchemaLocator {
        public XSDSchema locateSchema(XSDSchema schema, String namespaceURI, String rawSchemaLocationURI, String resolvedSchemaLocationURI) {
    
             ... Implementation ...
    
        }
    }
    
  4. Set up a configuration for use with the Parser:

    Parser parser = new Parser(configuration);
    
    parser.setValidating(false);
    parser.setFailOnValidationError(false);
    parser.setStrict(false);
    FeatureCollection<SimpleFeatureType, SimpleFeature> features = parser.parse(... WFS response InputStream Here ...);
    

Render FAQ

How do I display a shapefile?

Have a look at Tutorials which provides a quickstart showing how to do this.

Q: What is SLD?

Style Layer Descriptor Specification (SLD) is an OGC standard defining styles used when drawing maps. Think of it as CSS for maps.

GeoTools rendering is based around the Style Layer Descriptor standard, for details please see the gt-api module.

This standard is divided into two parts:

  • Style Layer Descriptor 1.0 and 1.1 covers the integration of styles with a web map server. This defines an entire map, listing layers, with the name of the content to draw, and the style to be used for that layer.

  • Symbology Encoding 1.1 covers the definition of a feature type style controlling how a rendering engine draws features.

Q: What is a MapContent?

A MapContent object holds one or more Layers which are rendered in the order that they were added.

Q: What about the Widget?

This module only draws into a Graphics2D context (so printer or image buffer). You can use this functionality in your own Swing widget in order to draw something on screen.

  • gt-swing

    GeoTools does not provide comprehensive GUI components but there is a basic Swing widget JMapFrame in the ``gt-swing`` module which is used in GeoTools example code. This can be used directly in your applications or it could form the starting point for writing your own Swing components. See JMapFrame for more details.

  • gt-swt

    The gt-swing JMapFrame has been ported to an SWT widget as an unsupported module.

  • uDig

    uDig is an application and SDK built around the Eclipse platform, please consider this a real world solution suitable for desktop applications. It makes use of the SWT toolkit so while you can use it as an example of how to do really fast rendering you will not be able to directly use the code in a swing application.

Q: What about Raster Advanced Projection Handling?

Advanced Projection Handling is a feature provided by the GridCoverageRenderer class for handling Raster reprojection. It is especially useful when trying to read a GridCoverage with a BoundingBox crossing the Date Line: the final image is not cut on the Date Line but it is replicated as many times as the Date Line is crossed.

This feature can be enabled/disabled using the related method setAdvancedProjectionHandlingEnabled() in the same class.

Q: Why does my SVG external graphic display as a gray square?

GeoTools uses a pluggable External Graphics factory system to render an icon (see Icon for more details) onto the screen. To render SVG files as icons it needs access to the SVGExternalGraphics factory which is included in the SVG Plugin.

Brewer FAQ

Q: I have 47 classes to represent and ColorBrewer only goes up to 12!

Feel free to create your own Color[] for use with StyleGenerator.

Q: But why does it only go up to 12?

This is a surprisingly common question!

Have a look at the http://colorbrewer2.org/ website above; the point of the research is that the human eye cannot tell very many colors apart. Indeed the number goes down depending on what you are trying communicate (i.e. that the things shown are of equal importance, or do they form a smooth spread of values?).

In other words you are free to create a pretty map with more than 12 colors; but you should not be surprised if that is too complicated for people to understand.

WMS FAQ

Q: Scrambled PNG Images?

A couple versions of Java ship with broken native PNG support (gasp!). If you find your WMS image scrambled you can try the following:

ImageUtilities.allowNativeCodec("png", ImageReaderSpi.class, false);

This code fragments disables the native PNG reader (the pure Java one is fine; and in some platforms faster).

Swing FAQ

Q: What is JMapPane for?

The JMapPane class is primarily used as a teaching aid for the tutorials used to explore the GeoTools library.

It is developed in collaboration with the user list, and while not a intended as a GIS application it is a good starting point for trying out your ideas.

Q: What is the best way to simulate a car moving on a map?

There is a flying saucers demo you can review; but the real answer is to set up a second raster to draw your moving car into; and draw that over top of the map rendered by gt-renderer.

Remember that JMapPane is just a demo showing how you can use StreamingRenderer to draw into a BufferedImage. You can do the same thing in your own code; and have one buffered image for the map and a second one for your “overlays” including the moving car.

Q: JMapPane is Slow how do I make it faster?

This really comes down to how you use the GeoTools renderer. Remember that the GeoTools renderer is doing a lot of calculation and data access; not what you want in the middle of animation.

The gt-renderer is optimized for memory use; it does not loading your data into memory (it is drawing from disk, or database, each time). You can experiment with loading your data into memory (specifically into a spatial index) if you want faster performance out of it.

For raster rendering you have a great deal of control over performance using JAI TileCache settings in addition to converting your rasters into an efficient format (anything is better than JPEG).

References:

Building FAQ

What version of JDK?

Our policy is waiting for the majority of our users before migrating to a new version of the Java language. In general we are held up by the slow migration of Java Enterprise Edition environments such as websphere.

GeoTools 29.x uses Java 11.

How do I build from source code?

Complete build instructions are provided in the user guide:

GeoTools makes use of the Maven build system (in part to help us reused code from a number of other Java projects).

To build all the modules:

mvn install -Dall

To load the modules into the eclipse IDE.

  1. Use Windows ‣ Preferences to open the Preference Dialog. Using the tree on the left navigate to the Java > Build path > Classpath Variables preference Page.

  2. Add an M2_REPO classpath variable pointing to your local repository where maven downloads jars.

    PLATFORM

    LOCAL REPOSITORY

    Windows XP:

    C:\Documents and Settings\Jody\.m2\repository

    Windows:

    C:\Users\Jody.m2\repository

    Linux and Mac:

    ~/.m2/repository

  1. Generate the .project and .classpath files needed for eclipse:

    mvn eclipse:eclipse -Dall
    
  1. You can now use the eclipse import wizard to load existing projects.

Why is Maven 3 Slower?

Maven 3 is not faster out of the box with the default settings.

However what is new is that you can ask it to use more than one core:

mvn install -Dall -T 2C

The above asks the build to go in “threaded” mode; using two threads for each core.

What the fastest build?

This is the fastest build on my machine:

mvn install -DskipTests -o -T 2C

The above options:

  • install (without clean) only re-compiles modified code

  • no profiles or flags are used to build optional code; only the core library is built

  • skipTests - the tests are still built; they are just not run

  • o - allows the build to work “offline” (thus no external servers are checked during the build)

  • T 2C - builds with two threads per core

I use this configuration to quickly push all local changes into my local maven repository so I can test in a downstream application such as uDig or GeoServer.

How do I create an executable jar for my GeoTools app?

If you’re familiar with Maven you might have used the assembly plugin to create self-contained, executable jars. The bad news is that this generally won’t work with GeoTools. The problem is that GeoTools modules often define one or more files in its META-INF/services directory with the same names as files defined in other modules. The assembly plugin just copies files with the same name over the top of each other rather than merging their contents.

The good news is that the Maven shade plugin can be used instead and it will correctly merge the META-INF/services files from each of the GeoTools modules used by your application.

The pom below will create an executable jar for the GeoTools Quickstart module which includes all of the required GeoTools modules and their dependencies.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.geotools.demo</groupId>
  <artifactId>quickstart</artifactId>
  <packaging>jar</packaging>
  <version>1.0</version>
  <name>GeoTools Quickstart example</name>
  <url>http://geotools.org</url>

  <properties>
      <geotools.version>14.1</geotools.version>
  </properties>

  <build>
      <plugins>
          <plugin>
              <artifactId>maven-compiler-plugin</artifactId>
              <configuration>
                  <encoding>UTF-8</encoding>
                  <target>11</target>
                  <source>11</source>
              </configuration>
          </plugin>
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-shade-plugin</artifactId>
              <version>1.3.1</version>
              <executions>
                  <execution>
                      <phase>package</phase>
                      <goals>
                          <goal>shade</goal>
                      </goals>
                      <configuration>
                          <transformers>
                              <!-- This bit sets the main class for the executable jar as you otherwise -->
                              <!-- would with the assembly plugin                                       -->
                              <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                  <manifestEntries>
                                      <Main-Class>org.geotools.demo.Quickstart</Main-Class>
                                  </manifestEntries>
                              </transformer>
                              <!-- This bit merges the various GeoTools META-INF/services files         -->
                              <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                          </transformers>
                      </configuration>
                  </execution>
              </executions>
          </plugin>
      </plugins>
  </build>

  <dependencies>
      <dependency>
          <groupId>org.geotools</groupId>
          <artifactId>gt-shapefile</artifactId>
          <version>${geotools.version}</version>
      </dependency>
      <dependency>
          <groupId>org.geotools</groupId>
          <artifactId>gt-epsg-hsql</artifactId>
          <version>${geotools.version}</version>
      </dependency>
      <dependency>
          <groupId>org.geotools</groupId>
          <artifactId>gt-swing</artifactId>
          <version>${geotools.version}</version>
      </dependency>
      <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.5</version>
          <scope>test</scope>
      </dependency>
  </dependencies>
</project>