locationtech / jts

The JTS Topology Suite is a Java library for creating and manipulating vector geometry.
Other
1.99k stars 443 forks source link

Custom attributes in exported GeoJSON? #491

Open fpetry opened 5 years ago

fpetry commented 5 years ago

I wonder if there is a possibility to add custom fields to the GeoJSON output from GeoJsonWriter. This could be helpful if some metadata (userData) should be displayed in another software that uses the GeoJson-String.

At the moment I only see the following possibility: Get a Json String, parse it again with a JSON-Parser and manipulate the object.

One could extend GeoJsonWriter to be able to retrieve the Simple Json object and then manipulate it. Another way would be extending GeoJsonWriter in a way that it adds UserData as attributes (i.e. "toString"), but this would only work with UserData that supports a string representation and one would have to derive an attribute name...

Am I overseeing something or is one of the above feasible? I would be happy to also try to contribute some code.

dr-jts commented 5 years ago

The GeoJsonWriter only writes GeoJSON geometry fragments. The spec doesn't allow these to contain any other properties, AFAIK. So if extra data is required in the output, this probably should be supplied as properties on the GeoJSON Feature. JTS doesn't support writing features, so this needs to be done by external code.

I have thought it might be useful to supply a GeoJsonFeatureWriter, which could accept a Geometry and say a HashMap of key-value pairs, and write out a Feature (and possibly FeatureCollection by an obvious extension). This could be a useful code contribution.

fpetry commented 5 years ago

I think this is a good idea, and I will see if I can look into contributing to a GeoJsonFeatureWriter.

In section 6 of the specification, there is no limitation on geometry objects (https://tools.ietf.org/html/rfc7946#section-6).

Section 3 "GeoJSON Object" explicitly states:

A GeoJSON object MAY have other members

Section 3.1 "Geometry Object" states:

Every Geometry object is a GeoJSON object no matter where it occurs in a GeoJSON text.

Hence, I cannot see, that the specification really forbids foreign members in geometry objects.

In a Use Case where one wants to extend not just a feature with all its geometries, but augment the information for every single geometry, would the way to go then be having a feature for every geometry and then collect them in a FeatureCollection?

To have a real world example: Object detection of a camera. The camera detects several objects with a position, but also other attributes like speed, class etc. One could collect the data in a Multipoint geometry and augment every geometry or have a FeatureCollections with a Feature and a geometry for each detected object.

dr-jts commented 5 years ago

Agreed, it looks like the spec leaves the door open to adding members to a Geometry oblect. But it does have this warning:

Accordingly, implementations that rely too heavily on the use of foreign members might experience reduced interoperability with other implementations

It all comes down to the client. If you are using a custom client then you can do custom things - but most clients won't read custom attributes. Or are you proposing to enhance the GeoJsonReader as well, to populate the userData somehow? That sounds like going down the road of having to supply custom readers for userData properties, which is getting really complex.

As for adding custom attributes to every element of a MultiGeometry, that is just going to compound the problem.