5 releases (stable)
| new 1.1.1 | Feb 26, 2026 |
|---|---|
| 1.1.0 | Feb 21, 2026 |
| 1.0.1 | Feb 9, 2026 |
| 0.1.0 | Feb 8, 2026 |
#88 in Geospatial
96KB
1.5K
SLoC
Fast reverse geocoding with enriched location data
Sub-millisecond coordinate lookups returning timezone, currency, region, and 16+ other fields
๐ Quick Start โข โจ Features โข ๐ก Examples โข ๐ Docs
Overview
genom converts latitude/longitude coordinates into detailed place information including city, region, country, timezone, currency, postal code, and more. Built for high-performance applications that need offline geocoding with rich metadata.
Whether you're enriching analytics data, adding geographic context to logs, or building location-aware APIs โ genom gives you comprehensive location data with zero external API calls.
use genom;
// Single function call returns 18 fields
let place = genom::lookup(40.7128, -74.0060)?;
println!("{}, {}", place.city, place.country_name);
// Output: New York, United States
println!("Timezone: {} ({})", place.timezone, place.timezone_abbr);
// Output: Timezone: America/New_York (EST)
println!("Currency: {} | EU: {}", place.currency, place.is_eu);
// Output: Currency: USD | EU: false
โจ Features
โก Blazing FastGrid-based spatial indexing delivers consistent sub-millisecond performance. Optimized binary format with string interning keeps memory usage minimal (~150 MB). |
๐ฏ Rich Data18 fields per location including timezone, currency, postal code, region, continent, EU membership, and DST status. Everything you need in one call. |
๐ง Zero SetupDatabase builds automatically on first install from GeoNames data. No downloads, no configuration files, no external dependencies. Just add and use. |
๐งต Thread-SafeGlobal singleton with lazy initialization. Lock-free reads mean zero contention in multi-threaded applications. Safe by default. |
Complete Location Data
Every lookup returns comprehensive information organized into logical categories:
Location: city, region, region_code, district, postal_code
Geography: country_code, country_name, continent_code, continent_name, is_eu
Time & Currency: timezone, timezone_abbr, utc_offset, utc_offset_str, dst_active, currency
Coordinates: latitude, longitude
๐ Quick Start
Add to your Cargo.toml:
[dependencies]
genom = "1.0"
Or via cargo:
cargo add genom
Basic usage:
use genom;
fn main() {
// Look up coordinates
if let Some(place) = genom::lookup(48.8566, 2.3522) {
println!("{}, {}", place.city, place.country_name);
// Paris, France
}
}
๐ก Examples
Basic Lookup
use genom;
// Tokyo coordinates
let place = genom::lookup(35.6762, 139.6503)?;
println!("City: {}", place.city); // Tokyo
println!("Country: {}", place.country_name); // Japan
println!("Timezone: {}", place.timezone); // Asia/Tokyo
println!("Currency: {}", place.currency); // JPY
Complete Location Context
use genom;
// London coordinates
let place = genom::lookup(51.5074, -0.1278)?;
// Location information
println!("City: {}", place.city); // London
println!("Region: {}", place.region); // England
println!("Postal Code: {}", place.postal_code); // EC1A
// Geographic details
println!("Country: {} ({})",
place.country_name, place.country_code); // United Kingdom (GB)
println!("Continent: {}", place.continent_name); // Europe
println!("EU Member: {}", place.is_eu); // false
// Timezone information
println!("Timezone: {}", place.timezone); // Europe/London
println!("TZ Abbr: {}", place.timezone_abbr); // GMT or BST
println!("UTC Offset: {}", place.utc_offset_str); // UTC+0 or UTC+1
println!("DST Active: {}", place.dst_active); // true/false
// Economic data
println!("Currency: {}", place.currency); // GBP
Multi-threaded Usage
use std::thread;
use genom;
fn main() {
let coordinates = vec![
(40.7128, -74.0060), // New York
(51.5074, -0.1278), // London
(35.6762, 139.6503), // Tokyo
];
let handles: Vec<_> = coordinates
.into_iter()
.map(|(lat, lon)| {
thread::spawn(move || {
genom::lookup(lat, lon)
})
})
.collect();
for handle in handles {
if let Some(place) = handle.join().unwrap() {
println!("{}: {}", place.city, place.timezone);
}
}
}
Distance Calculations
use genom::Location;
let nyc = Location::new(40.7128, -74.0060);
let la = Location::new(34.0522, -118.2437);
let distance = nyc.distance_to(&la);
println!("Distance: {:.0} km", distance); // ~3944 km
CLI Tool
# Build and run
cargo build --release
./target/release/genom 40.7128 -74.0060
# Output:
# New York
# Region: New York
# Country: United States (US)
# Timezone: America/New_York (EST) UTC-5
# Currency: USD
# EU Member: false
โก Performance
- First lookup: ~100ms (database initialization)
- Subsequent lookups: <1ms (typically 0.1-0.5ms)
- Memory usage: ~150 MB (embedded database in memory)
- Binary size increase: ~150 MB (embedded database)
The database is initialized lazily on first use and cached in a static OnceLock, making it safe and efficient for concurrent access.
Lookup Algorithm
- Quantize input coordinates to grid key (0.1ยฐ resolution)
- Search target cell and 8 neighboring cells (3ร3 grid)
- Calculate haversine distance to all candidates
- Return nearest place with enriched metadata
This provides O(1) average-case lookup with typically 10-50 candidates to check.
๐ ๏ธ Build Process
On first cargo build, the library automatically:
- Downloads geographic data from GeoNames.org
- Processes and filters place data (cities, towns, villages)
- Merges postal code information
- Deduplicates nearby entries
- Builds string interning table and spatial index
- Serializes to compact binary format
This takes 2-5 minutes depending on network speed. The database is cached in target/ and only rebuilt when necessary.
Skipping the Build
To skip database generation (e.g., for docs.rs or CI where you'll provide a pre-built database):
[dependencies]
genom = { version = "1.0", features = ["no-build-database"] }
You can also manually build the database using the builder binary:
cargo run --release --bin build-database --features builder,no-build-database
๐ Use Cases
- Analytics: Enrich user location data with timezone and region
- Logging: Add geographic context to log entries
- APIs: Convert coordinates to human-readable locations
- IoT: Offline geocoding for edge devices
- Mobile: Embedded geocoding without network requests
- Privacy: No external API calls, all data stays local
๐ Data Structure
The library uses a pre-built binary database embedded in your compiled binary:
- String Interning: Common strings (country codes, timezones) stored once
- Fixed-Point Coordinates: 32-bit integers instead of 64-bit floats
- Spatial Grid Index: World divided into 0.1ยฐ ร 0.1ยฐ cells (~11km at equator)
This reduces memory footprint by approximately 70% compared to storing full structs.
โ ๏ธ Limitations
- Ocean coordinates: Returns
Nonefor coordinates far from land - Precision: Nearest city/town, not street-level accuracy
- Coverage: Limited to 100+ countries with significant population
- Updates: Database is static; requires rebuild for updated data
- Size: Adds ~150 MB to your binary
๐ Data Sources
All geographic data comes from GeoNames.org, which provides free geographic data under the Creative Commons Attribution 4.0 License.
๐ API Reference
Core Functions
lookup(latitude: f64, longitude: f64) -> Option<Place>- Main entry point for geocoding
Types
Place- Enriched output with 18 fields of location dataLocation- Coordinate pair with distance calculationsGeocoder- Core geocoding engine (usually accessed vialookup)
See full documentation for detailed API reference.
๐ค Contributing
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
๐ License
Copyright 2026 TN3W
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
๐ Website โข ๐ Documentation โข ๐ป GitHub โข ๐ฆ crates.io
Built with data from GeoNames.org
Dependencies
~18โ33MB
~380K SLoC