编辑:我试图在Python中操纵JSON文件。在我的数据中,一些多边形有多个相关信息:坐标(LineString
)和面积百分比和面积(Text
中的Area
和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
的Area
和LineString
键和值组合到EntityHandle
,并且还删除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]
]
}
}
]
}
是否可以在Python中获得上述结果?谢谢。
更新的解决方案,感谢@dodopy:
import json
features = data["features"]
point_handle_text = {
i["properties"]["EntityHandle"]: i["properties"]["Text"]
for i in features
if i["geometry"]["type"] == "Point"
}
point_handle_area = {
i["properties"]["EntityHandle"]: i["properties"]["Area"]
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
combine_features = []
for i in features:
if i["geometry"]["type"] == "LineString":
i["properties"]["Area"] = point_handle_area.get(i["properties"]["EntityHandle"])
combine_features.append(i)
data["features"] = combine_features
with open('test.geojson', 'w+') as f:
json.dump(data, f, indent=2)
但是我收到一个错误:
Traceback (most recent call last):
File "<ipython-input-131-d132c8854a9c>", line 6, in <module>
for i in features
File "<ipython-input-131-d132c8854a9c>", line 7, in <dictcomp>
if i["geometry"]["type"] == "Point"
KeyError: 'Text'
像这样的例子:
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)
是的,可以在python中获得结果。它只需要将json数据存储到我们可以在python中使用的数据结构中,然后编写一个算法来组合具有相同实体类型的功能。我写了一个脚本来做这个,以及评论。该程序从Point
特征中提取text属性,并将其放入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()