I am converting GML, that includes wrappers, into Geometry objects. Currently I have converting a Point from the GML to Geometry working but the Line strings and polygons are not being parsed correctly.
Using xpath to create a relevant node list of all the xml sections I care about, and using the Geotools Parser to create an Object based off that with the GML Configuration. With Point it creates and Object that is an instanceof Geometry - so that can be cast easily. But with line string and polygon the return type of parsedObject is a String...
What I have tried:
- Adjusting nodeToString
- Converting node -> string -> inputStream
- Confirming that xpath is in fact returning nodes
Is this geotools parsing problem or does JTS not recognize it?
If I try to cast it no matter what I get this:
Exception in thread "main" java.lang.ClassCastException: class java.lang.String cannot be cast to class org.locationtech.jts.geom.Geometry (java.lang.String is in module java.base of loader 'bootstrap'; org.locationtech.jts.geom.Geometry is in unnamed module of loader 'app')
Relevant code and examples:
import org.geotools.gml3.GMLConfiguration;
import org.geotools.xsd.Parser; import org.locationtech.jts.geom.*;
// relevant xpath stuff
XPathExpression expr = xpath.compile("//n1:geometry//n2:pointProperty");
private static Geometry extractAndHandleGeometries(NodeList geometryNodes) throws Exception {
List<Geometry> geometries = new ArrayList<>();
GeometryFactory geometryFactory = new GeometryFactory();
// Use GeoTools to parse each GML node
GMLConfiguration configuration = new GMLConfiguration();
Parser parser = new Parser(configuration);
for (int i = 0; i < geometryNodes.getLength(); i++) {
// Directly pass the node's content to the parser
// String gml = parser.encodeToString(geometryNodes.item(i));
String geoNode = nodeToString(geometryNodes.item(i));
Object parsedObject = parser.parse(new StringReader(nodeToString(geoNode)));
if(parsedObject instanceof Geometry){
Geometry geometry = (Geometry) parsedObject;
geometries.add(geometry);
}
}
return geometryFactory.createGeometryCollection(geometries.toArray(new Geometry[0]));
}
public static String nodeToString(Node node) throws Exception {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.setOutputProperty(OutputKeys.INDENT, "no");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(node), new StreamResult(writer));
return writer.getBuffer().toString();
}
}
This is the sample data I am working with:
<n1:geometry>
<n2:pointProperty>
<n2:maskReference />
<n2:Point gml:id="ID2" srsName="urn:ogc:def:crs:EPSG::4326" srsDimension="2">
<gml:pos srsName="http://www.altova.com/" srsDimension="2">40.682432 -74.043333</gml:pos>
</n2:Point>
</n2:pointProperty>
</n1:geometry>
<n1:geometry>
<n2:curveProperty xlink:type="simple">
<n2:Curve gml:id="ID101" srsName="EPSG:4326" srsDimension="2">
<gml:segments>
<gml:LineStringSegment interpolation="linear">
<gml:segments>
<gml:LineStringSegment interpolation="linear">
<gml:pos>37.0 -122.0</gml:pos>
<gml:pos>37.5 -121.5</gml:pos>
<gml:pos>38.0 -121.0</gml:pos>
</gml:LineStringSegment>
</gml:segments>
</gml:LineStringSegment>
</gml:segments>
</n2:Curve>
</n2:curveProperty>
</n1:geometry>
And this is the return result of entering in the linestring xml chunk into nodetostring:
<n2:curveProperty xmlns:xlink= http:// www.w3.org/ 1999/ xlink xlink:type="simple" xmlns:n2= http:// www.iho.int/ s100gml/ 5.0>
<n2:Curve xmlns:gml= http:// www.opengis.net/ gml/ 3.2 gml:id="ID101" srsDimension="2" srsName="EPSG:4326">
<gml:segments>
<gml:LineStringSegment interpolation="linear">
<gml:pos>37.0 -122.0</gml:pos>
<gml:pos>37.5 -121.5</gml:pos>
<gml:pos>38.0 -121.0</gml:pos>
</gml:LineStringSegment>
</gml:segments>
</n2:Curve>
</n2:curveProperty>
-
I can't be sure but it looks like you are parsing GML3 with a GML 2 parserIan Turton– Ian Turton2024年08月23日 18:49:11 +00:00Commented Aug 23, 2024 at 18:49
-
Just edited the code snippet - I am using the parser from the geotools xsd package - and the gmlconfig from the geotools.gml3 package. Are these the correct packages?rckst– rckst2024年08月23日 18:53:17 +00:00Commented Aug 23, 2024 at 18:53
-
I used this documentation- docs.geotools.org/stable/userguide/library/xml/geometry.html and changed the parser and config declarations to this and it still didn't work : org.geotools.xsd.Configuration configuration = new org.geotools.gml3.GMLConfiguration(); org.geotools.xsd.Parser parser = new org.geotools.xsd.Parser( configuration );rckst– rckst2024年08月23日 19:22:23 +00:00Commented Aug 23, 2024 at 19:22
-
Without the namespace declarations it's hard to tell, and I can't remember which version introduced lineStringSegmentsIan Turton– Ian Turton2024年08月23日 19:30:51 +00:00Commented Aug 23, 2024 at 19:30
-
Have a look at the source and check the comments and package infoIan Turton– Ian Turton2024年08月23日 19:31:45 +00:00Commented Aug 23, 2024 at 19:31