[GIS] Read GML using Java

geotoolsgmljavaosgeoparse

I have a use case on reading and extracting data from GML (Geography Markup Language) using Java. There is a sample file in GitHub by clicking here.

The imported packages in Java were as follows

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.io.IOUtils;
import org.w3c.dom.*;
import org.geotools.xsd.Configuration;
import org.geotools.xsd.Parser;
import org.geotools.xsd.StreamingParser;
import org.opengis.feature.simple.SimpleFeature;
import org.geotools.gml3.GML;
import org.geotools.gml3.GMLConfiguration;
import org.geotools.gml3.bindings.GML3ParsingUtils;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.util.Version;

My java code was as follows

URL url = TestData.getResource(this, "states.gml");
InputStream in = url.openStream();

GML gml = new GML(Version.GML3);
SimpleFeatureCollection featureCollection = gml.decodeFeatureCollection(in);

My pom.xml file dependencies is as follows

    <dependencies>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-shapefile</artifactId>
        <version>15.2</version>
    </dependency>

    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-epsg-hsql</artifactId>
        <version>15.2</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.geotools.schemas/gml-3.1 -->
    <dependency>
        <groupId>org.geotools.schemas</groupId>
        <artifactId>gml-3.1</artifactId>
        <version>3.1.1-4</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.geotools.xsd/gt-xsd-core -->
    <dependency>
        <groupId>org.geotools.xsd</groupId>
        <artifactId>gt-xsd-core</artifactId>
        <version>22.2</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.geotools.xsd/gt-gml3 -->
    <dependency>
        <groupId>org.geotools.xsd</groupId>
        <artifactId>gt-gml3</artifactId>
        <version>2.5-M2</version>
    </dependency>

    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-opengis</artifactId>
        <version>22.2</version>
    </dependency>

    <dependency>
        <groupId>org.w3c</groupId>
        <artifactId>dom</artifactId>
        <version>2.3.0-jaxb-1.0.6</version>
    </dependency>
</dependencies>

    <repositories>
        <repository>
            <id>osgeo</id>
            <name>Open Source Geospatial Foundation Repository</name>
            <url>http://download.osgeo.org/webdav/geotools/</url>
        </repository>

        <repository>
            <id>opengeo</id>
            <name>OpenGeo Maven Repository</name>
            <url>http://repo.opengeo.org</url>
        </repository>
    </repositories>

I am unable to compile the code as I am getting three errors, which are listed below

  1. GML3 cannot be resolved or is not a field
  2. The method decodeFeatureCollection(InputStream) is undefined for the type GML
  3. TestData cannot be resolved

File structure of my GML is as follows:

<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation=""
     xmlns:ogr="http://ogr.maptools.org/"
     xmlns:gml="http://www.opengis.net/gml">
  <gml:boundedBy>
    <gml:Box>
      <gml:coord><gml:X>80.15029999991516</gml:X><gml:Y>12.85896555313963</gml:Y></gml:coord>
      <gml:coord><gml:X>80.32580000121733</gml:X><gml:Y>13.22749999937753</gml:Y></gml:coord>
    </gml:Box>
  </gml:boundedBy>

  <gml:featureMember>
    <ogr:Chennai_GML fid="Chennai_GML.0">
      <ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>80.235681595542232,12.980574654917618</gml:coordinates></gml:Point></ogr:geometryProperty>
      <ogr:id>139</ogr:id>
      <ogr:name>Amma Unavagam</ogr:name>
      <ogr:lat>12.9805746549176</ogr:lat>
      <ogr:lon>80.2356815955422</ogr:lon>
      <ogr:dataid>poi_amdcm_494series_194_tab</ogr:dataid>
      <ogr:groupid>didcm_162</ogr:groupid>
      <ogr:uniqueid>poi_amdcm_494series_194_tab139</ogr:uniqueid>
      <ogr:category>POI</ogr:category>
      <ogr:address>GOTHAVARI STREET BHARATHI NAGAR TARAMANI CH-113</ogr:address>
      <ogr:region_id>3</ogr:region_id>
      <ogr:zone_id>13</ogr:zone_id>
      <ogr:ward_id>180</ogr:ward_id>
      <ogr:region_name>South</ogr:region_name>
      <ogr:phone>9876543210</ogr:phone>
      <ogr:email>abc@xyz.com</ogr:email>
    </ogr:Chennai_GML>
  </gml:featureMember>
  <gml:featureMember>
    <ogr:Chennai_GML fid="Chennai_GML.1">
      <ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>80.246665672288927,12.944373445970513</gml:coordinates></gml:Point></ogr:geometryProperty>
      <ogr:id>146</ogr:id>
      <ogr:name>Amma Unavagam</ogr:name>
      <ogr:lat>12.9443734459705</ogr:lat>
      <ogr:lon>80.2466656722889</ogr:lon>
      <ogr:dataid>poi_amdcm_494series_194_tab</ogr:dataid>
      <ogr:groupid>didcm_162</ogr:groupid>
      <ogr:uniqueid>poi_amdcm_494series_194_tab146</ogr:uniqueid>
      <ogr:category>POI</ogr:category>
      <ogr:address>PANDIAN NAGR, (PALAVAN STREET)          THORAIPAKKAM CH-97</ogr:address>
      <ogr:region_id>3</ogr:region_id>
      <ogr:zone_id>15</ogr:zone_id>
      <ogr:ward_id>193</ogr:ward_id>
      <ogr:region_name>South</ogr:region_name>
      <ogr:phone>9876543210</ogr:phone>
      <ogr:email>abc@xyz.com</ogr:email>
    </ogr:Chennai_GML>
  </gml:featureMember>
  <gml:featureMember>...
  </gml:featureMember>
