Offline, deterministic reverse geocoding for South Korean administrative divisions (WGS84 latitude/longitude to province / city / district / town / village).
Project description
krgc
Offline, deterministic reverse geocoding for South Korean administrative divisions.
Turn a (latitude, longitude) into the exact Korean administrative region that contains it —
province, city/district, town, and village — with no network, no API key, and no surprises.
Introduction
Korea has excellent reverse-geocoding services — Kakao, Naver — but they're effectively closed to developers abroad: getting an API key requires Korean identity verification, which you can't clear without a Korean phone number. So a developer outside Korea who simply needs to turn a coordinate into a Korean address often can't.
krgc exists to close that gap. The administrative boundaries are bundled into the package and every lookup is pure local geometry — no API key, no sign-up, no identity check, no network. Install it and it works, anywhere, the same way every time:
import krgc
krgc.lookup(33.4587, 126.9427)
# → Region(sido='제주특별자치도', sigungu='서귀포시', emd='성산읍', ri='성산리')
The coordinate above is Seongsan Ilchulbong, a well-known peak on Jeju Island. krgc resolves it
all the way down to the legal village (리), the same hierarchy used in an official Korean address.
Scope: krgc resolves coordinates within South Korea only. Any coordinate outside South Korea returns
None.
Install
pip install krgc
Requires Python 3.10+.
Quickstart
from krgc import lookup
# Default: resolve as deep as the data allows.
r = lookup(37.5663, 126.9779)
print(r) # 서울특별시 중구 태평로1가
print(r.sido) # 서울특별시
print(r.sigungu) # 중구
print(r.sigungu_code) # 11140
# Cap the depth you want.
lookup(37.5663, 126.9779, level="sido") # → 서울특별시
lookup(37.5663, 126.9779, level="sigungu") # → 서울특별시 중구
# Outside South Korea → None (krgc never guesses).
lookup(35.6762, 139.6503) # Tokyo → None
Coordinate order is
(latitude, longitude)— the order you read them aloud. Swapping lat/lon is the single most common geocoding bug, so krgc fixes the order and the names.
API
lookup(lat, lon, level="ri") -> Region | None
| Param | Type | Description |
|---|---|---|
lat |
float |
WGS84 latitude, -90 .. 90. |
lon |
float |
WGS84 longitude, -180 .. 180. |
level |
str |
Deepest level to resolve: "sido", "sigungu", "emd", or "ri" (default). Parent levels are always included. |
Returns a Region, or None if the point is in open sea or outside South Korea.
Raises ValueError for an out-of-range coordinate or an unknown level.
Region
A frozen dataclass carrying the administrative names and their codes:
| Field | Example | Field | Example | |
|---|---|---|---|---|
sido |
제주특별자치도 |
sido_code |
50 |
|
sigungu |
서귀포시 |
sigungu_code |
50130 |
|
emd |
성산읍 |
emd_code |
50130259 |
|
ri |
성산리 |
ri_code |
5013025921 |
A field is None when that level does not apply (e.g. ri in urban areas) or was capped by level.
str(region) joins the present names: "제주특별자치도 서귀포시 성산읍 성산리".
Administrative levels
| Level | Korean | Meaning | Count |
|---|---|---|---|
sido |
시 / 도 | Province / metropolitan city | 17 |
sigungu |
시 / 군 / 구 | City / county / district | ~250 |
emd |
읍 / 면 / 동 | Town / township / neighborhood | ~3,500 |
ri |
리 | Village (rural areas only) | ~15,000 |
Names are the legal administrative names (법정동), the ones used in official addresses.
How it works
Boundaries are converted to WGS84, simplified, and bundled as compact gzipped WKB. At lookup time krgc builds an in-memory STRtree and runs a point-in-polygon test, resolving at the deepest level that contains the point and deriving the parent regions from the hierarchical code. No projection, no network, no nondeterminism.
Data & license
- Code — MIT. See LICENSE.
- Boundary data — © National Geographic Information Institute (NGII), Ministry of Land,
Infrastructure and Transport, Republic of Korea: the Spatial Information Co-use dataset, via
data.go.kr (open public data,
이용허락범위: 제한 없음, source attribution). Base date 2023-09-15. Licensed separately from the code. - Administrative boundaries change over time. The snapshot date is documented, and the island/remote fixtures are regression-tested so a data update can't silently break them.
Contributing
Issues and PRs welcome.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file krgc-0.1.0.tar.gz.
File metadata
- Download URL: krgc-0.1.0.tar.gz
- Upload date:
- Size: 22.9 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
956fbcace5a9f561c45a594d1bf412bd05fc1339630fe337ca651aac78508b42
|
|
| MD5 |
95a73f923c0bf9716e904bf2413a7cc9
|
|
| BLAKE2b-256 |
7c9b225f678776d601a211d8178524941ad5601bd0a6337cde2f47a8cbbc4868
|
File details
Details for the file krgc-0.1.0-py3-none-any.whl.
File metadata
- Download URL: krgc-0.1.0-py3-none-any.whl
- Upload date:
- Size: 22.9 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c144a1978e39b716097973c4dbb081e422cdee4d3f617f6b21f23c5a7f28389
|
|
| MD5 |
48a341fda136b1a466ea8179b4a11534
|
|
| BLAKE2b-256 |
f69b359102950680ec6659a8bb43932a6d72f838bd734a4a805c0381394757c4
|