Skip to main content

dongnae v.0.3.0

Ultra-Lightweight, Dependency-Free Spatial Engine

  • dongnae is a dependency-free, pure Python library designed for high-performance reverse geocoding, radius search, spatial lookup, and Area-of-Effect lookup. It operates from self-contained native script & pre-rendered CSV dataframe. Designed for high-performance microservices and client-side applications.

    • Zero backend
    • Zero auth
    • Zero dependencies
  • It is optimized for local/regional datasets (e.g., Neighborhoods in a specific country) using latitude-based auto-calibration instead of expensive spherical trigonometry for every calculation.

Key Features

  • Quasi-Geocoding to Dongnae

    • Sometimes you just want to lookup roughly which neighborhood you are in.

    • Instead of precise street-level addresses, it maps coordinates to the nearest "Dongnae" (Neighborhood/District node), which is not quite precise but still good enough for some applications.

    • Key concept of this engine is "dongnae" - an object that has ID(dnid), Name(dnname), 2D coordinates(dnlatitude, dnlongitude), and radius(dnradius).

    • Dictionary of dongnaes should be loaded from CSV / JS prior to using this engine.

    • Recommended for lightweight, suggestion-based frontends; e.g. Web / PWAs.

  • Boundary Distance calculation

    • Calculates the ballpark 'Boundary Distance' from a specific coordinate to a target Dongnae.

    • Great for quickly looking up geopoints within Area-of-Effect from certain dongnae in kilometer scale.

    • Recommended for microsystem backend, AWS Lambda, embedded, push service, etc.

  • Zero Dependencies

    • Pure Python: Runs on pure Python & essential libraries (csv, math). No pip install required for dependencies.

    • Ultra lightweight : Does not require heavy GIS libraries (pandas, geopandas, or shapely)

  • Lightning Fast

    • Auto-Calibration: Computes the equirectangular (planar) distance coefficients once upon loading, avoiding repeated trigonometric operations (cos, sin) during queries.

    • Bounding-Box Pre-filtering: A dynamic BBox narrows the linear scan to a local candidate set before distance calculation. (A pre-filter, not a persistent spatial index — spatial queries remain O(n) over candidates; ID lookup is O(1).)

    • $O(1)$ ID Lookup: Instant retrieval by ID using an internal Hash Map.

    • In an internal benchmark with ROK Regional Geometry data, dongnae was ~15x faster than a VWorld API response, with a 71.67% top-1 / 97.31% top-3 neighbourhood hit rate against the API ground truth. (The speed gap is a local lookup vs a network call, not an algorithm-to-algorithm comparison.)

  • Self-contained

    • Zero backend : No networking, GIS server required

    • Zero dependencies : Runs on Python standard libraries (csv, math),

    • Zero authentication : No authentication, API key required

    • No network attack surface : The engine opens no network connections, so there is no remote attack surface. (You still control the local CSV / coordinate input you feed it — you can't remotely hack what doesn't quack.)

  • Business-Ready Logic:

    • Boundary Distance: Calculates distance from the edge of a neighborhood, not just the center.

    • Soft Geofencing: Determines if a point is "roughly" within neighborhood with an adjustable threshold.

    • Text Search: Built-in keyword search functionality.

    • Privacy by Design : No Personal Information including Geolocation sent outside.

Getting Started

1. Prerequisite: Data Format

You need a CSV file containing your local spatial nodes. The file must have the following headers:

Column Type Description
dnid String Unique Identifier (e.g., Zipcode, Legal Code)
dnname String Name of the area (e.g., "Gangnam-gu")
dnlatitude Float Y Coordinate
dnlongitude Float X Coordinate
dnradius Float Effective radius of the area (km)

2. Installation

  • dongnae — the engine only (bring your own CSV).
  • dongnae-kr — the engine plus a ready-made Korean Regional dataset CSV.
pip install dongnae       # engine only
pip install dongnae-kr    # engine + Korean dataset

3. Initiate Dongnae Engine & Load up Dongnae Dictionary

Using the dongnae-kr data package? Skip CSV loading entirely: from dongnae_kr import dongnaekr; engine = dongnaekr(). The snippet below is for loading your own CSV with the bare dongnae engine (which ships no data).

import sys
from dongnae import DongnaeEngine

csv_path = r"./data/dongnaeKR.csv" # Replace with the path to your own CSV

try:
    engine = DongnaeEngine() 
    engine.load(csv_path)
    print(f"Successfully loaded engine from {csv_path}")

    count = len(engine._dongnaes)
    print(f"   - Number of Dongnaes: {count:,}")
    print(f"   - Latitude Coefficient: {engine._lat_coef}")
    print(f"   - Longitude Coefficient: {engine._lon_coef}")

except Exception as e:
    print(f"[Fatal] Engine initiation failure: {e}")
    sys.exit(1)

Usage Examples

1. Reverse Geocoding (where)

Find the nearest neighborhood for a given coordinate.

lat, lon = 37.5665, 126.9780
town = engine.where(lat, lon)
if town:
    print(f"Welcome to {town['dnname']}!")

2. K-Nearest Neighbors (nearest)

Returns a list of k nearest nodes sorted by distance.

Find 3 nearest neighborhoods.

