def get_path(self, zoom, x, y): nw_lat, nw_lon = unproject_from_tilespace(x, y, zoom) se_lat, se_lon = unproject_from_tilespace(x+1, y+1, zoom) query_params = {'bbox':",".join(map(str,(nw_lon, se_lat, se_lon, nw_lat)))} query_params.update(self.wms_params) path = "%s?%s" % (self.url_template.path, urlencode(query_params)) return path
def application(environ, start_response): stderr = environ['wsgi.errors'] m = re.match(r'^/([^/]+)/(\d+)/(\d+)/(\d+)\.geojson$', environ['PATH_INFO']) assert m, environ['PATH_INFO'] layer_name = m.group(1) zoom = int(m.group(2)) x = int(m.group(3)) y = int(m.group(4)) stderr.write("%s tile (%d, %d) at zoom %d...\n" % (layer_name, x, y, zoom)) assert zoom <= 16 cursor, response_headers = dbopen(environ, "osm_map.sqlite") if cursor is None: start_response("304 Not Modified", response_headers) return [] p1 = unproject_from_tilespace(x, y, zoom) p2 = unproject_from_tilespace(x + 1.0, y + 1.0, zoom) small_bbox = 'BuildMBR(%f,%f,%f,%f,4326)' % (p1[1], p1[0], p2[1], p2[0]) p1 = unproject_from_tilespace(x - 0.05, y - 0.05, zoom) p2 = unproject_from_tilespace(x + 1.05, y + 1.05, zoom) large_bbox = 'BuildMBR(%f,%f,%f,%f,4326)' % (p1[1], p1[0], p2[1], p2[0]) if layer_name in map_layer_sets: layer_names = map_layer_sets[layer_name] geojson = {} for layer_name in layer_names: tile_geojson = get_tile(stderr, cursor, layer_name, small_bbox, large_bbox, zoom) if tile_geojson is not None: geojson[layer_name.replace("osm-vector-","")] = tile_geojson else: geojson = get_tile(stderr, cursor, layer_name, small_bbox, large_bbox, zoom) # Convert Python objects to JSON and compress out = io.BytesIO() with gzip.GzipFile(fileobj=out, mode='w') as fo: json.dump(geojson, fo) geojson = out.getvalue() start_response("200 OK", response_headers + [ ('Content-Type', 'application/json'), ('Content-Encoding', 'gzip'), ]) return [geojson]
def render_tile(self, x, y, zoom): self.top_left_pixel = (x, y) self.zoom = zoom self.width = 256 self.height = 256 self.lat, self.lon = unproject_from_tilespace(x + 0.5, y + 0.5, zoom) surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 256, 256) ctx = cairo.Context(surface) for layer in self.layers_ordered: layer.do_viewport() layer.do_draw(ctx) surface.flush() data = surface.get_data() if self.re_blank_surface.match(data): return None else: sio = StringIO.StringIO() surface.write_to_png(sio) return sio.getvalue()
def application(environ, start_response): stderr = environ['wsgi.errors'] m = re.match(r'^/(\d+)/(\d+)/(\d+)\.geojson$', environ['PATH_INFO']) assert m, environ['PATH_INFO'] zoom = int(m.group(1)) x = int(m.group(2)) y = int(m.group(3)) stderr.write("Parcel tile (%d, %d) at zoom %d...\n" % (x, y, zoom)) assert zoom <= 16 cursor, response_headers = dbopen(environ, "parcels.sqlite") if cursor is None: start_response("304 Not Modified", response_headers) return [] p1 = unproject_from_tilespace(x - 0.05, y - 0.05, zoom) p2 = unproject_from_tilespace(x + 1.05, y + 1.05, zoom) bbox = 'BuildMBR(%f,%f,%f,%f,4326)' % (p1[1], p1[0], p2[1], p2[0]) geometry = "Intersection(Geometry,{bbox})".format(bbox=bbox) if zoom < 16: geometry = "SimplifyPreserveTopology({geometry},{simplification})".format( geometry=geometry, simplification = 360.0 / (2.0 ** zoom) / 256.0 # one pixel ) else: stderr.write("Not simplified\n") query = """SELECT rowid as __id__, AsGeoJSON({geometry}) as __geometry__, house_number, street, centroid FROM parcels WHERE MBRIntersects({bbox}, Geometry) AND ROWID IN ( SELECT ROWID FROM SpatialIndex WHERE f_table_name = 'parcels' AND search_frame = {bbox} ) """.format(geometry=geometry, bbox=bbox) cursor.execute(query) features = [] for row in cursor: if row['__geometry__'] is None: continue row = dict(row) feature = { 'type': 'Feature', 'id': row.pop("__id__"), 'geometry': json.loads(row.pop("__geometry__")), 'properties': row, } features.append(feature) stderr.write("Found %d feature(s)\n" % len(features)) geojson = { 'type': 'FeatureCollection', 'features': features, } # Convert to JSON and compress out = io.BytesIO() with gzip.GzipFile(fileobj=out, mode='w') as fo: json.dump(geojson, fo) geojson = out.getvalue() start_response("200 OK", response_headers + [ ('Content-Type', 'application/json'), ('Content-Encoding', 'gzip'), ]) return [geojson]
def application(environ, start_response): stderr = environ['wsgi.errors'] m = re.match(r'^/(\d+)/(\d+)/(\d+)\.geojson$', environ['PATH_INFO']) assert m, environ['PATH_INFO'] zoom = int(m.group(1)) x = int(m.group(2)) y = int(m.group(3)) stderr.write("Parcel tile (%d, %d) at zoom %d...\n" % (x, y, zoom)) assert zoom <= 16 cursor, response_headers = dbopen(environ, "parcels.sqlite") if cursor is None: start_response("304 Not Modified", response_headers) return [] p1 = unproject_from_tilespace(x - 0.05, y - 0.05, zoom) p2 = unproject_from_tilespace(x + 1.05, y + 1.05, zoom) bbox = 'BuildMBR(%f,%f,%f,%f,4326)' % (p1[1], p1[0], p2[1], p2[0]) geometry = "Intersection(Geometry,{bbox})".format(bbox=bbox) if zoom < 16: geometry = "SimplifyPreserveTopology({geometry},{simplification})".format( geometry=geometry, simplification=360.0 / (2.0**zoom) / 256.0 # one pixel ) else: stderr.write("Not simplified\n") query = """SELECT rowid as __id__, AsGeoJSON({geometry}) as __geometry__, house_number, street, centroid FROM parcels WHERE MBRIntersects({bbox}, Geometry) AND ROWID IN ( SELECT ROWID FROM SpatialIndex WHERE f_table_name = 'parcels' AND search_frame = {bbox} ) """.format(geometry=geometry, bbox=bbox) cursor.execute(query) features = [] for row in cursor: if row['__geometry__'] is None: continue row = dict(row) feature = { 'type': 'Feature', 'id': row.pop("__id__"), 'geometry': json.loads(row.pop("__geometry__")), 'properties': row, } features.append(feature) stderr.write("Found %d feature(s)\n" % len(features)) geojson = { 'type': 'FeatureCollection', 'features': features, } # Convert to JSON and compress out = io.BytesIO() with gzip.GzipFile(fileobj=out, mode='w') as fo: json.dump(geojson, fo) geojson = out.getvalue() start_response( "200 OK", response_headers + [ ('Content-Type', 'application/json'), ('Content-Encoding', 'gzip'), ]) return [geojson]
def unproject_point(self, x, y): tile_x = self.top_left_pixel[0] + x / 256.0 tile_y = self.top_left_pixel[1] + y / 256.0 return Point(unproject_from_tilespace(tile_x, tile_y, self.zoom))