| 1 |
import geojson |
|---|
| 2 |
from pyproj import Proj |
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
PROJ_900913 = """ |
|---|
| 6 |
+proj=merc +a=6378137 +b=6378137 |
|---|
| 7 |
+lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 |
|---|
| 8 |
+units=m +nadgrids=@null +no_defs |
|---|
| 9 |
""" |
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
class Transform(object): |
|---|
| 13 |
|
|---|
| 14 |
def __init__(self, proj_defn): |
|---|
| 15 |
self.proj = Proj(proj_defn) |
|---|
| 16 |
|
|---|
| 17 |
def __call__(self, ob, inverse=False, object_hook=None): |
|---|
| 18 |
"""Transform an object which provides the geo interface from |
|---|
| 19 |
geographic to projected coordinates. |
|---|
| 20 |
|
|---|
| 21 |
If the inverse keyword is True, pyproj computes the inverse transform. |
|---|
| 22 |
|
|---|
| 23 |
If an object_hook callable is provided (as in geojson), instances of |
|---|
| 24 |
a particular class will be returned. Otherwise instances of geojson |
|---|
| 25 |
geometry classes are returned. |
|---|
| 26 |
""" |
|---|
| 27 |
geo = getattr(ob, '__geo_interface__', ob) |
|---|
| 28 |
geo = geo.get('geometry', geo) |
|---|
| 29 |
constructor = object_hook or geojson.GeoJSON.to_instance |
|---|
| 30 |
return constructor(self.transform_geom(geo, inverse)) |
|---|
| 31 |
|
|---|
| 32 |
def transform_coords1(self, coords, inverse=False): |
|---|
| 33 |
x, y = self.proj(coords[0], coords[1], **dict(inverse=inverse)) |
|---|
| 34 |
return (x, y) |
|---|
| 35 |
|
|---|
| 36 |
def transform_coords2(self, coords, inverse=False): |
|---|
| 37 |
values = zip(*coords) |
|---|
| 38 |
xs, ys = self.proj(values[0], values[1], **dict(inverse=inverse)) |
|---|
| 39 |
return tuple(zip(xs, ys)) |
|---|
| 40 |
|
|---|
| 41 |
def transform_coords3(self, coords, inverse=False): |
|---|
| 42 |
return tuple([self.transform_coords2(r, inverse) for r in coords]) |
|---|
| 43 |
|
|---|
| 44 |
def transform_coords4(self, coords, inverse=False): |
|---|
| 45 |
return tuple([self.transform_coords3(p, inverse) for p in coords]) |
|---|
| 46 |
|
|---|
| 47 |
def transform_geom(self, geo, inverse=False): |
|---|
| 48 |
gtype = geo['type'] |
|---|
| 49 |
coords = geo['coordinates'] |
|---|
| 50 |
if gtype == 'Point': |
|---|
| 51 |
result = self.transform_coords1(coords, inverse) |
|---|
| 52 |
elif gtype in ['LineString', 'LinearRing', 'MultiPoint']: |
|---|
| 53 |
result = self.transform_coords2(coords, inverse) |
|---|
| 54 |
elif gtype in ['Polygon', 'MultiLineString']: |
|---|
| 55 |
result = self.transform_coords3(coords, inverse) |
|---|
| 56 |
elif gtype == 'MultiPolygon': |
|---|
| 57 |
result = self.transform_coords4(coords, inverse) |
|---|
| 58 |
else: |
|---|
| 59 |
raise NotImplemented, "No geometry collections in this version" |
|---|
| 60 |
return dict(type=gtype, coordinates=result) |
|---|