Объединить часть объекта geojson в другую и разделить на пары ключ-значение в Python - PullRequest
0 голосов
/ 03 апреля 2019

У меня есть следующие данные в формате JSON:

data = {
        "type": "FeatureCollection",
        "name": "entities",
        "features": [{
                "type": "Feature",
                "properties": {
                    "Layer": "0",
                    "SubClasses": "AcDbEntity:AcDbBlockReference",
                    "EntityHandle": "33C"
                },
                "geometry": {
                    "type": "LineString",
                    "coordinates": [
                        [128.300698763698563, 19.589569788550868],
                        [122.210459610233059, 19.589569886701838],
                        [91.721736710604787, 50.193073963419501],
                        [92.273710172523337, 50.74297719953902],
                        [84.75859656427339, 58.28638302549696],
                        [77.215190738315442, 50.771269417247012],
                        [77.767111309618613, 50.221418867368563],
                        [47.250149385217803, 19.589569788550868],
                        [44.193587348941939, 22.634667872682869],
                        [79.046846852783347, 57.619139235591419],
                        [79.046846852783347, 59.232600372409372],
                        [84.751660603974528, 64.916017788151933],
                        [90.413761870149756, 59.232600372409372],
                        [90.413761870149756, 57.619139235591419],
                        [128.300698763698563, 19.589569788550868]
                    ]
                }
            },
            {
                "type": "Feature",
                "properties": {
                    "Layer": "0",
                    "SubClasses": "AcDbEntity:AcDbMText",
                    "ExtendedEntity": "ACAD_MTEXT_COLUMN_INFO_BEGIN     75      2     79      0     76      1     78      0     48 8.650739891855252     49 12.5     50      1 0.0 ACAD_MTEXT_COLUMN_INFO_END",
                    "EntityHandle": "33C",
                    "Text": "HouseID: B6G31; Area: 143"
                },
                "geometry": {
                    "type": "Point",
                    "coordinates": [82.573226323750248, 61.543228505735186, 0.0]
                }
            },
            {
                "type": "Feature",
                "properties": {
                    "Layer": "0",
                    "SubClasses": "AcDbEntity:AcDbBlockReference",
                    "EntityHandle": "33D"
                },
                "geometry": {
                    "type": "LineString",
                    "coordinates": [
                        [74.682310358766699, 53.238171737765796],
                        [79.046846852783347, 57.619139235591419],
                        [79.046846852783347, 59.232600372409372],
                        [81.695660487894202, 61.8913860732074],
                        [75.420855001691947, 68.142657499885104],
                        [67.600779996399069, 60.293142300223842],
                        [74.682310358766699, 53.238171737765796]
                    ]
                }
            },
            {
                "type": "Feature",
                "properties": {
                    "Layer": "0",
                    "SubClasses": "AcDbEntity:AcDbMText",
                    "ExtendedEntity": "ACAD_MTEXT_COLUMN_INFO_BEGIN     75      2     79      0     76      1     78      0     48 8.650739891855252     49 12.5     50      1 0.0 ACAD_MTEXT_COLUMN_INFO_END",
                    "EntityHandle": "33D",
                    "Text": "HouseID: B622; Area: 31; Type: B"
                },
                "geometry": {
                    "type": "Point",
                    "coordinates": [72.482530938336538, 62.10442248906768, 0.0]
                }
            }
        ]
    }

Я хочу объединить ключ Point Text и значения в LineString на основе значений EntityHandle, а затем преобразоватьследующую часть "Text": "HouseID: B6G31; Area: 143" до "HouseID": "B6G31"; "Area": "143" и, наконец, удалите Point строк.Ожидаемый результат:

