Skip to content

Commit 099223d

Browse files
authored
Merge pull request #6 from SOORAJTS2001/feat/readthedocs
Add read the docs
2 parents 24704c4 + e3731cf commit 099223d

File tree

13 files changed

+773
-22
lines changed

13 files changed

+773
-22
lines changed

.readthedocs.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Read the Docs configuration file
2+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
3+
4+
# Required
5+
version: 2
6+
7+
# Set the OS, Python version, and other tools you might need
8+
build:
9+
os: ubuntu-24.04
10+
tools:
11+
python: "3.13"
12+
13+
# Build documentation in the "docs/" directory with Sphinx
14+
sphinx:
15+
configuration: docs/conf.py
16+
17+
# Optionally, but recommended,
18+
# declare the Python requirements required to build your documentation
19+
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
20+
python:
21+
install:
22+
- requirements: docs/requirements.txt

docs/Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Minimal makefile for Sphinx documentation
2+
#
3+
4+
# You can set these variables from the command line, and also
5+
# from the environment for the first two.
6+
SPHINXOPTS ?=
7+
SPHINXBUILD ?= sphinx-build
8+
SOURCEDIR = source
9+
BUILDDIR = build
10+
11+
# Put it first so that "make" without argument is like "make help".
12+
help:
13+
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14+
15+
.PHONY: help Makefile
16+
17+
# Catch-all target: route all unknown targets to Sphinx using the new
18+
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19+
%: Makefile
20+
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

docs/make.bat

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
@ECHO OFF
2+
3+
pushd %~dp0
4+
5+
REM Command file for Sphinx documentation
6+
7+
if "%SPHINXBUILD%" == "" (
8+
set SPHINXBUILD=sphinx-build
9+
)
10+
set SOURCEDIR=source
11+
set BUILDDIR=build
12+
13+
%SPHINXBUILD% >NUL 2>NUL
14+
if errorlevel 9009 (
15+
echo.
16+
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
17+
echo.installed, then set the SPHINXBUILD environment variable to point
18+
echo.to the full path of the 'sphinx-build' executable. Alternatively you
19+
echo.may add the Sphinx directory to PATH.
20+
echo.
21+
echo.If you don't have Sphinx installed, grab it from
22+
echo.https://www.sphinx-doc.org/
23+
exit /b 1
24+
)
25+
26+
if "%1" == "" goto help
27+
28+
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29+
goto end
30+
31+
:help
32+
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33+
34+
:end
35+
popd

docs/requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
myst-parser
2+
sphinx
3+
sphinxawesome-theme

docs/source/_static/custom.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/* Wrap long code lines instead of horizontal scroll */
2+
pre code {
3+
white-space: pre-wrap;
4+
word-break: break-word;
5+
}

docs/source/_static/img.png

187 KB
Loading

