Metadata-Version: 2.4
Name: pygeokit
Version: 0.1.0
Summary: Offline geo features from lat/lon: country, cities, capitals, city types, distances, density, city structure
Author: A. Osinkin
License-Expression: MIT
Keywords: geo,features,geonames,machine learning,latitude,longitude
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy
Requires-Dist: pandas
Requires-Dist: scipy
Requires-Dist: scikit-learn
Provides-Extra: h3
Requires-Dist: h3; extra == "h3"
Dynamic: license-file

# pygeokit

Offline geo features from latitude / longitude for tabular ML: country, nearest and
main city, capitals, city types and sizes, distances, density of neighbours, ring /
sector / multi-core city structure, grids, and a few urban-economics formulas
(Reilly, Huff, Zipf). The city data is bundled, so nothing is downloaded at run time.

```
pip install pygeokit
```

Depends only on `numpy`, `pandas`, `scipy`, `scikit-learn`. `h3` is optional (`hex_cell`).

## Quick start

```python
import pygeokit as gk

gk.help()                                   # cheat sheet (in Russian)

X, cat = gk.make_X(df, "lat", "lon")        # ready matrix + categorical columns
model = CatBoostRegressor(cat_features=cat).fit(X, y)

feats = gk.get_features(df, lat_col="lat", lon_col="lon")   # reference features only

gk.get_country(55.75, 37.62)                # 'RU'
gk.get_capital("RU")                        # {'name': 'Moscow', 'lat': ..., ...}
gk.get_main_city(lat, lon)                  # biggest city within 60 km
gk.get_city_type(lat, lon)                  # capital / region_center / ... + size class
gk.haversine(lat1, lon1, lat2, lon2)        # km
```

## What is inside

| Group | Functions |
|---|---|
| Ready matrix for CatBoost | `make_X`, `cat_columns` |
| Everything at once | `get_features` |
| Cities and countries | `get_country`, `get_country_info`, `get_capital`, `get_nearest_city`, `get_main_city`, `get_city_type`, `dist_to_capital`, `load_cities`, `load_countries` |
| Distances | `haversine`, `manhattan`, `bearing`, `to_km`, `travel_minutes` |
| Your own points | `dist_to_nearest`, `count_within` |
| Density / neighbours | `neighbor_features`, `oof_neighbor_features` (leak-free target stats) |
| City structure | `find_centers`, `center_features`, `multi_center_features`, `city_shape` (ring / sector / multi-core heuristic) |
| Grids and validation | `grid_cell`, `hex_cell`, `spatial_groups`, `group_stats` |
| Urban economics | `city_gravity`, `huff_probabilities`, `reilly_breakpoint`, `zipf_expected` |

`city_type` comes from the GeoNames feature code: `PPLC` capital, `PPLA` region
center, `PPLA2` district center, `PPLA3/4/5` local center, `PPLX` city section,
everything else settlement. `size_class`: tiny < 10k, small < 50k, medium < 100k,
big < 250k, large < 1M, million.

`get_country` returns the country of the nearest city, so points right on a border
or far out at sea can get the neighbouring country.

## Leak-free neighbour target features

```python
tr_f = gk.oof_neighbor_features(train.lat, train.lon, y)                 # train rows
te_f = gk.neighbor_features(test.lat, test.lon, train.lat, train.lon, values=y)
```

## Building from source

The data files are not stored in the repository. Build them once:

```
python tools/build_data.py      # downloads GeoNames dumps (~12 MB)
python -m pytest tests          # tests use a tiny fake data set
python -m build
```

Set `PYGEOKIT_DATA_DIR` to use your own data directory.

## Data and license

Code: MIT. City and country data: [GeoNames](https://www.geonames.org), licensed
under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).
