Example #1
0
 def withinDistance2D(cls, bbox, fromSrid=4326, toSrid=4326, tolerance=0.):
     bboxGeom = shapelyBBox(bbox)
     wkbGeometry = WKBElement(buffer(bboxGeom.wkb), fromSrid)
     if fromSrid != toSrid:
         wkbGeometry = func.ST_Transform(wkbGeometry, toSrid)
     geomColumn = cls.geometryColumn()
     return func.ST_DWithin(geomColumn, wkbGeometry, tolerance)
def find_properties_near_ewkt(ewkt_string, distance_meters):
    """
    Finds all properties within `distance_meters` of the geometry
    specified by `ewkt_string`.
    """
    session = Session()
    return session.query(Property).filter(
        func.ST_DWithin(Property.geocode_geo,
                        cast(func.ST_GeomFromEWKT(ewkt_string), Geography),
                        distance_meters)).all()
Example #3
0
    def UserSearch(self, request, context):
        with session_scope() as session:
            query = session.query(User).filter(~User.is_banned)
            if request.HasField("query"):
                if request.query_name_only:
                    query = query.filter(
                        or_(User.name.ilike(f"%{request.query.value}%"),
                            User.username.ilike(f"%{request.query.value}%")))
                else:
                    query = query.filter(
                        or_(
                            User.name.ilike(f"%{request.query.value}%"),
                            User.username.ilike(f"%{request.query.value}%"),
                            User.city.ilike(f"%{request.query.value}%"),
                            User.hometown.ilike(f"%{request.query.value}%"),
                            User.about_me.ilike(f"%{request.query.value}%"),
                            User.my_travels.ilike(f"%{request.query.value}%"),
                            User.things_i_like.ilike(
                                f"%{request.query.value}%"),
                            User.about_place.ilike(f"%{request.query.value}%"),
                            User.additional_information.ilike(
                                f"%{request.query.value}%"),
                        ))

            if request.HasField("last_active"):
                raw_dt = to_aware_datetime(request.last_active)
                coarsened_dt = raw_dt.replace(minute=(raw_dt.minute // 15) *
                                              15,
                                              second=0,
                                              microsecond=0)
                query = query.filter(User.last_active >= coarsened_dt)

            if request.HasField("gender"):
                query = query.filter(
                    User.gender.ilike(f"%{request.gender.value}%"))

            if len(request.hosting_status_filter) > 0:
                query = query.filter(
                    User.hosting_status.in_([
                        hostingstatus2sql[status]
                        for status in request.hosting_status_filter
                    ]))
            if len(request.smoking_location_filter) > 0:
                query = query.filter(
                    User.smoking_allowed.in_([
                        smokinglocation2sql[loc]
                        for loc in request.smoking_location_filter
                    ]))
            if len(request.sleeping_arrangement_filter) > 0:
                query = query.filter(
                    User.sleeping_arrangement.in_([
                        sleepingarrangement2sql[arr]
                        for arr in request.sleeping_arrangement_filter
                    ]))
            if len(request.parking_details_filter) > 0:
                query = query.filter(
                    User.parking_details.in_([
                        parkingdetails2sql[det]
                        for det in request.parking_details_filter
                    ]))

            if request.HasField("guests"):
                query = query.filter(User.max_guests >= request.guests.value)
            if request.HasField("last_minute"):
                query = query.filter(User.last_minute == last_minute.value)
            if request.HasField("has_pets"):
                query = query.filter(User.has_pets == has_pets.value)
            if request.HasField("accepts_pets"):
                query = query.filter(User.accepts_pets == accepts_pets.value)
            if request.HasField("has_kids"):
                query = query.filter(User.has_kids == has_kids.value)
            if request.HasField("accepts_kids"):
                query = query.filter(User.accepts_kids == accepts_kids.value)
            if request.HasField("has_housemates"):
                query = query.filter(
                    User.has_housemates == has_housemates.value)
            if request.HasField("wheelchair_accessible"):
                query = query.filter(
                    User.wheelchair_accessible == wheelchair_accessible.value)
            if request.HasField("smokes_at_home"):
                query = query.filter(
                    User.smokes_at_home == smokes_at_home.value)
            if request.HasField("drinking_allowed"):
                query = query.filter(
                    User.drinking_allowed == drinking_allowed.value)
            if request.HasField("drinks_at_home"):
                query = query.filter(
                    User.drinks_at_home == drinks_at_home.value)
            if request.HasField("parking"):
                query = query.filter(User.parking == parking.value)
            if request.HasField("camping_ok"):
                query = query.filter(User.camping_ok == camping_ok.value)

            if request.HasField("search_in_area"):
                # EPSG4326 measures distance in decimal degress
                # we want to check whether two circles overlap, so check if the distance between their centers is less
                # than the sum of their radii, divided by 111111 m ~= 1 degree (at the equator)
                search_point = create_coordinate(request.search_in_area.lat,
                                                 request.search_in_area.lng)
                query = query.filter(
                    func.ST_DWithin(
                        User.geom, search_point,
                        (User.geom_radius + request.search_in_area.radius) /
                        111111))
            if request.HasField("search_in_community_id"):
                # could do a join here as well, but this is just simpler
                node = session.query(Node).filter(
                    Node.id == request.search_in_community_id).one_or_none()
                if not node:
                    context.abort(grpc.StatusCode.NOT_FOUND,
                                  errors.COMMUNITY_NOT_FOUND)
                query = query.filter(func.ST_Contains(node.geom, User.geom))

            if request.only_with_references:
                query = query.join(Reference, Reference.to_user_id == User.id)

            # TODO:
            # google.protobuf.StringValue language = 11;
            # bool friends_only = 13;
            # google.protobuf.UInt32Value age_min = 14;
            # google.protobuf.UInt32Value age_max = 15;

            page_size = min(MAX_PAGINATION_LENGTH, request.page_size
                            or MAX_PAGINATION_LENGTH)
            next_user_id = int(request.page_token) if request.page_token else 0

            users = query.filter(User.id >= next_user_id).order_by(
                User.id).limit(page_size + 1).all()

            return search_pb2.UserSearchRes(
                results=[
                    search_pb2.Result(
                        rank=1,
                        user=user_model_to_pb(user, session, context),
                    ) for user in users[:page_size]
                ],
                next_page_token=str(users[-1].id)
                if len(users) > page_size else None,
            )