-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathfiona_rtree_renderer.py
More file actions
71 lines (61 loc) · 2.6 KB
/
fiona_rtree_renderer.py
File metadata and controls
71 lines (61 loc) · 2.6 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
from rtree import index
from rtree import Rtree
from fiona import collection
from shapely.geometry import mapping, shape
from shapely.wkt import loads
from ogr_renderer import Extent, Request, CoordTransform, Grid
import json
class Renderer:
def __init__(self,grid,ctrans):
self.grid = grid
self.ctrans = ctrans
self.req = ctrans.request
def apply(self,ds_name,field_names=[]):
p = index.Property()
idx = index.Index(properties=p)
with collection(ds_name, "r") as source:
e = ctrans.extent
for feat in source.filter(bbox=(e.minx, e.miny, e.maxx, e.maxy)):
geom = shape(feat['geometry'])
attrs = feat['properties']
saved_attrs = {}
for field, val in attrs.iteritems():
if field in field_names:
saved_attrs[field] = val
# Break up multipolygons for more efficient index
if geom.type == "MultiPolygon":
for g in geom.geoms:
idx.insert(int(feat['id']), g.bounds, obj=(g, saved_attrs))
else:
idx.insert(int(feat['id']), geom.bounds, obj=(geom, saved_attrs))
for y in xrange(0,self.req.height,self.grid.resolution):
row = []
for x in xrange(0,self.req.width,self.grid.resolution):
found = False
minx,maxy = self.ctrans.backward(x,y)
maxx,miny = self.ctrans.backward(x+1,y+1)
wkt = 'POINT(%f %f)' \
% (minx + (maxx - minx)/2, miny + (maxy - miny)/2)
g = loads(wkt)
candidates = list(idx.intersection((minx,miny,maxx,maxy), objects=True))
for f in candidates:
geom, attrs = f.object
# See if the candidate geometry contains the center point of the cell
# In the interest of speed, we grab the first hit
if geom.contains(g):
row.append(f.id)
self.grid.feature_cache[f.id] = attrs
found = True
if not found:
row.append("")
self.grid.rows.append(row)
if __name__ == "__main__":
box = Extent(-140,0,-50,90)
tile = Request(256,256,box)
ctrans = CoordTransform(tile)
grid = Grid()
renderer = Renderer(grid,ctrans)
renderer.apply('data/ne_110m_admin_0_countries.shp',
field_names=['NAME_FORMA', 'POP_EST'])
utfgrid = grid.encode()
print json.dumps(utfgrid)