neighbors = engine.nearest(lat, lon, k=3)
for n in neighbors:
    print(f"- {n['dnname']} is {n['distance']}km away")

distance is a signed boundary distance in km — negative means the point is inside that neighbourhood's radius (so it can read as e.g. -0.08).

3. Radius Search (within)

Find all neighborhoods within a 2km radius.

spots = engine.within(lat, lon, radius_km=2.0)
print(f"Found {len(spots)} neighborhoods nearby.")

4. Soft Geofencing (resolve)

Determines if a coordinate falls within a neighborhood's effective radius, with an optional tolerance buffer (fuzziness). Useful for checking "if the user is inside certain district, with some padded buffer", e.g.;

  • threshold=1.0: Strict boundary.
  • threshold=1.2: 20% buffer zone (Loose).
matches = engine.resolve(lat, lon, threshold=1.2)
if matches:
    print(f"You are inside {matches[0]['dnname']}'s area.")

Search by name. Supports "Best Shot" (quasi-geocoding mode) or List return.

  • best_shot = True (default): Returns a single DongnaeData object. Can be utilized as approximate quasi-geocoding tool.
  • best_shot = False: Returns a list of candidates sorted by relevance score.
# 1. Best Shot (quasi-geocoding Mode)
best = engine.search("PalletTown", best_shot=True)
if best:
    print(f"Found: {best['dnname']}")

# 2. Search Mode
candidates = engine.search("PalletTown", best_shot=False)
for c in candidates:
    print(f"- {c['dnname']}")

6. ID Lookup (get)

Instant lookup by ID ($O(1)$).

info = engine.get("12345467890")
if info:
    print(f"Loaded: {info['dnname']} (Radius: {info['dnradius']}km)")

7. Boundary Distance Calculator (howfar)

Calculates the distance from a specific coordinate to the boundary of a target Dongnae. (Negative value means inside the boundary, Positive means outside)

target_id = "1234567890"
distance = engine.howfar(lat, lon, dnid=target_id)

if distance is not None:
    dn_info = engine.get(target_id)
    if distance < 0:
        print(f"You are INSIDE {dn_info['dnname']} ({-distance:.2f}km from edge)")
    else:
        print(f"You are OUTSIDE {dn_info['dnname']} ({distance:.2f}km to edge)")

API Reference

DongnaeEngine

__init__(csv_path: str = None)

Initializes the engine. If csv_path is provided, it calls load().

load(csv_path: str)

Loads CSV data, detects encoding (utf-8/cp949), builds the ID index, and auto-calculates distance coefficients based on the dataset's average latitude.

where(lat: float, lon: float) -> Optional[DongnaeData]

Returns the single nearest node. Returns None if no data is loaded.

nearest(lat: float, lon: float, k: int = 1, radius_km: float = None) -> List[DongnaeData]

Returns a list of k nearest nodes sorted by distance.

  • radius_km: Optimization parameter. Only searches within this radius (+ buffer).

within(lat: float, lon: float, radius_km: float, limit: int = None) -> List[DongnaeData]

Returns all nodes strictly within radius_km.

resolve(lat: float, lon: float, threshold: float = 1.0) -> List[DongnaeData]

Determines spatial inclusion.

  • Returns nodes where distance <= radius * (threshold - 1.0).

search(keyword: str, limit: int = 5, best_shot: bool = True) -> Union[List[DongnaeData], Optional[DongnaeData]]

Performs a text-based search.

  • best_shot=True (default): Returns a single DongnaeData object.
  • best_shot=False: Returns a list of candidates sorted by relevance score. If no match is found, returns None when best_shot=True, and an empty list [] when best_shot=False.

get(dnid: str) -> Optional[DongnaeData]

Retrieves a node by its dnid using a Hash Map ($O(1)$ complexity). If dnid is not within dictionary, returns None.

howfar(lat: float, lon: float, dnid: str) -> Optional[float]

Calculates the distance from a specific coordinate to the boundary of a target Dongnae. (Negative value means inside the boundary, Positive means outside) If dnid is not within dictionary, returns None.

Metadata

Release files for dongnae 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dongnae 0.3.0
File Size Uploaded
dongnae-0.3.0.tar.gz 14.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for dongnae 0.3.0
File Interpreter ABI Platform
dongnae-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 25.2 kB

Release files / dongnae-0.3.0.tar.gz

Download URL dongnae-0.3.0.tar.gz
Size 14.2 kB
Tags Source
SHA-256 checksum
How to use checksums
5991126a0e231e8b8fecb0e67ea7c3e20163504f3bf9460a1931611b56447f61
BLAKE2b-256 checksum
How to use checksums
d4174946dab7e25ec73553eaddec4676d3e33b25e56a3377833836117ad60856
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 23, 2026.

Transparency log

Release files / dongnae-0.3.0-py3-none-any.whl

Download URL dongnae-0.3.0-py3-none-any.whl
Size 11.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
24c809b00217a6314a97b6d32f0f9ae28d088d3734abdd6fc2b52492573096b0
BLAKE2b-256 checksum
How to use checksums
2892554a1236302cd4ad9a2a3d11f537c7f4b4306393a7dbf5a433a59b803475
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 23, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page