-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgeojson.py
More file actions
122 lines (105 loc) · 3.88 KB
/
Copy pathgeojson.py
File metadata and controls
122 lines (105 loc) · 3.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import os, arcpy, common
def pointJSON(point):
part = point.getPart()
return {u'type' : u'Point', u'coordinates' : [part.X, part.Y]}
def multiPointJSON(multipoint):
return {u'type' : u'MultiPoint', u'coordinates' : [[point.X, point.Y] for point in multipoint]}
def polylineJSON(polyline):
geom = [[[point.X, point.Y] for point in part] for part in polyline]
if len(geom) == 1:
return {u'type' : 'LineString', u'coordinates' : geom[0]}
else:
return {u'type' : 'MultiLineString', u'coordinates' : geom}
def polygonJSON(polygon):
geom = []
partI = 0
partN = polygon.partCount
while partI < partN:
partGeom = [[]]
part = polygon.getPart(partI)
point = part.next()
while point:
# common.message(point)
partGeom[-1].append([point.X, point.Y])
point = part.next()
if not point: # interior ring (hole)
partGeom.append([])
point = part.next()
if partGeom[-1] == []:
partGeom = partGeom[:-1]
geom.append(partGeom)
partI += 1
if len(geom) == 1:
return {u'type' : 'Polygon', u'coordinates' : geom[0]}
else:
return {u'type' : 'MultiPolygon', u'coordinates' : geom}
class JSONTransformer:
START = '{"type" : "FeatureCollection", "features" : ['
END = ']}'
JOINER = ','
def __init__(self, layer, fields=[], precision=None):
self.layer = layer
if not precision: precision = '2'
self.floatFormatter = (u'%i' if precision == '0' else u'%.{}f'.format(precision))
self.description = arcpy.Describe(self.layer)
if hasattr(self.description, 'shapeFieldName'):
self.shapeFld = self.description.shapeFieldName
self.getGeometry = {u'Point' : pointJSON, u'MultiPoint' : multiPointJSON, u'Polyline' : polylineJSON, u'Polygon' : polygonJSON}[self.description.shapeType]
else:
self.shapeFld = None
self.fields = fields
def getFeatures(self):
common.progress('opening layer')
count = common.count(self.layer)
cursor = arcpy.SearchCursor(self.layer)
prog = common.progressor('converting', count)
for row in cursor:
now = {u'type' : u'Feature', u'properties' : self.getProperties(row)}
if self.shapeFld is not None:
now[u'geometry'] = self.getGeometry(row.getValue(self.shapeFld))
yield now
prog.move()
prog.end()
def getProperties(self, row):
props = {}
for field in self.fields:
props[field] = row.getValue(field)
return props
def output(self, file, encoding='utf8'):
file.write(self.START)
start = True
for featDict in self.getFeatures():
if not start:
file.write(self.JOINER)
else:
start = False
file.write(self.toString(featDict).encode(encoding))
file.write(self.END)
# @staticmethod
# def toString(object):
# return json.dumps(object, separators=(',', ':')).replace("'", '"')
# obsolete methods (fail for large datasets)
def getDict(self):
return {u'type' : 'FeatureCollection', u'features' : list(self.getFeatures())}
def getString(self):
return self.toString(self.getDict())
def toString(self, object):
if isinstance(object, str):
return u'"' + object.decode('utf8') + u'"'
elif isinstance(object, unicode):
return u'"' + object + u'"'
elif isinstance(object, float):
return self.floatFormatter % object
elif isinstance(object, list):
return u'[' + u','.join([self.toString(sub) for sub in object]) + u']'
elif isinstance(object, dict):
return u'{' + u','.join([self.toString(key) + u':' + self.toString(value) for key, value in object.items()]) + u'}'
elif object is None:
return u'null'
else:
return unicode(str(object))
with common.runtool(4) as parameters:
layerName, target, fields, precision = parameters
transformer = JSONTransformer(layerName, fields.split(';'), precision=precision)
with open(target, 'w') as outfile:
transformer.output(outfile)