Search in a BoundingBox with GeoDjango

search in boundingbox with geodjango

My need was to search in a limited square area.

Actually it was a little bit more tricky, I implemented a « Search in this zone » button in a map, after moving in the map by drag and drop a point in the map, I displayed a button in the map which proposed to search in this new area.

Then I get the coordinates of the displayed square of the maps and I rerun the same research but around the center of the maps and limited to the map displayed.

You can see the result on website : https://longuevieauxobjets.ademe.fr/

Search in a BoundingBox in Django

In Backend, you just need to get the coordinate, create a polygon, and search on it

search_in_zone = self.request.GET.get("search_in_zone", None)
distance_in_degrees = 30 / 111320
# expected a structure like 
# { "center":{"lat":48.9402260006218,"lng":2.3499047756195073},
#   "southWest":{"lat":48.93985602297261,"lng":2.348467111587525},
#   "northEast":{"lat":48.940595978270984,"lng":2.3513424396514897} }
center = [
    search_in_zone["center"]["lng"],
    search_in_zone["center"]["lat"],
]
my_bbox_polygon = [
    search_in_zone["southWest"]["lng"],
    search_in_zone["southWest"]["lat"],
    search_in_zone["northEast"]["lng"],
    search_in_zone["northEast"]["lat"],
]  # [xmin, ymin, xmax, ymax]

reference_point = Point(float(center[0]), float(center[1]), srid=4326)

poi = PointOfInterest.objects
        .annotate( distance=Distance("location", reference_point) )
        .filter(
            location__dwithin=(
                reference_point,
                distance_in_degrees,
            )
        )
        .order_by("distance")
        .filter(
            location__within=Polygon.from_bbox(my_bbox_polygon)
        )[:10]

annotate( distance=Distance("location", reference_point)) create a field distance between the POI and the center of the map

distance_in_degrees = 30 / 111320 and .filter( location__dwithin=( reference_point, distance_in_degrees ) ) limit the search in the 30 km around the center

.filter( location__within=Polygon.from_bbox(my_bbox_polygon) ) limit the search in the bounding box

Leave a Reply

Your email address will not be published. Required fields are marked *