docs/source/conf.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Configuration file for the Sphinx documentation builder.
2+
#
3+
# For the full list of built-in configuration values, see the documentation:
4+
# https://www.sphinx-doc.org/en/master/usage/configuration.html
5+
6+
# -- Project information -----------------------------------------------------
7+
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
8+
9+
project = 'python-gazetteer'
10+
copyright = '2025, Sooraj Sivadasan'
11+
author = 'Sooraj Sivadasan'
12+
release = 'v0.1.0'
13+
14+
# -- General configuration ---------------------------------------------------
15+
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
16+
17+
extensions = [
18+
"myst_parser",
19+
]
20+
21+
templates_path = ['_templates']
22+
exclude_patterns = ["_build"]
23+
pygments_style = "one-dark"
24+
pygments_dark_style = "one-dark"
25+
26+
27+
28+
# -- Options for HTML output -------------------------------------------------
29+
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
30+
31+
html_theme = "sphinxawesome_theme"
32+
html_static_path = ['_static']
33+
html_theme_options = {
34+
"show_prev_next": True,
35+
"awesome_external_links": True,
36+
}
37+
html_css_files = [
38+
"custom.css",
39+
]
40+
source_suffix = {
41+
".rst": "restructuredtext",
42+
".md": "markdown",
43+
}
44+
html_sidebars = {
45+
"**": ["sidebar_main_nav_links.html", "sidebar_toc.html"]
46+
}
47+
html_title = "Python Gazetteer"
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Implementation
2+
## Why it was made ?
3+
4+
Latitude and longitude are precise but not meaningful on their own. Most systems and people reason in terms of places - cities, regions, and addresses, not raw coordinates. Converting lat - long into an address adds semantic context, making location data understandable, searchable, and actionable in real-world applications.
5+
6+
This method of converting coordinates into sensible locations is known as reverse geocoding
7+
They are heavily used in almost every customer facing applications like delivery, travel booking etc
8+
9+
Conventional way of doing was using commercial API's like Google Maps, Mapbox
10+
They are very much accurate, but costly in nature, also they come with various rate limits.
11+
For large data intensive applications this may incur as a limitation
12+
13+
Hence, there are Offline Reverse Geocoding libraries, they would be completely offline, since it runs on your machine
14+
there would be no rate limiting
15+
But they come at a cost of accuracy, their normal working procedure is to use a large point based dataset
16+
(most likely cities) coordinates and finding the nearest neighbour from the given coordinates using algorithms like
17+
`KDTree` from scipy
18+
19+
## Problem with the conventional approach
20+
Suppose we have a situation like this
21+
```{image} ../_static/img.png
22+
:alt: Reverse geocoding flow
23+
:width: 600px
24+
:align: center
25+
```
26+
Here, we are trying to find address of this given location (blue point), but the closes point
27+
to it is Lisbon, If you are naively using the nearest neighbour algorithm it is going to return
28+
the address of Lisbon, but that is wrong because the point is visibly inside the boundary of Vermount
29+
30+
## Our approach
31+
Instead of focusing entirely on points, we would be considering boundaries also.
32+
- Step 1
33+
- Find the nearest neighbouring boundaries from the given coordinate
34+
- This could be done by computing the centroid of polygons and use `KDTree`
35+
algorithm to get the nearest **boundaries**
36+
- By default, the nearest 3 neighbours are considered
37+
38+
- Step 2
39+
- Check whether which boundary encloses the given point
40+
41+
This approach gives a validation that the given point is actually inside that boundary
42+
43+
## Challenges
44+
**Storage**: This is one of the biggest challenges faced, because boundary data is huge, but
45+
Geoboundaries provide their simplified geometries free and open source, even though the total size
46+
was around 1.5 GB, so it was converted to WKB and stored inside sqlite for querying and filtering, hence the overall
47+
size reduced to around 90 MB
48+
49+
**Speed**: It was impractical to check boundary enclosure for every boundary there is, hence computed
50+
their centroid instead and use them for primary layer of filtering, and enclosure was validated
51+
on the fly, saving time and space

docs/source/index.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Python Gazetteer
2+
3+
A simple offline, fast and accurate boundary based reverse geocoding library in python
4+
5+
<table>
6+
<tbody>
7+
<tr>
8+
<td>Countries</td>
9+
<td>210+</td>
10+
</tr>
11+
<tr>
12+
<td>Boundaries</td>
13+
<td>145,000+</td>
14+
</tr>
15+
<tr>
16+
<td>Available Divisions</td>
17+
<td>ADM0, ADM1, ADM2/ADM3</td>
18+
</tr>
19+
</tbody>
20+
</table>
21+
22+
23+
```{toctree}
24+
:caption: Important links
25+
:maxdepth: 3
26+
27+
installation/index
28+
usage/index
29+
implementation/index
30+
```

docs/source/installation/index.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Installation Guide
2+
## How to install
3+
4+
Python Gazetteer is available in PyPI and could be installed via
5+
```bash
6+
pip install python-gazetteer
7+
```
8+
Or one could visit the release page from [here](https://github.com/SOORAJTS2001/gazetteer/releases) and download the source code<br>
9+
10+
This package is compatible with Python versions of `3.12` `3.13` and `3.14` and depends on
11+
following packages
12+
```md
13+
pydantic
14+
scipy
15+
shapely
16+
```

0 commit comments

Comments
 (0)