def query_building_elms(way): debug('Building elements of ' + str(way['id'])) result = api.query("""way({}); out geom; >; out body;""".format(way['id'])) points = [(float(result.get_node(n).lon), float(result.get_node(n).lat)) for n in way['nd']] shape = Polygon(points).envelope result = api.query(""" way({}); node(around:5) -> .na; ( node.na[shop]; node.na[amenity]; node.na[tourism]; ); out; """.format(way['id']), cache=False) elms = [] for n in result.nodes: n_point = Point(float(n.lon), float(n.lat)) if n_point.within(shape): elms.append({ 'id': n.id, 'lat': float(n.lat), 'lon': float(n.lon), 'tags': n.tags }) return elms
def g_area(id): result = api.query("""area({});out;""".format(id)) area = result.areas.pop() admin_level = int(area.tags.get('admin_level', -1)) spec_type = None if admin_level == 4: spec_type = 'province' elif admin_level == 8: spec_type = 'municipality' elif admin_level == 2: spec_type = 'country' type = 'area' if spec_type: type = ':'.join([type, spec_type]) debug('Sub areas of ' + area.tags['name']) contained_areas = query_sub_areas(id, admin_level) return { 'type': type, 'id': id, 'tag': { k: v for k, v in area.tags.iteritems() if not k.startswith('name') or k == 'name' or k == 'name:es' or k == 'name:es' or k == 'name:it' }, 'contains': contained_areas }
def g_way_geom(id): debug('Geometry of ' + str(id)) geom = api.query(""" way({}); (._; >;); out geom; """.format(id), cache=False) return map(lambda n: (float(n.lon), float(n.lat)), list(geom.ways).pop().nodes)
def query_way_buildings(id): debug('Way buildings of ' + str(id)) query = """ way({}); way(around:20)[building]["building"!~"no"]; out center;""".format(id) result = api.query(query, cache=False) all_way_buildings = filter(lambda w: w.id != int(id), result.ways) return map( lambda x: { 'id': x.id, 'center_lat': float(x.center_lat), 'center_lon': float(x.center_lon) }, all_way_buildings)
def query_way_elms(id): debug('Way elements of ' + str(id)) query = """ way({}); ( node(around:20)[highway]; node(around:20)[footway]; ); out body;""".format(id) result = api.query(query, cache=False) return map( lambda x: { 'id': x.id, 'lat': float(x.lat), 'lon': float(x.lon), 'tags': x.tags }, result.nodes)
def query_surrounding_buildings(id): debug('Surrounding buildings of ' + str(id)) result = api.query(""" way({}); out center; > -> .wn; node(around:10) -> .ar; node.ar.wn; <; out center;""".format(id), cache=False) return map( lambda x: { 'id': x.id, 'center_lat': float(x.center_lat), 'center_lon': float(x.center_lon) }, filter(lambda w: w.id != int(id) and 'building' in w.tags, result.ways))
def query_building_ways(id): debug('Building ways of ' + str(id)) def filter_way(w): buildings = query_way_buildings(w.id) return any([b for b in buildings if b['id'] == int(id)]) result = api.query(""" way({}); way(around:20) -> .aw; ( way.aw[highway]; way.aw[footway]; ); out ids; """.format(id), cache=False) all_near_ways = result.ways building_ways = filter(lambda w: filter_way(w), all_near_ways) return map(lambda x: {'id': x.id}, filter(lambda w: w.id != int(id), building_ways))
def get_node(id): debug('Getting node ' + str(id)) node = g_node(id) tags = request.args.get('tags') tags = tags is not None n_key = _elm_key(node, MATCH_TAGS) node['type'] = n_key if not tags: n_building = query_node_building(node) if n_building: node['building'] = 'way/{}'.format(n_building['id']) node['areas'] = map(lambda aid: 'area/{}'.format(aid), g_coord_area(node['lat'], node['lon'])) response = jsonify(node) response.headers['Cache-Control'] = 'max-age={}'.format(MAX_AGE) response.headers['Last-Modified'] = format_date_time( time.mktime(datetime.now().timetuple())) return response
def query_intersect_ways(id): debug('Intersecting ways of ' + str(id)) result = api.query(""" way({}); >; out body; < -> .wall; ( way.wall[highway]; way.wall[footway]; ); out geom;""".format(id), cache=False) node_ids = set(map(lambda x: x.id, result.nodes)) ways = filter(lambda w: w.id != int(id), result.ways) intersections = {} for w in ways: cuts = set(w._node_ids).intersection(node_ids) if cuts: intersections[w.id] = list(cuts) return intersections
def g_area_geom(id): debug('Area geometry of ' + str(id)) def transform_tag_value(k, v): if k == 'admin_level': return int(v) return u'"{}"'.format(v) result = api.query("""area({});out;""".format(id)) area_tags = result.areas[0].tags area_tags = { key: transform_tag_value(key, v) for key, v in area_tags.items() if key in ['type', 'name:en', 'name', 'boundary', 'wikidata', 'is_in'] } if 'name' not in area_tags: return [] geom = api.query(u""" area({}); rel(pivot); out geom; """.format(id), cache=False) if geom is None: return [] tag_filters = u''.join( [u'["{}"={}]'.format(key, value) for key, value in area_tags.items()]) if not geom.relations: geom = api.query(u""" rel{}; out geom; """.format(tag_filters), cache=False) if geom.relations: area_poly = relation_multipolygon(geom.relations) else: geom = api.query(u""" area({}); way(pivot); out geom; >; out skel qt; """.format(id), cache=False) all_points = list(geom.ways).pop().nodes area_poly = Polygon( map(lambda n: (float(n.lon), float(n.lat)), all_points)) if isinstance(area_poly, Polygon): area_poly = MultiPolygon([area_poly]) return [ map(lambda x: tuple(x[0]), zip(p.exterior.coords)) for p in area_poly ]
def __request(self, query): debug("querying:" + query) if self.url.startswith('https'): gcontext = ssl.SSLContext(ssl.PROTOCOL_TLSv1) else: gcontext = None if self.jwt: request = Request(self.url, headers={"Authorization": self.jwt}) else: request = self.url future = self.pool.submit(urlopen, request, query, context=gcontext) try: f = future.result() except HTTPError as e: f = e response = f.read(self.read_chunk_size) while True: data = f.read(self.read_chunk_size) if len(data) == 0: break response = response + data f.close() if f.code == 200: if overpy.PY2: http_info = f.info() content_type = http_info.getheader("content-type") else: content_type = f.getheader("Content-Type") if content_type == "application/json": if isinstance(response, bytes): response = response.decode("utf-8") response = json.loads(response) return response raise exception.OverpassUnknownContentType(content_type) if f.code == 400: msgs = [] for msg in self._regex_extract_error_msg.finditer(response): tmp = self._regex_remove_tag.sub(b"", msg.group("msg")) try: tmp = tmp.decode("utf-8") except UnicodeDecodeError: tmp = repr(tmp) msgs.append(tmp) raise exception.OverpassBadRequest(query, msgs=msgs) if f.code == 429: raise exception.OverpassTooManyRequests if f.code == 504: raise exception.OverpassGatewayTimeout raise exception.OverpassUnknownHTTPStatusCode(f.code)