ODK geoshape/geotrace/geopoint to WKT

For the moment I have quite the same result as yours (a geom union instead of a collect).
I will take a look at it when I'll get a bit of time.

1 Like

I forgot to welcome and encourage you onboard and to introduce yourself here @Satinder

Please take some time to do it :slight_smile:

I achieved to do what we discuss last few days with @ahblake .
3 repeat-groups :

  • one for point,
  • one fore line
  • and one for polygon.
    Every geometries of each loop are merged into :
  • one MULTIPOINT,
  • one MULTILINESTRING
  • and one MULTIPOLYGON.

And in the end those geometries (max 3) are collected into a single GEOMETRYCOLLECTION

Disclaimer, this in not really beautiful, I duplicate what worked for polygon for both lines and points. Unnecessary steps remain :-).

geopoints_lines_and_polygons_to_wkt_geometrycollection.xlsx (13.7 KB)

3 Likes

Thanks @mathieubossaert! This is the key that unlocked what I was trying to achieve: selected-at(${geo_polygon},${index_polygon}, I was reading the docs and knew this was the direction I needed to go in but hadn't worked it out.

The output is exactly what I was chasing, the ability to construct a collection of any number of different geo elements.

2 Likes

In case this trips anyone else in future:

In the repeat_count field in the example file @mathieubossaert has attached, the count is eg ${numpoints_polygon}. This will not throw an error in Enketo, and will function in Collect, but it will throw an error message on validation in Collect without pointing anywhere specific and preventing save/submit.

Sorry, form save failed! java.lang.Double cannot be cast to java.lang.Integer

Changing the repeat_count to eg int(${numpoints_polygon}) will fix this in Collect

Two posts tipped me off to this, one & two

(An old post points to the docs for a FAQ on how to get error logs, but the link is no more and redirects to docs)

Issue filed at https://github.com/getodk/javarosa/issues/686

@all,

the solution given in above thread works absolutely fine for smaller polygons i.e. number of points less than 40-50 in a single polygon.
APP freezes when it exceed 100 points which is above 1 acre in area.
we are mapping farms having different shapes (not necessarily square or rectangular) to capture that irregular shape we are collecting points at 3 seconds interval.
Any alternative solution for this or better to write a function at server side to convert from ODK shape to WKT?

That is likely your best bet for polygons of that size.

There is a $wkt attribute that can be used when requesting a JSON representation of the data. We currently only document it in the API docs: https://odkcentral.docs.apiary.io/#reference/odata-endpoints/odata-form-service/data-document

This will give you a WKT snippet associated with every field of a geo type:

{
  "value": [
    {
      "point": "POINT (-4.535363 9.869207 0)",
      "shape": "POLYGON ((173.4375 -44.51889095578011 0,143.203125 -6.381852166115692 0,120.10044642857142 14.993303789037626 0,112.60044642857144 0.2678561671694837 0,173.4375 -44.51889095578011 0))"
    }
  ], ...
}

value represents an array of submissions. Submissions are key value pairs with nesting for groups and references for repeats.

You probably would need to do another post-processing step but depending on your needs, this could be a good starting point. You can access it with pyodk with client.submissions.get_table(form_id=<form_id>, wkt=True) (see get_table example here) and with ruODK using geo_wkt.

You can also access it directly with:
https://<server>/v1/projects/<projectID>/forms/<form-id>.svc/Submissions?$wkt=true

If I want to get a response in-browser I usually copy the URL from the "Analyze via OData" button on the Submissions page and add /Submissions?$wkt=true. Unfortunately, there's one more step which is that your browser needs to request a JSON response. I use this browser extension to set the Accept header to application/json. We generally expect users to get this representation programmatically but it can be helpful to see in-browser when testing.

1 Like

Apologies, I think I have missed something here, but the returned value for polygons etc is in WKT format when queried via OData & Powerquery with the default svc URL, and displays in Central as WKT also but without SRID=4326;. Is this different with pyodk & other methods?

eg for an ODK polygon which would be (and is this format in the CSV)
-38 147 0.0 0.0;-39 147 0.0 0.0;-39 148 0.0 0.0;-39 147 0.0 0.0;-38 147 0.0 0.0
is returned as
SRID=4326;POLYGON ((147 -38 0, 147 -39 0, 148 -39 0, 147 -39 0, 147 -38 0))

:grimacing: No, it's just confusing. The default format returned as part of the OData JSON is geoJSON because that's what the OData spec defines. Powerquery transforms it to WKT. I hadn't thought about this but you might be able to use Excel/PowerBI connected to OData as part of your data pipeline depending on what you need to do next with WKT.

The Central frontend uses the OData JSON request with $wkt.