Skip to content

Commit

Permalink
Moved Vector provider into a new submodule to better isolate Arc-spec…
Browse files Browse the repository at this point in the history
…ific parts
  • Loading branch information
Michal Migurski committed Apr 2, 2011
1 parent 2cafaaf commit 2d5cd5a
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 68 deletions.
1 change: 1 addition & 0 deletions Makefile
Expand Up @@ -55,6 +55,7 @@ doc:
pydoc -w TileStache.Caches
pydoc -w TileStache.Config
pydoc -w TileStache.Vector
pydoc -w TileStache.Vector.Arc
pydoc -w TileStache.Geography
pydoc -w TileStache.Providers
pydoc -w TileStache.Goodies
Expand Down
68 changes: 68 additions & 0 deletions TileStache/Vector/Arc.py
@@ -0,0 +1,68 @@
""" Arc-specific Vector provider helpers.
"""
from TileStache.Core import KnownUnknown

geometry_types = {
'Point': 'esriGeometryPoint',
'LineString': 'esriGeometryPolyline',
'Polygon': 'esriGeometryPolygon',
'MultiPoint': 'esriGeometryMultipoint',
'MultiLineString': 'esriGeometryPolyline',
'MultiPolygon': 'esriGeometryPolygon'
}

def reserialize_to_arc(content):
""" Convert from "geo" (GeoJSON) to ESRI's GeoServices REST serialization.
Much of this cribbed from sample server queries and page 191+ of:
http://www.esri.com/library/whitepapers/pdfs/geoservices-rest-spec.pdf
"""
found_geometry_types = set([feat['geometry']['type'] for feat in content['features']])
found_geometry_types = set([geometry_types.get(type) for type in found_geometry_types])

if len(found_geometry_types) > 1:
raise KnownUnknown('Arc serialization needs a single geometry type, not ' + ', '.join(found_geometry_types))

response = {'spatialReference': {'wkid': 4326}, 'features': []}

if 'wkid' in content['crs']:
response['spatialReference'] = {'wkid': content['crs']['wkid']}

elif 'wkt' in content['crs']:
response['spatialReference'] = {'wkt': content['crs']['wkt']}

for feature in content['features']:
geometry = feature['geometry']

if geometry['type'] == 'Point':
x, y = geometry['coordinates']
arc_geometry = {'x': x, 'y': y}

elif geometry['type'] == 'LineString':
path = geometry['coordinates']
arc_geometry = {'paths': [path]}

elif geometry['type'] == 'Polygon':
rings = geometry['coordinates']
arc_geometry = {'rings': rings}

elif geometry['type'] == 'MultiPoint':
points = geometry['coordinates']
arc_geometry = {'points': points}

elif geometry['type'] == 'MultiLineString':
paths = geometry['coordinates']
arc_geometry = {'paths': paths}

elif geometry['type'] == 'MultiPolygon':
rings = reduce(add, geometry['coordinates'])
arc_geometry = {'rings': rings}

else:
raise Exception(geometry['type'])

arc_feature = {'attributes': feature['properties'], 'geometry': arc_geometry}
response['geometryType'] = geometry_types[geometry['type']]
response['features'].append(arc_feature)

return response
72 changes: 4 additions & 68 deletions TileStache/Vector.py → TileStache/Vector/__init__.py
Expand Up @@ -151,8 +151,9 @@
# At least we'll be able to build the documentation.
pass

from Core import KnownUnknown
from Geography import getProjectionByName
from TileStache.Core import KnownUnknown
from TileStache.Geography import getProjectionByName
from Arc import reserialize_to_arc

class VectorResponse:
""" Wrapper class for Vector response that makes it behave like a PIL.Image object.
Expand Down Expand Up @@ -190,7 +191,7 @@ def save(self, out, format):
del content['crs']

elif format in ('ArcJSON', 'ArcBSON', 'ArcAMF'):
content = _reserialize_to_arc(self.content)
content = reserialize_to_arc(self.content)

else:
raise KnownUnknown('Vector response only saves .geojson, .arcjson, .geobson, .arcbson, .geoamf, .arcamf and .wkt tiles, not "%s"' % format)
Expand Down Expand Up @@ -231,71 +232,6 @@ def _sref_4326():

return sref

def _reserialize_to_arc(content):
""" Convert from "geo" (GeoJSON) to ESRI's GeoServices REST serialization.
Much of this cribbed from sample server queries and page 191+ of:
http://www.esri.com/library/whitepapers/pdfs/geoservices-rest-spec.pdf
"""
arc_geometry_types = {
'Point': 'esriGeometryPoint',
'LineString': 'esriGeometryPolyline',
'Polygon': 'esriGeometryPolygon',
'MultiPoint': 'esriGeometryMultipoint',
'MultiLineString': 'esriGeometryPolyline',
'MultiPolygon': 'esriGeometryPolygon'
}

found_geometry_types = set([feat['geometry']['type'] for feat in content['features']])
found_geometry_types = set([arc_geometry_types.get(type) for type in found_geometry_types])

if len(found_geometry_types) > 1:
raise KnownUnknown('Arc serialization needs a single geometry type, not ' + ', '.join(found_geometry_types))

response = {'spatialReference': {'wkid': 4326}, 'features': []}

if 'wkid' in content['crs']:
response['spatialReference'] = {'wkid': content['crs']['wkid']}

elif 'wkt' in content['crs']:
response['spatialReference'] = {'wkt': content['crs']['wkt']}

for feature in content['features']:
geometry = feature['geometry']

if geometry['type'] == 'Point':
x, y = geometry['coordinates']
arc_geometry = {'x': x, 'y': y}

elif geometry['type'] == 'LineString':
path = geometry['coordinates']
arc_geometry = {'paths': [path]}

elif geometry['type'] == 'Polygon':
rings = geometry['coordinates']
arc_geometry = {'rings': rings}

elif geometry['type'] == 'MultiPoint':
points = geometry['coordinates']
arc_geometry = {'points': points}

elif geometry['type'] == 'MultiLineString':
paths = geometry['coordinates']
arc_geometry = {'paths': paths}

elif geometry['type'] == 'MultiPolygon':
rings = reduce(add, geometry['coordinates'])
arc_geometry = {'rings': rings}

else:
raise Exception(geometry['type'])

arc_feature = {'attributes': feature['properties'], 'geometry': arc_geometry}
response['geometryType'] = arc_geometry_types[geometry['type']]
response['features'].append(arc_feature)

return response

def _tile_perimeter(coord, projection):
""" Get a tile's outer edge for a coordinate and a projection.
Expand Down

0 comments on commit 2d5cd5a

Please sign in to comment.