11
6

More than 3 years have passed since last update.

Vultr で GeoDjango アプリケーションを動かすまでの長かった道のり

Last updated at Posted at 2019-12-17

このポストは、Django Advent Calendar 2019 - Qiitaの17日目の記事です。

こんちは!しんせいたろうです。モグモグDjangoの主宰してます。

現在、アーバンデータチャレンジに東東京のアザラシチームの一員として、DRFを頑張っています。

「アーバンデータチャレンジ」とは、地域課題の解決を目的とした地方自治体を中心とする公共データを活用した年間のイベント開催を伴う一般参加型コンテストです。東東京チームは定期的にがやがや会という楽しくもくもくする会を開催していますので、公共データや地域課題解決などに興味があるエンジニアの方、ぜひぜひお越しくださいませ。くわしくはこちら→UDC東東京 - connpass

今回、ある公共データを地図にマッピングするアプリケーションを作成するチームに入っています。そこでGeoDjangoを使うことになり、そのサーバー側の設定を全くわからない状態から始めました。以下、サーバー設定&最初のアプリケーション立ち上げまでの、辛かった道のりでメモしていたので、まとめて書きました。

目次

  1. Vultr 登録
  2. インスタンス作成
  3. ウェブアプリケーションインストール
  4. データベースインストール
  5. データベース作成と設定
  6. Django App 作成
  7. 独自ドメイン登録

Vultr 登録

今回、Vultrというインスタンス上にDjangoとPostgresを使って、地図アプリを作って見ることにしました。

まずはユーザー登録します。初めての人には50ドル分サービスがありますので、最初の50ドルまでは課金されずにフル機能使うことができます。使ってみてイマイチだな?と思ったらインスタンスをdestroy すれば一切お金はかかりません。

インスタンス作成

作成

+ボタンを押せば作成開始です。

インスタンスを選ぶ

今回は、Cloud Compute / Tokyo (region) / Ubuntu 18.04 x64 を選びました。

サーバーサイズについて

今回は、25GBSSDを選びました。料金は、$5/MO $0.007/h です。これは、インスタンスを作っている間は毎時70セントはかかるよ。だけど、Max月5ドルだよ。という意味です。何もしていなくてもインスタンスをDestroyするまでは課金されます。しかし、どんなに使ってもMax5ドルまでということです。

Enter server label に任意の名前をつけたらDeploy Now

shinseitaro という名前をつけてインスタンスを作りました。

Deploy Now を押すと、インスタンス作成が始まります。

Instance 確認

インスタンスが出来上がったら、下記のようにリストが表示されます。
自分のインスタンスを開きましょう。

パスワードは、目のマークを押すと表示され、コピーマークを押すとコピーされます。

SSH 接続

ローカルマシンから、リモートインスタンスにSSH接続します。(ローカルマシンでSSHが使えることを前提に話しています。)

  1. ローカルマシンから、root@[Your IP Address] で接続する。IP と password は先ほどのインスタンス確認画面でできます。

    $ ssh root@xx.xx.xx.xxx
    
    The authenticity of host 'xx.xx.xx.xxx (xx.xx.xx.xxx)' can't be established.
    ECDSA key fingerprint is xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    Are you sure you want to continue connecting (yes/no)? yes
    
    Warning: Permanently added 'xx.xx.xx.xxx' (ECDSA) to the list of known hosts.
    root@xx.xx.xx.xxx's password: 
    

