1

For geojson type file named data as follows:

{
    "type": "FeatureCollection",
    "name": "entities",
    "features": [{
            "type": "Feature",
            "properties": {
                "Layer": "0",
                "SubClasses": "AcDbEntity:AcDbPolyline",
                "EntityHandle": "1A0"
            },
            "geometry": {
                "type": "LineString",
                "coordinates": [
                    [3220.136443006845184, 3001.530372177397112],
                    [3847.34171007254281, 3000.86074447018018],
                    [3847.34171007254281, 2785.240077064262096],
                    [3260.34191304818205, 2785.240077064262096],
                    [3260.34191304818205, 2795.954148466309107]
                ]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "Layer": "0",
                "SubClasses": "AcDbEntity:AcDbPolyline",
                "EntityHandle": "1A4"
            },
            "geometry": {
                "type": "LineString",
                "coordinates": [
                    [3611.469650131302842, 2846.845982610575902],
                    [3695.231030111376185, 2846.845982610575902],
                    [3695.231030111376185, 2785.240077064262096],
                    [3611.469650131302842, 2785.240077064262096],
                    [3611.469650131302842, 2846.845982610575902]
                ]
            }
        }
    ]
}

I hope to realize the following manipulation to data:

  1. replace key EntityHandle with Name;
  2. replace EntityHandle's value from hex number with 'sf_001', 'sf_002', 'sf_003', etc;
  3. replace type's value LineString with Polygon;
  4. replace coordinates's two square brackets with three square brackets.

This is expected output:

{
    "type": "FeatureCollection",
    "name": "entities",
    "features": [{
            "type": "Feature",
            "properties": {
                "Layer": "0",
                "SubClasses": "AcDbEntity:AcDbPolyline",
                "Name": "sf_001"
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [ [
                    [3220.136443006845184, 3001.530372177397112],
                    [3847.34171007254281, 3000.86074447018018],
                    [3847.34171007254281, 2785.240077064262096],
                    [3260.34191304818205, 2785.240077064262096],
                    [3260.34191304818205, 2795.954148466309107]
                ] ]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "Layer": "0",
                "SubClasses": "AcDbEntity:AcDbPolyline",
                "Name": "sf_002"
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [ [
                    [3611.469650131302842, 2846.845982610575902],
                    [3695.231030111376185, 2846.845982610575902],
                    [3695.231030111376185, 2785.240077064262096],
                    [3611.469650131302842, 2785.240077064262096],
                    [3611.469650131302842, 2846.845982610575902]
                ] ]
            }
        }
    ]
}

I'm new in JSON file manipulation using Python. Please help me, thanks at advance.

import json
from pprint import pprint

with open('data.geojson') as f:
    data = json.load(f)

pprint(data)

for feature in data['features']:
    #print(feature)
    print(feature['properties']['EntityHandle'])

for feature in data['features']: 
    feature['properties']['EntityHandle'] = feature['properties']['Name'] #Rename `EntityHandle` to `Name`
    del feature['properties']['EntityHandle']

Result:

Traceback (most recent call last):

  File "<ipython-input-79-8b30b71fedf9>", line 2, in <module>
    feature['properties']['EntityHandle'] = feature['properties']['Name']

KeyError: 'Name'
andnik
  • 2,405
  • 2
  • 22
  • 33
ah bon
  • 9,293
  • 12
  • 65
  • 148
  • Have you tried anything? Consulting Google about how to replace a key inside a dictionary will get you 1/4 of the way to your answer in a heartbeat. While you have given a nice example of what you're working with, there is really nothing in here about what you tried. – TomMP Mar 28 '19 at 10:00
  • 1
    Also, since you're new to JSON files as you say: once you used the json library to load a file, it just becomes a regular dictionary data type. If you have worked with them before, you will find it easy to manipulate. – TomMP Mar 28 '19 at 10:03
  • 1
    Thanks for your comments. I'm trying and will update my question while I proceed. – ah bon Mar 28 '19 at 10:52
  • 1
    See if pydash helps. It has a few 'pick' 'get' 'rename' functionnalities that are interesting . – Born Tbe Wasted Mar 28 '19 at 10:53
  • Thanks. The problem for me here is this dictionary structure looks very complicated, especially for the part of replacement `EntityHandle`'s value from hex number with `'sf_001', 'sf_002', 'sf_003',` ... – ah bon Mar 28 '19 at 11:13

1 Answers1

6

Give this a shot:

You can rename a key by using:

dict['NewKey'] = dict.pop('OldKey')

And to replace a value, it's just as simple as setting the new vale equal to the specific key:

dict['Key'] = new_value

Full Code:

data =  {
    "type": "FeatureCollection",
    "name": "entities",
    "features": [{
            "type": "Feature",
            "properties": {
                "Layer": "0",
                "SubClasses": "AcDbEntity:AcDbPolyline",
                "EntityHandle": "1A0"
            },
            "geometry": {
                "type": "LineString",
                "coordinates": [
                    [3220.136443006845184, 3001.530372177397112],
                    [3847.34171007254281, 3000.86074447018018],
                    [3847.34171007254281, 2785.240077064262096],
                    [3260.34191304818205, 2785.240077064262096],
                    [3260.34191304818205, 2795.954148466309107]
                ]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "Layer": "0",
                "SubClasses": "AcDbEntity:AcDbPolyline",
                "EntityHandle": "1A4"
            },
            "geometry": {
                "type": "LineString",
                "coordinates": [
                    [3611.469650131302842, 2846.845982610575902],
                    [3695.231030111376185, 2846.845982610575902],
                    [3695.231030111376185, 2785.240077064262096],
                    [3611.469650131302842, 2785.240077064262096],
                    [3611.469650131302842, 2846.845982610575902]
                ]
            }
        }
    ]
}



sf_count = 0
for feature in data['features']: 
    feature['properties']['Name'] = feature['properties'].pop('EntityHandle') #Rename `EntityHandle` to `Name`

    sf_count += 1
    feature['properties']['Name'] = 'sf_%.3d' %sf_count # Replace hex with incrimental sf_xxx

    feature['geometry']['type'] = 'Polygon' # Replace `LineString` to `Polygon`

    feature['geometry']['coordinates'] = [[ each for each in feature['geometry']['coordinates'] ]]
chitown88
  • 27,527
  • 4
  • 30
  • 59
  • Thanks a lot, I appreciate your help. I have divided each coordinate by 1000 to make it smaller with following code, `num = 1000`, `feature['geometry']['coordinates'] = np.divide(feature['geometry']['coordinates'], num)` May I ask one more question: how can I calculate area percent of each polygon? – ah bon Mar 28 '19 at 15:06
  • Sorry, there are errors in result of my code above, `array()` part should be removed . – ah bon Mar 28 '19 at 15:22