Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework #...

34
Maps with GeoDjango PostGIS and Leaflet Paolo Melchiorre @pauloxnet paulox.net 20tab.com

Transcript of Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework #...

Page 1: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

Mapswith GeoDjango

PostGISand Leaflet

Paolo Melchiorre@pauloxnet

paulox.net20tab.com

Page 2: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Paolo Melchiorre @pauloxnet

2

● Computer Science Engineer

● Python Developer since 2006

● PostgreSQL user (not a DBA)

● Django Developer since 2011

● Remote Worker since 2015

● Senior Developer at 20tab

Page 3: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

www.20tab.com

3

● Rome based with remote workers

● Meetup and conferences

● Agile and Lean methodologies

● Growth marketing

● Software development

● Python, Django, React JS, uWSGI

Page 4: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Goal

4

Find a simple way

to integrate a web map

in a Django project.

Page 5: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Outline

5

Basic map

GeoDjangoLeaflet JS

PostGISUse case

Page 6: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Web map

6

● Map delivered by GIS

● Static and Dynamic

● Interactive and view only

● Raster or Vector tiles

● Spatial databases

● Javascript library

Page 7: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

GeoDjango

7

● django.contrib.gis

● Geographic framework

● Spatial Field Types

● Spatial ORM queries

● Admin geometry fields

● Four database backends

Page 8: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

PostGIS

8

● Best GeoDjango backend

● PostgreSQL extension

● Integrated spatial data

● Spatial data types

● Spatial indexing

● Spatial functions

Page 9: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Leaflet

9

● JavaScript library for maps

● Free Software

● Desktop & Mobile friendly

● Light (> 40 KB of gizp JS)

● Well documented

● Simple, performing, usable

Page 10: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Basic map example

10

from django.db import models

class Blog(models.Model): name = models.CharField(max_length=100)

class Author(models.Model): name = models.CharField(max_length=200)

class Entry(models.Model): blog = models.ForeignKey(Blog, on_delete=models.CASCADE) authors = models.ManyToManyField(Author) headline = models.CharField(max_length=255)

Page 11: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Settings

11

INSTALLED_APPS = [ # … 'django.contrib.gis',]

DATABASES = {'default': { 'ENGINE': 'django.contrib.gis.db.backends.postgis', # …}}

Page 12: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Migrations

12

from django.contrib.postgres import operationsfrom django.db import migrations

class Migration(migrations.Migration): dependencies = [('blog', '0001_initial')] operations = [ operations.CreateExtension('postgis') ]

Page 13: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Models

13

from django.contrib.gis.db.models import PointFieldfrom django.db import models

class Entry(models.Model): # … point = PointField()

@property def lat_lng(self): return list(getattr(self.point, 'coords', [])[::-1])

Page 14: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Admin

14

from django.contrib import adminfrom django.contrib.gis.admin import OSMGeoAdminfrom .models import Entry

@admin.register(Entry)class EntryAdmin(OSMGeoAdmin): default_lon = 1400000 default_lat = 7495000 default_zoom = 12 # …

Page 15: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Admin page

15

Page 16: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Views and urls

16

from django.urls import pathfrom django.views.generic import ListViewfrom .models import Entry

class EntryList(ListView): queryset = Entry.objects.filter(point__isnull=False)

urlpatterns = [ path(map/', EntryList.as_view()),]

Page 17: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Template

17

<html><head> <link rel="stylesheet" href="//unpkg.com/leaflet/dist/leaflet.css"/> <script src="//unpkg.com/leaflet/dist/leaflet.js"></script></head>

<body><h1>DjangoCon Europe 2019 Venues</h1> <div id="m" style="width: 1920px; height: 1080px;"></div> <!-- add javascript here --></body></html>

Page 18: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Javascript

18

<script type="text/javascript">

var m = L.map('m').setView([55.67, 12.55], 13); # CPH

L.tileLayer('//{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(m);

{% for e in object_list %} L.marker({{e.lat_lng}}).addTo(m).bindPopup('{{e}}'); {% endfor %}

</script>

Page 19: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Basic map page

19

Page 20: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Mer et Demeures

20

● Coastal properties

● Active since 2014

● 8 Languages

● ~ 100k active advertisements

● ~ 40 Countries

● 6 Continents

Page 21: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Version 1.0

21

● Django 1.6

● Python 2.7

● PostgreSQL 9.3

● Textual Spatial Fields

● Leaflet 1.0

● Static/View-only map

Page 22: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Version 2.0

22

● Django 2.1 / GeoDjango

● Python 3.6

● PostgreSQL 10

● PostGIS 2.4 / Spatial data

● Leaflet 1.4

● Dynamic/Interactive map

Page 23: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Models

23

from django.db import modelsfrom django.contrib.gis.db.models import ( MultiPolygonField, PointField)

class City(models.Model): borders = MultiPolygonField()

class Ad(models.Model): city = models.ForeignKey(City, on_delete=models.CASCADE) location = PointField()

Page 24: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Setup

24

$ pip install djangorestframework # RESTful API$ pip install djangorestframework-gis # Geographic add-on$ pip install django-filter # Filtering support

INSTALLED_APPS = [ # … 'django.contrib.gis', 'rest_framework', 'rest_framework_gis', 'django_filters',]

Page 25: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Serializer

25

from rest_framework_gis.serializers import ( GeoFeatureModelSerializer)from .models import Ad

class AdSerializer(GeoFeatureModelSerializer): class Meta: model = Ad geo_field = 'location' fields = ('id',)

Page 26: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Views

from rest_framework.viewsets import ReadOnlyModelViewSetfrom rest_framework_gis.filters import InBBoxFilterfrom .models import Adfrom .serializers import AdSerializer

class AdViewSet(ReadOnlyModelViewSet): bbox_filter_field = 'location' filter_backends = (InBBoxFilter,) queryset = Ad.objects.filter(location__isnull=False) serializer_class = AdSerializer

26

Page 27: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Urls

from rest_framework.routers import DefaultRouterfrom .views import AdViewSet

router = DefaultRouter()router.register(r'markers', AdViewSet, basename='marker')urlpatterns = router.urls

27

Page 28: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

GeoJSON

{"type": "FeatureCollection", "features": [{ "id": 1, "type": "Feature", "geometry": { "type": "Point", "coordinates": [12.54, 55.66] }, "properties": {}}]}

28

Page 30: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Conclusion

30

● Out-of-the-box features

● Spatial & Relational queries

● Django/PostgreSQL

● Backend clusterization

● Administrative levels

● Dynamic spatial entity

Page 31: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Resources

31

● docs.djangoproject.com/en/

● github.com/django/django

● postgis.net/docs/

● github.com/postgis/postgis

● leafletjs.com/reference.html

● github.com/leaflet/leaflet

Page 32: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Acknowledgments

32

Mer et Demeuresmeretdemeures.com

[email protected]

> Hiring a Django developer !

Page 33: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

paulox.net20tab.com

Info

33

● www.paulox.net/talks

● Slides

● Code samples

● Resource URLs

● Questions and comments

● License (CC BY-SA)

Page 34: Paolo Melchiorre GeoDjango @pauloxnet with PostGIS...Setup 24 $ pip install djangorestframework # RESTful API $ pip install djangorestframework-gis # Geographic add-on $ pip install

Paolo Melchiorre www.paulox.net

@pauloxnet

Thank you!

paulox.net20tab.com