Grid9 Python Implementation

The Python implementation of Grid9 provides pure Python coordinate compression perfect for data science, geospatial analysis, and scientific computing. With 92% test coverage and support for Python 3.7+, it integrates seamlessly with NumPy, Pandas, and Jupyter notebooks.

Key Features: Pure Python (no dependencies) • NumPy/Pandas compatible • Jupyter notebook friendly • Scientific computing ready • 92% test coverage

Installation

PyPI Package

# Install with pip
pip install grid9

# Install with development dependencies
pip install grid9[dev]

# Upgrade to latest version
pip install --upgrade grid9

Conda Installation

# Install from conda-forge
conda install -c conda-forge grid9

# Create new environment with grid9
conda create -n myproject python=3.11 grid9

From Source

git clone https://github.com/pedrof69/Grid9.git
cd Grid9/python
pip install -e .

Quick Start

Basic Usage

from grid9 import UniformPrecisionCoordinateCompressor

# Encode coordinates to Grid9 code
code = UniformPrecisionCoordinateCompressor.encode(40.7128, -74.0060)
# Result: "Q7KH2BBYF"

# Decode Grid9 code to coordinates
lat, lon = UniformPrecisionCoordinateCompressor.decode("Q7KH2BBYF")
# Result: (40.712779, -74.005988)

# Human-readable format
readable = UniformPrecisionCoordinateCompressor.encode(40.7128, -74.0060, True)
# Result: "Q7K-H2B-BYF"

Jupyter Notebook Integration

import pandas as pd
from grid9 import UniformPrecisionCoordinateCompressor as Grid9

# Create a DataFrame with coordinates
df = pd.DataFrame({
    'city': ['New York', 'London', 'Tokyo'],
    'latitude': [40.7128, 51.5074, 35.6762],
    'longitude': [-74.0060, -0.1278, 139.6503]
})

# Add Grid9 codes column
df['grid9_code'] = df.apply(
    lambda row: Grid9.encode(row['latitude'], row['longitude']), 
    axis=1
)

print(df)
#       city  latitude  longitude grid9_code
# 0  New York   40.7128   -74.0060  Q7KH2BBYF
# 1    London   51.5074    -0.1278  S50MBZX2Y
# 2     Tokyo   35.6762   139.6503  PAYMZ39T7

NumPy Array Processing

import numpy as np
from grid9 import CoordinateOperations

# Process arrays of coordinates
latitudes = np.array([40.7128, 51.5074, 35.6762])
longitudes = np.array([-74.0060, -0.1278, 139.6503])

# Vectorized encoding
coordinates = list(zip(latitudes, longitudes))
codes = CoordinateOperations.batch_encode(coordinates)

# Convert back to arrays for further processing
codes_array = np.array(codes)
print(f"Generated {len(codes_array)} Grid9 codes")

API Reference

UniformPrecisionCoordinateCompressor

Method Description Returns
encode(lat, lon, human_readable=False) Encode coordinates to Grid9 code str
decode(code) Decode Grid9 code to coordinates tuple[float, float]
calculate_distance(code1, code2) Calculate distance in meters float
get_neighbors(code) Get adjacent Grid9 codes list[str]
is_valid_encoding(code) Validate Grid9 code format bool
get_actual_precision(lat, lon) Get precision at coordinates tuple[float, float, float]

CoordinateOperations

Method Description Returns
batch_encode(coordinates) Encode multiple coordinates list[str]
batch_decode(codes) Decode multiple codes list[tuple[float, float]]
find_nearby(lat, lon, radius) Find codes within radius list[str]

Data Science Integration

Pandas DataFrame Operations

import pandas as pd
from grid9 import UniformPrecisionCoordinateCompressor as Grid9

# Load GPS tracking data
df = pd.read_csv('gps_data.csv')

# Add Grid9 encoding
df['grid9'] = df.apply(lambda x: Grid9.encode(x.lat, x.lon), axis=1)

# Group by Grid9 codes (3m resolution)
location_groups = df.groupby('grid9').agg({
    'timestamp': ['min', 'max', 'count'],
    'speed': 'mean',
    'heading': 'mean'
})

# Find most visited locations
top_locations = df['grid9'].value_counts().head(10)

Geospatial Analysis

from grid9 import CoordinateOperations
import matplotlib.pyplot as plt

