Metadata-Version: 2.4
Name: tiny-osm
Version: 0.1.0
Summary: Fetch OpenStreetMap road, waterway, and water-body data for a bounding box.
Project-URL: Changelog, https://github.com/cheginit/tiny-osm/blob/main/CHANGELOG.md
Project-URL: CI, https://github.com/cheginit/tiny-osm/actions
Project-URL: Documentation, https://cheginit.github.io/tiny-osm
Project-URL: Homepage, https://cheginit.github.io/tiny-osm
Project-URL: Issues, https://github.com/cheginit/tiny-osm/issues
Author-email: Taher Chegini <cheginit@gmail.com>
License: MIT
License-File: AUTHORS.md
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: httpx
Provides-Extra: dev
Requires-Dist: geopandas>=1; extra == 'dev'
Requires-Dist: git-cliff; extra == 'dev'
Requires-Dist: ipykernel; extra == 'dev'
Requires-Dist: ipywidgets; extra == 'dev'
Requires-Dist: jupytext; extra == 'dev'
Requires-Dist: matplotlib; extra == 'dev'
Requires-Dist: nbconvert; extra == 'dev'
Requires-Dist: orjson; extra == 'dev'
Requires-Dist: pyproj; extra == 'dev'
Requires-Dist: pytest; extra == 'dev'
Provides-Extra: docs
Requires-Dist: jupytext; extra == 'docs'
Requires-Dist: mike>=2; extra == 'docs'
Requires-Dist: mkdocs-jupyter; extra == 'docs'
Requires-Dist: mkdocs-materialx; extra == 'docs'
Requires-Dist: mkdocs>=1.6; extra == 'docs'
Requires-Dist: mkdocstrings[python]>=0.27; extra == 'docs'
Requires-Dist: ruff; extra == 'docs'
Provides-Extra: lint
Requires-Dist: codespell; extra == 'lint'
Requires-Dist: pre-commit; extra == 'lint'
Provides-Extra: test
Requires-Dist: coverage[toml]; extra == 'test'
Requires-Dist: pytest-cov; extra == 'test'
Requires-Dist: pytest-sugar; extra == 'test'
Provides-Extra: typecheck
Requires-Dist: pyright; extra == 'typecheck'
Description-Content-Type: text/markdown

# TinyOSM: Lightweight OpenStreetMap GeoJSON Fetcher

[![PyPI](https://img.shields.io/pypi/v/tiny-osm)](https://pypi.org/project/tiny-osm/)
[![Conda](https://img.shields.io/conda/vn/conda-forge/tiny-osm)](https://anaconda.org/conda-forge/tiny-osm)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/cheginit/tiny-osm/HEAD?labpath=docs%2Fexamples)

[![codecov](https://codecov.io/gh/cheginit/tiny-osm/graph/badge.svg?token=U2638J9WKM)](https://codecov.io/gh/cheginit/tiny-osm)
[![CI](https://github.com/cheginit/tiny-osm/actions/workflows/test.yml/badge.svg)](https://github.com/cheginit/tiny-osm/actions/workflows/test.yml)
[![Documentation](https://github.com/cheginit/tiny-osm/actions/workflows/docs.yml/badge.svg)](https://github.com/cheginit/tiny-osm/actions/workflows/docs.yml)
[![Downloads](https://static.pepy.tech/badge/tiny-osm)](https://pepy.tech/project/tiny-osm)

Fetch OpenStreetMap data for a bounding box as GeoJSON. One function, one dependency,
minimal footprint.

## Why

[OSMnx](https://github.com/gboeing/osmnx) is the go-to tool for working with
OpenStreetMap data in Python. It handles street-network analysis, building footprints,
amenity lookups, graph-theoretic routing, and more. But it pulls in `geopandas`,
`shapely`, and `networkx`, a heavy dependency stack, that can be slow to install in
constrained environments like AWS Lambda, minimal Docker images, or CI runners.

`tiny-osm` exists for the narrower case where you just need **OSM features as clean
GeoJSON**. It ships with presets for roads, waterways, and water bodies, and accepts any
Overpass QL tag-filter for custom queries. It has one runtime dependency (`httpx`),
installs in seconds, and returns standards-compliant GeoJSON that works with any
downstream tool such as `geopandas`, `shapely`, or even a JavaScript map library.

|               | `tiny-osm`              | `osmnx`                                      |
| ------------- | ----------------------- | -------------------------------------------- |
| Dependencies  | 1 (`httpx`)             | 7+ (`geopandas`, `shapely`, `networkx`, ...) |
| Output format | GeoJSON dicts           | GeoDataFrames/`networkx` graphs              |
| Scope         | Any Overpass tag-filter | Full OSM toolkit                             |
| API surface   | 1 function              | Dozens of modules                            |

## Installation

```console
pip install tiny-osm
```

Or with conda/pixi:

```console
pixi add tiny-osm
```

> **Tip:** If [`orjson`](https://github.com/ijl/orjson) is installed, `tiny-osm` uses it
> automatically for faster JSON parsing of Overpass API responses.

## Usage

```python
import tiny_osm

# Each call returns a GeoJSON FeatureCollection dict
bbox = (-97.75, 30.25, -97.70, 30.30)
highways = tiny_osm.fetch(*bbox, osm_filter=tiny_osm.OSMFilters.HIGHWAY)
waterways = tiny_osm.fetch(*bbox, osm_filter=tiny_osm.OSMFilters.WATERWAY)
water_bodies = tiny_osm.fetch(*bbox, osm_filter=tiny_osm.OSMFilters.WATER_BODY)

# Load into geopandas (optional - tiny-osm doesn't require it)
import geopandas as gpd

gdf = gpd.GeoDataFrame.from_features(highways, crs=4326)

# Custom Overpass QL filter
parks = tiny_osm.fetch(*bbox, osm_filter='["leisure"="park"]')
```

### Filters

| `osm_filter`            | What it queries                                                             |
| ----------------------- | --------------------------------------------------------------------------- |
| `OSMFilters.HIGHWAY`    | `highway=*` ways (excluding areas, abandoned, planned, raceway)             |
| `OSMFilters.WATERWAY`   | `waterway=*` ways                                                           |
| `OSMFilters.WATER_BODY` | Closed water features: ponds, lakes, reservoirs, detention/retention basins |
| any string              | Raw Overpass QL tag-filter (e.g. `'["amenity"="restaurant"]'`)              |

### What it handles

- Auto-subdivides large bounding boxes into tiles
- Retries across multiple Overpass API mirrors with automatic failover
- Assembles multi-polygon relations (ring stitching, hole assignment)
- Deduplicates elements across tile boundaries
- Applies the OSM polygon-features rule tree (area=yes/no, coastline exceptions, etc.)

## Contributing

Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for details.

## License

MIT License. See [LICENSE](LICENSE) for details.