{
    "type": "FeatureCollection",
    "name": "entities",
    "features": [{
            "type": "Feature",
            "properties": {
                "Layer": "0",
                "SubClasses": "AcDbEntity:AcDbBlockReference",
                "EntityHandle": "33C",
                "HouseID": "B6G31",
                "Area": "143"
            },
            "geometry": {
                "type": "LineString",
                "coordinates": [
                    [128.300698763698563, 19.589569788550868],
                    [122.210459610233059, 19.589569886701838],
                    [91.721736710604787, 50.193073963419501],
                    [92.273710172523337, 50.74297719953902],
                    [84.75859656427339, 58.28638302549696],
                    [77.215190738315442, 50.771269417247012],
                    [77.767111309618613, 50.221418867368563],
                    [47.250149385217803, 19.589569788550868],
                    [44.193587348941939, 22.634667872682869],
                    [79.046846852783347, 57.619139235591419],
                    [79.046846852783347, 59.232600372409372],
                    [84.751660603974528, 64.916017788151933],
                    [90.413761870149756, 59.232600372409372],
                    [90.413761870149756, 57.619139235591419],
                    [128.300698763698563, 19.589569788550868]
                ]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "Layer": "0",
                "SubClasses": "AcDbEntity:AcDbBlockReference",
                "EntityHandle": "33D",
                "HouseID": "B622",
                "Area": "31",
                "Type": "B"
            },
            "geometry": {
                "type": "LineString",
                "coordinates": [
                    [74.682310358766699, 53.238171737765796],
                    [79.046846852783347, 57.619139235591419],
                    [79.046846852783347, 59.232600372409372],
                    [81.695660487894202, 61.8913860732074],
                    [75.420855001691947, 68.142657499885104],
                    [67.600779996399069, 60.293142300223842],
                    [74.682310358766699, 53.238171737765796]
                ]
            }
        }
    ]
}

Решение, безусловно, благодаря @dodopy из ссылки здесь Объединение части объекта geojson в другую в Python , я понял, чтобы объединить Pointи LineString получите следующий результат:

import json
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
print(data)
{
    'type': 'FeatureCollection',
    'name': 'entities',
    'features': [{
            'type': 'Feature',
            'properties': {
                'Layer': '0',
                'SubClasses': 'AcDbEntity:AcDbBlockReference',
                'EntityHandle': '33C',
                'Text': 'HouseID: B6G31; Area: 143'
            },
            'geometry': {
                'type': 'LineString',
                'coordinates': [
                    [128.30069876369856, 19.589569788550868],
                    [122.21045961023306, 19.589569886701838],
                    [91.72173671060479, 50.1930739634195],
                    [92.27371017252334, 50.74297719953902],
                    [84.75859656427339, 58.28638302549696],
                    [77.21519073831544, 50.77126941724701],
                    [77.76711130961861, 50.22141886736856],
                    [47.2501493852178, 19.589569788550868],
                    [44.19358734894194, 22.63466787268287],
                    [79.04684685278335, 57.61913923559142],
                    [79.04684685278335, 59.23260037240937],
                    [84.75166060397453, 64.91601778815193],
                    [90.41376187014976, 59.23260037240937],
                    [90.41376187014976, 57.61913923559142],
                    [128.30069876369856, 19.589569788550868]
                ]
            }
        },
        {
            'type': 'Feature',
            'properties': {
                'Layer': '0',
                'SubClasses': 'AcDbEntity:AcDbBlockReference',
                'EntityHandle': '33D',
                'Text': 'HouseID: B622; Area: 31; Type: B'
            },
            'geometry': {
                'type': 'LineString',
                'coordinates': [
                    [74.6823103587667, 53.238171737765796],
                    [79.04684685278335, 57.61913923559142],
                    [79.04684685278335, 59.23260037240937],
                    [81.6956604878942, 61.8913860732074],
                    [75.42085500169195, 68.1426574998851],
                    [67.60077999639907, 60.29314230022384],
                    [74.6823103587667, 53.238171737765796]
                ]
            }
        }
    ]
}

Возможно ли получить ожидаемый результат в Python?Спасибо.

1 Ответ

1 голос
/ 03 апреля 2019

Я просто перебрал словари и списки.

По сути, если ключ "Text" отсутствует, возьмите это EntitiyHandle и найдите найденные значения "Text", а затем разделите их. Затем просто включите это в элементы, у которых не было ключа "Text" (если это имеет смысл):

