GeoDjango チュートリアルLink to this heading

はじめにLink to this heading

GeoDjangoは、Django用の標準のcontribモジュールであり、それを世界クラスの地理情報Webフレームワークに変えます。GeoDjangoは、位置情報サービスなどの地理情報Webアプリケーションを作成するのを可能な限り簡単にすることを目指しています。その特徴は次のとおりです:

  • OGC ジオメトリとラスターデータ用のDjangoモデルフィールド。

  • 空間データのクエリと操作のための Django の ORM の拡張機能。

  • GISジオメトリとラスタの操作、およびさまざまな形式のデータ操作のための、疎結合の高レベルPythonインターフェース。

  • admin アプリケーションからジオメトリフィールドを編集する

このチュートリアルは Django に慣れていることを前提にしています。従って、 Django が初めての方は、まず 通常のチュートリアル を読んで Django に慣れてください。

このチュートリアルでは、地理情報を表示するためのウェブアプリケーションの作成方法を説明します。このチュートリアルでは、world borders [1] を表示します。このチュートリアルで使用されるコードの一部は、GeoDjango basic apps プロジェクトから取得されたか、その影響を受けています。 [2]

セットアップLink to this heading

空間データベースを作成するLink to this heading

通常、特別な設定は必要ないので、他のプロジェクトと同じようにデータベースを作成できます。選択したデータベースについて、いくつかのヒントを提供します:

新しいプロジェクトを作成するLink to this heading

標準の django-admin スクリプトを使って、 geodjango というプロジェクトを作成します:

Linux / macOS

Shell
$ django-admin startproject geodjango

Windows

Windows
...\> django-admin startproject geodjango

これで新しいプロジェクトが初期化されます。ここで、 geodjango プロジェクトの中に world Django アプリケーションを作成します:

Linux / macOS

Shell
$ cd geodjango
$ python manage.py startapp world

Windows

Windows
...\> cd geodjango
...\> py manage.py startapp world

settings.py の設定Link to this heading

geodjango プロジェクトの設定は geodjango/settings.py ファイルに保存されています。データベース接続設定を編集して、自分の環境に合わせてください:

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

さらに、 INSTALLED_APPS 設定を変更して、 django.contrib.admin, django.contrib.gis, world (新しく作成したアプリケーション) を含めるようにします:

Code
INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "django.contrib.gis",
    "world",
]

地理データLink to this heading

世界の国境Link to this heading

世界の国境データはこの zip file にあります。アプリケーション worlddata ディレクトリを作成し、国境データをダウンロードして解凍してください。GNU/Linuxプラットフォームでは、以下のコマンドを使用します:

Linux / macOS

Shell
$ mkdir world/data
$ cd world/data
$ wget https://web.archive.org/web/20231220150759/https://thematicmapping.org/downloads/TM_WORLD_BORDERS-0.3.zip
$ unzip TM_WORLD_BORDERS-0.3.zip
$ cd ../..

Windows

Windows
...\> mkdir world\data
...\> cd world\data
...\> wget https://web.archive.org/web/20231220150759/https://thematicmapping.org/downloads/TM_WORLD_BORDERS-0.3.zip
...\> unzip TM_WORLD_BORDERS-0.3.zip
...\> cd ..\..

このZIPファイルには、最も一般的な地理空間データ形式の1つである ESRI Shapefile として知られているデータファイルが含まれています。解凍すると、world borders データセットには以下の拡張子のファイルが含まれます:

  • .shp: 世界の国境のジオメトリのベクトルデータを保持します。

  • .shx: .shp に保存されているジオメトリのための空間インデックスファイル。

  • .dbf: 整数や文字列フィールドなどの非ジオメトリ属性データを保持するデータベースファイル。

  • .prj: シェープファイルに格納されている地理データの空間参照情報が含まれています。

ogrinfo を使って空間データを調べるLink to this heading

GDAL の ogrinfo ユーティリティを使うと、シェープファイルやその他のベクトルデータソースのメタデータを調べることができます:

Linux / macOS

Shell
$ ogrinfo world/data/TM_WORLD_BORDERS-0.3.shp
INFO: Open of `world/data/TM_WORLD_BORDERS-0.3.shp'
      using driver `ESRI Shapefile' successful.
1: TM_WORLD_BORDERS-0.3 (Polygon)

Windows

