在Python中将geojson对象的一部分合并到另一个对象中

时间:2019-03-29 06:20:12

标签: python json dictionary geojson

编辑:我正在尝试在Python中操作JSON文件。在我的数据中,某些多边形具有多个相关信息:坐标(LineString面积百分比面积TextArea Point),我想将它们组合到单个JSON对象中。例如,来自文件的数据如下:

data = {
        "type": "FeatureCollection",
        "name": "entities",
        "features": [{
                "type": "Feature",
                "properties": {
                    "Layer": "0",
                    "SubClasses": "AcDbEntity:AcDbBlockReference",
                    "EntityHandle": "2F1"
                },
                "geometry": {
                    "type": "LineString",
                    "coordinates": [
                        [61.971069681118479, 36.504485105673659],
                        [46.471068755199667, 36.504485105673659],
                        [46.471068755199667, 35.954489281866685],
                        [44.371068755199758, 35.954489281866685],
                        [44.371068755199758, 36.10448936390457],
                        [43.371069617387093, 36.104489150107824],
                        [43.371069617387093, 23.904496401184584],
                        [48.172716774891342, 23.904496401184584],
                        [48.171892994728751, 17.404489374370311],
                        [61.17106949647404, 17.404489281863786],
                        [61.17106949647404, 19.404489281863786],
                        [61.971069689453991, 19.404489282256687],
                        [61.971069681118479, 36.504485105673659]
                    ]
                }
            },
            {
                "type": "Feature",
                "properties": {
                    "Layer": "0",
                    "SubClasses": "AcDbEntity:AcDbMText",
                    "EntityHandle": "2F1",
                    "Text": "6%"
                },
                "geometry": {
                    "type": "Point",
                    "coordinates": [49.745686139884583, 28.11445704760262, 0.0]
                }
            },
            {
                "type": "Feature",
                "properties": {
                    "Layer": "0",
                    "SubClasses": "AcDbEntity:AcDbMText",
                    "EntityHandle": "2F1",
                    "Area": "100"
                },
                "geometry": {
                    "type": "Point",
                    "coordinates": [50.216857362443989, 63.981197759829229, 0.0]
                }
            },
            {
                "type": "Feature",
                "properties": {
                    "Layer": "0",
                    "SubClasses": "AcDbEntity:AcDbBlockReference",
                    "EntityHandle": "2F7"
                },
                "geometry": {
                    "type": "LineString",
                    "coordinates": [
                        [62.37106968111857, 36.504489398648715],
                        [62.371069689452725, 19.404489281863786],
                        [63.171069496474047, 19.404489281863786],
                        [63.171069496474047, 17.404489281863786],
                        [77.921070051947027, 17.404489281863786],
                        [77.921070051947027, 19.504489281855054],
                        [78.671070051947027, 19.504489281855054],
                        [78.671070051897914, 36.504485105717322],
                        [62.37106968111857, 36.504489398648715]
                    ]
                }
            },
            {
                "type": "Feature",
                "properties": {
                    "Layer": "0",
                    "SubClasses": "AcDbEntity:AcDbMText",
                    "EntityHandle": "2F7",
                    "Text": "5.8%"
                },
                "geometry": {
                    "type": "Point",
                    "coordinates": [67.27548061311245, 28.11445704760262, 0.0]
                }
            }
        ]
    }

我想基于Point的值将Text的{​​{1}}和Area键和值组合到LineString,并删除{{ 1}}行。预期的输出是:

EntityHandle

是否可以在Python上面获得结果?谢谢。

更新的解决方案,感谢@dodopy:

Point

