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.
Files changed (28) hide show
  1. pak_geodata-0.1.0/LICENSE +21 -0
  2. pak_geodata-0.1.0/PKG-INFO +245 -0
  3. pak_geodata-0.1.0/README.md +216 -0
  4. pak_geodata-0.1.0/pak_geodata/__init__.py +45 -0
  5. pak_geodata-0.1.0/pak_geodata/data/areas/islamabad-ict/islamabad.json +821 -0
  6. pak_geodata-0.1.0/pak_geodata/data/areas/punjab/faisalabad.json +531 -0
  7. pak_geodata-0.1.0/pak_geodata/data/areas/punjab/lahore.json +1124 -0
  8. pak_geodata-0.1.0/pak_geodata/data/areas/punjab/rawalpindi.json +626 -0
  9. pak_geodata-0.1.0/pak_geodata/data/areas/sindh/karachi.json +1122 -0
  10. pak_geodata-0.1.0/pak_geodata/data/cities/ajk.json +90 -0
  11. pak_geodata-0.1.0/pak_geodata/data/cities/balochistan.json +112 -0
  12. pak_geodata-0.1.0/pak_geodata/data/cities/gilgit-baltistan.json +90 -0
  13. pak_geodata-0.1.0/pak_geodata/data/cities/islamabad-ict.json +24 -0
  14. pak_geodata-0.1.0/pak_geodata/data/cities/kpk.json +134 -0
  15. pak_geodata-0.1.0/pak_geodata/data/cities/punjab.json +310 -0
  16. pak_geodata-0.1.0/pak_geodata/data/cities/sindh.json +134 -0
  17. pak_geodata-0.1.0/pak_geodata/data/provinces.json +51 -0
  18. pak_geodata-0.1.0/pak_geodata/lookups.py +477 -0
  19. pak_geodata-0.1.0/pak_geodata/models.py +125 -0
  20. pak_geodata-0.1.0/pak_geodata/py.typed +1 -0
  21. pak_geodata-0.1.0/pak_geodata.egg-info/PKG-INFO +245 -0
  22. pak_geodata-0.1.0/pak_geodata.egg-info/SOURCES.txt +26 -0
  23. pak_geodata-0.1.0/pak_geodata.egg-info/dependency_links.txt +1 -0
  24. pak_geodata-0.1.0/pak_geodata.egg-info/requires.txt +3 -0
  25. pak_geodata-0.1.0/pak_geodata.egg-info/top_level.txt +1 -0
  26. pak_geodata-0.1.0/pyproject.toml +70 -0
  27. pak_geodata-0.1.0/setup.cfg +4 -0
  28. 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
+ ]