I've successfully created GeoTools (8.3) bindings for parsing and encoding XML bindings as described in their tutorial: http://docs.geotools.org/latest/userguide/library/xml/internal/bindings.html
I can parse the XML data + GML 3.1.1 geometries successfully, including combining multiple XSD's and using the binding context for factories, etc.. but the encoding seems to result in XML data with geometries that are not linked to a particular namespace ('null:'). Since the above tutorial (or anything else I could find) doesn't mention specifics about encoding GML-geometies I have the following question(s):
- Which bindings do I have to make myself and which can be handled by GeoTools?
- In the repository I see a number of util classes (e.g. GML3EncodingUtils), Geometry type bindings (implemented) and normal geometry bindings (unimplemented). Does anyone have experience using these? Again, which to implement, and which not?
I'm only interested in a limited part specifying the geometries. Here's the fragment of the XSD that connects to GML geometries (Dutch Cadastral data):
<?xml version="1.0" encoding="UTF-8"?>
...
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="../../gml/bag-gml.xsd"/>
...
<xs:complexType name="PuntOfVlak">
<xs:annotation>
<xs:documentation>Keuze tussen een punt (gml:Point) of een vlak (gml:Surface).</xs:documentation>
</xs:annotation>
<xs:choice>
<xs:element ref="gml:Point"/>
<xs:element ref="gml:_Surface"/>
</xs:choice>
</xs:complexType>
...
<xs:complexType name="VlakOfMultiVlak">
<xs:choice>
<xs:element ref="gml:_Surface"/>
<xs:element ref="gml:MultiSurface"/>
</xs:choice>
</xs:complexType>
...
So basically, its about how to implement the encode(..) or getProperty(..) method of my PuntOfVlakBinding and VlakOfMultiVlakBinding.
The original XSD's can be found here:
- The GML XSD: http://pastebin.com/nMisVg2Q
The VlakOfMultiVlakBinding:
...
public class VlakOfMultiVlakBinding extends AbstractComplexBinding {
private static final String SURFACE = "_Surface";
private static final String POLYGON = "Polygon";
private static final String MULTI_POLYGON = "MultiSurface";
@Override
public Object getProperty(Object object, QName name) throws Exception {
if (SURFACE.equals(name.getLocalPart())) {
return object;
}
if (POLYGON.equals(name.getLocalPart())) {
return object;
}
if (MULTI_POLYGON.equals(name.getLocalPart())) {
return object;
}
return null;
}
@Override
public QName getTarget() {
return BAGType.VlakOfMultiVlak;
}
@Override
public Class<?> getType() {
return Geometry.class;
}
@Override
public Object parse(ElementInstance instance, Node node, Object value) throws Exception {
if (node.hasChild(SURFACE)) {
return node.getChildValue(SURFACE);
}
if (node.hasChild(POLYGON)) {
return node.getChildValue(POLYGON);
}
if (node.hasChild(MULTI_POLYGON)) {
return node.getChildValue(MULTI_POLYGON);
}
throw new IllegalArgumentException("Unsupported GML type detected for binding " + VlakOfMultiVlakBinding.class.toString());
}
}
I can also post attempts at the _SurfaceBinding.java if that helps
Edit: This post already scratches the surface of the use of bindings, but doesnt elaborate yet: https://gis.stackexchange.com/a/6430/14253
Edit 2: I've implemented my own bindings where each element with subelements now has it's getProperty() method implemented and each 'end'-element it's encode() method implemented:
What this looks like for the polygon binding tree:
<gml:Polygon srsName="..."> --> PolygonBinding + getProperty()
<gml:exterior> --> ExteriorBinding + getProperty()
<gml:LinearRing> --> LinearRingBinding + getProperty()
<gml:posList srsDimension="2" count="..."> --> PosListBinding + encode()
This seems to work, encoding wise, but I'm still stuck with the 'null:' namespace. Rather than the expected 'gml:' namespace. This is strange, because debugging through the bindings shows the namespaceURI is at all times known as "http://www.opengis.net/gml".
The current result for the VlakOfMultiVlak binding for a test case:
<bag_LVC:woonplaatsGeometrie>
<null:Polygon srsName="urn:ogc:def:crs:EPSG::28992">
<null:exterior>
<null:LinearRing>
<null:posList count="6" srsDimension="2">193273.335 389233.922 194582.516 389880.369 194456.597 389867.675 194207.272 389712.575 194201.368 389710.434 193273.335 389233.922 </null:posList>
</null:LinearRing>
</null:exterior>
</null:Polygon>
</bag_LVC:woonplaatsGeometrie>