User 追加

  • root で作業するのは危険なので、必ずユーザーを作成しましょう (下記例では shinseitaro で作成しています。適宜読み替えてください。)
  • 新規ユーザーを作成したあとは、必ず root では SSH 接続できない設定をしましょう。
  • パスワードは十分複雑なものにしてください。パスワード生成(パスワード作成)などを使うのが便利です。
  1. ユーザー作成
  2. ssh 接続したターミナルで、adduser your-new-nameします。user information を聞かれますが、全部Enterを押して行けばOKです

    root@vultr:~# adduser shinseitaro
    
    Adding user `shinseitaro' ...
    Adding new group `shinseitaro' (1000) ...
    Adding new user `shinseitaro' (1000) with group `shinseitaro' ...
    Creating home directory `/home/shinseitaro' ...
    Copying files from `/etc/skel' ...
    New password: 
    Retype new password: 
    passwd: password updated successfully
    Changing the user information for shinseitaro
    Enter the new value, or press ENTER for the default
        Full Name []: 
        Room Number []: 
        Work Phone []: 
        Home Phone []: 
        Other []: 
    Is the information correct? [Y/n] Y
    
    
  3. 新規ユーザーに sudo 権限を与えます

    root@vultr:~# gpasswd -a shinseitaro sudo
    Adding user shinseitaro to group sudo
    
    # いったんログアウト
    root@vultr:~# exit
    logout
    
  4. 新規ユーザーで ssh

    $ ssh shinseitro@xxx.xxx.xxx.xx
    $ shinseitaro@vultr:~$ 
    
  5. rootでは SSH で入れないようにします。/etc/ssh/sshd_config を修正して root では SSH出来ないようにします。

    # 私は nano 使ってますが vim でもなんでもいいです
    shinseitaro@vultr:~$ sudo nano /etc/ssh/sshd_config
    
    # ここを yes から no へ変更
    PermitRootLogin no
    
    
  6. 変更を反映

    shinseitaro@vultr:~$ sudo service ssh restart
    

SSH 接続を公開鍵で行う(任意)

ターミナルを閉じると、毎回パスワードを確認されるのはめんどくさいので、公開鍵を使ってログインできるようにします。
【注意】:Windowsでの設定はわかりません。だれかコメントしといてくれると嬉しいです。

Vultr インスタンス側:

```
$ mkdir /home/[username]/.ssh 
 ```

ローカルマシン側:

  1. ssh-keygenを使って公開/秘密鍵のペアを作成。

    $ mkdir $HOME/.ssh
    $ cd $HOME/.ssh
    $ ssh-keygen -t rsa -b 4096 -f id_rsa_vultr
    

    ファイル名id_rsa_vultr は何でもOKです。

  2. Vultr へ 公開鍵を scp で送信する。

    $ scp id_rsa_vultr.pub [user_name]@[remote_ip_addr]:/home/[user_name]/.ssh/authorized_keys
    
  3. ./ssh/config に設定を追加

    $ vi ~/.ssh/config
    
    # 下記貼り付け
    Host hoge
    HostName xx.xx.xx.xxx
    User your-username
    IdentityFile ~/.ssh/id_rsa_vultr
    ServerAliveInterval 60
    ServerAliveCountMax 3
    
    • Host は、ssh 接続するときに呼び出す設定名です。何でもOK。
    • HostName は Vulter インスタンスIP
    • User は、先程追加した新規ユーザ名
    • IdentityFile は、ssh-keygenしたとき作ったファイル名

Vultr インスタンス側:

$ chmod 644 ~/.ssh/authorized_keys

ローカルマシン側:

接続確認。./ssh/configHostに指定した名前でssh接続できます。

$ ssh hoge
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-55-generic x86_64)
:
:

いろいろインストール

上記までで、インスタンスに関連する設定は終わりです。これからアプリケーション用のインストールや設定にはいります。

  • Python (miniconda)
  • Django
  • Git
  • psycopg2 (Python からPostgresSQLに接続するためのライブラリ)
  • GDAL (地図データを触るためのライブラリ。)

Python

色々悩んだ結果、miniconda で pythonをインストールすることにしました。(今となっては何に悩んだかさえ忘れました)

miniconda をインストール

$ curl -O https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
$ bash ./Miniconda3-latest-Linux-x86_64.sh

# このあと色々と聞かれる。
Do you accept the license terms? [yes|no]
>>> yes

