LoginSignup
3
1

More than 1 year has passed since last update.

MacOS上にGeodjango+PostGIS環境を構築

Last updated at Posted at 2021-03-08

はじめに

MacOS上に、GIS(地理空間情報)を扱えるように、GeoDjango+PostGIS環境を構築した手順のメモです。MacOSのターミナル操作ができ、Django/PostGISはよくわからなくても構築できるレベルで記載。ただし途中でやり直したので、手順のズレや漏れがあるかもしれません。
(追記)バージョンを修正

  • 環境

    • MacBook Pro (2020)
    • macOS BigSur 11.4
    • Homebrew 3.1.11
  • インストールバージョン

    • Python 3.9.6
    • Django 3.2.6
    • PostgreSQL 13.4
    • PostGIS 3.1.2

環境構築

Python

  • ターミナルでまず xcode を導入し、python3.9を brew で入れる
% sudo rm -r /Library/Developer/CommandLineTools  # 念のため既存のコマンドラインツールを削除
% xcode-select --install    # コマンドラインツールをインストール
% brew install python@3.9       

(注) MacOSのアップデートにより、xcode-selectの再導入が必要になる場合がある
(注) この手順では、公式Python3のpkg版はアンインストールした方が無難
参考:https://code-graffiti.com/how-to-uninstall-official-python3-on-mac/

※ (省略可)pyenvでpythonのバージョンを切り替える場合

% brew update && brew upgrade pyenv # 念のためpyenvを更新
% pyenv install --list  # インストールできるバージョンの確認
% pyenv install 3.9.6   # バージョン指定して python をインストール
% pyenv global 3.9.6    # 全体で 3.9.6 を利用するように設定
% python -V             # pythonのバージョン確認
Python 3.9.6
% vi ~/.zprofile 
export PYENV_ROOT="$HOME/.pyenv"      # PATHを追加
export PATH="$PYENV_ROOT/bin:$PATH"   # PATHを追加
eval "$(pyenv init -)"

Venv仮想環境

venvを使い、対象ごとにpython環境を管理

% python -m venv test        # 任意の環境名(ここではtest)を作成
% source test/bin/activate   # test環境に切り替え
(test) %

参考: deactivate でもとの環境に戻る

Django

test環境で、pip自身をアップグレードしてからDjangoを導入

(test) % pip install --upgrade pip
(test) % pip install django psycopg2 django-geojson
(test) % python -m django --version   # djangoのバージョン確認
3.2.6

PostgreSQL+PostGIS

PostgraSQLデータベースと、そのGIS拡張のPostGISをインストール。

% brew install postgres
% brew install postgis

念の為 /usr/local/var/postgres を初期化し、postgresユーザを作成

% initdb /usr/local/var/postgres -E utf8
% createuser -s postgres

PostgreSQLを起動

brew services start postgresql

GDAL

GISライブラリであるGDALをインストール

brew install gdal 

設定

Django初期プロジェクト

空プロジェクトを作成し、そのまま起動

% django-admin startproject testmap
% cd testmap
% ./manage.py runserver 

http://localhost:8000 にアクセスし、 "The install worked successfully! Congratulations!" 「インストールは成功しました!おめでとうございます!」もしくは Django administration のログイン画面が表示されれば、Djangoプロジェクトはできている。
確認できればCtrl-Cで終了。再起動時はvenvでpython環境を変えるを忘れずに。

データベースの作成

通常のPostgreデータベースと、PostGIS拡張データベースを作成

% createdb -U postgres testdb     # 通常のデータベースの場合
% createdb -U postgres postgisdb  # DB作成後PostGIS拡張を適用する手順
% psql -U postgres postgisdb
psql (13.3)
Type "help" for help.

postgisdb=# CREATE EXTENSION postgis;
CREATE EXTENSION
postgisdb=# SELECT PostGIS_Version();
            postgis_version            
---------------------------------------
 3.1 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
(1 row)

ついでに対象DBのみにアクセス権限を持つユーザも作っておく

postgisdb=# CREATE USER dbuser WITH PASSWORD 'passwords';
CREATE ROLE
postgisdb=# GRANT ALL PRIVILEGES ON DATABASE postgisdb TO dbuser;
GRANT
postgisdb=# ¥q

Djangoの設定

testmap/setting.py

作成したプロジェクト配下のsetting.pyの以下の部分を編集

  • GIS指定と、作成したプロジェクトのアプリを追加
INSTALLED_APPS = [ 
    'django.contrib.admin', 
    'django.contrib.auth',  
    'django.contrib.contenttypes',
    'django.contrib.sessions', 
    'django.contrib.messages', 
    'django.contrib.staticfiles', 
    'django.contrib.gis',         # 追加:GIS機能
    ’testmap',                    # 追加:作成したプロジェクト
]       
  • データベースの設定
DATABASES = {    
    'default': {
        'ENGINE': 'django.contrib.gis.db.backends.postgis',
        'HOST': 'localhost',    # DBホスト
        'NAME': 'postgisdb',    # データベース名
        'USER': 'dbuser',        # DBユーザ名
        'PASSWORD': 'passwords', # DBパスワード
    }
}
  • 文字コードと時刻設定(必要に応じて)
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'   

