Skip to content

GeoDjango

changwu edited this page Mar 10, 2016 · 1 revision

GeoDjango

http://invisibleroads.com/tutorials/geodjango-googlemaps-build.html https://docs.djangoproject.com/en/dev/ref/contrib/gis/tutorial/ http://mutolisp.logdown.com/posts/192197

資料庫

1. PostGIS

$ brew install postgresql
$ brew install postgis
$ brew install gdal
$ brew install libgeoip

zshconfig

export PATH=/Library/Frameworks/UnixImageIO.framework/Programs:$PATH
export PATH=/Library/Frameworks/PROJ.framework/Programs:$PATH
export PATH=/Library/Frameworks/GEOS.framework/Programs:$PATH
export PATH=/Library/Frameworks/SQLite3.framework/Programs:$PATH
export PATH=/Library/Frameworks/GDAL.framework/Programs:$PATH
export PATH=/usr/local/pgsql/bin:$PATH

Creating a spatial database

$ createdb geodjango
$ psql geodjango

postgres# CREATE EXTENSION postgis;
postgres# CREATE USER geodjango PASSWORD 'my_passwd';
postgres# CREATE DATABASE geodjango OWNER geodjango;

2. SpatiaLite library (libspatialite)

SQLite3, SpatiaLite, PROJ, and GEOS

$ brew update
$ brew install spatialite-tools
$ brew install gdal

加入設定 settings.py

SPATIALITE_LIBRARY_PATH = '/usr/local/lib/mod_spatialite.dylib'

術語

  • raster data 網格資料

應用

新增專案與應用

$ mkdir geoApp
$ cd geoApp
$ django-admin startproject geodjango
$ cd geodjango
$ python manage.py startapp world

設定 settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.contrib.gis.db.backends.postgis',
        'NAME': 'geodjango',
        'USER': 'geo',
    }
}


INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.gis',
    'world'
)

下載地理資料

$ mkdir world/data
$ cd world/data
$ wget http://thematicmapping.org/downloads/TM_WORLD_BORDERS-0.3.zip
$ unzip TM_WORLD_BORDERS-0.3.zip
$ cd ../..

資料型態屬於 ESRI Shapefile

建立 models

models.py

from django.db import models

from django.contrib.gis.db import models


class WorldBorder(models.Model):
    name = models.CharField(max_length=50)
    area = models.IntegerField()
    po2005 = models.IntegerField('Population 2005')
    fips = models.CharField('FIPS Code', max_length=2)
    iso2 = models.CharField('2 Digit ISO', max_length=2)
    iso3 = models.CharField('3 Digit ISO', max_length=3)
    un = models.IntegerField('United Nations Code')
    region = models.IntegerField('Region Code')
    subregion = models.IntegerField('Sub-Region Code')
    lon = models.FloatField()
    lat = models.FloatField()

    mpoly = models.MultiPolygonField()

    def __str__(self):
        return self.name

Create a database migration

$ python manage.py makemigrations

Migrations for 'world':
  0001_initial.py:
    - Create model WorldBorder

Generate the table for the WorldBorder model

$ python manage.py sqlmigrate world 0001

BEGIN;
CREATE TABLE "world_worldborder" ("id" serial NOT NULL PRIMARY KEY, "name" varchar(50) NOT NULL, "area" integer NOT NULL, "po2005" integer NOT NULL, "fips" varchar(2) NOT NULL, "iso2" varchar(2) NOT NULL, "iso3" varchar(3) NOT NULL, "un" integer NOT NULL, "region" integer NOT NULL, "subregion" integer NOT NULL, "lon" double precision NOT NULL, "lat" double precision NOT NULL, "mpoly" geometry(MULTIPOLYGON,4326) NOT NULL);
CREATE INDEX "world_worldborder_mpoly_id" ON "world_worldborder" USING GIST ("mpoly" );

COMMIT;

Run migrate to create this table in the database

$ python manage.py migrate

Operations to perform:
  Synchronize unmigrated apps: staticfiles, gis, messages
  Apply all migrations: admin, world, contenttypes, auth, sessions
Synchronizing apps without migrations:
  Creating tables...
    Running deferred SQL...
  Installing custom SQL...
Running migrations:
  Rendering model states... DONE
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying sessions.0001_initial... OK
  Applying world.0001_initial... OK

load.py

import os

from django.contrib.gis.utils import LayerMapping
from models import WorldBorder

world_mapping = {
    'fips': 'FIPS',
    'iso2': 'ISO2',
    'iso3': 'ISO3',
    'un': 'UN',
    'name': 'NAME',
    'area': 'AREA',
    'pop2005': 'POP2005',
    'region': 'REGION',
    'subregion': 'SUBREGION',
    'lon': 'LON',
    'lat': 'LAT',
    'mpoly': 'MULTIPOLYGON',
}

world_shp = os.path.abspath(os.path.join(os.path.dirname(__file__), 'data', 'TM_WORLD_BORDERS-0.3.shp'))


def run(verbose=True):
    lm = LayerMapping(WorldBorder, world_shp, world_mapping,
                      transform=False, encoding='iso-8859-1')
    lm.save(strict=True, verbose=verbose)

admin.py

from django.contrib.gis import admin
from models import WorldBorder

admin.site.register(WorldBorder, admin.GeoModelAdmin)

urls.py

from django.conf.urls import include, url
from django.contrib.gis import admin

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
]

Clone this wiki locally