</ogr:FeatureCollection>

Please let me know the queries on the same if any.

Best Answer

You've imported the wrong GML and Version you want:

import org.geotools.wfs.GML;
import org.geotools.wfs.GML.Version;

To do this you will need to import gt-xsd-wfs using:

   <dependency>
        <groupId>org.geotools.xsd</groupId>
        <artifactId>gt-xsd-wfs</artifactId>
        <version>${geotools.version}</version>
    </dependency>

This will solve 1 & 2.

Point 3 is just weird - the most likely answer is that you don't have a file called states.gml in your test-data folder in the test resources folder. Since your file is on the web you probably want to use that URL instead.

Here is a full working example:

package com.ianturton.cookbook.input;

import java.io.IOException;
import java.net.URL;

import javax.xml.parsers.ParserConfigurationException;

import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.wfs.GML;
import org.geotools.wfs.GML.Version;
import org.opengis.feature.simple.SimpleFeature;
import org.xml.sax.SAXException;

public class ReadGML {
  URL url;

  public ReadGML(URL url) {
    this.url = url;
  }

  private SimpleFeatureCollection read() throws IOException, SAXException, ParserConfigurationException {
    GML gml = new GML(Version.GML3);
    SimpleFeatureCollection features = gml.decodeFeatureCollection(url.openStream());
    return features;
  }

  public static void main(String[] args) throws IOException, SAXException, ParserConfigurationException {
    URL url = new URL(
        "https://raw.githubusercontent.com/basilmohammed/GML-Data-Extraction-using-java/master/Files/Chennai/Chennai_GML.gml");
    ReadGML me = new ReadGML(url);
    SimpleFeatureCollection features = me.read();
    try (SimpleFeatureIterator itr = features.features()) {
      while (itr.hasNext()) {
        SimpleFeature feature = itr.next();
        System.out.println(feature);
      }
    }
  }
}

TO complete the question here is a full pom.xml

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <groupId>com.ianturton.cookbook</groupId>
  <modelVersion>4.0.0</modelVersion>
  <artifactId>input</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <geotools.version>22-SNAPSHOT</geotools.version>
    <geoserver.version>2.16-SNAPSHOT</geoserver.version>
    <fork.javac>true</fork.javac>
    <javac.maxHeapSize>256M</javac.maxHeapSize>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <postgresql.jdbc.version>42.1.1</postgresql.jdbc.version>
  </properties>
  <dependencies>
    <dependency>                                                                                                                       
      <groupId>org.geotools</groupId>
      <artifactId>gt-epsg-hsql</artifactId>
      <version>${geotools.version}</version>
    </dependency>
    <dependency>
      <groupId>org.geotools.xsd</groupId>
      <artifactId>gt-xsd-wfs</artifactId>
      <version>${geotools.version}</version>
    </dependency>
  </dependencies>
  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <configuration>
            <source>1.8</source>
            <target>1.8</target>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>
    <plugins>
      <!-- ======================================================= -->
      <!-- Compilation. -->
      <!-- ======================================================= -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
          <source>1.8</source>
          <!-- The -source argument for the Java compiler. -->
          <target>1.8</target>
          <!-- The -target argument for the Java compiler. -->
          <debug>true</debug>
          <!-- Whether to include debugging information. -->
          <encoding>UTF-8</encoding>
          <!-- The -encoding argument for the Java compiler. -->
          <fork>${fork.javac}</fork>
          <maxmem>${javac.maxHeapSize}</maxmem>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <repositories>
    <repository>
      <id>maven2-repository.dev.java.net</id>
      <name>Java.net repository</name>
      <url>http://download.java.net/maven/2</url>
    </repository>
    <repository>
      <id>osgeo</id>
      <name>Open Source Geospatial Foundation Repository</name>
      <url>http://download.osgeo.org/webdav/geotools/</url>
    </repository>
    <repository>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
      <id>imageio-ext-repository</id>
      <name>imageio-ext Repository</name>
      <url>http://maven.geo-solutions.it/</url>
    </repository>
    <repository>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
      <id>boundless</id>
      <name>Boundless Maven Repository</name>
      <url>http://repo.boundlessgeo.com/main</url>
    </repository>
  </repositories>
</project>