Computing the center of gravity of a geoJSON Polygon using jq

假如想象 提交于 2019-12-11 06:21:28

问题


I have a list of cities described by their polygon in geoJSON files.

I would like to get a sample inside point of the polygon.

Basic maths says the center of gravity is inside the polygon and it suffices to sum all longitudes and all latitudes together then divide it by the number of points.

Full file to process (visualization is available on GitHub)

{
  "type": "FeatureCollection",
  "features": [
  {
    "type": "Feature",
    "geometry": {
      "type": "Polygon",
      "coordinates": [[[2.41101, 48.72605], [2.41554, 48.72656], [2.41718, 48.72791], [2.4211, 48.72953], [2.42603, 48.72824], [2.42756, 48.72865], [2.42922, 48.72723], [2.43133, 48.72646], [2.43404, 48.72665], [2.43513, 48.72409], [2.42554, 48.7227], [2.42072, 48.72105], [2.41426, 48.71782], [2.41327, 48.71869], [2.41582, 48.72086], [2.41238, 48.72193], [2.41136, 48.72325], [2.41101, 48.72605]]]
    },
    "properties": {
      "code": "94001",
      "nom": "Ablon-sur-Seine"
    }
  },
  {
    "type": "Feature",
    "geometry": {
      "type": "Polygon",
      "coordinates": [[[2.41959, 48.81691], [2.4159, 48.81633], [2.40936, 48.81667], [2.40787, 48.81746
    },
    "properties": {
      "code": "94018",
      "nom": "Charenton-le-Pont"
    }
  },
  ...
  ]
}

I already have a command that computes the length of the polygon vertices.

$ curl -s https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/departements/94-val-de-marne/communes-94-val-de-marne.geojson \
> | jq '.features[0].geometry.coordinates[0][][0]' \
> | jq -s 'add/length'
2.4206944444444445

See https://unix.stackexchange.com/questions/13731/

Using jq and simple bash commands, how can I compute the sum of the longitudes and sum of the latitudes as well, and reinject the barycenter in properties field in another geoJSON file?

Thank you.


回答1:


So if I understood correctly, you're trying to get the averages of the first set of coordinates, then updating the properties to store the result.

.features[] |= (
    (.geometry.coordinates[0] | length as $len | reduce .[] as [$x, $y] ([0,0];
        [.[0] + $x, .[1] + $y]
    ) | map(. / $len)) as $barrycenter |
    .properties.barycenter = $barrycenter
)



回答2:


Warning

The "center of gravity" of a polygon is in general not the same as the point defined in terms of the averages of the x and y co-ordinates of its vertices. See e.g. https://math.stackexchange.com/questions/3177/why-doesnt-a-simple-mean-give-the-position-of-a-centroid-in-a-polygon

The averages of the latitudes and of the longitudes

Here is a jq filter that will, with a single invocation of jq and without redundancy, compute the averages of the latitudes and of the longitudes of each "feature":

.features[].geometry.coordinates[0]
| [ [.[][0]], [.[][1]] ]
| map(add/length)

With the -c command-line option, this produces a stream of arrays, one array for each "feature". The stream begins:

[2.4206944444444445,48.724651111111115]
[2.407614,48.82250133333333]
...

Of course there are other alternatives but note that there is no need to use string interpolation to perform grouping, so there is usually no need for tr as your first version did.



来源:https://stackoverflow.com/questions/52467305/computing-the-center-of-gravity-of-a-geojson-polygon-using-jq

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!