Miniconda3 will now be installed into this location:
/home/shinseitaro/miniconda3

>>> [Enter]押す

installation finished.
Do you wish the installer to initialize Miniconda3
by running conda init? [yes|no]
[no] >>> yes

# ながなが色々インストールされる。
# これが出たらインストール完了です
Thank you for installing Miniconda3!

python3.7 の仮想環境をつくってアクティベートする。

Pythonのバージョン、および仮想環境名はお好きなものに変えてください。

# bashrc を適用する
$ source ~/.bashrc

# プロンプトが下記の様に(base) yourname@vultrに変わればOK。
(base) shinseitaro@vultr:~$ 

# python3.7 の仮想環境をつくってアクティベート
(base) shinseitaro@vultr:~$ conda create --name py37 python=3.7 -y
(base) shinseitaro@vultr:~$ conda activate py37


# プロンプトが base から py37 に変わればOK。
(py37) shinseitaro@vultr:~$ 

# python 起動して3.7か確認
$ python 
Python 3.7.4 (default, Aug  9 2019, 18:51:30) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 

# インストール用の miniconda.sh はもういらないので削除
(py37) shinseitaro@vultr:~$ rm Miniconda3-latest-Linux-x86_64.sh 

次回起動時からは、デフォルトで py37 が起動するように変更(任意)

この設定をすると、次回 ssh接続したときに、 (base) ではなく (py37) がデフォルトで起動します。

$ nano ~/.bashrc

# 最後の行に追加して保存
source activate py37

Django

$ pip install Django==2.1.11

注意:現在Djangoのバージョン指定を行わないと、3.0がデフォルトでインストールされます。2系以下を選びたいときはバージョンを指定してください。

psycopg2

$ conda install psycopg2 -y

メモ:pip で入れようと試行錯誤したのですが ERROR: Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-lefl0f21/psycopg2/を解決できず、conda にしました。

データベースインストール

PostgreSQL + PostGIS のインストールと設定

GeoDjangoアプリを作りたいので、以下をインストールして、設定していきます。

  • PostgreSQL
  • PostGIS
  • GEOS
  • GDAL
  • PROJ.4

PostgreSQL

レポジトリキーをインポート

$ apt-get install curl ca-certificates gnupg
$ curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -

/etc/apt/sources.list.d/pgdg.list を作成

:fire: 注意
[bionic]のところは、自分のUBUNTU_CODENAMEを入れてください。cat /etc/os-releaseすればわかります。

root@vultr:~# echo "deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main" | sudo tee -a /etc/apt/sources.list.d/pgdg.list

package listsを更新してインストール

$ apt-get update 
$ apt-get install postgresql-11 pgadmin4

確認

インストールすると、postgres ユーザというDB管理用のユーザが、インスタンスに自動で生成されます。postgresにスイッチしてDBの確認をします。

# shinseitaro から postgres にスイッチ
shinseitaro $ su - postgres

# スイッチしたらDB確認
postgres@vultr:~$ psql -V
psql (PostgreSQL) 11.5 (Ubuntu 11.5-1.pgdg18.04+1)

postgres にパスワードを与える

postgresにパスワードを与えます。今後は su するときにこのパスワードを入力します。

$ passwd postgres
New password: 
Retype new password: 
passwd: password updated successfully

PostGIS

$ apt-get install postgis -y
$ apt install postgresql-11-postgis-2.5
$ apt-get install postgresql-contrib 
$ apt install postgresql-11-postgis-2.5-scripts

GEOS

$ apt-get install libgeos-dev -y

PROJ.4

$ apt-get install libproj-dev proj-data proj-bin -y

データベース 作成

新規DBを作成します。postgres ユーザにスイッチして作業します。

$ su - postgres
postgres@vultr:~$ 

現在のDBを確認

まったく新しい現時点では下記のようなDBが存在すると思います。

混乱しがちですが、先程新規作成された postgres ユーザはマシンユーザーです。

