Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

The AsShape documentation provides examples that work very well.

However, I have been given what I believe to be valid GeoJSON that is a FeatureCollection of two polygons each with a Label.

It validates fine with the JSON Formatter & Validator but when I try AsShape on it, as per the code below, it throws an AssertionError on FeatureCollection.

I'm assuming that is because AsShape does not support FeatureCollections and so am wondering if there is another approach that I could use?

import arcpy

polyX2_string = {"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[151.669111722222,-28.8913181547568],[151.669712422222,-28.890733765868],[151.670252222222,-28.8896441436458],[151.670847433333,-28.8891966436458],[151.670976977778,-28.8865389769791],[151.670112977778,-28.8846608880903]]]},"properties":{"Label":"National Park"}},{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[151.711278388889,-28.8201784658692],[151.710854355556,-28.8192543325359],[151.7100674,-28.8187800769803],[151.709037344444,-28.8184233992026],[151.707838755556,-28.8182234992026],[151.705821266667,-28.8180901992026],[151.705597933333,-28.8194629992025],[151.705198088889,-28.8212781880914]]]},"properties":{"Label":"National Park"}}]}

polygon = arcpy.AsShape(polyX2_string)
share|improve this question
    
Well right off the bat, it won't work because a shape can only have one feature, although that one feature can be made up of multiple parts. Additionally, it looks like a FeatureCollection can contain dissimilar types of features, while a shapefile or feature class can only contain one type of feature. So you will need some additional logic to decompose the JSON object into individual features as well as match only the feature type supported by your feature class. –  blah238 Mar 24 '12 at 1:48
    
Thanks blah238 - I'll work with the developer who is writing the GeoJSON that I ingest, to see if the polygon(s) can be passed as polygons rather than FeatureCollections. –  PolyGeo Mar 26 '12 at 11:20
add comment

3 Answers

up vote 2 down vote accepted

I have not used the AsShape before. Looking at the samples they all seems to start at the "type": portion of the json. So, you should be able to loop through the json after it is loaded and get to that part. It should be a python dict that you can then just go through the key, value pairs and pull what you need. The code below has been run but you will most likely need to modify. Once you get to the geometry you can start filtering by type. That should then let you process the various shapes within the feature collection. No need to split them first just adjust the dictionary loop and add in some Error checks. Bang!

import json, arcpy

main_json_string = '{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[151.669111722222,-28.8913181547568],[151.669712422222,-28.890733765868],[151.670252222222,-28.8896441436458],[151.670847433333,-28.8891966436458],[151.670976977778,-28.8865389769791],[151.670112977778,-28.8846608880903]]]},"properties":{"Label":"National Park"}},{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[151.711278388889,-28.8201784658692],[151.710854355556,-28.8192543325359],[151.7100674,-28.8187800769803],[151.709037344444,-28.8184233992026],[151.707838755556,-28.8182234992026],[151.705821266667,-28.8180901992026],[151.705597933333,-28.8194629992025],[151.705198088889,-28.8212781880914]]]},"properties":{"Label":"National Park"}}]}'


jsonData = json.loads(main_json_string)

for key,value in jsonData.iteritems():
    if value == 'FeatureCollection': # skip the salad and get to the steak
        pass
    else:
        for i in value:                    
            try:
                for k,v in i.iteritems():
                    if k == 'geometry':
                        print v
                        polygon = arcpy.AsShape(v)
                        print "Made it this far with no errors"
                    else:
                        pass
            except:
                pass
share|improve this answer
add comment

arcpy.AsShape only accepts pure GeoJSON geometries (Polygon, PolyLine, Point) as defined by this spec, not Feature records.

share|improve this answer
add comment

I'm going to give theJones the points for Answer and Jason an upvote because both were helpful. I'd actually worked out a solution soon after asking the question which I had been intending to post after further refinement - I will do so now.

import arcpy,json

jsonGeometry_string = '{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[151.669111722222,-28.8913181547568],[151.669712422222,-28.890733765868],[151.670252222222,-28.8896441436458],[151.670847433333,-28.8891966436458],[151.670976977778,-28.8865389769791],[151.670112977778,-28.8846608880903]]]},"properties":{"Label":"National Park"}},{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[151.711278388889,-28.8201784658692],[151.710854355556,-28.8192543325359],[151.7100674,-28.8187800769803],[151.709037344444,-28.8184233992026],[151.707838755556,-28.8182234992026],[151.705821266667,-28.8180901992026],[151.705597933333,-28.8194629992025],[151.705198088889,-28.8212781880914]]]},"properties":{"Label":"National Park"}}]}'
jsonGeometry_object = json.loads(jsonGeometry_string)

testFolder = "C:\\Temp"
testGDBName = "PolyFromJSONtest.gdb"
testGDB = testFolder + "\\" + testGDBName
if arcpy.Exists(testGDB):
    arcpy.Delete_management(testGDB)
arcpy.CreateFileGDB_management(testFolder, testGDBName)

prjFile = "C:/Program Files/ArcGIS/Desktop10.0/Coordinate Systems/Geographic Coordinate Systems/Australia and New Zealand/Geocentric Datum of Australia 1994.prj"
sr = arcpy.SpatialReference(prjFile)

arcpy.CreateFeatureclass_management(testGDB, "PolyFromJSON", "POLYGON", spatial_reference=sr)
arcpy.AddField_management(testGDB + "\\PolyFromJSON", "ParkName", "TEXT", field_length=50)
arcpy.CopyFeatures_management(testGDB + "\\PolyFromJSON",testGDB + "\NewPolyNoValue")

for jsonFeat in jsonGeometry_object['features']:
    polygon = arcpy.AsShape(jsonFeat['geometry'])
    label_string = jsonFeat['properties']['Label']
    print label_string
    arcpy.CopyFeatures_management(testGDB + "\NewPolyNoValue",testGDB + "\\NewPolyWithValue")
    arcpy.Append_management([polygon], testGDB + "\\NewPolyWithValue", "NO_TEST")
    arcpy.CalculateField_management(testGDB + "\\NewPolyWithValue", "ParkName", "'" + label_string + "'","PYTHON")
    arcpy.AddMessage("Appending " + label_string + " polygon into " + testGDB + "\\PolyFromJSON")
    arcpy.Append_management([testGDB + "\\NewPolyWithValue"], testGDB + "\\PolyFromJSON", "NO_TEST")
    arcpy.Delete_management(testGDB + "\\NewPolyWithValue")

arcpy.Delete_management(testGDB + "\NewPolyNoValue")
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.