Add support for geojson external secondary instance

We propose ODK XForms spec additions/updates to support a new question type for selecting a geo feature.

  1. Allow .geojson files defining one and only one FeatureCollection to be specified as external secondary instances using the existing jr://file prefix. When we introduced .csv files, we used the existing jr://file-csv prefix. Currently the jr://file prefix is documented as being for XML files so this proposal would expand that. I don't see a compelling reason for the different prefixes in general other than they've always existed.
  2. Parse .geojson files according to their XML secondary instance equivalent. That is, all properties would be treated like XML elements. Additionally, the geometry would be added and converted to ODK XForms format as described below.

Given the following file named myfile.geojson

  "type": "FeatureCollection",
  "features": [{
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [102, 0.5]},
      "properties": {
        "id": "fs87b",
        "name": "My cool point",
        "foo": "bar"
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [104, 0.5]},
      "properties": {
        "id": "67abie",
        "name": "Your cool point",
        "foo": "quux",
        "special-property": "special value"

We could define in an ODK XForm:

<instance id="some-geojson" src="jr://file/myfile.geojson"/>

And then use the some-geojson instance exactly the same way as any other secondary instance. The id, name, geometry, foo, and special-property properties would be accessible. The value of the geometry property would be the geometry from the geojson converted to ODK XForms format and with altitude and accuracy filled in as 0. For example, the value of geometry for the first feature in the sample file above would be 102, 0.5, 0, 0. This is a decision point, we could alternately keep the geojson string but I think it will be easier for people authoring forms to have a consistent representation within the form context.

When defining a select from a .geojson file, the id property would be used as the value ref (underlying value) and the name property as the label ref (display label). I don't think this would need to be part of the XForms spec and would really just affect form builders like pyxform. Here's what it would look like:

<itemset nodeset="instance('some-geojson')/root/item[foo = /data/my_foo ])">
    <value ref="id"/>
    <label ref="name"/>

Pinging @martijnr in case you want to opine here. You've got the most context on things like the file:// prefix and any implications for Enketo. My sense is that this is pretty similar to the CSV support so not a big deal to add to clients.


Thanks @LN!

This looks solid to me from XForms spec perspective. I didn't look at the complexity of the geojson format but if it's always flat like the example above, it seems like a simple conversion.

Setting altitude and accuracy to 0 seems the way to go to me to have one geopoint format.

jr://file-csv was chosen to be consistent with jr://image, jr://audio and jr://video and I think these endpoints might work if extensions are not used in the URI. It doesn't seem like a big deal to rely on the file extension though (for geojson) and use a generic jr://file.

This is probably beyond the scope of this discussion but in terms of implementation, I wonder if the converted XML should actually be used by the geo widget(s) since Enketo uses leaflet which can read a geojson file (I believe) and I imagine the library Collect uses may also. Of course the conversion should still be done to allow querying properties of the selected feature using XPath (calculations) (e.g. calculate="instance('some-geojson')/root/item[./id=current()/../id]/name".

1 Like

Thanks so much for thinking this through, @martijnr! Thrilled to read it’s looking good to you.

Yes! Same question on the Collect side. The plan is to look at what can be reused between the various geo components, do some empirical performance checks and make a decision. I think that will be invisible to users so the same analysis can happen on Enketo!

1 Like