def match_point(self, s): if isinstance(s, str): try: point = Point.from_string(s) except ValueError: return None normalized_point = point if self.is_lat_long(point): point = point.reproject() geom = func.ST_GeomFromText(point.wkt, DEFAULT_SRID) distance = func.ST_Distance(geom, Intersection.geom) distance = distance.label('distance') # Try to get an Intersection first q = self.session.query(Intersection, distance) q = q.filter(distance < 5) # 5 meters (make configurable) q = q.order_by(distance) result = q.first() if result is not None: closest_object = result.Intersection closest_point = closest_object.geom else: # Otherwise, get a Street distance = func.ST_Distance(geom, Street.geom).label('distance') q = self.session.query(Street, distance) q = q.order_by(distance) closest_object = q.first().Street # Get point on Street closest to input point closest_point = func.ST_ClosestPoint(Street.geom, geom) closest_point = closest_point.label('closest_point') q = self.session.query(closest_point).select_from(Street) q = q.filter_by(id=closest_object.id) closest_point = q.scalar() closest_point = Point.from_wkb(closest_point) name = closest_object.name return LookupResult(s, normalized_point, closest_point, closest_object, name)
def match_point(self, s): if isinstance(s, str): try: point = Point.from_string(s) except ValueError: return None normalized_point = point geom = func.ST_GeomFromText(point.wkt, DEFAULT_SRID) distance = func.ST_Distance( func.ST_GeogFromWKB(geom), func.ST_GeogFromWKB(Intersection.geom)) distance = distance.label('distance') # Distance threshold in meters # TODO: Should this be scale-dependent? distance_threshold = self.config.get('distance_threshold', 10) # Try to get an Intersection first q = self.session.query(Intersection, distance) q = q.filter(distance < distance_threshold) q = q.order_by(distance) result = q.first() if result is not None: closest_object = result.Intersection closest_point = closest_object.geom name = closest_object.name else: # Otherwise, get a Street distance = func.ST_Distance(geom, Street.geom).label('distance') q = self.session.query(Street, distance) q = q.filter( Street.highway.in_(Street.routable_types) | Street.bicycle.in_(Street.bicycle_allowed_types) ) q = q.order_by(distance) closest_object = q.first().Street # Get point on Street closest to input point closest_point = func.ST_ClosestPoint(Street.geom, geom) closest_point = closest_point.label('closest_point') q = self.session.query(closest_point).select_from(Street) q = q.filter_by(id=closest_object.id) closest_point = q.scalar() closest_point = Point.from_wkb(closest_point) name = closest_object.display_name return LookupResult(s, normalized_point, closest_point, closest_object, name, 'byCycle point')