GeoDjango

 kiedy GIS spotyka Django

Krzysztof Żuraw

Dlaczego GeoDjango?

Python

Wspiera standard OGC

Django ORM

Wymagania

Postgres + PostGIS

GEOS

GDAL

PROJ 4

Dane

www.codgik.gov.pl/index.php/darmowe-dane/prg.html
$ ogrinfo -so PRG_jednostki_administracyjne_v10/województwa.shp województwa
# INFO: Open of `PRG_jednostki_administracyjne_v10/województwa.shp'
#      using driver `ESRI Shapefile' successful.

# Layer name: województwa
# Geometry: 3D Polygon
# Feature Count: 16
# Extent: (171677.555190, 133223.725152) - (861895.746988, 774923.747473)
# Layer SRS WKT:
# PROJCS["ETRS89 / Poland CS92",
#    GEOGCS["ETRS89",
#        DATUM["European Terrestrial Reference System 1989",
#            SPHEROID["GRS 1980",6378137.0,298.257222101],
#            TOWGS84[0,0,0]],
#        PRIMEM["Greenwich",0.0],
#        UNIT["Decimal Degree",0.017453292519943295]],
#    PROJECTION["Transverse_Mercator"],
#    PARAMETER["latitude_of_origin",0.0],
#    PARAMETER["central_meridian",18.999999999999982],
#    PARAMETER["scale_factor",0.9993],
#    PARAMETER["false_easting",500000.0],
#    PARAMETER["false_northing",-5300000.0],
#    UNIT["Meter",1.0],
    AUTHORITY["EPSG","2180"]]

Aktualnie stosowane układy współrzędnych w Polsce

 

  • 1992 (EPSG: 2180)
  • 2000 (EPSG od 2176 do 2179)

Inne potrzebne układy

  • WGS 84 (EPSG: 4326)
  • Google Mercator (EPSG: 3857)

models.py

# This is an auto-generated Django model module created by ogrinspect.
from django.contrib.gis.db import models

class Wojewodztwo(models.Model):
    # ... rest of fields here
    jpt_nazwa_field = models.CharField(max_length=255)
    # ... rest of fields here

    geom = models.MultiPolygonField(srid=2180)
    objects = models.GeoManager()

    def __str__(self):
        return self.jpt_nazwa

# Auto-generated `LayerMapping` dictionary for wojewodztwo model
wojewodztwo_mapping = {
    # ... 
    'jpt_nazwa_field' : 'jpt_nazwa_',
    # ...
    'geom' : 'MULTIPOLYGON',
}
$ ./manage.py ogrinspect data/PRG_jednostki_administracyjne_v10/województwa.shp województwa \
 --srid=2180 --mapping --multi > poland/models.py

load.py

import os
from django.contrib.gis.utils import LayerMapping
from .models import Wojewodztwo

wojewodztwo_mapping = {
    # ...
    'jpt_nazwa_field' : 'jpt_nazwa_',
    # ...
    'geom' : 'MULTIPOLYGON',
}


wojewodztwo_shp = os.path.abspath(os.path.join('data', 
                                               'PRG_jednostki_administracyjne_v10', 
                                               'województwa.shp'))


def run(verbose=True):
    lm = LayerMapping(Wojewodztwo, wojewodztwo_shp, wojewodztwo_mapping,
                      transform=False, encoding='iso-8859-1')

    lm.save(strict=True, verbose=verbose)

models. py cdn.

class Point(models.Model):
    name = models.CharField(max_length=200)
    geom = models.PointField('longitude/latitude', blank=True, null=True)
    objects = models.GeoManager()

load.py

from django.contrib.gis import geos

def point_run():
    with open(point_csv) as point_file:
        for line in point_file:
            name, lon, lat = line.split(',')
            point = "POINT(%s %s)" % (lat.strip(), lon.strip())
            Point.objects.create(name=name, geom=geos.fromstr(point))

admin.py

from django.contrib.gis import admin
from .models import Wojewodztwo, Point

admin.site.register(Wojewodztwo, admin.GeoModelAdmin)
admin.site.register(Point, admin.GeoModelAdmin)

