Metadata-Version: 2.4
Name: digipinpy
Version: 1.4.1
Summary: Official Python implementation of DIGIPIN - India's national geocoding standard by Department of Posts
Author-email: SAMARTHA H V <samarthsmg14@gmail.com>
Maintainer-email: MR SHIVAKUMAR <hmrshivu@gmail.com>
License: MIT License
        
        Copyright (c) 2025 SAMARTHA H V
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://github.com/DEADSERPENT/digipinpy
Project-URL: Documentation, https://github.com/DEADSERPENT/digipinpy/blob/main/docs/index.md
Project-URL: Repository, https://github.com/DEADSERPENT/digipinpy
Project-URL: Issue Tracker, https://github.com/DEADSERPENT/digipinpy/issues
Project-URL: Source Code, https://github.com/DEADSERPENT/digipinpy
Project-URL: Changelog, https://github.com/DEADSERPENT/digipinpy/blob/main/CHANGELOG.md
Project-URL: Bug Reports, https://github.com/DEADSERPENT/digipinpy/issues/new?template=bug_report.md
Project-URL: Feature Requests, https://github.com/DEADSERPENT/digipinpy/issues/new?template=feature_request.md
Keywords: digipin,geocoding,geolocation,india,gis,addressing,postal,location,coordinates,government,department-of-posts
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Information Technology
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Scientific/Engineering :: GIS
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Utilities
Classifier: Typing :: Typed
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: black>=22.0; extra == "dev"
Requires-Dist: flake8>=5.0; extra == "dev"
Requires-Dist: mypy>=0.990; extra == "dev"
Provides-Extra: test
Requires-Dist: pytest>=7.0; extra == "test"
Requires-Dist: pytest-cov>=4.0; extra == "test"
Provides-Extra: pandas
Requires-Dist: pandas>=1.3.0; extra == "pandas"
Requires-Dist: numpy>=1.21.0; extra == "pandas"
Provides-Extra: django
Requires-Dist: django>=3.2; extra == "django"
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.68.0; extra == "fastapi"
Requires-Dist: pydantic>=1.8.0; extra == "fastapi"
Requires-Dist: uvicorn>=0.15.0; extra == "fastapi"
Provides-Extra: geo
Requires-Dist: shapely>=2.0.0; extra == "geo"
Dynamic: license-file

<div align="center">

# 🇮🇳 DIGIPIN-Py

**The Official Python Implementation of India's National Addressing Grid**

