在MacOS上配置Geodjango+PostGIS环境
首先
以下是在MacOS上构建GeoDjango+PostGIS环境的步骤备忘录,以便处理地理空间信息(GIS)。这些步骤假设您能在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/
如果需要切换Python版本,可以使用pyenv(省略可)。
% 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 is a virtual environment.
使用venv,根据每个目标管理Python环境。
% python -m venv test # 任意の環境名(ここではtest)を作成
% source test/bin/activate # test環境に切り替え
(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 — PostgreSQL与PostGIS
安装PostgreSQL数据库以及其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是Geospatial Data Abstraction Library的缩写。
安装GDAL,这是一个GIS库。
brew install gdal
设定
Django项目的初始阶段
创建一个空项目并直接启动。
% django-admin startproject testmap
% cd testmap
% ./manage.py runserver
请访问 http://localhost:8000,如果显示“安装成功!恭喜!”或者显示Django管理界面的登录页面,则表示Django项目已完成。确认后使用Ctrl-C终止。在重新启动时,请记得切换到venv环境中的Python。
创建数据库
创建通常的PostgreSQL数据库和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)
顺便创建一个只有访问目标数据库权限的用户。
postgisdb=# CREATE USER dbuser WITH PASSWORD 'passwords';
CREATE ROLE
postgisdb=# GRANT ALL PRIVILEGES ON DATABASE postgisdb TO dbuser;
GRANT
postgisdb=# ¥q
Django的配置
测试地图/设置.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并将unicode更改为str形式。
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创建的用户名/密码进行登录。
如果设置正确,选择管理站点页面上显示的行政区域列表表格,每个市镇都有一条记录,例如选择生駒市,地图上将显示边界如下所示。
以上内容包括环境搭建和数据导入的确认已经完成。
创建应用程序
因为已经建立了最低限度的环境,所以在接下来的过程中,将使用Django框架来创建基于geojson数据的应用程序和WebAPI。
请参考
-
- GeoDjangoではじめる地理空間情報 https://homata.gitbook.io/geodjango/hajimeni/readme
測地系と座標系 https://homata.gitbook.io/geodjango/hajimeteno/coordinate