I'm trying to make a script that converts the GeoJson format into a shapefile. For the most part, the script in complete, but I'm having an odd issue with the output polygon.
The JSON geometry has a large number of vertices, but ArcMap seem to be GREATLY simplifying the output polygon when arcpy.Polygon(arcpy.Array(point, point, point ...)) happens.
The script I'm using is posted below. Though note, I left out many of the not relevant parts.
The inputs and outputs have been hardcoded for this example, but eventually it will end up as a Python Toolbox
For testing purposes, below is the JSON file I was trying to convert in this example:
Any help is appreciated,
Thanks!
Matt
The JSON geometry has a large number of vertices, but ArcMap seem to be GREATLY simplifying the output polygon when arcpy.Polygon(arcpy.Array(point, point, point ...)) happens.
The script I'm using is posted below. Though note, I left out many of the not relevant parts.
Code:
from collections import OrderedDict
import arcpy, json, os
arcpy.env.overwriteOutput = True
def createPolygon(data):
"""
This function receives a python dictionary representing the JSON array and its geometry
type. It will create a feature class of that geometry type and add in the features geometry
and attributes (if any).
"""
# Create feature class and define as WGS84
outFC = arcpy.CreateFeatureclass_management(outLocation,outName,"POLYGON")
arcpy.DefineProjection_management(outFC, coordinateSystem)
features = data["features"]
# Get a list of fields and add them to the feature class
fields = [key for key, value in features[0]["properties"].iteritems()]
if len(fields) != 0:
# dummyField is used because ArcMap requires at least one non-required field.
arcpy.AddField_management(outFC,"dummyField","TEXT")
arcpy.DeleteField_management(outFC,"Id")
for field in fields:
arcpy.AddField_management(outFC,field,"TEXT")
arcpy.DeleteField_management(outFC,"dummyField")
# Create search cursor
cursor = arcpy.da.InsertCursor(outFC, ["SHAPE@"] + fields)
#Create Arcpy Array to add Polygon verticies too.
array = arcpy.Array()
# Building Polygon
n = 0
for feature in features:
n += 1
for geom in feature["geometry"]["coordinates"]:
for coords in geom:
# Adding verticies to array
array.add(arcpy.Point( float(coords[0]), float(coords[1]) ))
# Get attributes for insert cursor fields
attributes = [attr for key, attr in feature["properties"].iteritems()]
# Some debugging prints
print len(array) # this reads 150 arcpy.Point objects
print arcpy.Polygon(array).pointCount # This only reads 15 points, none of which are the original points. Somehow ArcMap is GREATLY simplifyig this geometry.
cursor.insertRow([arcpy.Polygon(array)] + attributes)
array.removeAll()
del cursor
jsonFileName = "inputjsonfile.json"
shpOutput = "C:\Path\To\Output\Location\polygon.shp"
outLocation = os.path.dirname(shpOutput)
outName = os.path.basename(shpOutput)
coordinateSystem = arcpy.SpatialReference(4326)
with open(jsonFileName,"r") as json_file:
data = json.load(json_file, object_pairs_hook=OrderedDict)
# Get geometry type
geomType = data["features"][0]["geometry"]["type"]
if geomType == "Polygon":
createPolygon(data)
For testing purposes, below is the JSON file I was trying to convert in this example:
Code:
{"type": "FeatureCollection", "features": [{"type": "Feature", "properties": {"Id": "0", "NAME": "Untitled Polygon", "DESCR": " ", "FOLDER": " "}, "geometry": {"bbox": [-105.6266922454426, 33.309856365277824, -105.61766863755298, 33.31951402483418], "coordinates": [[["-105.623511", "33.317474"], ["-105.623508", "33.317525"], ["-105.623477", "33.317550"], ["-105.623410", "33.317651"], ["-105.623255", "33.317725"], ["-105.623129", "33.317825"], ["-105.623035", "33.317875"], ["-105.622915", "33.317873"], ["-105.622794", "33.317871"], ["-105.622647", "33.317792"], ["-105.622592", "33.317715"], ["-105.622505", "33.317612"], ["-105.622352", "33.317536"], ["-105.622136", "33.317434"], ["-105.622015", "33.317357"], ["-105.621831", "33.317304"], ["-105.621673", "33.317253"], ["-105.621551", "33.317226"], ["-105.621368", "33.317174"], ["-105.621337", "33.317173"], ["-105.621242", "33.317223"], ["-105.621115", "33.317298"], ["-105.621108", "33.317450"], ["-105.621133", "33.317578"], ["-105.621186", "33.317732"], ["-105.621241", "33.317861"], ["-105.621356", "33.318016"], ["-105.621381", "33.318119"], ["-105.621464", "33.318275"], ["-105.621482", "33.318507"], ["-105.621507", "33.318610"], ["-105.621497", "33.318791"], ["-105.621424", "33.318972"], ["-105.621257", "33.319179"], ["-105.621129", "33.319230"], ["-105.620967", "33.319334"], ["-105.620837", "33.319411"], ["-105.620739", "33.319489"], ["-105.620644", "33.319514"], ["-105.620457", "33.319512"], ["-105.620182", "33.319507"], ["-105.619851", "33.319423"], ["-105.619417", "33.319278"], ["-105.619082", "33.319195"], ["-105.618724", "33.319046"], ["-105.618416", "33.318900"], ["-105.618238", "33.318741"], ["-105.618051", "33.318500"], ["-105.617920", "33.318313"], ["-105.617896", "33.318209"], ["-105.617900", "33.318081"], ["-105.617877", "33.317926"], ["-105.617718", "33.317613"], ["-105.617669", "33.317381"], ["-105.617673", "33.317152"], ["-105.617674", "33.316846"], ["-105.617685", "33.316565"], ["-105.617703", "33.316411"], ["-105.617751", "33.316283"], ["-105.617761", "33.316181"], ["-105.617843", "33.315979"], ["-105.617887", "33.315878"], ["-105.617963", "33.315777"], ["-105.618075", "33.315652"], ["-105.618192", "33.315553"], ["-105.618349", "33.315406"], ["-105.618570", "33.315260"], ["-105.618872", "33.315167"], ["-105.619245", "33.315051"], ["-105.619605", "33.314985"], ["-105.619946", "33.314869"], ["-105.620061", "33.314845"], ["-105.620328", "33.314726"], ["-105.620592", "33.314631"], ["-105.620778", "33.314487"], ["-105.621017", "33.314367"], ["-105.621149", "33.314248"], ["-105.621169", "33.314104"], ["-105.621163", "33.313937"], ["-105.621128", "33.313771"], ["-105.621072", "33.313558"], ["-105.620928", "33.313370"], ["-105.620776", "33.313155"], ["-105.620615", "33.312986"], ["-105.620475", "33.312766"], ["-105.620310", "33.312694"], ["-105.620201", "33.312646"], ["-105.620090", "33.312573"], ["-105.619838", "33.312450"], ["-105.619617", "33.312304"], ["-105.619412", "33.312105"], ["-105.619183", "33.311882"], ["-105.619016", "33.311614"], ["-105.618821", "33.311273"], ["-105.618801", "33.311131"], ["-105.618895", "33.310834"], ["-105.619041", "33.310570"], ["-105.619432", "33.310313"], ["-105.619758", "33.310103"], ["-105.620176", "33.309952"], ["-105.620624", "33.309856"], ["-105.621002", "33.309897"], ["-105.621464", "33.309992"], ["-105.621709", "33.310086"], ["-105.621857", "33.310213"], ["-105.621952", "33.310367"], ["-105.621971", "33.310478"], ["-105.622093", "33.310607"], ["-105.622246", "33.310834"], ["-105.622495", "33.311170"], ["-105.622773", "33.311533"], ["-105.622925", "33.311762"], ["-105.623194", "33.312341"], ["-105.623289", "33.312598"], ["-105.623422", "33.312690"], ["-105.623501", "33.312759"], ["-105.623716", "33.312825"], ["-105.623853", "33.312845"], ["-105.623964", "33.312868"], ["-105.624024", "33.312869"], ["-105.624166", "33.312943"], ["-105.624244", "33.313062"], ["-105.624417", "33.313212"], ["-105.624569", "33.313244"], ["-105.624833", "33.313324"], ["-105.625213", "33.313455"], ["-105.625559", "33.313582"], ["-105.625844", "33.313705"], ["-105.625987", "33.313779"], ["-105.626188", "33.313878"], ["-105.626360", "33.313976"], ["-105.626472", "33.314123"], ["-105.626612", "33.314319"], ["-105.626692", "33.314538"], ["-105.626684", "33.314782"], ["-105.626677", "33.315003"], ["-105.626641", "33.315224"], ["-105.626548", "33.315396"], ["-105.626513", "33.315569"], ["-105.626420", "33.315741"], ["-105.625983", "33.316182"], ["-105.625570", "33.316456"], ["-105.625347", "33.316607"], ["-105.625094", "33.316757"], ["-105.624817", "33.316904"], ["-105.624307", "33.317195"], ["-105.624008", "33.317363"], ["-105.623802", "33.317433"], ["-105.623655", "33.317479"], ["-105.623511", "33.317474"]]], "type": "Polygon"}}]}
Thanks!
Matt