GML Parser for Java
Introduction
This project implements an easy-to-use lightweight GML parser for Java. Using this parser you can easily parse GML documents into JTS geometries.
This project also implements a GML serializer which can output JTS geometries as GML.
GML
The Geography Markup Language (GML) is the XML grammar defined by the Open Geospatial Consortium (OGC) to express geographical features. GML serves as a modeling language for geographic systems as well as an open interchange format for geographic transactions on the Internet.
GML is widely used in GIS applications as an exchange format for geographical objects (features). Among other things, GML can also describe geometries of these features. Here's an example of a polygon definition:
<Polygon xmlns="http://www.opengis.net/gml"> <exterior> <LinearRing> <pos> 0 0</pos> <pos>10 0</pos> <pos>10 10</pos> <pos> 0 10 </pos> <pos> 0 0</pos> </LinearRing> </exterior> </Polygon>
JTS
The JTS Topology Suite (JTS) is an open source Java software library that provides an object model for Euclidean planar linear geometry together with a set of fundamental geometric function.
When developing GIS applications you often need to work with geometries: perform operations (ex. build an intersection of two geometries), evaluate predicates (ex. check if two geometries are disjoint), store geometries in a database and so on.
JTS is a popular Java library which provides API for working with geometries. It is used in many GIS products and libraries.
Converting between GML and JTS
One of the most common tasks when working with GML and JTS is reading JTS geometries from GML - and vice verse - exporting JTS geometries as GML. This project provides a lightweight implementation of GML-JTS converter for GML 3.1.1.
| GML 3.1.1 is backwards-compatible with older GML 3.x and GML 2.x specifications. It is not directly compatible with GML 3.2 due to the update of the namespace URI in GML 3.2. |
Using the GML-JTS library
Supported elements and types
| GML Element | GML Type | JTS Type |
|---|---|---|
| Point | PointType | Point |
| pointProperty | PointPropertyType | Point |
| LineString | LineStringType | LineString |
| lineStringProperty | LineStringPropertyType | LineString |
| LinearRing | LinearRingType | LinearRing |
| linearRingProperty | LinearRingPropertyType | LinearRing |
| Polygon | PolygonType | Polygon |
| polygonProperty | PolygonPropertyType | Polygon |
| MultiPoint | MultiPointType | MultiPoint |
| multiPointProperty | MultiPointPropertyType | MultiPoint |
| MultiLineString | MultiLineStringType | MultiLineString |
| multiLineStringProperty | MultiLineStringPropertyType | MultiLineString |
| MultiPolygon | MultiPolygonType | MultiPolygon |
| multiPolygonProperty | MultiPolygonPropertyType | MultiPolygon |
| MultiGeometry | MultiGeometryType | GeometryCollection |
| multiGeometryProperty | MultiGeometryPropertyType | GeometryCollection |
| _Geometry | AbstractGeometryType | Geometry |
Adding the GML-JTS library to your project
Adding dependencies with Maven
GML-JTS is distributed via the central Maven repository.
| Check this link for information on GML-JTS Maven artifact. |
In order to use GML-JTS
<dependency> <groupId>org.jvnet.ogc</groupId> <artifactId>ogc-tools-gml-jts</artifactId> <version><!-- Version --></version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version><!-- Version --></version> </dependency>
Adding dependencies without Maven
If you're not using Maven, you'll need to add GML-JTS JAR (ogc-tools-gml-jts-version.jar) as well as a number of dependencies to your project on your own.
Version 1.0.2
- OGC Tools GML-JTS (ogc-gml-v_3_1_1-schema-1.0.2.jar)
Dependencies:
- GML 3.1.1 Schema (gml-v_3_1_1-schema-1.0.2.jar)
- JTS (jts-1.11.jar)
- JAXB2-Basics (jaxb2-basics-runtime-0.6.0.jar)
- Commons Lang (commons-lang-2.4.jar)
- JAXB dependencies (typically shipped with JRE):
- JAXB2 Reference Implementation (jaxb-impl-2.1.13.jar)
- JAXB2 API (jaxb-api-2.1.jar)
- StAX (stax-api-1.0-2.jar)
- Java Activation Framework(activation-1.1.jar)
Parsing and serializing geometries
GML-JTS provides a custom JAXB context implementation which can be used to unmarshal JTS geometries from XML in GML format or to marshal JTS geometries as GML.
- Create a JAXB context for the org.jvnet.ogc.gml.v_3_1_1.jts context path;
- Create an instance of unmarshaller for parsing/unmarshalling;
- Create an instance of marshaller for serializing/marshalling.
JAXBContext context = JAXBContext.newInstance("org.jvnet.ogc.gml.v_3_1_1.jts"); // Unmarshal Point point = (Point) context.createUnmarshaller().unmarshal(getClass().getResource("Point[0].xml")); // Marshal context.createMarshaller().marshal(point, System.out);
Examples
Converting GML to WKT
Here's a simple code snippet which converts GML to WKT:
JAXBContext context = JAXBContext.newInstance("org.jvnet.ogc.gml.v_3_1_1.jts"); WKTWriter wktWriter = new WKTWriter(); Unmarshaller unmarshaller = context.createUnmarshaller(); Geometry geometry = (Geometry) unmarshaller.unmarshal(resource); System.out.println(wktWriter.write(geometry));
| GML | WKT |
|---|---|
<gml:Point xmlns:gml="http://www.opengis.net/gml">
<gml:pos>0 1</gml:pos>
</gml:Point>
|
POINT(0 1) |
<?xml version="1.0" encoding="UTF-8"?> <gml:LineString xmlns:gml="http://www.opengis.net/gml"> <gml:posList> 0 0 1 0 1 1 0 1 </gml:posList> </gml:LineString> |
LINESTRING(0 0, 1 0, 1 1, 0 1) |
<?xml version="1.0" encoding="UTF-8"?> <gml:Polygon xmlns:gml="http://www.opengis.net/gml"> <gml:exterior> <gml:LinearRing> <gml:pos>0 0</gml:pos> <gml:pos>1 0</gml:pos> <gml:pos>1 1</gml:pos> <gml:pos>0 1</gml:pos> <gml:pos>0 0</gml:pos> </gml:LinearRing> </gml:exterior> </gml:Polygon> |
POLYGON((0 0, 1 0, 1 1, 0 1, 0 0)) |
<?xml version="1.0" encoding="UTF-8"?> <gml:MultiPoint xmlns:gml="http://www.opengis.net/gml"> <gml:pointMember> <gml:Point> <gml:pos>0 0 </gml:pos> </gml:Point> </gml:pointMember> <gml:pointMember> <gml:Point> <gml:pos>1 0</gml:pos> </gml:Point> </gml:pointMember> <gml:pointMembers> <gml:Point> <gml:pos>1 1</gml:pos> </gml:Point> <gml:Point> <gml:pos>0 1</gml:pos> </gml:Point> </gml:pointMembers> </gml:MultiPoint> |
MULTIPOINT(0 0, 1 0, 1 1, 0 1) |
<?xml version="1.0" encoding="UTF-8"?> <gml:MultiLineString xmlns:gml="http://www.opengis.net/gml"> <gml:lineStringMember> <gml:LineString> <gml:posList> 0 0 1 0 1 1 0 1 </gml:posList> </gml:LineString> </gml:lineStringMember> </gml:MultiLineString> |
MULTILINESTRING((0 0, 1 0, 1 1, 0 1)) |
<?xml version="1.0" encoding="UTF-8"?> <gml:MultiPolygon xmlns:gml="http://www.opengis.net/gml"> <gml:polygonMember> <gml:Polygon> <gml:exterior> <gml:LinearRing> <gml:pos>0 0</gml:pos> <gml:pos>1 0</gml:pos> <gml:pos>1 1</gml:pos> <gml:pos>0 1</gml:pos> <gml:pos>0 0</gml:pos> </gml:LinearRing> </gml:exterior> </gml:Polygon> </gml:polygonMember> </gml:MultiPolygon> |
MULTIPOLYGON(((0 0, 1 0, 1 1, 0 1, 0 0))) |
Handling reference systems
Unmarshalling
When unmarshalling GML, GML-JTS tries to parse srsName as EPSG code using the following patterns:
- EPSG:{0,number,integer}
- urn:ogc:def:crs:EPSG::{0,number,#}
- urn:ogc:def:crs:EPSG:{1}:{0,number,#}
- urn:x-ogc:def:crs:EPSG::{0,number,#}
- urn:x-ogc:def:crs:EPSG:{1}:{0,number,#}
- http://www.opengis.net/gml/srs/epsg.xml#\{0,number,#}
If srsName matched one of the pattern, it will be parsed as assigned to the SRID property of the JTS geometry.
If none of the patterns matched, srsName will be simply saved to the UserData property of the JTS geometry.
Examples
Both geometries will have SRID set to 4326:
<?xml version="1.0" encoding="UTF-8"?> <gml:Point xmlns:gml="http://www.opengis.net/gml" srsName="urn:ogc:def:crs:EPSG::4326"> <gml:pos>0 1</gml:pos> </gml:Point>
<?xml version="1.0" encoding="UTF-8"?> <gml:Point xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326"> <gml:pos>0 1</gml:pos> </gml:Point>
Marshalling
If UserData property of the JTS geometry is a string, it will be marshalled as srsName of the GML geometry.
Otherwise, if JTS geometry has a SRID set (geometry.getSRID() != 0), it will be formatted using the following pattern:
- urn:ogc:def:crs:EPSG::{0,number,#}
The result will be serialized as the srsName attribute of the geometry.
Examples
Marshalling
GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(), 4326); Point point = geometryFactory.createPoint(new Coordinate(0, 1));
Will produce:
<?xml version="1.0" encoding="UTF-8"?> <gml:Point xmlns:gml="http://www.opengis.net/gml" srsName="urn:ogc:def:crs:EPSG::4326"> <gml:pos>0.0 1.0</gml:pos> </gml:Point>