Windows
...\> ogrinfo world\data\TM_WORLD_BORDERS-0.3.shp
INFO: Open of `world/data/TM_WORLD_BORDERS-0.3.shp'
      using driver `ESRI Shapefile' successful.
1: TM_WORLD_BORDERS-0.3 (Polygon)

ogrinfo によると、シェープファイルには1つのレイヤーがあり、そのレイヤーにはポリゴンデータが含まれています。詳細を知るために、レイヤー名を指定して -so オプションを使用して重要なサマリ情報のみを取得します:

Linux / macOS

Shell
$ ogrinfo -so world/data/TM_WORLD_BORDERS-0.3.shp TM_WORLD_BORDERS-0.3
INFO: Open of `world/data/TM_WORLD_BORDERS-0.3.shp'
      using driver `ESRI Shapefile' successful.

Layer name: TM_WORLD_BORDERS-0.3
Geometry: Polygon
Feature Count: 246
Extent: (-180.000000, -90.000000) - (180.000000, 83.623596)
Layer SRS WKT:
GEOGCS["GCS_WGS_1984",
    DATUM["WGS_1984",
        SPHEROID["WGS_1984",6378137.0,298.257223563]],
    PRIMEM["Greenwich",0.0],
    UNIT["Degree",0.0174532925199433]]
FIPS: String (2.0)
ISO2: String (2.0)
ISO3: String (3.0)
UN: Integer (3.0)
NAME: String (50.0)
AREA: Integer (7.0)
POP2005: Integer (10.0)
REGION: Integer (3.0)
SUBREGION: Integer (3.0)
LON: Real (8.3)
LAT: Real (7.3)

Windows

Windows
...\> ogrinfo -so world\data\TM_WORLD_BORDERS-0.3.shp TM_WORLD_BORDERS-0.3
INFO: Open of `world/data/TM_WORLD_BORDERS-0.3.shp'
      using driver `ESRI Shapefile' successful.

Layer name: TM_WORLD_BORDERS-0.3
Geometry: Polygon
Feature Count: 246
Extent: (-180.000000, -90.000000) - (180.000000, 83.623596)
Layer SRS WKT:
GEOGCS["GCS_WGS_1984",
    DATUM["WGS_1984",
        SPHEROID["WGS_1984",6378137.0,298.257223563]],
    PRIMEM["Greenwich",0.0],
    UNIT["Degree",0.0174532925199433]]
FIPS: String (2.0)
ISO2: String (2.0)
ISO3: String (3.0)
UN: Integer (3.0)
NAME: String (50.0)
AREA: Integer (7.0)
POP2005: Integer (10.0)
REGION: Integer (3.0)
SUBREGION: Integer (3.0)
LON: Real (8.3)
LAT: Real (7.3)

この詳細なサマリー情報には、レイヤー内のフィーチャ数 (246)、データの地理的範囲、空間参照システム ("SRS WKT")、および各属性フィールドの型情報が記載されています。たとえば、FIPS: String (2.0) は、 FIPS 文字列フィールドの最大長が2であることを示しています。同様に、 LON: Real (8.3) は、最大8桁までの浮動小数点フィールドで、小数点以下3桁までの数字を保持します。

地理情報モデルLink to this heading

地理情報モデルを定義するLink to this heading

さて、 ogrinfo を使ってデータセットを調べたので、このデータを表す GeoDjango モデルを作成しましょう:

Code
from django.contrib.gis.db import models


class WorldBorder(models.Model):
    # Regular Django fields corresponding to the attributes in the
    # world borders shapefile.
    name = models.CharField(max_length=50)
    area = models.IntegerField()
    pop2005 = models.IntegerField("Population 2005")
    fips = models.CharField("FIPS Code", max_length=2, null=True)
    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()

    # GeoDjango-specific: a geometry field (MultiPolygonField)
    mpoly = models.MultiPolygonField()

    # Returns the string representation of the model.
    def __str__(self):
        return self.name

models モジュールが django.contrib.gis.db からインポートされていることに注意してください。

ジオメトリフィールドのデフォルトの空間参照系は WGS84 です (SRID は 4326 を意味します) 。つまり、フィールドの座標は度単位の経度、緯度のペアです。別の座標系を使用するには、srid 引数を使用してジオメトリフィールドの SRID を設定します。座標系の EPSG コードを表す整数を使用します。

migrate を実行するLink to this heading

モデルを定義した後、データベースと同期する必要があります。まず、データベースマイグレーションを作成してください:

