DjangSstreetMap is a Django application to load OSM data into a postgis database and deliver OSM data as MVT tiles.
"A vector tile is a lightweight data format for storing geospatial vector data"
For an introduction to MVT (Mapbox Vector Tiles) see the mapbox docs For an introduction to OSM see openstreetmap.org
This is a Django application to
- Import OSM data as Django models
- Expose Django models as MVT (Mapbox Vector Tile) geographic format data
Tile generation is much faster when geometry is in srid=3857 (or maybe with an index in that SRID?)
You need the gdal
libraries installed
On Ubuntu:
sudo apt install binutils libproj-dev gdal-bin
Otherwise refer to the Django docs "Installing geospatial libraries"
If necessary install psycopg2 in your env
Extend installed_apps with the following apps:
pip install osmflex
[
"django.contrib.gis",
"djangostreetmap",
"osmflex",
]
You likely want to set a fast cache for your tiles like Memcached. If this is not found
the default cache will be used; this can be a bit slower and is very much non persistent
This assumes you're running memcached (Linux: apt install memcached
) and installed memcached(pip install python-memcached
)
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
}
Run poetry install
To run pytest, you need to have an appropriate postgis database If you use docker one option is to run the following:
docker run \
--rm \
-p 49155:5432 \
--name=djangostreetmap \
-e POSTGRES_PASSWORD=post1234 \
postgis/postgis:14-3.2 \
-c fsync=off \
-c shared_buffers=4096MB
Run poetry run pytest
Runserver is "ok" but this recipe will give faster performance for demonstration purposes
pip install gunicorn
gunicorn -w 8 djangostreetmap.wsgi:application
poetry version patch poetry build poetry publish
To set up a new View, create a subclass of TileLayerView with some MvtQuery
instances as layers:
class RoadLayerView(TileLayerView):
layers = [
MvtQuery(table=OsmHighway._meta.db_table, attributes=["name"], filters=[f"\"highway\"='{road_class}'"], layer=road_class)
for road_class in ("primary", "secondary", "tertiary")
]
Append the URL to your urls.py as follows. Note the zoom, x and y are mandatory.
path("highways/<int:zoom>/<int:x>/<int:y>.pbf", RoadLayerView.as_view()),
docker run --name=osm \
-e POSTGRES_DB=postgres \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=post1234 \
-p 49155:5432 \
postgis/postgis:12-3.1
Find your port: if you do not use 49155
as above:
(env) josh@m4800:~/github/joshbrooks/djangostreetmap$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c619232fe38a postgis/postgis:12-3.1 "docker-entrypoint.s…" 33 seconds ago Up 32 seconds 0.0.0.0:49155->5432/tcp, :::49155->5432/tcp osm
...
OSM is on port 49155
To apply this to your project:
DATABASES = {
"default": {
"ENGINE": "django.contrib.gis.db.backends.postgis",
"USER": "postgres",
"PASSWORD": "post1233",
"HOST": "localhost",
"PORT": "49154",
"NAME": "postgres",
}
}
wget https://download.geofabrik.de/australia-oceania/papua-new-guinea-latest.osm.pbf
or
wget https://download.geofabrik.de/asia/east-timor-latest.osm.pbf
To run the management command below you'll need an osm2pgsql
version of around 1.3 or greater. This is not available in the ubuntu package manager (yet)...
The "osmflex" app has two management commands to run which will populate osmflex models
./manage.py run_osm2pgsql /media/josh/blackgate/osm/asia/east-timor-latest.osm.pbf
./manage.py import_from_pgosmflex
See the Django admin for osmflex:
http://localhost:8000/admin/osmflex
psql --host localhost --username postgres --port 49159
- Add a new Postgres Connection with the following settings:
Name: DjangoStreetMap Host: localhost Port: 49155 Database: postgres
Authentication: Basic postgres / post1233
Code is blacked, flaked, isorted and mypy'd.
pip install pre-commit