covjson / specification

CoverageJSON specification
https://covjson.org/spec/
45 stars 6 forks source link

Allow for polygons to be labelled #94

Open jonblower opened 2 years ago

jonblower commented 2 years ago

In domains that use polygons (e.g. Polygon, PolygonSeries, MultiPolygon, MultiPolygonSeries), the polygons will often relate to well-known geographic regions, e.g. countries or administrative areas. It would be very useful if we could associate the polygons with labels (and perhaps unique IDs) to enable visualisation tools to display them. Maybe it would even be useful to associate polygons with arbitrary objects and properties.

Note that it would not be appropriate to make these labels a kind of range. This would technically work for (Multi)Polygons, but not for (Multi)PolygonSeries, as we would end up repeating the labels for each timestep.

One possible structure would look like this, adding a new property to the relevant domain types:

{
  "type": "Domain",
  "domainType": "MultiPolygonSeries",
  "axes": {
    "composite": {
      "dataType": "polygon",
      "coordinates": ["x","y"],
      "values": [
        [ [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ]  ],
        [ [ [200.0, 10.0], [201.0, 10.0], [201.0, 11.0], [200.0, 11.0], [200.0, 10.0] ] ]
      ]
    },
    "z": { "values": [2] },
    "t": { "values": ["2008-01-01T04:00:00Z", "2010-01-01T00:00:00Z"] }
  },
  "polygonProperties" : [
    { "id": "id_1", "label" : { "en" : "Berkshire" } },
    { "id": "id_2", "label" : { "en" : "Oxfordshire" } },
  ],
  "referencing": [...]
}

In this structure, the order of objects in the polygonProperties array matches the order in the values array of the polygon axis

jonblower commented 2 years ago

An alternative structure would be to make the axis values full GeoJSON Features, not just geometries:

{
  "type": "Domain",
  "domainType": "MultiPolygonSeries",
  "axes": {
    "composite": {
      "dataType": "feature",
      "coordinates": ["x","y"],
      "values": [{
        "type" : "Feature",
        "properties" : {
          "id" : "id_1",
          "label" :  { "en" : "Berkshire" }
        },
        "geometry" : {
          "type" : "Polygon",
          "coordinates" :  [ [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ]  ]
        }
      },{
        "type" : "Feature",
        "properties" : {
          "id" : "id_2",
          "label" :  { "en" : "Oxfordshire" }
        },
        "geometry" : {
          "type" : "Polygon",
          "coordinates" :  [ [ [200.0, 10.0], [201.0, 10.0], [201.0, 11.0], [200.0, 11.0], [200.0, 10.0] ] ]
        }
      }]
    },
    "z": { "values": [2] },
    "t": { "values": ["2008-01-01T04:00:00Z", "2010-01-01T00:00:00Z"] }
  },
  "referencing": [...]
}

Pros:

Cons:

Ben-Lloyd-Hughes commented 2 years ago

I appreciate your point about it being a bigger change to the specification but would argue that in many practical uses cases the polygon geometries to be included in the CoverageJSON will have been extracted from a pre-existing GeoJSON source - so to my eye, a move to full GeoJSON Features would seem to be the most natural extension.

jonblower commented 2 years ago

In the GeoJSON example it may be worth noting that the values array is basically a GeoJSON FeatureCollection. It could be useful in some cases if this were literally a FeatureCollection, so client code could simply use this object as such.

One possible issue with the GeoJSON approach is that we would have to specify the linkage between the geometry coordinates and the CRS. GeoJSON only officially supports CRS:84, with any other CRSs being "prior arrangement" (see the GeoJSON spec).

A sample JSON file following this approach could look like:

{
  "type": "Domain",
  "domainType": "MultiPolygonSeries",
  "axes": {
    "geojson": {
      "type": "FeatureCollection",
      "features": [{
        "type" : "Feature",
        "properties" : {
          "id" : "id_1",
          "label" :  { "en" : "Berkshire" }
        },
        "geometry" : {
          "type" : "Polygon",
          "coordinates" :  [ [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ]  ]
        }
      },{
        "type" : "Feature",
        "properties" : {
          "id" : "id_2",
          "label" :  { "en" : "Oxfordshire" }
        },
        "geometry" : {
          "type" : "Polygon",
          "coordinates" :  [ [ [200.0, 10.0], [201.0, 10.0], [201.0, 11.0], [200.0, 11.0], [200.0, 10.0] ] ]
        }
      }]
    },
    "z": { "values": [2] },
    "t": { "values": ["2008-01-01T04:00:00Z", "2010-01-01T00:00:00Z"] }
  },
  "referencing": [...]
}