-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhancement #2 address details option #58
base: development
Are you sure you want to change the base?
Changes from all commits
4741345
d096aea
d71cab7
ea3a42b
513def3
d155c93
28e4d5b
44892c0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
from flask_cors import CORS | ||
from openpoiservice.server.categories.categories import CategoryTools | ||
from openpoiservice.server.api import api_exceptions | ||
from openpoiservice.server.db_import.objects import GeocoderSetup | ||
import yaml | ||
import os | ||
import time | ||
|
@@ -19,6 +20,13 @@ | |
basedir = os.path.abspath(os.path.dirname(__file__)) | ||
ops_settings = yaml.safe_load(open(os.path.join(basedir, 'ops_settings.yml'))) | ||
|
||
geocoder = None | ||
geocode_categories = None | ||
if ops_settings['geocoder'] is not None: | ||
geocoder = GeocoderSetup(list(ops_settings['geocoder'].items())[0]).define_geocoder() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. See above. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. |
||
geocode_categories = CategoryTools('categories.yml').generate_geocode_categories() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. See above |
||
|
||
|
||
if "TESTING" in os.environ: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here you have to decide if you replace the strings. I think this is a one time call so just leave it like that. |
||
ops_settings['provider_parameters']['table_name'] = ops_settings['provider_parameters']['table_name'] + '_test' | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
# openpoiservice/server/query_builder.py | ||
|
||
from openpoiservice.server import db | ||
from openpoiservice.server import categories_tools, ops_settings | ||
from openpoiservice.server import categories_tools, ops_settings, geocoder | ||
import geoalchemy2.functions as geo_func | ||
from geoalchemy2.types import Geography, Geometry | ||
from geoalchemy2.elements import WKBElement, WKTElement | ||
|
@@ -13,6 +13,7 @@ | |
from sqlalchemy import dialects | ||
import geojson as geojson | ||
import logging | ||
import json | ||
from timeit import default_timer as timer | ||
|
||
logger = logging.getLogger(__name__) | ||
|
@@ -105,7 +106,8 @@ def request_pois(self): | |
bbox_query.c.geom, | ||
keys_agg, | ||
values_agg, | ||
categories_agg) \ | ||
categories_agg, | ||
bbox_query.c.address) \ | ||
.order_by(*sortby_group) \ | ||
.filter(*category_filters) \ | ||
.filter(*custom_filters) \ | ||
|
@@ -115,14 +117,7 @@ def request_pois(self): | |
.group_by(bbox_query.c.osm_id) \ | ||
.group_by(bbox_query.c.osm_type) \ | ||
.group_by(bbox_query.c.geom) \ | ||
# .all() | ||
|
||
# end = timer() | ||
# print(end - start) | ||
|
||
# print(str(pois_query)) | ||
# for dude in pois_query: | ||
# print(dude) | ||
.group_by(bbox_query.c.address) | ||
|
||
# response as geojson feature collection | ||
features = self.generate_geojson_features(pois_query, params['limit']) | ||
|
@@ -147,12 +142,9 @@ def generate_geom_filters(geometry, Pois): | |
type_coerce(geom_bbox, Geography)), Pois.geom, 0)) | ||
|
||
elif 'bbox' not in geometry and 'geom' in geometry: | ||
|
||
geom = geometry['geom'].wkt | ||
|
||
filters.append( # buffer around geom | ||
geo_func.ST_DWithin(geo_func.ST_Buffer(type_coerce(geom, Geography), geometry['buffer']), Pois.geom, 0) | ||
) | ||
geo_func.ST_DWithin(geo_func.ST_Buffer(type_coerce(geom, Geography), geometry['buffer']), Pois.geom, 0)) | ||
|
||
return filters, geom | ||
|
||
|
@@ -264,12 +256,24 @@ def generate_geojson_features(cls, query, limit): | |
} | ||
properties["category_ids"] = category_ids_obj | ||
|
||
# Checks if Tags are available | ||
if q[5][0] is not None: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. try-except like in the array call in the following lines? |
||
key_values = {} | ||
for idx, key in enumerate(q[4]): | ||
key_values[key] = q[5][idx] | ||
properties["osm_tags"] = key_values | ||
|
||
# Checks if addresses are available | ||
try: | ||
if q[7] is not None: | ||
address_dict = {} | ||
address_data = json.loads(q[7]) | ||
for key, value in address_data.items(): | ||
address_dict[key] = value | ||
properties['address'] = address_dict | ||
except IndexError: | ||
pass | ||
|
||
geojson_feature = geojson.Feature(geometry=trimmed_point, | ||
properties=properties) | ||
geojson_features.append(geojson_feature) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -94,3 +94,16 @@ def get_category(self, tags): | |
categories.append(category_id) | ||
|
||
return categories | ||
|
||
def generate_geocode_categories(self): | ||
|
||
geocode_categories = {} | ||
|
||
for category in self.categories_object.items(): | ||
if 'geocoder' not in category[1]: | ||
for child in category[1]['children'].values(): | ||
for id in child.values(): | ||
geocode_categories[id] = {} | ||
|
||
return geocode_categories | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In general it's better to have no nested for-loops. Think about moving every for-loop to a different function... |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,6 +49,7 @@ education: | |
|
||
facilities: | ||
id: 160 | ||
geocoder: False | ||
children: | ||
amenity: | ||
compressed_air: 161 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,15 @@ | ||
# openpoiservice/server/poi_entity.py | ||
|
||
import json | ||
import logging | ||
from geopy.geocoders import get_geocoder_for_service | ||
# from geopy.extra.rate_limiter import RateLimiter | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
class PoiObject(object): | ||
|
||
def __init__(self, uuid, categories, osmid, lat_lng, osm_type): | ||
def __init__(self, uuid, categories, osmid, lat_lng, osm_type, address=None): | ||
self.uuid = uuid | ||
self.osmid = int(osmid) | ||
self.type = int(osm_type) | ||
|
@@ -14,9 +20,7 @@ def __init__(self, uuid, categories, osmid, lat_lng, osm_type): | |
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove dead code? |
||
self.geom = 'SRID={};POINT({} {})'.format(4326, float(lat_lng[0]), | ||
float(lat_lng[1])) | ||
|
||
# add geocoder connector here... | ||
self.address = None | ||
self.address = address | ||
|
||
|
||
class TagsObject(object): | ||
|
@@ -26,3 +30,56 @@ def __init__(self, uuid, osmid, key, value): | |
self.osmid = int(osmid) | ||
self.key = key | ||
self.value = value | ||
|
||
|
||
class GeocoderSetup(object): | ||
"""Initialises geocoder""" | ||
|
||
def __init__(self, geocoder_name): | ||
self.geocoder_name = geocoder_name | ||
self.geocoder = None | ||
|
||
def define_geocoder(self): | ||
|
||
# returns warning if no valid geocoder is provided | ||
try: | ||
self.geocoder_settings = get_geocoder_for_service(self.geocoder_name[0]) | ||
|
||
except Exception as err_geocoder: | ||
logger.warning(err_geocoder) | ||
return err_geocoder | ||
|
||
# returns warning if no valid geocoder settings are provided | ||
try: | ||
if self.geocoder_name[1] is not None: | ||
self.geocoder = self.geocoder_settings(**self.geocoder_name[1]) | ||
|
||
else: | ||
self.geocoder = self.geocoder_settings() | ||
return self.geocoder | ||
|
||
except Exception as err_parameter: | ||
logger.warning(err_parameter) | ||
return err_parameter | ||
|
||
|
||
class AddressObject(object): | ||
|
||
def __init__(self, lat_lng, geocoder): | ||
self.lat_lng = lat_lng[::-1] | ||
self.geocoder = geocoder | ||
|
||
def address_request(self): | ||
|
||
# address_delaied = RateLimiter(self.geocoder.reverse, min_delay_seconds=1) | ||
response = self.geocoder.reverse(query=self.lat_lng) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a try-except here to catch possible connection errors, e.g. resource not available etc. |
||
|
||
# Checks if address for location is available | ||
if response is not None: | ||
return json.dumps(response.raw) | ||
# try: | ||
# return json.dumps(response.raw) | ||
# except AttributeError: | ||
# return json.dumps(response) | ||
|
||
return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally it's better to define those recurring strings in a "static" object somewhere. In this case you could define a static settings variable class in
openpoiservice.server
and import it alongside theops_settings
object etc.Another option is that you define all the config file variables you need once in the
openpoiservice.server
and import these instead ofops_settings
.The reason is, it will reduce complexity and coding time when you have those strings in one place. Once you change something in the config file you'll only have to adjust one variable in the
openpoiservice.server
file.My advice
would be to followoption 2
.E.g.
openpoiservice.server
, assign config parameters to it and import them wherever you need themThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those strings won't be changed or modified by the user. He will just add further parameters, which will be checked the way you showed. Adjust the strings anyway?