GeoDjango WebアプリでEPSGを指定するにはどうすればいい?
こんなことを書く
- GeoDjangoでShapefileからデータinsertすると、座標がおかしい。
- どうすれば正しく座標を保存できる?
- そもそもGeoDjangoはどうやってEPSGを管理してる?
そもそもこんなことで困った
プロジェクトのEPSGを23032に指定していた。EPSG:23032とは、WGS 84 / UTM zone 32Nである。
で、ogr2ogrコマンドでShapefileをDBにインサートして、その後に、PostGISで確認すると、、、、あれEPSGが4326になってる!!
しかも値は変換されていないので、値は23032、計算系は4326というチグハグな感じ。
ちなみに、このときは、もともとの入力場所が東ドイツ地域の値。
で、チグハグ状態で、座標を示す場所を確認すると、アフリカの南の海。。。どこよ、それ(笑)
こうすれば解決できる
2つの方法がある。
- GeoDjangoで使うEPSGをすべて4326に指定する。ogr2ogrで変換時に指定する。
- GeoDjangoのモデル定義時にEPSGを指定する。
どちらも説明する。
GeoDjangoにおけるEPSGはどうやって管理されるのか?
そもそも、、、GeoDjangoにおけるEPSGはどうやって管理しているのか?
GeoDjangoにおいては、モデルのフィールドごとにEPSGを指定できる。
つまり、こいつらをモデル定義で指定する時にEPSGを指定する。ちなみにGeoDjangoの世界ではsridの変数名で表現している。
モデル定義の時にsridを指定するということは、つまり、テーブルの列ごとにEPSGが指定されるという意味である。
で、標準のsrid/EPSGは4326である(後述)。
GeoDjangoで使うEPSGをすべて4326に指定する
つまり、ogr2ogrで変換時に指定する。
-t_srsというフラグを書くと、変換先のEPSGを指定できる。例えば次のogr2ogrコマンド
1 |
ogr2ogr -f "PostgreSQL" PG:"host=localhost port=5432 user='postgis_test' password='devel' dbname='postgis_db'" shelter_locations -nln monaco_shelter -append -t_srs EPSG:4326 |
どうやってEPSGを指定するか?:GeoDjangoのモデル定義時にEPSGを指定する
EPSGを変換するのでなく、モデル定義を変更するやり方。
明示的な説明がなかったので、少し探すのに苦労した。このドキュメントにさらっと書いてある。
サンプルコードの断片にMultiPolygonFieldが指定されている。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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) |
で、引数にsrid=4326が指定されていることがわかる。
ちなみに、デフォルトのsridの値は4326である。つまり座標モデル定義の時にsridを指定しないと、srid=4326 (WGS84)が指定されることになる。
ちなみに:EPSG=4326でいいんじゃね?
EPSG間には完全な1対1関係が成立するわけではない。変換時にずれが発生することがある。
正確に言うと、変換計算は完全である。しかし、浮動小数点数の関係で完全な値を表現できるわけではない。
結果的に、変換計算時にズレが発生してしまう。
EPSG=4326は世界のすべての場所を表現する座標である。なので、その分だけ、多くの値を必要としている。
ディスカッション
コメント一覧
まだ、コメントがありません