3

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 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>
1

1 Answer 1

1

After asking this question on GeoTools-users mailinglist I was kindly pointed towards this bug:

http://jira.codehaus.org/browse/GEOT-2932

The secondary XSD reference (so a reference of another XSD's reference) doesn't seem to lead to correct prefixes during the encoding.

One of the related bugs is currently unresolved. However, the workaround mentioned there works. Adding the secondary reference (which prefixes don't work) of the namespace to the main XSD fixes it:

  • add a reference to the <xs:schema ... xmlns:gml="http://www.opengis.net/gml" ... >

  • add the import: <xs:import namespace="http://www.opengis.net/gml" schemaLocation="../../gml/bag-gml.xsd"/>

1
  • Also notice that GeoTools currently doesnt support _Ring type as a polygon's exterior: jira.codehaus.org/browse/GEOT-1754 Hence the required custom made bindings
    – Jur_
    Jan 17, 2013 at 12:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.