このリストに乗っている、Name privileges: postgresOwner: postgres はマシンユーザーのことではなく、データベース名とオーナー名とです。混乱しやすいので注意してください。

# psql に入る
postgres@vultr:~$ psql

# 現時点でのDataBaseリストを出力
postgres=# \l
                                List of databases
    Name     |    Owner    | Encoding |   Collate   |    Ctype    |   Access privileges   
-------------+-------------+----------+-------------+-------------+-----------------------
 postgres    | postgres    | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0   | postgres    | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
             |             |          |             |             | postgres=CTc/postgres
 template1   | postgres    | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +

この オーナーpostgresにパスワードを与えます。

postgres=# Alter Role postgres with password 'new_password';
postgres=# exit
postgres@vultr:~$ 

新規DBを作成

データベースとそのオーナーを作成します。
例として shinseitaro オーナーを作成して testdb1 というデータベースを作り、そのオーナーに指定しています。

# postgres ユーザにログインしている状態。shinseitaro 作成します。
postgres@vultr:~$ createuser shinseitaro

# testdb1を作成。オーナーをshinseitaroに指定。
postgres@vultr:~$ createdb testdb1 --owner shinseitaro

# password 設定 
postgres@vultr:~$ psql -c "ALTER USER shinseitaro WITH PASSWORD 'some_pwd'"
ALTER ROLE

pg_hba.conf 編集

では、shinseitarotestdb1 にログインしてみます。すると、psql: FATAL: Peer authentication failedが発生します。

postgres@vultr:~$ psql -U shinseitaro -d testdb1
psql: FATAL:  Peer authentication failed for user "shinseitaro"

これは、OS側(ここでは postgres)のユーザ名と、PostgreSQL にログインしようとしているユーザー名( shinseitaro )が一致していないときに起きるエラーです。これをPeer認証と言います。これをパスワード認証に変更して、ログインできるようにします。

この設定は、Web AppとDBが違うマシン上にあるときにも必要です。その場合はIPアドレスを設定する必要があります。

pg_hba.conf 確認

postgres ユーザをexit

postgres@vultr:~$ exit

pg_hba.conf ファイルを探す. わたしの場合はここにありました。このパスで進めます

$ find /etc/ -name pg_hba.conf
/etc/postgresql/11/main/pg_hba.conf

確認

$ cat /etc/postgresql/11/main/pg_hba.conf
# Database administrative login by Unix domain socket
local   all             postgres                                peer

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     peer
# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
host    all             all             ::1/128                 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     peer
host    replication     all             127.0.0.1/32            md5
host    replication     all             ::1/128                 md5

pg_hba.conf 編集

現在設定されている、

local   all             all                                     peer
local   replication     all                                     peer

peermd5 に変更します。

またIPアドレスの指定が必要な場合は、

# IPv4 local connections:
host    all             all             127.0.0.1/32            md5

ここにIPアドレスを追加していきます。

こうすれば、追加されたインスタンスからこのPostgresサーバー(インスタンス)にアクセスできるようになります。DjangoのMigrationで、Connection refusedSSL OFF といったエラーが発生する場合は、ここにIPが追加されていない可能性が高いです。

よって最終的にはこのようになります。

# Database administrative login by Unix domain socket
local   all             postgres                                peer

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     md5
# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
host    all             all             xxx.xxx.xxx.xx/32       md5
host    all             all             zzz.zzz.zz.zzz/32        md5

# IPv6 local connections:
host    all             all             ::1/128                 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     md5
host    replication     all             127.0.0.1/32            md5
host    replication     all             ::1/128                 md5

【注意】postgresは md5 にしないよう注意してください。

local   all             postgres                                peer

設定を有効化する

$ service postgresql restart

確認

$ psql -U shinseitaro -d testdb1
testdb1=> 

# table表示を試してみる.何も作ってないので無いよ,と言われる.
testdb1=> \d
Did not find any relations.
testdb1=> 

postgresql.conf 修正