但是我得到一个错误:

    {
        "type": "FeatureCollection",
        "name": "entities",
        "features": [{
                "type": "Feature",
                "properties": {
                    "Layer": "0",
                    "SubClasses": "AcDbEntity:AcDbBlockReference",
                    "EntityHandle": "2F1",
                    "Text": "6%",
                    "Area": "100"
                },
                "geometry": {
                    "type": "LineString",
                    "coordinates": [
                        [61.971069681118479, 36.504485105673659],
                        [46.471068755199667, 36.504485105673659],
                        [46.471068755199667, 35.954489281866685],
                        [44.371068755199758, 35.954489281866685],
                        [44.371068755199758, 36.10448936390457],
                        [43.371069617387093, 36.104489150107824],
                        [43.371069617387093, 23.904496401184584],
                        [48.172716774891342, 23.904496401184584],
                        [48.171892994728751, 17.404489374370311],
                        [61.17106949647404, 17.404489281863786],
                        [61.17106949647404, 19.404489281863786],
                        [61.971069689453991, 19.404489282256687],
                        [61.971069681118479, 36.504485105673659]
                    ]
                }
            },
            {
                "type": "Feature",
                "properties": {
                    "Layer": "0",
                    "SubClasses": "AcDbEntity:AcDbBlockReference",
                    "EntityHandle": "2F7",
                    "Text": "5.8%"
                },
                "geometry": {
                    "type": "LineString",
                    "coordinates": [
                        [62.37106968111857, 36.504489398648715],
                        [62.371069689452725, 19.404489281863786],
                        [63.171069496474047, 19.404489281863786],
                        [63.171069496474047, 17.404489281863786],
                        [77.921070051947027, 17.404489281863786],
                        [77.921070051947027, 19.504489281855054],
                        [78.671070051947027, 19.504489281855054],
                        [78.671070051897914, 36.504485105717322],
                        [62.37106968111857, 36.504489398648715]
                    ]
                }
            }
        ]
    }

2 个答案:

答案 0 :(得分:2)

是的,可以在python中获得结果。它只需要将json数据存储到我们可以在python中使用的数据结构中,然后编写一种算法即可将具有相同实体类型的特征组合在一起。我写了一个脚本来做到这一点以及评论。该程序从Point功能中提取文本属性,并将其放入LineString功能的属性中。然后,我们实质上丢弃了Point。 顺便说一句,您的JSON数据“之前”应该有一个逗号结尾。 使用Python 3.7.0:

import json
import collections


def main():
    with open('before_data.json') as f:
        before_data = json.load(f)  # makes a python dict from the json file and stores in before
        features = before_data['features']  # list of features
        # loop through features, construct dictionary of entity handle mapped to point texts
        point_entities = collections.defaultdict()  # to avoid 'if key not in' pattern
        for feature in features:
            entity_handle = feature['properties']['EntityHandle']
            # only append points
            if feature['geometry']['type'] == 'Point':
                point_entities[entity_handle] = feature['properties']['Text']
        merged_features = []
        for feature in features:
            if feature['geometry']['type'] == 'LineString':
                entity_handle = feature['properties']['EntityHandle']
                text_percent = point_entities[entity_handle]
                feature['properties']['Text'] = text_percent
                merged_features.append(feature)
        # print(json.dumps(before_data, indent=4))
        result = before_data
        result['features'] = merged_features
    # compare with your expected output
    with open('after_data.json') as f:
        after_data = json.load(f)
        print(result == after_data)  # returns True
    # finally, write your result to a file
    with open('result.json', 'w') as output_file:
        json.dump(result, output_file)


if __name__ == '__main__':
    main()

答案 1 :(得分:1)

像这样的例子:

import json
data = json.loads(json_data)
features = data["features"]
point_handle_text = {
    i["properties"]["EntityHandle"]: i["properties"]["Text"]
    for i in features
    if i["geometry"]["type"] == "Point"
}
combine_features = []
for i in features:
    if i["geometry"]["type"] == "LineString":
        i["properties"]["Text"] = point_handle_text.get(i["properties"]["EntityHandle"])
        combine_features.append(i)
data["features"] = combine_features
json_data = json.dumps(data)