用四舍五入坐标在Python中序列化GeoJSON

2024-06-29 01:10:44 发布

您现在位置:Python中文网/ 问答频道 /正文

我想用Python序列化GeoJSON FeatureCollections,但其坐标精度有限

例如,这里有一个FeatureCollection(在Python中表示为dictlist):

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "name": "Liberty Island",
        "area_sqm": 24950.40123456,
        "established": 1875,
        "height_ft": 305
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [ -74.04715418815613, 40.690994683044906 ],
            [ -74.04499769210815, 40.68873311507798 ],
            [ -74.04354929924011, 40.689676800252016 ],
            [ -74.04715418815613, 40.690994683044906 ]
          ]
        ]
      }
    }
  ]
}

我可以使用json.dumps将其序列化:

print(json.dumps(fc))

这将打印出JSON:

{"type": "FeatureCollection", "features": [{"type": "Feature", "properties": {"name": "Liberty Island", "area_sqm": 24950.40123456, "established": 1875, "height_ft": 305}, "geometry": {"type": "Polygon", "coordinates": [[[-74.04715418815613, 40.690994683044906], [-74.04499769210815, 40.68873311507798], [-74.04354929924011, 40.689676800252016], [-74.04715418815613, 40.690994683044906]]]}}]}

那些坐标太精确了。根据维基百科,7 digits is ~cm precision,这应该足够好了。我得到的是~纳米精度

我想序列化GeoJSON FeatureCollection,其坐标精度仅为7位。请注意,我想对properties中的所有内容使用Python的默认序列化:因为其中的值可以是任何内容,所以我无法对精度是否足够做出任何通用声明

我想要的输出是这样的:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "name": "Liberty Island",
        "area_sqm": 24950.40123456,
        "established": 1875,
        "height_ft": 305
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [ -74.0471541, 40.6909946 ],
            [ -74.0449976, 40.6887331 ],
            [ -74.0435492, 40.6896768 ],
            [ -74.0471541, 40.6909946 ]
          ]
        ]
      }
    }
  ]
}

Tags: name序列化type精度areapropertiesfeaturefeaturecollection
1条回答
网友
1楼 · 发布于 2024-06-29 01:10:44

我不确定您想要的是什么样的序列化,但是当涉及到FeatureCollection简化时,这应该让您开始:

import json
from copy import copy


def simplify_geometries(feat_collection):
    new_coll = copy(feat_collection)
    old_features = new_coll['features']
    new_features = []

    for feature in old_features:
        geometry = feature['geometry']
        coords = shorten_arr(geometry['coordinates'])
        geometry['coordinates'] = coords

        new_features.append(feature)

    new_coll['features'] = new_features
    return json.dumps(new_coll)


print(simplify_geometries(
    json.loads('{"type": "FeatureCollection",...')
))

其中shorten_arr是一个平凡的递归:

def shorten_arr(arr, dec_places=7):
    if not isinstance(arr, list):
        return round(arr, dec_places)

    to_ret = []
    for n in arr:
        if isinstance(n, list):
            n = shorten_arr(n, dec_places)
        to_ret.append(shorten_arr(n, dec_places))
    return to_ret

相关问题 更多 >