# Analyze location clusters
def analyze_location_density(coordinates, radius=100):
    """Find location clusters using Grid9 codes"""
    density_map = {}
    
    for lat, lon in coordinates:
        nearby_codes = CoordinateOperations.find_nearby(lat, lon, radius)
        for code in nearby_codes:
            density_map[code] = density_map.get(code, 0) + 1
    
    return density_map

# Visualize density
coords = [(40.7128, -74.0060), (40.7589, -73.9851), (40.6892, -74.0445)]
density = analyze_location_density(coords)
print(f"Found {len(density)} location clusters")

Scientific Computing

import numpy as np
from scipy.spatial.distance import pdist
from grid9 import UniformPrecisionCoordinateCompressor as Grid9

# Generate synthetic GPS data
n_points = 10000
latitudes = np.random.normal(40.7128, 0.1, n_points)
longitudes = np.random.normal(-74.0060, 0.1, n_points)

# Convert to Grid9 codes for efficient storage
codes = [Grid9.encode(lat, lon) for lat, lon in zip(latitudes, longitudes)]

# Analyze unique locations (3m resolution)
unique_locations = len(set(codes))
compression_ratio = len(codes) / unique_locations

print(f"Original points: {len(codes)}")
print(f"Unique 3m locations: {unique_locations}")
print(f"Compression ratio: {compression_ratio:.2f}x")

Performance

Encoding Speed

245K+ operations/second

Decoding Speed

280K+ operations/second

Memory Usage

Minimal (pure Python)

Advanced Features

Distance Calculations

# Calculate distances between locations
nyc = Grid9.encode(40.7128, -74.0060)
london = Grid9.encode(51.5074, -0.1278)

distance_meters = Grid9.calculate_distance(nyc, london)
distance_km = distance_meters / 1000
distance_miles = distance_meters / 1609.34

print(f"NYC to London: {distance_km:.0f}km ({distance_miles:.0f} miles)")

Precision Analysis

# Analyze precision at different latitudes
latitudes = np.linspace(-90, 90, 19)  # Every 10 degrees
longitude = 0.0

precision_data = []
for lat in latitudes:
    x_error, y_error, total_error = Grid9.get_actual_precision(lat, longitude)
    precision_data.append({
        'latitude': lat,
        'x_precision': x_error,
        'y_precision': y_error,
        'total_precision': total_error
    })

# Convert to DataFrame for analysis
precision_df = pd.DataFrame(precision_data)
print(precision_df)

Neighbor Analysis

# Find neighboring locations
center_code = Grid9.encode(40.7128, -74.0060)
neighbors = Grid9.get_neighbors(center_code)

print(f"Center: {center_code}")
print(f"Neighbors: {neighbors}")

# Calculate distances to neighbors
for neighbor in neighbors:
    distance = Grid9.calculate_distance(center_code, neighbor)
    print(f"  {neighbor}: {distance:.1f}m away")

Testing

# Run all tests with pytest
python -m pytest

# Run tests with coverage
python -m pytest --cov=grid9 --cov-report=html

# Run specific test file
python -m pytest test/test_uniform_precision_compressor.py

# Run performance benchmarks
python test_implementation.py

Requirements

Integration Examples

Flask Web API

from flask import Flask, request, jsonify
from grid9 import UniformPrecisionCoordinateCompressor as Grid9

app = Flask(__name__)

@app.route('/api/encode', methods=['POST'])
def encode_coordinates():
    data = request.get_json()
    try:
        code = Grid9.encode(data['latitude'], data['longitude'])
        return jsonify({'grid9_code': code})
    except (KeyError, ValueError) as e:
        return jsonify({'error': str(e)}), 400

@app.route('/api/decode/<code>')
def decode_coordinate(code):
    try:
        lat, lon = Grid9.decode(code)
        return jsonify({'latitude': lat, 'longitude': lon})
    except ValueError:
        return jsonify({'error': 'Invalid Grid9 code'}), 400

Django Model Integration

from django.db import models
from grid9 import UniformPrecisionCoordinateCompressor as Grid9

class Location(models.Model):
    name = models.CharField(max_length=100)
    latitude = models.FloatField()
    longitude = models.FloatField()
    
    @property
    def grid9_code(self):
        return Grid9.encode(self.latitude, self.longitude)
    
    @classmethod
    def from_grid9(cls, code, name):
        lat, lon = Grid9.decode(code)
        return cls(name=name, latitude=lat, longitude=lon)

Need help? Check out the full source code and examples on GitHub or open an issue.

View on GitHub Back to Home