data = {
        "type": "FeatureCollection",
        "name": "entities",
        "features": [{
                "type": "Feature",
                "properties": {
                    "Layer": "0",
                    "SubClasses": "AcDbEntity:AcDbBlockReference",
                    "EntityHandle": "33C"
                },
                "geometry": {
                    "type": "LineString",
                    "coordinates": [
                        [128.300698763698563, 19.589569788550868],
                        [122.210459610233059, 19.589569886701838],
                        [91.721736710604787, 50.193073963419501],
                        [92.273710172523337, 50.74297719953902],
                        [84.75859656427339, 58.28638302549696],
                        [77.215190738315442, 50.771269417247012],
                        [77.767111309618613, 50.221418867368563],
                        [47.250149385217803, 19.589569788550868],
                        [44.193587348941939, 22.634667872682869],
                        [79.046846852783347, 57.619139235591419],
                        [79.046846852783347, 59.232600372409372],
                        [84.751660603974528, 64.916017788151933],
                        [90.413761870149756, 59.232600372409372],
                        [90.413761870149756, 57.619139235591419],
                        [128.300698763698563, 19.589569788550868]
                    ]
                }
            },
            {
                "type": "Feature",
                "properties": {
                    "Layer": "0",
                    "SubClasses": "AcDbEntity:AcDbMText",
                    "ExtendedEntity": "ACAD_MTEXT_COLUMN_INFO_BEGIN     75      2     79      0     76      1     78      0     48 8.650739891855252     49 12.5     50      1 0.0 ACAD_MTEXT_COLUMN_INFO_END",
                    "EntityHandle": "33C",
                    "Text": "HouseID: B6G31; Area: 143"
                },
                "geometry": {
                    "type": "Point",
                    "coordinates": [82.573226323750248, 61.543228505735186, 0.0]
                }
            },
            {
                "type": "Feature",
                "properties": {
                    "Layer": "0",
                    "SubClasses": "AcDbEntity:AcDbBlockReference",
                    "EntityHandle": "33D"
                },
                "geometry": {
                    "type": "LineString",
                    "coordinates": [
                        [74.682310358766699, 53.238171737765796],
                        [79.046846852783347, 57.619139235591419],
                        [79.046846852783347, 59.232600372409372],
                        [81.695660487894202, 61.8913860732074],
                        [75.420855001691947, 68.142657499885104],
                        [67.600779996399069, 60.293142300223842],
                        [74.682310358766699, 53.238171737765796]
                    ]
                }
            },
            {
                "type": "Feature",
                "properties": {
                    "Layer": "0",
                    "SubClasses": "AcDbEntity:AcDbMText",
                    "ExtendedEntity": "ACAD_MTEXT_COLUMN_INFO_BEGIN     75      2     79      0     76      1     78      0     48 8.650739891855252     49 12.5     50      1 0.0 ACAD_MTEXT_COLUMN_INFO_END",
                    "EntityHandle": "33D",
                    "Text": "HouseID: B622; Area: 31; Type: B"
                },
                "geometry": {
                    "type": "Point",
                    "coordinates": [72.482530938336538, 62.10442248906768, 0.0]
                }
            }
        ]
    }







temp_dict = {}
for each in data['features']:
    entity_handle = each['properties']['EntityHandle']
    if 'Text' not in each['properties']:
        continue
    else:
        #temp_dict[entity_handle] = each['properties']['Text']
        text = each['properties']['Text']
        text_split = text.split(';')
        temp_dict2 = {}
        for item in text_split:
            k,v = item.split(':')[0].strip(), item.split(':')[1].strip()
            temp_dict2[k] = v
        temp_dict[entity_handle] = temp_dict2



updated_data = {}
for k,v in data.items():
    if type(v) == list:
        updated_data[k] = []
    else:
        updated_data[k] = v



completed = []
for each in data['features']:
    temp_dict3 = {}
    entity_handle = each['properties']['EntityHandle']
    if 'Text' not in each['properties']:
        temp_dict3.update(each)
        temp_dict3['properties'].update(temp_dict[entity_handle])
        updated_data['features'].append(temp_dict3)
    else:
        continue
...