[![PyPI version](https://img.shields.io/pypi/v/digipinpy.svg?color=blue)](https://pypi.org/project/digipinpy/)
[![Python Version](https://img.shields.io/pypi/pyversions/digipinpy.svg)](https://pypi.org/project/digipinpy/)
[![License](https://img.shields.io/pypi/l/digipinpy.svg)](https://github.com/DEADSERPENT/digipinpy/blob/main/LICENSE)
[![Tests](https://github.com/DEADSERPENT/digipinpy/workflows/Tests/badge.svg)](https://github.com/DEADSERPENT/digipinpy/actions)
[![codecov](https://codecov.io/github/DEADSERPENT/digipinpy/graph/badge.svg?token=G8NZBWAWPY)](https://codecov.io/github/DEADSERPENT/digipinpy)
[![Downloads](https://static.pepy.tech/badge/digipinpy)](https://pepy.tech/project/digipinpy)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

*Based on the Department of Posts, Ministry of Communications Specification (March 2025)*

[Installation](#-installation) •
[Quick Start](#-quick-start) •
[Features](#-features) •
[Documentation](https://github.com/DEADSERPENT/digipinpy/blob/main/docs/index.md) •
[API Reference](https://github.com/DEADSERPENT/digipinpy/blob/main/DOCUMENTATION.md) •
[Contributing](CONTRIBUTING.md)

</div>

---

## 📍 What is DIGIPIN?

**DIGIPIN** (Digital Postal Index Number) is India's revolutionary national geocoding system developed by the **Department of Posts, Ministry of Communications, Government of India**. It divides the entire country into a seamless hierarchical grid of **4m × 4m** cells, assigning a unique 10-character code to every location.

`digipinpy` is a high-performance, zero-dependency Python library implementing the official specification with precision and efficiency.

### 🎯 Why DIGIPIN?

- **🏛️ Government Standard**: Official addressing system for India
- **🎯 Pinpoint Accuracy**: ~3.8 meter precision at level 10
- **🗺️ Hierarchical**: Variable precision from 1000km down to 3.8m
- **🔒 Privacy-First**: Convert coordinates to codes without storing personal data
- **📦 Zero Dependencies**: Pure Python, lightweight, fast

---

## 📦 Installation

```bash
pip install digipinpy
```

**Optional Dependencies:**

```bash
# For data science workflows with Pandas
pip install digipinpy[pandas]

# For Django web applications
pip install digipinpy[django]

# For FastAPI microservices (NEW in v1.3.0)
pip install digipinpy[fastapi]

# For geospatial operations - Polyfill (NEW in v1.4.0)
pip install digipinpy[geo]

# For complete ecosystem (pandas + django + fastapi + geo)
pip install digipinpy[pandas,django,fastapi,geo]

# For development (testing, linting, type checking)
pip install digipinpy[dev]
```

**Requirements:** Python 3.8+ (3.7 supported but not tested in CI)

---

## 🚀 Quick Start

### Basic Encoding & Decoding

```python
from digipin import encode, decode

# Encode coordinates to DIGIPIN code
code = encode(28.622788, 77.213033)  # Dak Bhawan, New Delhi
print(code)  # Output: '39J49LL8T4'

# Decode DIGIPIN code back to coordinates
lat, lon = decode('39J49LL8T4')
print(f"{lat:.6f}, {lon:.6f}")  # Output: 28.622788, 77.213033
```

### Variable Precision

```python
from digipin import encode

# Encode with different precision levels
code_full = encode(28.622788, 77.213033, precision=10)  # ~3.8m accuracy
code_city = encode(28.622788, 77.213033, precision=5)   # ~1km accuracy
code_region = encode(28.622788, 77.213033, precision=3) # ~16km accuracy

print(code_full)   # '39J49LL8T4'
print(code_city)   # '39J49'
print(code_region) # '39J'
```

### Proximity Search (New in v1.1.0)

```python
from digipin import get_neighbors, get_ring, get_disk

# Find immediate neighbors (8 surrounding cells)
neighbors = get_neighbors('39J49LL8T4')
print(neighbors)  # ['39J49LL8T9', '39J49LL8TC', '39J49LL8TL', ...]

# Get cells at a specific distance
ring_2 = get_ring('39J49LL8T4', distance=2)

# Get all cells within a radius (for area searches)
search_area = get_disk('39J49LL8T4', radius=3)
print(f"Search area covers {len(search_area)} cells")
```

### Batch Processing

```python
from digipin import batch_encode, batch_decode

# Encode multiple locations at once
locations = [
    (28.622788, 77.213033),  # New Delhi
    (19.076090, 72.877426),  # Mumbai
    (13.082680, 80.270721),  # Chennai
]

codes = batch_encode(locations)
print(codes)  # ['39J49LL8T4', '2MK8MP3K63', '2C4LKPTM5T']

# Decode multiple codes
coordinates = batch_decode(codes)
```

### Data Science with Pandas (New in v1.2.0)

```python
import pandas as pd
import digipin.pandas_ext  # Enables the .digipin accessor

df = pd.DataFrame({
    'location': ['Dak Bhawan', 'India Gate', 'Red Fort'],
    'lat': [28.622788, 28.612912, 28.656159],
    'lon': [77.213033, 77.229510, 77.240963]
})

# Encode coordinates to DIGIPIN codes
df['digipin_code'] = df.digipin.encode('lat', 'lon')

# Decode back to coordinates
df[['decoded_lat', 'decoded_lon']] = df.digipin.decode('digipin_code')

# Validate codes
df['is_valid'] = df.digipin.is_valid('digipin_code')

# Get parent regions for grouping
df['district'] = df.digipin.get_parent('digipin_code', level=5)

print(df)
```

### Django Web Applications (New in v1.2.0)

```python
from django.db import models
from digipin.django_ext import DigipinField

class DeliveryLocation(models.Model):
    name = models.CharField(max_length=100)
    digipin = DigipinField()  # Auto-validates and normalizes!

# Usage
location = DeliveryLocation.objects.create(
    name="Customer Home",
    digipin="39j49ll8t4"  # Automatically converted to '39J49LL8T4'
)

# Hierarchical queries with custom lookup
delhi_locations = DeliveryLocation.objects.filter(digipin__within='39')
specific_area = DeliveryLocation.objects.filter(digipin__within='39J49L')
```

### FastAPI Microservices (New in v1.3.0)

```python
from fastapi import FastAPI
from digipin.fastapi_ext import router as digipin_router

app = FastAPI(title="DIGIPIN Microservice")

# Mount the pre-built router
app.include_router(digipin_router, prefix="/api/v1")

# Run with: uvicorn app:app --reload
# Visit: http://127.0.0.1:8000/docs for auto-generated Swagger UI

# API Endpoints:
# POST   /api/v1/encode          - Encode coordinates to DIGIPIN
# GET    /api/v1/decode/{code}   - Decode DIGIPIN to coordinates
# GET    /api/v1/neighbors/{code} - Get neighboring cells
```

### Geospatial Polyfill (New in v1.4.0)

```python
from digipin import polyfill, encode

# Define delivery zone as polygon
delivery_zone = [
    (28.6328, 77.2197),  # Top
    (28.6289, 77.2155),  # Bottom Left
    (28.6289, 77.2239),  # Bottom Right
]

# Convert polygon to DIGIPIN codes (precision 8 = ~60m)
zone_codes = polyfill(delivery_zone, precision=8)
print(f"Zone covered by {len(zone_codes)} codes")

# Fast O(1) address validation
customer_code = encode(28.6310, 77.2200, precision=8)
if customer_code in zone_codes:
    print("Address IS in delivery zone!")
```

---

## ✨ Features

### Core Capabilities

| Feature | Description | Function |
|---------|-------------|----------|
| **Encoding** | Coordinates → DIGIPIN | `encode(lat, lon, precision=10)` |
| **Decoding** | DIGIPIN → Coordinates | `decode(code)` |
| **Validation** | Check code validity | `is_valid(code)` |
| **Batch Operations** | Process arrays efficiently | `batch_encode()`, `batch_decode()` |
| **Proximity Search** | Find neighboring cells | `get_neighbors()`, `get_ring()`, `get_disk()` |
| **Hierarchical Ops** | Parent/child relationships | `get_parent()`, `is_within()` |
| **Bounds Calculation** | Get cell boundaries | `get_bounds(code)` |
| **Pandas Integration** | DataFrame operations | `.digipin.encode()`, `.digipin.decode()` |
| **Django Integration** | Database field with validation | `DigipinField()`, `__within` lookup |
| **FastAPI Integration** | REST API microservice | Pre-built router with Pydantic models |
| **Polyfill** | Polygon to codes conversion | `polyfill(polygon, precision)` |

### Performance Characteristics

- ⚡ **Fast**: ~50,000 encodes/second on modern hardware
- 💾 **Memory Efficient**: Stateless operations, minimal footprint
- 🔀 **Thread Safe**: All functions are immutable
- 📦 **Zero Dependencies**: Pure Python implementation

---

## 📜 Official Specification

This library implements the standard defined by:

> **Department of Posts, Ministry of Communications, Government of India**
> *"Digital Postal Index Number (DIGIPIN) - Technical Document, Final Version"*
> **March 2025**

**Specification Compliance:** 100% ✅

### Technical Details

- **Coverage Area**:
  - Latitude: 2.5°N to 38.5°N
  - Longitude: 63.5°E to 99.5°E
  - Includes full Indian territory and maritime EEZ

- **Grid System**:
  - 10-level hierarchical structure
  - 4×4 subdivision at each level
  - Spiral anticlockwise labeling pattern

- **Character Set**: `23456789CFJKLMPT` (16 symbols)
  - Excludes confusing characters: 0, 1, A, B, D, E, G, H, I, N, O, Q, R, S, U, V, W, X, Y, Z

---

## 📚 Documentation

- **[Complete API Reference](https://github.com/DEADSERPENT/digipinpy/blob/main/DOCUMENTATION.md)** - Detailed function documentation
- **[Documentation Index](https://github.com/DEADSERPENT/digipinpy/blob/main/docs/index.md)** - Full documentation hub
- **[Technical Specification](https://github.com/DEADSERPENT/digipinpy/blob/main/docs/technical_spec.md)** - Official DIGIPIN spec
- **[Changelog](https://github.com/DEADSERPENT/digipinpy/blob/main/CHANGELOG.md)** - Version history and updates
- **[Contributing Guide](https://github.com/DEADSERPENT/digipinpy/blob/main/CONTRIBUTING.md)** - How to contribute

---

## 🎓 Use Cases

### 🚚 Logistics & Delivery

```python
# Optimize delivery routes with precise location codes
from digipin import encode, get_disk

delivery_hub = encode(28.622788, 77.213033)
delivery_zone = get_disk(delivery_hub, radius=5)
print(f"Delivery zone covers {len(delivery_zone)} cells")
```

### 🚨 Emergency Services

```python
# Locate incident and surrounding areas for emergency response
from digipin import encode, get_neighbors

incident_location = encode(19.076090, 72.877426)
response_area = get_neighbors(incident_location)
```

### 🏙️ Urban Planning

```python
# Analyze geographic coverage and density
from digipin import get_parent, is_within

building_code = '39J49LL8T4'
district_code = get_parent(building_code, level=5)

# Check if location is within district
is_within(building_code, district_code)  # True
```

### 📊 Data Analysis

```python
# Aggregate location data by regions
import pandas as pd
import digipin.pandas_ext

df = pd.read_csv('locations.csv')
df['digipin'] = df.digipin.encode('latitude', 'longitude')
df['district'] = df['digipin'].str[:5]  # First 5 chars = district level

# Analyze by district
district_stats = df.groupby('district').agg({'value': 'sum'})
```

---

## 🧪 Testing

```bash
# Run all tests
pytest tests/ -v

# Run with coverage report
pytest tests/ --cov=src/digipin --cov-report=html

# Run specific test file
pytest tests/test_encoder.py -v
```

**Test Coverage:** 163 comprehensive test cases covering:
- Core DIGIPIN package (29 tests)
- Neighbor discovery (29 tests)
- Pandas integration (33 tests)
- Django integration (31 tests)
- FastAPI integration (41 tests) - NEW in v1.3.0

---

## 🤝 Contributing

We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.

### Development Setup

```bash
# Clone the repository
git clone https://github.com/DEADSERPENT/digipinpy.git
cd digipinpy

# Create virtual environment
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install in development mode
pip install -e ".[dev]"

# Run tests
pytest tests/ -v

# Format code
black src/digipin tests/

# Type checking
mypy src/digipin
```

---

## 📊 Project Status

- ✅ **Production Ready**: Version 1.4.0
- ✅ **100% Specification Compliant**
- ✅ **163 Tests Passing** (100% coverage)
- ✅ **Framework Integrations**: Pandas, Django, FastAPI & Geospatial
- ✅ **Type Hints**: Full type annotation support
- ✅ **Zero Dependencies**: Pure Python core
- ✅ **Multi-Platform**: Windows, macOS, Linux
- ✅ **CI/CD**: Automated testing on Python 3.8-3.13

---

## 📄 License

MIT License - see [LICENSE](LICENSE) file for details.

---

## 👥 Authors & Maintainers

**Lead Developer:** SAMARTHA H V
**Maintainer:** MR SHIVAKUMAR

📧 Contact: samarthsmg14@gmail.com, hmrshivu@gmail.com

---

## 🙏 Acknowledgments

This implementation is based on the official DIGIPIN specification published by:

- **Department of Posts**
- **Ministry of Communications**
- **Government of India**

We acknowledge the technical document "Digital Postal Index Number (DIGIPIN) - Technical Document, Final Version, March 2025" as the authoritative specification.

---

## 🔗 Links

- **PyPI**: https://pypi.org/project/digipinpy/
- **GitHub**: https://github.com/DEADSERPENT/digipinpy
- **Issue Tracker**: https://github.com/DEADSERPENT/digipinpy/issues
- **Discussions**: https://github.com/DEADSERPENT/digipinpy/discussions

---

## 📈 Stats

![PyPI - Downloads](https://img.shields.io/pypi/dm/digipinpy?label=Downloads%2FMonth)
![GitHub Repo stars](https://img.shields.io/github/stars/DEADSERPENT/digipinpy?style=social)
![GitHub forks](https://img.shields.io/github/forks/DEADSERPENT/digipinpy?style=social)

---

<div align="center">

**Government of India | Department of Posts | National Addressing Initiative**

Made with ❤️ for India's Digital Future

</div>