Web AppとDBが違うマシン上にあるときは、postgresql.conf 修正も必要です。listen_addressesにIPを追加します。

確認

Postgres がどのアドレスをlistenしてるか確認します。localhostだけですね。これを変更します。

$ lsof -i :5432
COMMAND    PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
postgres 11840 postgres    5u  IPv6 490443      0t0  TCP localhost:postgresql (LISTEN)
postgres 11840 postgres    6u  IPv4 490444      0t0  TCP localhost:postgresql (LISTEN)

postgresql.confのパスを探す

$ find /etc/ -name postgresql.conf
/etc/postgresql/11/main/postgresql.conf 

修正する。ここでは、全てを受け入れる * にしているが、ちゃんとアドレス書いたほうがいいと思います。

$ nano /etc/postgresql/11/main/postgresql.conf 

# listen_addresses を変更する。 
#listen_addresses = 'localhost' 
listen_addresses = '*' 

設定を有効化して確認。さきほどは localhost だったところが、* になっていると思います。

$ service postgresql restart

$ lsof -i :5432
COMMAND    PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
postgres 15606 postgres    5u  IPv4 542478      0t0  TCP *:postgresql (LISTEN)
postgres 15606 postgres    6u  IPv6 542479      0t0  TCP *:postgresql (LISTEN)

PostGIS Extention インストール

やっとPostgresの設定が終わりました。しかし空間データをDBで扱うためには、PostgreSQL+PostGISのインストールだけではだめです。拡張機能をインストールする必要があります。

:fire: 注意

  • 拡張機能は、それぞれのDBにインストールします。
  • postgres ユーザに追加権限があります。
  • postgres ユーザは postgres というDBを所有していますが、このDBには決して拡張機能を追加してはいけません。

例では、データベースtestdb1に空間データを扱うためのエクステンションを追加しています。

$ su - postgres

# Extention を追加していく。
$ psql -d testdb1 -c "CREATE EXTENSION postgis;"
CREATE EXTENSION

# 以下同じように全部追加
$ psql -d testdb1 -c "CREATE EXTENSION postgis_topology;"
$ psql -d testdb1 -c "CREATE EXTENSION postgis_sfcgal;"
$ psql -d testdb1 -c "CREATE EXTENSION fuzzystrmatch;"
$ psql -d testdb1 -c "CREATE EXTENSION address_standardizer;"
$ psql -d testdb1 -c "CREATE EXTENSION address_standardizer_data_us;"
$ psql -d testdb1 -c "CREATE EXTENSION postgis_tiger_geocoder;"

全部追加したらExtensionを表示してみましょう。

$ psql -U shinseitaro -d testdb1

psql (11.5 (Ubuntu 11.5-1.pgdg18.04+1))
Type "help" for help.

# 拡張機能リストを見る
testdb1=> \dx
                                                                        List of installed extensions
                Name             | Version |   Schema   |                                                     Description                                                     
------------------------------+---------+------------+---------------------------------------------------------------------------------------------------------------------
    address_standardizer         | 2.5.2   | public     | Used to parse an address into constituent elements. Generally used to support geocoding address normalization step.
    address_standardizer_data_us | 2.5.2   | public     | Address Standardizer US dataset example
    fuzzystrmatch                | 1.1     | public     | determine similarities and distance between strings
    plpgsql                      | 1.0     | pg_catalog | PL/pgSQL procedural language
    postgis                      | 2.5.2   | public     | PostGIS geometry, geography, and raster spatial types and functions
    postgis_sfcgal               | 2.5.2   | public     | PostGIS SFCGAL functions
    postgis_tiger_geocoder       | 2.5.2   | tiger      | PostGIS tiger geocoder and reverse geocoder
    postgis_topology             | 2.5.2   | topology   | PostGIS topology spatial types and functions
(8 rows)


Django App 作成

やっとここまで来ましたYo!長すぎて頭おかしくなりそうです。