データベース設定

  • Djangoが利用するテーブルを作成
% ./manage.py makemigrations
No changes detected
% ./manage.py migrate
Operations to perform:
    [中略]
  Applying sessions.0001_initial... OK

Django管理ユーザを作成

% ./manage.py createsuperuser         
ユーザー名 (leave blank to use 'geojson'): testmap
メールアドレス: testmap@example.com
Password: 
Password (again): 

geojsonデータを表示

表示データ

  • 準備

サンプルとして、国土数値情報ダウンロードサービス http://nlftp.mlit.go.jp/ksj/index.html から行政境界(ポリゴン)をダウンロード。全国だとサイズが大きいので適当な都道府県(今回は奈良県)を選び、ダウンロードしたN03-20200101_29_GML.zipを展開。
含まれている N03_20_29_200101.geojson を djangoプロジェクト直下に配置

  • 形式の確認

どのような要素があるか確認。

% ./manage.py ogrinspect --srid=4326 N03-20_29_200101.geojson Border          

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

class Border(models.Model):
    n03_001 = models.CharField(max_length=0)
    n03_002 = models.CharField(max_length=0)
    n03_003 = models.CharField(max_length=0)
    n03_004 = models.CharField(max_length=0)
    n03_007 = models.CharField(max_length=0)
    _color = models.CharField(max_length=0)
    _opacity = models.IntegerField()
    _weight = models.IntegerField()
    _fillcolor = models.CharField(max_length=0)
    _fillopacity = models.FloatField()
    geom = models.PolygonField(srid=4326)

※ データの座標系がJGD2011なので、世界座標系のsrid=4326を指定。一般にGPS測位はこれを利用。

データモデル

testmap/models.py で行政境界のモデルを定義します。models.pyがなければ作成。
Django 3.2.4 ではワーニングがでるのでidを追加し、unicodestr に修正。

from django.contrib.auth import get_user_model
from django.contrib.gis.db import models

class Border(models.Model):
    id      = models.AutoField(primary_key=True)
    n03_001 = models.CharField(verbose_name='都道府県名', max_length=10)
    n03_002 = models.CharField(verbose_name='支庁名', max_length=20, blank=True)
    n03_003 = models.CharField(verbose_name='群・政令市名', max_length=20, blank=True)
    n03_004 = models.CharField(verbose_name='市区町村名', max_length=20, blank=True)
    n03_007 = models.CharField(verbose_name='行政区域コード', max_length=5)
    geom = models.PolygonField(srid=4612)
    objects = models.Manager()

    def __str__(self):
        return "%s_%s_%s" % (self.n03_001,self.n03_003,self.n03_004)

    class Meta:
        verbose_name = "行政区域"
        verbose_name_plural = "行政区域一覧"

マイグレーション実行しモデルで定義したテーブルを作成

% ./manage.py makemigrations testmap   # アプリを指定してマイグレーション作成
% ./manage.py migrate                  # マイグレーション実行

データインポート

  • geojsonファイルをデータベースに登録するスクリプト load_nara.py を作成

どこに作っても良いが、Djangoプロジェクト直下に置く。

import os
from django.contrib.gis.utils import LayerMapping
from testmap.models import Border

# ModelとGeojsonのマッピング
mapping = {
    'n03_001' : 'N03_001',
    'n03_002' : 'N03_002',
    'n03_003' : 'N03_003',
    'n03_004' : 'N03_004',
    'n03_007' : 'N03_007',
    'geom' : 'POLYGON',
}

# geojsonファイル
geojson_file = os.path.abspath(os.path.join(os.path.dirname(__file__), 'N03-20_29_200101.geojson'))

# 実行
def run(verbose=True):
    lm = LayerMapping(Border, geojson_file, mapping, transform=False, encoding='UTF-8')
    lm.save(strict=True, verbose=verbose)
  • Djangoシェルで、作成したスクリプトを実行
% ./manage.py shell
>>> from . import load_nara
>>> load_nara.run()
Saved: 奈良県__奈良市
   [snip]
>>> ^D

管理者画面で確認

testmap/admin.py に以下のように記述(なければ作成)。OSMGeoAdminで背景地図はOSMを指定。

from django.contrib import admin                                                                                                         
from django.contrib.gis import admin as geoadmin                                                                                         
from . import models
# Border
admin.site.register(models.Border, geoadmin.OSMGeoAdmin)

テストサーバを起動

% ./manage.py runserver

http://localhost:8000/admin にアクセスし、createsuperuser で作成したユーザID/パスワードでログインします。
正しく設定ができていれば、管理サイトページに表示された行政区域一覧テーブルを選択すると、各市町村のレコードがあり、例えば生駒市を選択すると、下のように地図上に境界が表示される。

スクリーンショット5.png

以上で環境構築とデータ投入の確認まで完了。

アプリケーション作成

最低限の環境が構築できたので、この先は、geojsonデータを利用したアプリケーションやWebAPIをDjangoフレームワークを使い作って行きます。

参考

3
1
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1