Location normalization system using geo-buckets for consistent property search results
On ExpertListing, users searching for properties in the same area sometimes get inconsistent results due to slightly different location names or coordinates in the database.
Search: "Sangotedo" → 0 properties found ❌
Search: "Sangotedo" → 47 properties found ✓
Both searches refer to the same physical area, but inconsistent results occur because:
- Properties have slightly different coordinates
- Location names vary ("Sangotedo", "Sangotedo, Ajah", "sangotedo lagos")
- No normalization system exists
This system groups nearby properties into logical buckets and ensures searches like "Sangotedo", "sangotedo lagos", or "Sangotedo, Ajah" return all relevant properties consistently.
✅ Automatic Geo-Bucketing - Properties automatically assigned to grid-based buckets
✅ Location Normalization - Case-insensitive, punctuation-agnostic matching
✅ Typo Tolerance - Handles 1-3 character typos using Levenshtein distance
✅ Alias Management - Tracks all location name variations
✅ Fast Searches - Indexed queries return results in <50ms
✅ RESTful API - Complete CRUD operations with DRF
✅ Interactive Documentation - Swagger/OpenAPI integration
- Python 3.11+
- PostgreSQL 18+ with PostGIS extension
- Clone the repository
git clone https://github.com/owolabi-develop/expert-listing.git
cd geo_bucket_system- Create virtual environment
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate- Install dependencies
pip install -r requirements.txt- Setup PostgreSQL Database and install PostGIS https://docs.djangoproject.com/en/6.0/ref/contrib/gis/install/postgis/
-- Create database
CREATE DATABASE expertlisting_db;
-- Connect to database
\c expertlisting_db
-- Enable PostGIS
CREATE EXTENSION postgis;. Download OSGeo4W installer https://docs.djangoproject.com/en/6.0/ref/contrib/gis/tutorial/#setting-up
- Configure environment variables
# Create .env file
.env
# Edit .env with your database credentials
DB_NAME=expertlisting_geo
DB_USER=postgres
DB_PASSWORD=your_password
DB_HOST=localhost
DB_PORT=5433- Run migrations
python manage.py migrate- Load test data
python seed_data.py- Start development server
python manage.py runserver- Access the application
- API: http://localhost:8000/api/
- Swagger Docs: http://localhost:8000/api/docs/
- ReDoc: http://localhost:8000/api/redoc/
- Admin: http://localhost:8000/admin/
POST /api/properties/GET /api/properties/search/?location=sangotedoGET /api/properties/GET /api/properties/{id}/PUT /api/properties/{id}/
PATCH /api/properties/{id}/DELETE /api/properties/{id}/GET /api/geo-buckets/GET /api/geo-buckets/stats/GET /api/geo-buckets/{id}/tests/
├── pytest.ini
├── test_api.py
├── test_location_services.py
### Running Tests
**Run with verbose output:**
pytest tests/ -v
```bash