Linux / macOS

Shell
$ python manage.py makemigrations
Migrations for 'world':
  world/migrations/0001_initial.py:
    - Create model WorldBorder

Windows

Windows
...\> py manage.py makemigrations
Migrations for 'world':
  world/migrations/0001_initial.py:
    - Create model WorldBorder

WorldBorder モデルのテーブルを生成するSQLを見てみましょう:

Linux / macOS

Shell
$ python manage.py sqlmigrate world 0001

Windows

Windows
...\> py manage.py sqlmigrate world 0001

このコマンドを実行すると、次の出力が生成されるはずです:

SQL
BEGIN;
--
-- Create model WorldBorder
--
CREATE TABLE "world_worldborder" (
    "id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
    "name" varchar(50) NOT NULL,
    "area" integer NOT NULL,
    "pop2005" 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;

これが正しければ、 migrate を実行して、このテーブルをデータベースに作成してください。

Linux / macOS

Shell
$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions, world
Running migrations:
  ...
  Applying world.0001_initial... OK

Windows

Windows
...\> py manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions, world
Running migrations:
  ...
  Applying world.0001_initial... OK

空間データをインポートするLink to this heading

このセクションでは、 LayerMapping データインポートユーティリティ を使用して、GeoDjangoモデルを介して世界の国境のシェープファイルをデータベースにインポートする方法を紹介します。

空間データベースにデータをインポートする方法は色々あります。GeoDjango に含まれるツール以外にも、以下のような方法があります:

  • ogr2ogr は、GDAL に含まれるコマンドラインユーティリティであり、多くのベクトルデータ形式を PostGIS、MySQL、および Oracle データベースにインポートできます。

  • shp2pgsql: このユーティリティはPostGISに含まれ、ESRI shapefileをPostGISにインポートします。

GDAL インターフェースLink to this heading

先ほど、 ogrinfo を使って世界の国境のシェープファイルの中身を調べましたね。GeoDjango には、GDAL の強力な OGR ライブラリへの Pythonic インタフェースも含まれており、 OGR がサポートしている全てのベクトルデータソースを扱うことができます。

まず、Django シェルを起動します:

Linux / macOS

Shell
$ python manage.py shell

Windows

Windows
...\> py manage.py shell

チュートリアルの最初の方で 世界の国境 データをダウンロードしている場合は、Pythonの pathlib.Path を使用してそのパスを指定できます:

Python console
>>> from pathlib import Path
>>> import world
>>> world_shp = Path(world.__file__).resolve().parent / "data" / "TM_WORLD_BORDERS-0.3.shp"

ここで、GeoDjango の DataSource インタフェースを使って、 world borders shapefile を開いてください:

Python console
>>> from django.contrib.gis.gdal import DataSource
>>> ds = DataSource(world_shp)
>>> print(ds)
/ ... /geodjango/world/data/TM_WORLD_BORDERS-0.3.shp (ESRI Shapefile)

データソースオブジェクトは異なるレイヤーの地理空間フィーチャを持つことができます。しかし、シェープファイルは 1 つのレイヤーしか持つことができません:

Python console
>>> print(len(ds))
1
>>> lyr = ds[0]
>>> print(lyr)
TM_WORLD_BORDERS-0.3

レイヤーのジオメトリタイプと、含まれているフィーチャの数を確認できます:

Python console
>>> print(lyr.geom_type)
Polygon
>>> print(len(lyr))
246

Layer には関連付けられた空間参照システムも存在する場合があります。もしそうであれば、srs 属性は SpatialReference オブジェクトを返します。

Python console
>>> srs = lyr.srs
>>> print(srs)
GEOGCS["WGS 84",
DATUM["WGS_1984",
    SPHEROID["WGS 84",6378137,298.257223563,
        AUTHORITY["EPSG","7030"]],
    AUTHORITY["EPSG","6326"]],
PRIMEM["Greenwich",0,
    AUTHORITY["EPSG","8901"]],
UNIT["degree",0.0174532925199433,
    AUTHORITY["EPSG","9122"]],
AXIS["Latitude",NORTH],
AXIS["Longitude",EAST],
AUTHORITY["EPSG","4326"]]
>>> srs.proj  # PROJ representation
'+proj=longlat +datum=WGS84 +no_defs'

このシェープファイルは一般的なWGS84空間参照システム、つまりデータは度の単位で経度緯度の組を使用しています。

さらに、シェープファイルは追加データを含む属性フィールドもサポートしています。以下はWorld Bordersレイヤーのフィールドです:

Code
>>> print(lyr.fields)
['FIPS', 'ISO2', 'ISO3', 'UN', 'NAME', 'AREA', 'POP2005', 'REGION', 'SUBREGION', 'LON', 'LAT']

以下のコードで、各フィールドに関連するOGRタイプ (整数や文字列など) を調べることができます:

Code
>>> [fld.__name__ for fld in lyr.field_types]
['OFTString', 'OFTString', 'OFTString', 'OFTInteger', 'OFTString', 'OFTInteger', 'OFTInteger64', 'OFTInteger', 'OFTInteger', 'OFTReal', 'OFTReal']

レイヤー内の各フィーチャをイテレートし、フィーチャのジオメトリ (geom 属性でアクセス) とフィーチャの属性フィールド (get() メソッドで にアクセス) の両方から情報を抽出できます:

Python console
>>> for feat in lyr:
...     print(feat.get("NAME"), feat.geom.num_points)
...
Guernsey 18
Jersey 26
South Georgia South Sandwich Islands 338
Taiwan 363

Layer オブジェクトはスライス可能です。

Python console
>>> lyr[0:2]
[<django.contrib.gis.gdal.feature.Feature object at 0x2f47690>, <django.contrib.gis.gdal.feature.Feature object at 0x2f47650>]

また、個々のフィーチャは、フィーチャ ID で検索できます:

Python console
>>> feat = lyr[234]
>>> print(feat.get("NAME"))
San Marino

国境ジオメトリは、WKT および GeoJSON としてエクスポートできます:

Python console
>>> geom = feat.geom
>>> print(geom.wkt)
POLYGON ((12.415798 43.957954,12.450554 ...
>>> print(geom.json)
{ "type": "Polygon", "coordinates": [ [ [ 12.415798, 43.957954 ], [ 12.450554, 43.979721 ], ...

LayerMappingLink to this heading

データをインポートするには、Pythonスクリプト内で LayerMapping を使用します。次のコードを含む world アプリケーション内に load.py というファイルを作成してください:

Code
from pathlib import Path
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 = Path(__file__).resolve().parent / "data" / "TM_WORLD_BORDERS-0.3.shp"


def run(verbose=True):
    lm = LayerMapping(WorldBorder, world_shp, world_mapping, transform=False)
    lm.save(strict=True, verbose=verbose)

何が起こっているかについての、ちょっとしたノート:

  • world_mapping 辞書の各キーは WorldBorder モデル内のフィールドに対応します。値はデータが読み込まれる shapefile フィールドの名前です。

  • ジオメトリフィールドのキー mpolyMULTIPOLYGON で、 GeoDjango がこのフィールドをインポートするジオメトリタイプです。シェープファイル内の単純なポリゴンも、データベースに挿入する前に自動的にコレクションに変換されます。

  • シェープファイルへのパスは絶対パスではないことに注意してください。つまり、 world アプリケーション ( data サブディレクトリを含む) を別の場所に移動しても、スクリプトは動作します。

  • transform キーワードは False に設定されています。なぜなら、shapefile のデータは変換する必要がないためです。これはすでに WGS84 (SRID=4326) であるからです。

その後、geodjango プロジェクトディレクトリから Django シェルを呼び出してください。

Linux / macOS

Shell
$ python manage.py shell

Windows

Windows
...\> py manage.py shell

次に、load モジュールをインポートし、 run ルーチンを呼び出して、 LayerMapping が作業を行う様子を見てください:

Python console
>>> from world import load
>>> load.run()

ogrinspect を試すLink to this heading

LayerMapping データインポートユーティリティ で地理情報モデルを定義し、データをインポートする方法を説明しましたが、 ogrinspect 管理コマンドを使用することで、このプロセスをさらに自動化できます。 ogrinspect コマンドは GDAL がサポートするベクトルデータソース (例えばシェープファイル) をイントロスペクトし、モデル定義と LayerMapping 辞書を自動的に生成します。

コマンドの一般的な使用法は以下の通りです:

Linux / macOS

Shell
$ python manage.py ogrinspect [options] <data_source> <model_name> [options]

Windows

Windows
...\> py manage.py ogrinspect [options] <data_source> <model_name> [options]

data_source は GDAL がサポートするデータソースへのパスであり、 model_name はモデルに使用する名前である。コマンドラインオプションを使用すると、モデルの生成方法をさらに定義できます。

たとえば、以下のコマンドを実行すると、ほぼ先ほど作成した WorldBorder モデルとマッピング辞書を自動的に再現します。

Linux / macOS

Shell
$ python manage.py ogrinspect world/data/TM_WORLD_BORDERS-0.3.shp WorldBorder \
    --srid=4326 --mapping --multi

Windows

Windows
...\> py manage.py ogrinspect world\data\TM_WORLD_BORDERS-0.3.shp WorldBorder \
    --srid=4326 --mapping --multi

上記のコマンドラインオプションに関していくつかの注意点があります:

  • --srid=4326 オプションは、地理フィールドのSRIDを設定します。

  • --mapping オプションは、ogrinspect に、 LayerMapping と一緒に使用するマッピング辞書を生成するよう指示します。

  • オプション --multi を指定すると、地理フィールドが単なる PolygonField ではなく MultiPolygonField になります。

このコマンドは次のような出力をします。GeoDjango アプリケーションの models.py に直接コピーできます:

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


class WorldBorder(models.Model):
    fips = models.CharField(max_length=2)
    iso2 = models.CharField(max_length=2)
    iso3 = models.CharField(max_length=3)
    un = models.IntegerField()
    name = models.CharField(max_length=50)
    area = models.IntegerField()
    pop2005 = models.IntegerField()
    region = models.IntegerField()
    subregion = models.IntegerField()
    lon = models.FloatField()
    lat = models.FloatField()
    geom = models.MultiPolygonField(srid=4326)


# Auto-generated `LayerMapping` dictionary for WorldBorder model
worldborders_mapping = {
    "fips": "FIPS",
    "iso2": "ISO2",
    "iso3": "ISO3",
    "un": "UN",
    "name": "NAME",
    "area": "AREA",
    "pop2005": "POP2005",
    "region": "REGION",
    "subregion": "SUBREGION",
    "lon": "LON",
    "lat": "LAT",
    "geom": "MULTIPOLYGON",
}

空間クエリLink to this heading

空間のルックアップ (Spatial Lookup)Link to this heading

GeoDjango は Django の ORM に空間ルックアップを追加します。たとえば、特定の地点を含む WorldBorder テーブルの国を見つけることができます。まず、管理シェルを起動してください:

Linux / macOS

Shell
$ python manage.py shell

Windows

Windows
...\> py manage.py shell

ここで、注目するポイント [3] を定義します:

Python console
>>> pnt_wkt = "POINT(-95.3385 29.7245)"

pnt_wkt 文字列は、経度 -95.3385 度、緯度 29.7245 度にある点を表します。この幾何情報は Well Known Text (WKT) として知られる形式で表されており、これは Open Geospatial Consortium (OGC) によって発行された標準です。 [4] WorldBorder モデルをインポートし、pnt_wkt をパラメータとして使用して contains ルックアップを実行します:

Python console
>>> from world.models import WorldBorder
>>> WorldBorder.objects.filter(mpoly__contains=pnt_wkt)
<QuerySet [<WorldBorder: United States>]>

ここでは、米国の国境という1つのモデルのみを持つ QuerySet を取得しました (まさに期待通りです)。

同様に、 GEOS ジオメトリオブジェクト を使用することもできます。ここでは、 intersects 空間ルックアップと get メソッドを組み合わせて、クエリセットの代わりにサンマリノの WorldBorder インスタンスのみを取得できます:

Python console
>>> from django.contrib.gis.geos import Point
>>> pnt = Point(12.4604, 43.9420)
>>> WorldBorder.objects.get(mpoly__intersects=pnt)
<WorldBorder: San Marino>

containsintersects のルックアップは利用可能なクエリの一部です。 GeoDjango データベース API のドキュメントにはさらに多くの内容があります。

座標系の自動変換Link to this heading

空間クエリを実行する際、GeoDjango は、異なる座標系のジオメトリを自動的に変換します。次の例では、座標は EPSG SRID 32140 、テキサス州南部に固有の座標系であり、単位は ではなく メートル で表されます。

Python console
>>> from django.contrib.gis.geos import GEOSGeometry, Point
>>> pnt = Point(954158.1, 4215137.1, srid=32140)

pnt は、SRIDを含むWKTの拡張形式であるEWKTで構築することもできることに注意してください。

Python console
>>> pnt = GEOSGeometry("SRID=32140;POINT(954158.1 4215137.1)")

GeoDjango の ORM は、ジオメトリの値を自動的に変換 SQL でラップし、開発者がより高い抽象度で作業できるようにします:

Python console
>>> qs = WorldBorder.objects.filter(mpoly__intersects=pnt)
>>> print(qs.query)  # Generating the SQL
SELECT "world_worldborder"."id", "world_worldborder"."name", "world_worldborder"."area",
"world_worldborder"."pop2005", "world_worldborder"."fips", "world_worldborder"."iso2",
"world_worldborder"."iso3", "world_worldborder"."un", "world_worldborder"."region",
"world_worldborder"."subregion", "world_worldborder"."lon", "world_worldborder"."lat",
"world_worldborder"."mpoly" FROM "world_worldborder"
WHERE ST_Intersects("world_worldborder"."mpoly", ST_Transform(%s, 4326))
>>> qs  # printing evaluates the queryset
<QuerySet [<WorldBorder: United States>]>

ジオメトリの遅延評価Link to this heading

GeoDjango はジオメトリを標準化されたテキスト表現で読み込みます。ジオメトリフィールドに最初にアクセスすると、 GeoDjango は GEOSGeometry オブジェクトを生成し、よく使われる地理空間フォーマット用のシリアライズプロパティなどの強力な機能を公開します:

Python console
>>> sm = WorldBorder.objects.get(name="San Marino")
>>> sm.mpoly
<MultiPolygon object at 0x24c6798>
>>> sm.mpoly.wkt  # WKT
MULTIPOLYGON (((12.4157980000000006 43.9579540000000009, 12.4505540000000003 43.9797209999999978, ...
>>> sm.mpoly.wkb  # WKB (as Python binary buffer)
<read-only buffer for 0x1fe2c70, size -1, offset 0 at 0x2564c40>
>>> sm.mpoly.geojson  # GeoJSON
'{ "type": "MultiPolygon", "coordinates": [ [ [ [ 12.415798, 43.957954 ], [ 12.450554, 43.979721 ], ...

これには、GEOSライブラリが提供するすべての高度な幾何演算へのアクセスが含まれます:

Python console
>>> pnt = Point(12.4604, 43.9420)
>>> sm.mpoly.contains(pnt)
True
>>> pnt.contains(sm.mpoly)
False

地理情報のアノテーションLink to this heading

GeoDjangoでは、距離などの地理情報アノテーションを計算するための一連の操作 (交差、差分など) を提供しています。詳細は、 地理情報データベース関数 ドキュメントを参照してください。

データを地図上に配置するLink to this heading

地理情報の AdminLink to this heading

Django の admin アプリケーション はジオメトリフィールドの編集をサポートしています。

基本Link to this heading

Django のadmin アプリケーションでは、ユーザが JavaScript のスリッピーマップ (OpenLayers を利用) 上でジオメトリを作成したり変更したりできます。

さあ、始めましょう。次のコードを含む world アプリケーション内に admin.py という名前のファイルを作成します:

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

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

次に、 geodjango アプリケーションフォルダにある urls.py を以下のように編集してください:

Code
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path("admin/", admin.site.urls),
]

admin ユーザーを作成します:

Linux / macOS

Shell
$ python manage.py createsuperuser

Windows

Windows
...\> py manage.py createsuperuser

次に、Django 開発サーバを起動します:

Linux / macOS

Shell
$ python manage.py runserver

Windows

Windows
...\> py manage.py runserver

最後に http://localhost:8000/admin/ にアクセスし、先ほど作成したユーザーでログインします。 WorldBorder のエントリーをブラウズし、ポリゴンをクリックして頂点を好きな位置までドラッグすることで、境界線を編集できます。

GISModelAdminLink to this heading

GISModelAdmin を使用すると、GeoDjango は admin アプリケーションで OpenStreetMap レイヤーを使用します。これにより、 ModelAdmin が使用する Vector Map Level 0 WMSデータセット (OSGeo でホストされている) よりも、より多くのコンテキスト (通りや通路の詳細を含む) が提供されます。

PROJの座標変換ファイルがインストールされている必要があります (詳しくは PROJ installation instructions を参照してください) 。

この要件を満たしている場合は、 admin.py ファイルで GISModelAdmin オプションクラスを使用してください:

Code
admin.site.register(WorldBorder, admin.GISModelAdmin)

脚注