# geolite <a href="https://www.buymeacoffee.com/pjpimentel"><img align=right width=150 src="https://img.buymeacoffee.com/button-api/?text=buy%20me%20a%20coffee&emoji=&slug=pjpimentel&button_colour=5F7FFF&font_colour=ffffff&font_family=Inter&outline_colour=000000&coffee_colour=FFDD01" /></a>
##### _making openstreetmap data usable by anyone: from `.osm.pbf` to the first query answer._
## open source geocode
[](https://github.com/pjpimentel/geolite/actions/workflows/11_crates_publish.yml)
[](https://sonarcloud.io/dashboard?branch=master&id=geolite)
[](https://sonarcloud.io/dashboard?branch=master&id=geolite)
[](https://crates.io/crates/geolite)
---
## getting started
### with cargo
```bash
$ cargo install geolite
$ geolite --version
$ geolite build brazil # needs +/- 45gb while building then +/- 3gb when finished
$ geolite http-server # open http://localhost:8080
```
### with docker
```bash
# command line
$ docker run pjpimentel/geolite:latest --version
# pre-built countries geocodes
$ docker run -p 8080:8080 pjpimentel/geolite:prebuilt-brazil
# open http://localhost:8080
```
---
## docs
1. [source code modules](src/readme.md)
1. [database](src/database/readme.md)
1. [osm-pbf-file](src/osm_pbf_file/readme.md)
1. [osm-tag](src/osm_tag/readme.md)
1. [osm-node](src/osm_node/readme.md)
1. [osm-way](src/osm_way/readme.md)
1. [osm-relation](src/osm_relation/readme.md)
1. [admin-level](src/admin_level/readme.md)
1. [admin-level-hierarchy](src/admin_level_hierarchy/readme.md)
1. [house-number](src/house_number/readme.md)
1. [address](src/address/readme.md)
1. [cli](src/interfaces/cli/)
1. [http](src/interfaces/http/readme.md)
1. [docker images](#docker-images)
1. [base image](#base-image)
1. [pre-built images](#pre-built-images)
1. [cookbook](#cookbook)
1. [execute all necessary steps](#execute-all-necessary-steps)
1. [extract each data from a pbf file](#extract-each-data-from-a-pbf-file)
1. [index extracted data](#index-extracted-data)
1. [optimize data](#optimize-data)
1. [query](#query)
1. [explore](#explore)
1. [merge separately-built databases](#merge-separately-built-databases)
1. [run the end-to-end suite](#run-the-end-to-end-suite)
---
## docker images
### base image
```bash
$ docker run pjpimentel/geolite:latest --version
$ docker run -t -v ./geolite-data:/.geolite pjpimentel/geolite:latest build brazil
```
### pre-built images
_size matters: once a country's data grows too large for a docker image, its pre-built image stops being updated and may be dropped._
```bash
docker run -p 8080:8080 pjpimentel/geolite:prebuilt-brazil
docker run -p 8080:8080 pjpimentel/geolite:prebuilt-brazil-YYYYMMDDHHMM
# open http://localhost:8080
```
#### available country list
| 1 | [brazil](https://hub.docker.com/layers/pjpimentel/geolite/prebuilt-brazil) | `docker run -p 8080:8080 pjpimentel/geolite:prebuilt-brazil` |
| 2 | [portugal](https://hub.docker.com/layers/pjpimentel/geolite/prebuilt-portugal) | `docker run -p 8080:8080 pjpimentel/geolite:prebuilt-portugal` |
| 3 | [argentina](https://hub.docker.com/layers/pjpimentel/geolite/prebuilt-argentina) | `docker run -p 8080:8080 pjpimentel/geolite:prebuilt-argentina` |
| 4 | [bolivia](https://hub.docker.com/layers/pjpimentel/geolite/prebuilt-bolivia) | `docker run -p 8080:8080 pjpimentel/geolite:prebuilt-bolivia` |
| 5 | [chile](https://hub.docker.com/layers/pjpimentel/geolite/prebuilt-chile) | `docker run -p 8080:8080 pjpimentel/geolite:prebuilt-chile` |
| 6 | [colombia](https://hub.docker.com/layers/pjpimentel/geolite/prebuilt-colombia) | `docker run -p 8080:8080 pjpimentel/geolite:prebuilt-colombia` |
| 7 | [ecuador](https://hub.docker.com/layers/pjpimentel/geolite/prebuilt-ecuador) | `docker run -p 8080:8080 pjpimentel/geolite:prebuilt-ecuador` |
| 8 | [guyana](https://hub.docker.com/layers/pjpimentel/geolite/prebuilt-guyana) | `docker run -p 8080:8080 pjpimentel/geolite:prebuilt-guyana` |
| 9 | [paraguay](https://hub.docker.com/layers/pjpimentel/geolite/prebuilt-paraguay) | `docker run -p 8080:8080 pjpimentel/geolite:prebuilt-paraguay` |
| 10 | [peru](https://hub.docker.com/layers/pjpimentel/geolite/prebuilt-peru) | `docker run -p 8080:8080 pjpimentel/geolite:prebuilt-peru` |
| 11 | [suriname](https://hub.docker.com/layers/pjpimentel/geolite/prebuilt-suriname) | `docker run -p 8080:8080 pjpimentel/geolite:prebuilt-suriname` |
| 12 | [uruguay](https://hub.docker.com/layers/pjpimentel/geolite/prebuilt-uruguay) | `docker run -p 8080:8080 pjpimentel/geolite:prebuilt-uruguay` |
| 13 | [venezuela](https://hub.docker.com/layers/pjpimentel/geolite/prebuilt-venezuela) | `docker run -p 8080:8080 pjpimentel/geolite:prebuilt-venezuela` |
| 14 | [netherlands](https://hub.docker.com/layers/pjpimentel/geolite/prebuilt-netherlands) | `docker run -p 8080:8080 pjpimentel/geolite:prebuilt-netherlands` |
| 15 | [switzerland](https://hub.docker.com/layers/pjpimentel/geolite/prebuilt-switzerland) | `docker run -p 8080:8080 pjpimentel/geolite:prebuilt-switzerland` |
---
## cookbook
### execute all necessary steps
```bash
$ geolite build brazil
# or with docker
$ docker run --rm -t -v ./geolite-data:/.geolite pjpimentel/geolite:latest build brazil
$ docker run --rm -p 8080:8080 -v ./geolite-data:/.geolite pjpimentel/geolite:latest http-server
```
### extract each data from a pbf file
```bash
$ geolite osm-pbf-file download brazil
$ geolite extract osm-pbf-blob-chunks brazil
$ geolite extract osm-pbf-header brazil
$ geolite extract osm-pbf-data brazil
$ geolite --preset brazil extract osm-admin-levels
$ geolite --preset brazil extract osm-house-numbers
```
### index extracted data
```bash
$ geolite index admin-levels-hierarchy
# folds the ways of one street into one row and clears the two indexes below
$ geolite optimize merge-admin-levels
$ geolite --preset brazil index user-friendly-name
$ geolite index coordinates
```
`geolite build` and `geolite merge` run the four steps in this order. `geolite index` without a
subcommand runs the three index steps and does not merge the streets.
### optimize data
```bash
$ geolite optimize delete-intermediary-data
$ geolite optimize sqlite-file
```
### query
```bash
$ geolite query "-23.970949,-46.318730"
$ geolite query "rua castro alves, embare, santos, sao paulo"
```
### explore
```bash
$ geolite http-server
```
### merge separately-built databases
```bash
# machine 1
$ geolite --sqlite-path sudeste.sqlite3 build sudeste
# machine 2
$ geolite --sqlite-path nordeste.sqlite3 build nordeste
# merge all builds into a new combined database (created fresh)
$ geolite --preset brazil merge brazil.sqlite3 sudeste.sqlite3 nordeste.sqlite3 ...
# or with docker
$ docker run --rm -t -v ./geolite-data:/.geolite pjpimentel/geolite:latest --sqlite-path /.geolite/sudeste.sqlite3 build sudeste
$ docker run --rm -t -v ./geolite-data:/.geolite pjpimentel/geolite:latest --sqlite-path /.geolite/nordeste.sqlite3 build nordeste
$ docker run --rm -t -v ./geolite-data:/.geolite pjpimentel/geolite:latest --preset brazil merge /.geolite/brazil.sqlite3 /.geolite/sudeste.sqlite3 /.geolite/nordeste.sqlite3
$ docker run --rm -p 8080:8080 -v ./geolite-data:/.geolite pjpimentel/geolite:latest --sqlite-path /.geolite/brazil.sqlite3 http-server
```
### run the end-to-end suite
```bash
$ cargo test --release --test '*' -- --ignored --nocapture
```
## question and answers
### a) why geolite?
"**geo**" comes from "**geo**code" and "**lite**" comes from "sq**lite**", no special meaning.
### b) where does the data come from?
the data comes from any `.osm.pbf` file (openstreetmap's protobuffer format). this project uses [geofabrik](https://download.geofabrik.de) as the initial source, which extracts its data from [openstreetmap](https://www.openstreetmap.org).
### c) which license applies?
the source code is under [agplv3](LICENSE) and its dependencies keep their own (all permissive: mit, apache-2.0, bsd, zlib, isc). databases built from openstreetmap data — including the ones shipped in the `prebuilt-*` images — are derivative databases under the [odbl](https://opendatacommons.org/licenses/odbl/), filtered and restructured for geocoding: © [openstreetmap contributors](https://www.openstreetmap.org/copyright).
### d) why build another geocoder?
two reasons, in this order: to practice rust on a problem large enough to be interesting, and because the alternatives i tried were a bit too complex for a quick run.
## license: [GNU AGPLv3](LICENSE)
---
##### _this is a *work in progress* and, for now, new patch versions have no backward-compatibility guarantees_