コード例 #1
0
ファイル: service.py プロジェクト: CDTai/bycycle.core
 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)
コード例 #2
0
    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')