-
Notifications
You must be signed in to change notification settings - Fork 0
/
tools.py
147 lines (114 loc) · 4.98 KB
/
tools.py
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# -*- coding: utf-8 -*-
import geojson
# import shapely.wkt
from hashids import Hashids
from pydal.objects import Table
from py4web import Field
from geomet import wkt
import mercantile as mc
import h3
from .common import db
def geojsonFeature(id, geometry, properties):
return geojson.Feature(
geometry = geometry,
properties = properties,
id = id
)
def raise_error(err):
raise err
class PlanetTable(Table):
"""docstring for PlanetTable."""
def __init__(self, *args, **kwargs):
super(PlanetTable, self).__init__(*args, **kwargs)
self._set_encoder()
self._set_feature_co()
def _set_encoder(self):
self._extra = {'encoder': Hashids(min_length=1)}
self._extra["_decode"] = lambda encoded: self._extra['encoder'].decode(encoded) or \
raise_error(Exception('String expected, "{}" found'.format(encoded)))
self._extra["decode"] = lambda encoded: dict(zip(['src_id', 'id'], self._extra['encoder'].decode(encoded)))
self._extra["get_by_hash"] = lambda encoded: self(**self._extra["decode"](encoded))
# self._extra["fetch_info"] = lambda encoded: info(id=self._extra["_decode"](encoded)[1])
def _set_alias(self, alias, fieldname):
""" Sets an alias for the given field value """
setattr(self, alias, Field.Virtual(alias,
lambda row: row[self._tablename][fieldname]
))
def _set_hashid(self, fieldname, first, *ofields):
setattr(self, fieldname, Field.Virtual(fieldname,
lambda row: self._extra['encoder'].encode(
row[self._tablename][first],
*map(lambda ff: row[self._tablename][ff], ofields)
)
))
def _set_feat_properties(self, **kwargs):
def _props(row):
properties = dict(
row[self._tablename].properties or row[self._tablename].tags,
id = row[self._tablename].hashid,
# **{"_{}_".format(row[self._tablename].source_name): row[self._tablename].source_id}
)
properties.update({
k: row[self._tablename][v] if not callable(v) else v(row[self._tablename])\
for k,v in kwargs.items()})
return properties
setattr(self, 'feat_properties', Field.Virtual('feat_properties', _props))
def _set_geometry(self):
if 'geom' in self.fields and self['geom'].type=='geometry()':
self.feat_geometry = Field.Virtual('feat_geometry', lambda row: wkt.loads(row[self._tablename].geom))
def _set_feature_co(self):
self._set_hashid('hashid', 'src_id', 'id')
self._set_feat_properties()
self._set_geometry()
if 'geom' in self.fields and self['geom'].type=='geometry()':
self.feature = Field.Virtual('feature', lambda row: geojsonFeature(
geometry = row[self._tablename].feat_geometry,
properties = row[self._tablename].feat_properties,
id = row[self._tablename].hashid
))
def get_tile(lon, lat, zoom, classic=True):
if classic is True:
return mc.tile(lon, lat, zoom)
elif classic is False:
return h3.geo_to_h3(lat, lon, resolution=zoom)
# def foo(row, zoom, classic=True):
# import pdb; pdb.set_trace()
class PlanetPointTable(PlanetTable):
"""docstring for PlanetPointTable."""
def __init__(self, *args, **kwargs):
super(PlanetPointTable, self).__init__(*args, **kwargs)
self._set_tile()
def _set_tile(self):
self.tile = Field.Method(
'tile',
lambda row, zoom, classic=True: get_tile(
*wkt.loads(row[self._tablename].geom)["coordinates"],
zoom = zoom,
classic = classic
)
)
class PlanetGraphTable(PlanetTable):
"""docstring for PlanetGraphTable."""
def _set_encoder(self):
PlanetTable._set_encoder(self)
self._extra['node_encoder'] = db.points._extra['encoder']
def _set_node_hashid(self, fieldname, first, *ofields):
setattr(self, fieldname, Field.Virtual(fieldname,
lambda row: self._extra['node_encoder'].encode(
row[self._tablename][first],
*map(lambda ff: row[self._tablename][ff], ofields)
)
))
def _set_feature_co(self):
self._set_hashid('hashid', 'src_id', 'id')
self._set_node_hashid('shashid', 'src_id', 'sinfo_id')
self._set_node_hashid('thashid', 'src_id', 'tinfo_id')
# self._set_alias("shid", 'shashid')
# self._set_alias("thid", 'thashid')
self._set_feat_properties(weight=lambda row: round(row.len, 3))
if 'geom' in self.fields and self['geom'].type=='geometry()':
self.feature = Field.Virtual('feature', lambda row: geojson.Feature(
geometry = wkt.loads(row[self._tablename].geom),
properties = row[self._tablename].feat_properties,
id = row[self._tablename].hashid
))