ここからは、mamix1116さんが以前書いた、GeoDjangoでWeb地図をつくろう!にフォローしてGeoDjangoアプリを作成していきます。やっとDjangoよ!

作業のすすめかた

今回は実験的に、Vultr上に作ったプロジェクトディレクトリを、ローカルマシンにマウントして、コーディングしていくことにします。よって、

  • Vultr側にプロジェクトディレクトリ(今回は code
  • ローカルにマウント用のディレクトリ(今回は /home/azarashi/vultr

を用意して進めます。この方法は、ローカルでコーディングをしてデプロイする普通の作業工程では必要ありません。デプロイする人は無視してください。

また、Vultrで実行するコマンドは、 :v: を、ローカルで実行するときは、 :house: をつけています。ファイルの修正時には何もつけていません。

事前準備

sshfs インストール

sshfs を使ってVultrのディレクトリを,ローカルにマウントします.sshfs のインストール方法は,以下を参照して下さい。

startproject と startapp

Vultr上でDjangoのプロジェクトを作成して、mapというアプリケーションを作成します。

:v: Vultr

$ mkdir ~/code
$ cd code 
$ pwd
/home/shinseitaro/code

# わたしは、あきよこせんせい信者なので、設定ファイルを全部 config 以下に置くように設定します。
$ django-admin startproject config .
$ ls
config  manage.py

# 地図用のアプリケーション
$ python manage.py startapp map
$ ls
config  manage.py  map

Vultrに作ったディレクトリをローカルにマウント(任意)

sshfs コマンドは,sshfs [youname]@[IP-Adress]:./code [Local Directory Path] です.

:house: Local

$ mkdir /home/azarashi/vultr 
$ sshfs shinseitaro@xxx.xxx.xxx.xx:./code /home/azarashi/vultr 

# cd して ls すると、先程 Vultr上で作ったDjangoプロジェクトファイルが見えるはずです。
$ cd /home/azarashi/vultr 
$ ls
config  manage.py  map

マウントされたディレクトリに入っているファイル等は、ローカルマシンのファイル等と同じように新規作成、修正、削除できます。
/home/azarashi/vultr を VSCode や Pycharm で開けば、あたかもローカルで作業しているかのようにインスタンス上のファイルを操作できます。

なお、アンマウントする場合は,fusermount -u します。

:house: Local

$ fusermount -u /home/azarashi/vultr 

もし fusermount して,【fusermount: failed to unmount Device or resource busy】 といったエラーが出る場合は umount を試してみてください。

$ sudo umount  -l /home/azarashi/vultr 

コーディング作業

セッティング

config/settings.py 修正:

INSTALLED_APPS = [
    ...
    'django.contrib.gis', # 追加
    'map',# 追加
]


# DBは PostgreSQLに変更
DATABASES = {
    # 'default': {
    #     'ENGINE': 'django.db.backends.sqlite3',
    #     'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    # }
    'default': {
        'ENGINE': 'django.contrib.gis.db.backends.postgis',
        'NAME': 'testdb1',
        'USER': 'shinseitaro',
        'PASSWORD': 'xxxxxx',
        'HOST': 'xxx.xxx.xx.xxx',
        'PORT': 5432,
    }    
}

createsuperuser

:v: Vultr

$ python manage.py migrate
$ python manage.py createsuperuser 
$ python manage.py runserver xx.xx.xxx.xx:8000

IPアドレス:8000 にアクセスするとロケットが飛んでいるはずです。

地図データをUploadする

今回は、保育所のデータをサンプルとして作成しました。

map/data ディレクトリを作成して、このjsonファイルを格納します。

ogrinspect を使って、json 構造から、GeoDjango model クラスを自動作成

ogrinspect オプションを使って model class を自動生成するには、以下のコマンドを使います。

$ python manage.py ogrinspect --srid=XXXX path/to/geojson modelname

今回の場合は、

$ python manage.py ogrinspect --srid=6668 ./map/data/201810-2-1-hoikusyo.geojson Hoikusho

これを実行すると、

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


class Hoikusho(models.Model):
    owned = models.CharField(max_length=0)
    name = models.CharField(max_length=0)
    postalcode = models.CharField(max_length=0)
    address = models.CharField(max_length=0)
    gcs = models.CharField(max_length=0)
    tel = models.CharField(max_length=0)
    capacity = models.IntegerField()
    geom = models.PointField(srid=6668)

と出力されますので、これを map/models.py にコピペします。

SRID:
srid に関してはこちらが詳しいので参照してください→空間参照系の概要 - Qiita
どのSRIDを使う必要があるのかは、データを作った人に聞くしかありません。もしわからない場合は、よく使われる上記記事中に出てくる、わが国の陸域でよく使われる空間参照系を一つずつ試して地図に出して、自分が知っている地図上の住所から、「なんとなくこれがあってそうだなー」とあたりをつける、という地道な作業を行うらしいです。なんかもやもやする。。。

モデル

自動出力された model に適切なオプションを追加しながら、map/models.py にコピペします。

# map/models.py
from django.contrib.gis.db import models

class Hoikusho(models.Model):
    owned = models.CharField(max_length=50)
    name = models.CharField(max_length=50)
    postalcode = models.CharField(max_length=10)
    address = models.CharField(max_length=250)
    gcs = models.CharField(max_length=10)
    tel = models.CharField(max_length=50)
    capacity = models.IntegerField()
    geom = models.PointField(srid=6668)

    def __str__(self):
        return self.name

ここでは主に max_length オプションの変更を行っています。もとの geojsonデータを見て、だいたいの感じでオプションを与えます。

migrations & migrate

:v: Vultr

$ python manage.py makemigrations
Migrations for 'map':
  map/migrations/0001_initial.py
    - Create model Hoikusho

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

データベースにデータをインポート

django.contrib.gis.utilsLayerMapping クラスは、空間データをGeoDjango モデルに適用するツールを提供しています。
geojsonのキーワードと、GeoDjangoのフィールド名をマッピングした辞書を渡すと、データベースにデータをアップロードしてくれます。

今回のgeojsonデータはこういう形で

{
   "type": "FeatureCollection",
   "features": [
  {
    "type": "Feature",
    "geometry": {
       "type": "Point",
       "coordinates":  [ 139.777421,35.699016 ]
    },
    "properties": {
    "owned":"区市町村",
    "name":"いずみこども園",
    "postalcode":"101-0024",
    "address":"千代田区神田和泉町1",
    "gcs":"JGD2011",
    "tel":"03-3866-9938",
    "capacity":36
    }
  },

モデルはこういう形なので、

class Hoikusho(models.Model):
    owned = models.CharField(max_length=50)
    name = models.CharField(max_length=50)
    postalcode = models.CharField(max_length=10)
    address = models.CharField(max_length=250)
    gcs = models.CharField(max_length=10)
    tel = models.CharField(max_length=50)
    capacity = models.IntegerField()
    geom = models.PointField(srid=6668)

下記のような辞書を渡すスクリプトを書きます。スクリプトファイルは map/load_hoikusho.py にしました。(任意)

#  map/load_hoikusho.py

import os 
from django.contrib.gis.utils import LayerMapping
from map.models import Hoikusho

mapping = {
    "owned": "owned", 
    "name": "name", 
    "postalcode": "postalcode",
    "address": "address", 
    "gcs": "gcs", 
    "tel": "tel", 
    "capacity": "capacity", 
    "geom": "Point", 

}

# `201810-2-1-hoikusyo.geojson` へのファイルパス
geojson_file = os.path.abspath(
    os.path.join(
        os.path.dirname(__file__), 'data', '201810-2-1-hoikusyo.geojson'
    )
)

# 実行
def run(verbose=True):
    lm = LayerMapping(
        Hoikusho, 
        geojson_file,
        mapping, 
        transform=False, 
        encoding='UTF-8',)
    lm.save(strict=True, verbose=verbose)

これをshellで実行します。

:v: Vultr

$ python manage.py shell

>>> from map import load_hoikusho
>>> load_hoikusho.run()
Saved: Hoikusho object (1)
Saved: Hoikusho object (2)
Saved: Hoikusho object (3)
......
Saved: Hoikusho object (2778)
Saved: Hoikusho object (2779)
>>> exit()

管理画面の設定

地図を管理画面で確認できるように設定します。

# map/admin.py

# from django.contrib import admin
from django.contrib.gis import admin
from map.models import Hoikusho

# オープンストリートマップにマッピングする
admin.site.register(Hoikusho, admin.OSMGeoAdmin)

url 設定

# config/urls.py

# from django.contrib import admin
from django.contrib.gis import admin
from django.urls import path

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

表示

:v: Vultr

$ python manage.py runserver xx.xxx.xx.xx:8000

xx.xxx.xx.xx:8000/admin で地図が表示されていれば成功です!

独自ドメインで表示

いつまでも IP アドレスのままではかっこ悪いので、自分のドメインで表示させるための設定を行います。すでにドメインは持っていることを前提にします。最近よく、porkbun.comでドメインを買っています。ぶたさんがかわいいので。

  1. Django設定:今回はDjangoの簡易ウェブサーバを使い続けることにしたので変更なし。
  2. レジストラで Name Server の設定変更
    • ns1.vultr.com / ns2.vultr.com を追加してください
  3. Vultr 設定
    1. https://my.vultr.com/dns/ > Add Domain ボタン(右上にある)を押す。
    2. Domainと、自分のインスタンスのIPアドレスを入れる
  4. firewall設定
    1. https://my.vultr.com/firewall/
    2. Add Firewall Group
    3. Add Firewall Group に適当な名前をつける。
    4. Action+ ボタンを押す
    5. Protocol を HTTP Port を 80 にして Action の + ボタンを押す。注意:HTTP を選んでも、表示上は TCP になる。これでOK。
    6. Firewall group updated. It may take up to 120 seconds for these changes to apply.と出たらOK
  5. npam して確認。80/tcpが追加されていたら80番ポートが開いたということなのでOK

    :house: Local

    $ nmap -v xx.xx.xx.xxx
    
    Starting Nmap 7.60 ( https://nmap.org ) at 2019-12-14 22:48 JST
    Initiating Ping Scan at 22:48
    Scanning xx.xx.xx.xxx [2 ports]
    Completed Ping Scan at 22:48, 0.00s elapsed (1 total hosts)
    Initiating Parallel DNS resolution of 1 host. at 22:48
    Completed Parallel DNS resolution of 1 host. at 22:48, 0.00s elapsed
    Initiating Connect Scan at 22:48
    Scanning xx.xx.xx.xxx.vultr.com (xx.xx.xx.xxx) [1000 ports]
    Discovered open port 22/tcp on xx.xx.xx.xxx
    Completed Connect Scan at 22:48, 4.41s elapsed (1000 total ports)
    Nmap scan report for xx.xx.xx.xxx.vultr.com (xx.xx.xx.xxx)
    Host is up (0.0032s latency).
    Not shown: 998 filtered ports
    PORT   STATE  SERVICE
    22/tcp open   ssh
    80/tcp closed http # ←ここ!
    

    runserver すると 80/tcp closed httpopen に変わります。

  6. runserver する。ただし sudo をつけてかつ、python へのFull path を指定しなくてはいけない.
    :v: Vultr

    $ sudo /home/shinseitaro/miniconda3/envs/py37/bin/python manage.py runserver xx.xx.xx.xxx:80
    
  7. もう一度 nmap すると open に変わっているはずです。

  8. 指定したドメインで開いてみてください。

おしまい。

あしたは、@kaizumakiさんです。

11
6
0

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
11
6