DEV Community

Cover image for Django: Find Nearby Users with Coordinates and Radius
AJAY SHRESTHA
AJAY SHRESTHA

Posted on

Django: Find Nearby Users with Coordinates and Radius

In today's world, location-based features are increasingly essential in web applications. Integrating geographic data can significantly enhance user experience, whether finding friends nearby, locating nearby services, or enabling geotagged content.
In this blog, we'll explore how to find nearby users based on their geographical coordinates (latitude and longitude) and a specified radius using Django's ORM.

First, we'll define a Location model to store each user's geographical coordinates. We'll use Django's built-in User model to associate each location with a user.

from django.db import models
from django.contrib.auth.models import User

class Location(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    latitude = models.DecimalField(max_digits=9, decimal_places=6, db_index=True)
    longitude = models.DecimalField(max_digits=9, decimal_places=6, db_index=True)

    def __str__(self):
        return str(self.user)
Enter fullscreen mode Exit fullscreen mode

user: A ForeignKey linking to Django's User model. This establishes a relationship where each user can have one or more locations.
latitude & longitude: DecimalField fields storing the geographical coordinates with precision up to six decimal places, which is sufficient for most location-based applications.

Implementing the Haversine Formula in Django

The Haversine formula is a widely used mathematical equation that calculates the great-circle distance between two points on the Earth’s surface, with latitudes and longitudes. This formula is especially useful in navigation, geofencing, geospatial analysis, and location-based services over the Earth's surface.

Here's the function with the Haversine formula integrated into the Location model to fetch users within a specified radius using Django ORM:

from django.db.models import F, Value
from django.db.models.functions import ACos, Cos, Radians, Sin

class Location(models.Model):
    # ... [fields as above] ...

    @classmethod
    def get_users_within_radius(cls, center_latitude, center_longitude, radius_km):
        # Haversine formula to calculate distances
        distance_expression = (
            ACos(
                Sin(Radians(F('latitude'))) * Sin(Radians(Value(center_latitude))) +
                Cos(Radians(F('latitude'))) * Cos(Radians(Value(center_latitude))) *
                Cos(Radians(F('longitude')) - Radians(Value(center_longitude)))
            ) * 6371  # Earth's radius in kilometers
        )

        # Filter users within the specified radius
        users_within_radius = cls.objects.annotate(
            distance=distance_expression
        ).filter(
          distance__lte=radius_km
        ).select_related('user')

        return users_within_radius
Enter fullscreen mode Exit fullscreen mode

This method calculates distances using the Haversine formulaand filters users within the given radius.

Fetching Users Within a Specified Radius

With the get_users_within_radius method in place, fetching nearby users becomes straightforward. Here's how you can use it:

from .models import Location

# Kathmandu latitude and longitude
center_latitude = 27.707460
center_longitude = 85.312205

radius_km = 10     # 10 kilometers

nearby_location_points = Location.get_users_within_radius(
    center_latitude, center_longitude, radius_km
)
nearby_users = [
    location.user for location in nearby_location_points
]
Enter fullscreen mode Exit fullscreen mode

Explanation

  • Defining Center Coordinates: Replace center_latitude and center_longitude with the desired center point, such as the current user's location.
  • Radius Specification: Set radius_km to the desired search radius in kilometers.
  • Fetching Nearby Locations: Call get_users_within_radius to retrieve Location instances within the specified radius.
  • Extracting Users: Iterate through the Location instances to collect the associated User objects.

Implementing geolocation search in Django is a valuable skill for developers aiming to create location-based services. By understanding the Haversine formula developers can build efficient location-based search.
For more advanced geographic capabilities, explore GeoDjango and spatial databases.

Top comments (0)