Django ORM

>>> from poland.models import Wojewodztwo, Point
>>> dolnoslaskie = Wojewodztwo.objects.get(jpt_nazwa_field='dolnoslaskie')
>>> wroclaw_point = Point.objects.get(name='Wrocław')
>>> dolnoslaskie.geom.contains(wroclaw_point.geom)
False
>>> dolnoslaskie.geom.srid
2180
>>> wroclaw_point.geom.srid
4326
>>> wroclaw_point.geom.transform(2180)
>>> dolnoslaskie.geom.contains(wroclaw_point.geom)
True
>>> opolskie = Wojewodztwo.objects.get(jpt_nazwa_field='opolskie')
>>> dolnoslaskie.geom.touches(opolskie.geom)
True
>>> krakow_point = Point.objects.get(name='Kraków')
>>> wroclaw_point.geom.distance(krakow_point.geom)
236870.07759711944  # m
>>> qs = Point.objects.all().gml()
>>> qs[4].gml
'<gml:Point srsName="EPSG:4326"><gml:coordinates>17.0230635,51.1071531
</gml:coordinates></gml:Point>'
>>> qs = Point.objects.all().geojson()
>>> qs[4].geojson
    '{"type":"Point","coordinates":[17.0230635,51.1071531]}'

Django ORM cdn.

GeoJSON

{
    "type": "FeatureCollection",
    "crs": {
        "type": "name",
        "properties": {
            "name": "EPSG:4326"
        }
    },
    "features": [
        {
            "properties": {
                "name": "Rzesz\\u00f3w"
            },
            "type": "Feature",
            "geometry": {
                "coordinates": [
                    22.006124806535,
                    50.04015435
                ],
                "type": "Point"
            }
        },
...

views.py

from django.http import HttpResponse
from django.core.serializers import serialize
from .models import Point, Wojewodztwo

def points_view(request):
    points_as_geojson = serialize('geojson', Point.objects.all())
    return HttpResponse(points_as_geojson, content_type='json')

def wojewodztwa_view(request):
    wojewodztwa_as_geojson = serialize('geojson', Wojewodztwo.objects.all())
    return HttpResponse(wojewodztwa_as_geojson, content_type='json')

Leaflet.js

django-leaflet

+

index.html

{% load leaflet_tags %}
<head>
    {% leaflet_js %}
    {% leaflet_css %}
</head>
</body>
    {% leaflet_map "yourmap" %}
</body>
{% load leaflet_tags %}
{% load static %}
<head>
    <style media="screen">
        #yourmap { width:100%; height:100% }
    </style>
    {% leaflet_js %}
    {% leaflet_css %}
    <script src="{% static 'js/leaflet.ajax.min.js' %}"></script>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/spin.js/2.3.2/spin.min.js'></script>
    <script src="{% static 'js/leaflet.spin.js' %}"></script>
</head>
</body>
    <script type="text/javascript">
        function map_init_basic (map, options) {
            var geojsonPointLayer = new L.GeoJSON.AJAX("{% url 'points' %}", {
                onEachFeature:function(feature, layer) {
                     layer.bindPopup(feature.properties.name.toString());
                 }
             });
            geojsonPointLayer.addTo(map);
            var geojsonWojewodztwaLayer = new L.GeoJSON.AJAX("{% url 'wojewodztwa' %}");
            geojsonWojewodztwaLayer.addTo(map);
        }
    </script>
    {% leaflet_map "yourmap" callback="window.map_init_basic" %}
</body>
from django.contrib import admin
from .models import Wojewodztwo, Point
from leaflet.admin import LeafletGeoAdmin

admin.site.register(Wojewodztwo, LeafletGeoAdmin)
admin.site.register(Point, LeafletGeoAdmin)

Dziękuję za uwagę

krzysztofzuraw.github.io

Geodjango- kiedy GIS spotyka Django

By Krzysztof Żuraw

Geodjango- kiedy GIS spotyka Django

  • 1,485
Loading comments...

More from Krzysztof Żuraw