pak-geodata 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pak_geodata-0.1.0/LICENSE +21 -0
- pak_geodata-0.1.0/PKG-INFO +245 -0
- pak_geodata-0.1.0/README.md +216 -0
- pak_geodata-0.1.0/pak_geodata/__init__.py +45 -0
- pak_geodata-0.1.0/pak_geodata/data/areas/islamabad-ict/islamabad.json +821 -0
- pak_geodata-0.1.0/pak_geodata/data/areas/punjab/faisalabad.json +531 -0
- pak_geodata-0.1.0/pak_geodata/data/areas/punjab/lahore.json +1124 -0
- pak_geodata-0.1.0/pak_geodata/data/areas/punjab/rawalpindi.json +626 -0
- pak_geodata-0.1.0/pak_geodata/data/areas/sindh/karachi.json +1122 -0
- pak_geodata-0.1.0/pak_geodata/data/cities/ajk.json +90 -0
- pak_geodata-0.1.0/pak_geodata/data/cities/balochistan.json +112 -0
- pak_geodata-0.1.0/pak_geodata/data/cities/gilgit-baltistan.json +90 -0
- pak_geodata-0.1.0/pak_geodata/data/cities/islamabad-ict.json +24 -0
- pak_geodata-0.1.0/pak_geodata/data/cities/kpk.json +134 -0
- pak_geodata-0.1.0/pak_geodata/data/cities/punjab.json +310 -0
- pak_geodata-0.1.0/pak_geodata/data/cities/sindh.json +134 -0
- pak_geodata-0.1.0/pak_geodata/data/provinces.json +51 -0
- pak_geodata-0.1.0/pak_geodata/lookups.py +477 -0
- pak_geodata-0.1.0/pak_geodata/models.py +125 -0
- pak_geodata-0.1.0/pak_geodata/py.typed +1 -0
- pak_geodata-0.1.0/pak_geodata.egg-info/PKG-INFO +245 -0
- pak_geodata-0.1.0/pak_geodata.egg-info/SOURCES.txt +26 -0
- pak_geodata-0.1.0/pak_geodata.egg-info/dependency_links.txt +1 -0
- pak_geodata-0.1.0/pak_geodata.egg-info/requires.txt +3 -0
- pak_geodata-0.1.0/pak_geodata.egg-info/top_level.txt +1 -0
- pak_geodata-0.1.0/pyproject.toml +70 -0
- pak_geodata-0.1.0/setup.cfg +4 -0
- pak_geodata-0.1.0/tests/test_lookups.py +391 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sohaib Bin Mohsin, The Mohsin Project Global (https://themohsinproject.org)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pak-geodata
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Comprehensive, typed, offline geographic data for all areas and cities in Pakistan
|
|
5
|
+
Author: The Mohsin Project Global
|
|
6
|
+
Author-email: Sohaib Bin Mohsin <sohaibbinmohsin@gmail.com>
|
|
7
|
+
Project-URL: Homepage, https://github.com/sohaibbinmohsin/pak-geodata
|
|
8
|
+
Project-URL: Documentation, https://github.com/sohaibbinmohsin/pak-geodata#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/sohaibbinmohsin/pak-geodata.git
|
|
10
|
+
Project-URL: Bug Tracker, https://github.com/sohaibbinmohsin/pak-geodata/issues
|
|
11
|
+
Project-URL: Founder, https://sohaibbinmohsin.com
|
|
12
|
+
Project-URL: Company, https://themohsinproject.org
|
|
13
|
+
Keywords: pakistan,geodata,gis,coordinates,provinces,cities,areas,sectors,postal-codes,lahore,karachi,islamabad,rawalpindi,faisalabad,geocoding,reverse-geocoding,haversine
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Operating System :: OS Independent
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# pak-geodata
|
|
31
|
+
|
|
32
|
+
> Comprehensive, typed, offline geographic data for all areas and cities in Pakistan.
|
|
33
|
+
|
|
34
|
+
`pak-geodata` is an open-source, production-grade Python client library providing offline access to verified geographic data for Pakistan, created and maintained by [Sohaib Bin Mohsin](https://sohaibbinmohsin.com) at [The Mohsin Project Global](https://themohsinproject.org).
|
|
35
|
+
|
|
36
|
+
It covers all administrative provinces, 40 major cities, and foundational flagship metropolitan areas (sectors, housing schemes, neighborhoods, and commercial centers).
|
|
37
|
+
|
|
38
|
+
Designed with **zero runtime dependencies** (pure Python standard library), strict geofencing, and sub-millisecond lookups.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Features
|
|
43
|
+
|
|
44
|
+
- **Zero Runtime Dependencies**: Powered entirely by the Python standard library (`dataclasses`, `json`, `math`, `re`, `pathlib`).
|
|
45
|
+
- **Offline & Self-Contained**: All verified golden datasets are bundled with the library: no remote API calls or internet access required.
|
|
46
|
+
- **Strict Geofencing & Validation**: Every coordinate is rigorously validated within Pakistan territorial boundaries (`23.5 <= lat <= 37.1`, `60.8 <= lng <= 77.8`) and city district bounding boxes.
|
|
47
|
+
- **Canonical Slugs**: Standardized `<city-slug>-<area-slug>` identifiers across all datasets (e.g. `lahore-dha-phase-5`).
|
|
48
|
+
- **Multi-Script & Alias Search**: Full support for English queries, colloquial aliases (e.g. `"dha 5"`), Urdu script queries (e.g. `"کلفٹن"`), and fuzzy typo tolerance.
|
|
49
|
+
- **Spatial Nearest Neighbor**: Instant reverse geocoding via spherical Haversine distance calculations.
|
|
50
|
+
- **Postal Code Resolution**: 5-digit Pakistan Post postal code lookup and reverse mapping.
|
|
51
|
+
- **Fully Typed & PEP 561 Compliant**: Includes `py.typed` marker and immutable frozen dataclasses for full IDE auto-completion.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Installation
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pip install pak-geodata
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Quick Start
|
|
64
|
+
|
|
65
|
+
### 1. Provinces & Cities
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from pak_geodata import (
|
|
69
|
+
get_all_provinces,
|
|
70
|
+
get_province_by_id,
|
|
71
|
+
get_all_cities,
|
|
72
|
+
get_cities_by_province,
|
|
73
|
+
get_city_by_id,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# List all 7 provinces and federal territories
|
|
77
|
+
provinces = get_all_provinces()
|
|
78
|
+
for p in provinces:
|
|
79
|
+
print(f"{p.name} ({p.urdu_name}) - Capital: {p.capital_city_id}")
|
|
80
|
+
|
|
81
|
+
# Find a province by ID
|
|
82
|
+
punjab = get_province_by_id("punjab")
|
|
83
|
+
print(punjab.name) # "Punjab"
|
|
84
|
+
|
|
85
|
+
# Retrieve all cities in a province
|
|
86
|
+
punjab_cities = get_cities_by_province("punjab")
|
|
87
|
+
print(f"Found {len(punjab_cities)} cities in Punjab")
|
|
88
|
+
|
|
89
|
+
# Get specific city details
|
|
90
|
+
lahore = get_city_by_id("lahore")
|
|
91
|
+
print(f"{lahore.name} coordinates: {lahore.coordinates.lat}, {lahore.coordinates.lng}")
|
|
92
|
+
print(f"Verified areas count: {lahore.total_areas_count}")
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 2. Areas by City
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from pak_geodata import get_areas_by_city
|
|
99
|
+
|
|
100
|
+
# Retrieve all verified areas for a city
|
|
101
|
+
lahore_areas = get_areas_by_city("lahore")
|
|
102
|
+
for area in lahore_areas[:5]:
|
|
103
|
+
print(f"{area.name} [{area.id}] - Postal Code: {area.postal_code}")
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 3. Intelligent Search
|
|
107
|
+
|
|
108
|
+
The search engine ranks results across multiple matching tiers:
|
|
109
|
+
1. Exact match on name, id, Urdu name, or alias
|
|
110
|
+
2. Prefix match
|
|
111
|
+
3. Substring / multi-word token match
|
|
112
|
+
4. Fuzzy edit-distance fallback for typos
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from pak_geodata import search_areas
|
|
116
|
+
|
|
117
|
+
# Search by colloquial alias scoped to a city
|
|
118
|
+
results = search_areas("dha 5", city_id="lahore")
|
|
119
|
+
print(results[0].id) # "lahore-dha-phase-5"
|
|
120
|
+
print(results[0].name) # "DHA Phase 5"
|
|
121
|
+
|
|
122
|
+
# Search using Urdu script
|
|
123
|
+
results = search_areas("کلفٹن")
|
|
124
|
+
for r in results:
|
|
125
|
+
print(f"{r.name} ({r.urdu_name}) in {r.city_id}")
|
|
126
|
+
|
|
127
|
+
# Scoped city search with limit
|
|
128
|
+
results = search_areas("phase", city_id="islamabad", limit=3)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### 4. Reverse Geocoding & Spatial Nearest Neighbor
|
|
132
|
+
|
|
133
|
+
Find the closest verified neighborhood or society to given GPS coordinates:
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
from pak_geodata import Coordinates, get_nearest_area, haversine_distance_km
|
|
137
|
+
|
|
138
|
+
# Distance calculation
|
|
139
|
+
lahore_lat, lahore_lng = 31.5204, 74.3587
|
|
140
|
+
rawalpindi_lat, rawalpindi_lng = 33.5651, 73.0169
|
|
141
|
+
distance_km = haversine_distance_km(lahore_lat, lahore_lng, rawalpindi_lat, rawalpindi_lng)
|
|
142
|
+
print(f"Distance: {distance_km:.2f} km")
|
|
143
|
+
|
|
144
|
+
# Nearest area from coordinates (or Coordinates object)
|
|
145
|
+
coords = Coordinates(lat=31.4581, lng=74.4121)
|
|
146
|
+
nearest = get_nearest_area(coords)
|
|
147
|
+
print(f"Nearest area: {nearest.name} ({nearest.id})")
|
|
148
|
+
|
|
149
|
+
# Filtered nearest search with maximum distance threshold
|
|
150
|
+
area_within_5km = get_nearest_area(
|
|
151
|
+
lat=33.5651,
|
|
152
|
+
lng=73.0169,
|
|
153
|
+
city_id="rawalpindi",
|
|
154
|
+
max_distance_km=5.0
|
|
155
|
+
)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### 5. Postal Code Resolution
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
from pak_geodata import find_area_by_postal_code, find_areas_by_postal_code
|
|
162
|
+
|
|
163
|
+
# Find primary area by 5-digit postal code
|
|
164
|
+
area = find_area_by_postal_code("54792")
|
|
165
|
+
print(area.name) # "DHA Phase 1"
|
|
166
|
+
|
|
167
|
+
# Find all areas sharing a postal code
|
|
168
|
+
all_dha = find_areas_by_postal_code("54792")
|
|
169
|
+
print(f"{len(all_dha)} areas share postal code 54792")
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Data Models
|
|
175
|
+
|
|
176
|
+
All models are immutable frozen dataclasses (`@dataclass(frozen=True)`):
|
|
177
|
+
|
|
178
|
+
### `Coordinates`
|
|
179
|
+
| Field | Type | Description |
|
|
180
|
+
|---|---|---|
|
|
181
|
+
| `lat` | `float` | WGS 84 latitude in decimal degrees |
|
|
182
|
+
| `lng` | `float` | WGS 84 longitude in decimal degrees |
|
|
183
|
+
|
|
184
|
+
### `PakistanProvince`
|
|
185
|
+
| Field | Type | Description |
|
|
186
|
+
|---|---|---|
|
|
187
|
+
| `id` | `str` | Canonical slug identifier (e.g. `'punjab'`, `'sindh'`) |
|
|
188
|
+
| `name` | `str` | English province name |
|
|
189
|
+
| `urdu_name` | `str` | Nastaliq Urdu name |
|
|
190
|
+
| `capital_city_id` | `str` | ID of capital city |
|
|
191
|
+
| `type` | `str` | Administrative type (`'province'`, `'federal_capital'`, `'autonomous_territory'`) |
|
|
192
|
+
|
|
193
|
+
### `PakistanCity`
|
|
194
|
+
| Field | Type | Description |
|
|
195
|
+
|---|---|---|
|
|
196
|
+
| `id` | `str` | Canonical slug identifier (e.g. `'lahore'`, `'karachi'`) |
|
|
197
|
+
| `name` | `str` | English city name |
|
|
198
|
+
| `urdu_name` | `str` | Nastaliq Urdu name |
|
|
199
|
+
| `province_id` | `str` | Enclosing province identifier |
|
|
200
|
+
| `district` | `str` | Enclosing administrative district |
|
|
201
|
+
| `coordinates` | `Coordinates` | City centroid coordinates |
|
|
202
|
+
| `division` | `Optional[str]` | Administrative division |
|
|
203
|
+
| `postal_code_range`| `Optional[List[str]]` | Range of postal codes |
|
|
204
|
+
| `bounds` | `Optional[CityBounds]`| Geographic bounding box |
|
|
205
|
+
| `total_areas_count`| `int` | Number of verified metropolitan areas |
|
|
206
|
+
|
|
207
|
+
### `PakistanArea`
|
|
208
|
+
| Field | Type | Description |
|
|
209
|
+
|---|---|---|
|
|
210
|
+
| `id` | `str` | Canonical slug (`<city-id>-<area-slug>`) |
|
|
211
|
+
| `city_id` | `str` | City identifier |
|
|
212
|
+
| `province_id` | `str` | Enclosing province identifier |
|
|
213
|
+
| `name` | `str` | Primary English area name |
|
|
214
|
+
| `aliases` | `List[str]` | Alternate names, abbreviations, and colloquial names |
|
|
215
|
+
| `coordinates` | `Optional[Coordinates]`| Centroid coordinates |
|
|
216
|
+
| `urdu_name` | `Optional[str]` | Nastaliq Urdu name |
|
|
217
|
+
| `postal_code` | `Optional[str]` | 5-digit Pakistan Post postal code |
|
|
218
|
+
| `type` | `Optional[str]` | Area type (`'neighborhood'`, `'suburb'`, `'commercial'`, `'housing_society'`, etc.) |
|
|
219
|
+
| `verified` | `bool` | True if verified against survey and GIS boundaries |
|
|
220
|
+
| `sources` | `List[str]` | Verification sources |
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## API Reference
|
|
225
|
+
|
|
226
|
+
| Function | Return Type | Description |
|
|
227
|
+
|---|---|---|
|
|
228
|
+
| `get_all_provinces()` | `List[PakistanProvince]` | Returns all 7 provinces/territories |
|
|
229
|
+
| `get_province_by_id(id)` | `Optional[PakistanProvince]` | Case-insensitive province lookup |
|
|
230
|
+
| `get_all_cities()` | `List[PakistanCity]` | Returns all 40 verified cities |
|
|
231
|
+
| `get_cities_by_province(province_id)` | `List[PakistanCity]` | Filters cities by province |
|
|
232
|
+
| `get_city_by_id(id)` | `Optional[PakistanCity]` | Finds city by canonical slug |
|
|
233
|
+
| `get_all_areas()` | `List[PakistanArea]` | Returns all verified areas (189 total) |
|
|
234
|
+
| `get_areas_by_city(city_id)` | `List[PakistanArea]` | Returns verified areas in a city |
|
|
235
|
+
| `search_areas(query, city_id=None, limit=None, province_id=None)` | `List[PakistanArea]` | Ranked multi-tier search |
|
|
236
|
+
| `find_area_by_postal_code(postal_code)` | `Optional[PakistanArea]` | Resolves area by 5-digit postal code |
|
|
237
|
+
| `find_areas_by_postal_code(postal_code)` | `List[PakistanArea]` | Returns all areas sharing a postal code |
|
|
238
|
+
| `haversine_distance_km(lat1, lng1, lat2, lng2)` | `float` | Spherical distance in kilometers |
|
|
239
|
+
| `get_nearest_area(lat, lng, city_id=None, max_distance_km=None, province_id=None)` | `Optional[PakistanArea]` | Spatial nearest neighbor resolver |
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## License
|
|
244
|
+
|
|
245
|
+
MIT © 2026 [Sohaib Bin Mohsin](https://sohaibbinmohsin.com) • [The Mohsin Project Global](https://themohsinproject.org)
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# pak-geodata
|
|
2
|
+
|
|
3
|
+
> Comprehensive, typed, offline geographic data for all areas and cities in Pakistan.
|
|
4
|
+
|
|
5
|
+
`pak-geodata` is an open-source, production-grade Python client library providing offline access to verified geographic data for Pakistan, created and maintained by [Sohaib Bin Mohsin](https://sohaibbinmohsin.com) at [The Mohsin Project Global](https://themohsinproject.org).
|
|
6
|
+
|
|
7
|
+
It covers all administrative provinces, 40 major cities, and foundational flagship metropolitan areas (sectors, housing schemes, neighborhoods, and commercial centers).
|
|
8
|
+
|
|
9
|
+
Designed with **zero runtime dependencies** (pure Python standard library), strict geofencing, and sub-millisecond lookups.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- **Zero Runtime Dependencies**: Powered entirely by the Python standard library (`dataclasses`, `json`, `math`, `re`, `pathlib`).
|
|
16
|
+
- **Offline & Self-Contained**: All verified golden datasets are bundled with the library: no remote API calls or internet access required.
|
|
17
|
+
- **Strict Geofencing & Validation**: Every coordinate is rigorously validated within Pakistan territorial boundaries (`23.5 <= lat <= 37.1`, `60.8 <= lng <= 77.8`) and city district bounding boxes.
|
|
18
|
+
- **Canonical Slugs**: Standardized `<city-slug>-<area-slug>` identifiers across all datasets (e.g. `lahore-dha-phase-5`).
|
|
19
|
+
- **Multi-Script & Alias Search**: Full support for English queries, colloquial aliases (e.g. `"dha 5"`), Urdu script queries (e.g. `"کلفٹن"`), and fuzzy typo tolerance.
|
|
20
|
+
- **Spatial Nearest Neighbor**: Instant reverse geocoding via spherical Haversine distance calculations.
|
|
21
|
+
- **Postal Code Resolution**: 5-digit Pakistan Post postal code lookup and reverse mapping.
|
|
22
|
+
- **Fully Typed & PEP 561 Compliant**: Includes `py.typed` marker and immutable frozen dataclasses for full IDE auto-completion.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install pak-geodata
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
### 1. Provinces & Cities
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from pak_geodata import (
|
|
40
|
+
get_all_provinces,
|
|
41
|
+
get_province_by_id,
|
|
42
|
+
get_all_cities,
|
|
43
|
+
get_cities_by_province,
|
|
44
|
+
get_city_by_id,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# List all 7 provinces and federal territories
|
|
48
|
+
provinces = get_all_provinces()
|
|
49
|
+
for p in provinces:
|
|
50
|
+
print(f"{p.name} ({p.urdu_name}) - Capital: {p.capital_city_id}")
|
|
51
|
+
|
|
52
|
+
# Find a province by ID
|
|
53
|
+
punjab = get_province_by_id("punjab")
|
|
54
|
+
print(punjab.name) # "Punjab"
|
|
55
|
+
|
|
56
|
+
# Retrieve all cities in a province
|
|
57
|
+
punjab_cities = get_cities_by_province("punjab")
|
|
58
|
+
print(f"Found {len(punjab_cities)} cities in Punjab")
|
|
59
|
+
|
|
60
|
+
# Get specific city details
|
|
61
|
+
lahore = get_city_by_id("lahore")
|
|
62
|
+
print(f"{lahore.name} coordinates: {lahore.coordinates.lat}, {lahore.coordinates.lng}")
|
|
63
|
+
print(f"Verified areas count: {lahore.total_areas_count}")
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 2. Areas by City
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from pak_geodata import get_areas_by_city
|
|
70
|
+
|
|
71
|
+
# Retrieve all verified areas for a city
|
|
72
|
+
lahore_areas = get_areas_by_city("lahore")
|
|
73
|
+
for area in lahore_areas[:5]:
|
|
74
|
+
print(f"{area.name} [{area.id}] - Postal Code: {area.postal_code}")
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 3. Intelligent Search
|
|
78
|
+
|
|
79
|
+
The search engine ranks results across multiple matching tiers:
|
|
80
|
+
1. Exact match on name, id, Urdu name, or alias
|
|
81
|
+
2. Prefix match
|
|
82
|
+
3. Substring / multi-word token match
|
|
83
|
+
4. Fuzzy edit-distance fallback for typos
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from pak_geodata import search_areas
|
|
87
|
+
|
|
88
|
+
# Search by colloquial alias scoped to a city
|
|
89
|
+
results = search_areas("dha 5", city_id="lahore")
|
|
90
|
+
print(results[0].id) # "lahore-dha-phase-5"
|
|
91
|
+
print(results[0].name) # "DHA Phase 5"
|
|
92
|
+
|
|
93
|
+
# Search using Urdu script
|
|
94
|
+
results = search_areas("کلفٹن")
|
|
95
|
+
for r in results:
|
|
96
|
+
print(f"{r.name} ({r.urdu_name}) in {r.city_id}")
|
|
97
|
+
|
|
98
|
+
# Scoped city search with limit
|
|
99
|
+
results = search_areas("phase", city_id="islamabad", limit=3)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 4. Reverse Geocoding & Spatial Nearest Neighbor
|
|
103
|
+
|
|
104
|
+
Find the closest verified neighborhood or society to given GPS coordinates:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
from pak_geodata import Coordinates, get_nearest_area, haversine_distance_km
|
|
108
|
+
|
|
109
|
+
# Distance calculation
|
|
110
|
+
lahore_lat, lahore_lng = 31.5204, 74.3587
|
|
111
|
+
rawalpindi_lat, rawalpindi_lng = 33.5651, 73.0169
|
|
112
|
+
distance_km = haversine_distance_km(lahore_lat, lahore_lng, rawalpindi_lat, rawalpindi_lng)
|
|
113
|
+
print(f"Distance: {distance_km:.2f} km")
|
|
114
|
+
|
|
115
|
+
# Nearest area from coordinates (or Coordinates object)
|
|
116
|
+
coords = Coordinates(lat=31.4581, lng=74.4121)
|
|
117
|
+
nearest = get_nearest_area(coords)
|
|
118
|
+
print(f"Nearest area: {nearest.name} ({nearest.id})")
|
|
119
|
+
|
|
120
|
+
# Filtered nearest search with maximum distance threshold
|
|
121
|
+
area_within_5km = get_nearest_area(
|
|
122
|
+
lat=33.5651,
|
|
123
|
+
lng=73.0169,
|
|
124
|
+
city_id="rawalpindi",
|
|
125
|
+
max_distance_km=5.0
|
|
126
|
+
)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### 5. Postal Code Resolution
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
from pak_geodata import find_area_by_postal_code, find_areas_by_postal_code
|
|
133
|
+
|
|
134
|
+
# Find primary area by 5-digit postal code
|
|
135
|
+
area = find_area_by_postal_code("54792")
|
|
136
|
+
print(area.name) # "DHA Phase 1"
|
|
137
|
+
|
|
138
|
+
# Find all areas sharing a postal code
|
|
139
|
+
all_dha = find_areas_by_postal_code("54792")
|
|
140
|
+
print(f"{len(all_dha)} areas share postal code 54792")
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Data Models
|
|
146
|
+
|
|
147
|
+
All models are immutable frozen dataclasses (`@dataclass(frozen=True)`):
|
|
148
|
+
|
|
149
|
+
### `Coordinates`
|
|
150
|
+
| Field | Type | Description |
|
|
151
|
+
|---|---|---|
|
|
152
|
+
| `lat` | `float` | WGS 84 latitude in decimal degrees |
|
|
153
|
+
| `lng` | `float` | WGS 84 longitude in decimal degrees |
|
|
154
|
+
|
|
155
|
+
### `PakistanProvince`
|
|
156
|
+
| Field | Type | Description |
|
|
157
|
+
|---|---|---|
|
|
158
|
+
| `id` | `str` | Canonical slug identifier (e.g. `'punjab'`, `'sindh'`) |
|
|
159
|
+
| `name` | `str` | English province name |
|
|
160
|
+
| `urdu_name` | `str` | Nastaliq Urdu name |
|
|
161
|
+
| `capital_city_id` | `str` | ID of capital city |
|
|
162
|
+
| `type` | `str` | Administrative type (`'province'`, `'federal_capital'`, `'autonomous_territory'`) |
|
|
163
|
+
|
|
164
|
+
### `PakistanCity`
|
|
165
|
+
| Field | Type | Description |
|
|
166
|
+
|---|---|---|
|
|
167
|
+
| `id` | `str` | Canonical slug identifier (e.g. `'lahore'`, `'karachi'`) |
|
|
168
|
+
| `name` | `str` | English city name |
|
|
169
|
+
| `urdu_name` | `str` | Nastaliq Urdu name |
|
|
170
|
+
| `province_id` | `str` | Enclosing province identifier |
|
|
171
|
+
| `district` | `str` | Enclosing administrative district |
|
|
172
|
+
| `coordinates` | `Coordinates` | City centroid coordinates |
|
|
173
|
+
| `division` | `Optional[str]` | Administrative division |
|
|
174
|
+
| `postal_code_range`| `Optional[List[str]]` | Range of postal codes |
|
|
175
|
+
| `bounds` | `Optional[CityBounds]`| Geographic bounding box |
|
|
176
|
+
| `total_areas_count`| `int` | Number of verified metropolitan areas |
|
|
177
|
+
|
|
178
|
+
### `PakistanArea`
|
|
179
|
+
| Field | Type | Description |
|
|
180
|
+
|---|---|---|
|
|
181
|
+
| `id` | `str` | Canonical slug (`<city-id>-<area-slug>`) |
|
|
182
|
+
| `city_id` | `str` | City identifier |
|
|
183
|
+
| `province_id` | `str` | Enclosing province identifier |
|
|
184
|
+
| `name` | `str` | Primary English area name |
|
|
185
|
+
| `aliases` | `List[str]` | Alternate names, abbreviations, and colloquial names |
|
|
186
|
+
| `coordinates` | `Optional[Coordinates]`| Centroid coordinates |
|
|
187
|
+
| `urdu_name` | `Optional[str]` | Nastaliq Urdu name |
|
|
188
|
+
| `postal_code` | `Optional[str]` | 5-digit Pakistan Post postal code |
|
|
189
|
+
| `type` | `Optional[str]` | Area type (`'neighborhood'`, `'suburb'`, `'commercial'`, `'housing_society'`, etc.) |
|
|
190
|
+
| `verified` | `bool` | True if verified against survey and GIS boundaries |
|
|
191
|
+
| `sources` | `List[str]` | Verification sources |
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## API Reference
|
|
196
|
+
|
|
197
|
+
| Function | Return Type | Description |
|
|
198
|
+
|---|---|---|
|
|
199
|
+
| `get_all_provinces()` | `List[PakistanProvince]` | Returns all 7 provinces/territories |
|
|
200
|
+
| `get_province_by_id(id)` | `Optional[PakistanProvince]` | Case-insensitive province lookup |
|
|
201
|
+
| `get_all_cities()` | `List[PakistanCity]` | Returns all 40 verified cities |
|
|
202
|
+
| `get_cities_by_province(province_id)` | `List[PakistanCity]` | Filters cities by province |
|
|
203
|
+
| `get_city_by_id(id)` | `Optional[PakistanCity]` | Finds city by canonical slug |
|
|
204
|
+
| `get_all_areas()` | `List[PakistanArea]` | Returns all verified areas (189 total) |
|
|
205
|
+
| `get_areas_by_city(city_id)` | `List[PakistanArea]` | Returns verified areas in a city |
|
|
206
|
+
| `search_areas(query, city_id=None, limit=None, province_id=None)` | `List[PakistanArea]` | Ranked multi-tier search |
|
|
207
|
+
| `find_area_by_postal_code(postal_code)` | `Optional[PakistanArea]` | Resolves area by 5-digit postal code |
|
|
208
|
+
| `find_areas_by_postal_code(postal_code)` | `List[PakistanArea]` | Returns all areas sharing a postal code |
|
|
209
|
+
| `haversine_distance_km(lat1, lng1, lat2, lng2)` | `float` | Spherical distance in kilometers |
|
|
210
|
+
| `get_nearest_area(lat, lng, city_id=None, max_distance_km=None, province_id=None)` | `Optional[PakistanArea]` | Spatial nearest neighbor resolver |
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## License
|
|
215
|
+
|
|
216
|
+
MIT © 2026 [Sohaib Bin Mohsin](https://sohaibbinmohsin.com) • [The Mohsin Project Global](https://themohsinproject.org)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""pak_geodata: Comprehensive, offline geographic data for all areas and cities in Pakistan."""
|
|
2
|
+
|
|
3
|
+
from .lookups import (
|
|
4
|
+
find_area_by_postal_code,
|
|
5
|
+
find_areas_by_postal_code,
|
|
6
|
+
get_all_areas,
|
|
7
|
+
get_all_cities,
|
|
8
|
+
get_all_provinces,
|
|
9
|
+
get_areas_by_city,
|
|
10
|
+
get_cities_by_province,
|
|
11
|
+
get_city_by_id,
|
|
12
|
+
get_nearest_area,
|
|
13
|
+
get_province_by_id,
|
|
14
|
+
haversine_distance_km,
|
|
15
|
+
search_areas,
|
|
16
|
+
)
|
|
17
|
+
from .models import (
|
|
18
|
+
CityBounds,
|
|
19
|
+
Coordinates,
|
|
20
|
+
PakistanArea,
|
|
21
|
+
PakistanCity,
|
|
22
|
+
PakistanProvince,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
__version__ = "0.1.0"
|
|
26
|
+
|
|
27
|
+
__all__ = [
|
|
28
|
+
"Coordinates",
|
|
29
|
+
"CityBounds",
|
|
30
|
+
"PakistanProvince",
|
|
31
|
+
"PakistanCity",
|
|
32
|
+
"PakistanArea",
|
|
33
|
+
"get_all_provinces",
|
|
34
|
+
"get_province_by_id",
|
|
35
|
+
"get_all_cities",
|
|
36
|
+
"get_cities_by_province",
|
|
37
|
+
"get_city_by_id",
|
|
38
|
+
"get_all_areas",
|
|
39
|
+
"get_areas_by_city",
|
|
40
|
+
"search_areas",
|
|
41
|
+
"find_area_by_postal_code",
|
|
42
|
+
"find_areas_by_postal_code",
|
|
43
|
+
"get_nearest_area",
|
|
44
|
+
"haversine_distance_km",
|
|
45
|
+
]
|