Windows 10下GEO Djangoインストール構成


目次
  • 1. 説明
  • 1.1必要なソフトウェア
  • 1.2実験環境
  • 2. インストール手順
  • 2.1 PythonとDjango
  • 2.2 PostGIS
  • 2.3 psycopg2
  • 2.4 PROJ.4,GDALおよびGEOS
  • 2.5環境変数
  • の構成
  • 3. 試験GeoDjango
  • 3.1準備
  • 3.2新規プロジェクトの作成
  • 3.2地理データを表示
  • 3.3地理図形モデル
  • を定義する
  • 3.4 GDALインタフェースShapefileデータを読む
  • 3.5インポートデータ


  • 1.説明
    1.1必要なソフトウェア
  • PythonとDjango
  • 空間データベースPostgreSQL/MySQL/Oracle/SQLite
  • 地理関連ライブラリ
  • データベース#データベース#
    ライブラリ依存
    PostgreSQL
    GEOS, GDAL, PROJ.4, PostGIS
    MySQL
    GEOS, GDAL
    Oracle
    GEOS, GDAL
    SQLite
    GEOS, GDAL, PROJ.4, SpatiaLite
    1.2実験環境
    ソフトウェア
    バージョン#バージョン#
    Python
    3.7.6
    Django
    3.0.8
    PostgreSQL
    12.3.1
    PostGIS
    3.0.1
    Geos
    3.8.1
    Proj
    6.3.2
    GDAL
    3.0.4
    2.インストールプロセス
    2.1 PythonとDjango
    2.2 PostGIS
    まずPostgreSQLをインストールし、インストールが完了した後、Stack Builderを実行するように要求する.このツールでPostGISをインストールする.
    Stack Builder拡張プラグインのダウンロードとインストールに失敗すると、ダウンロードpostgis-bundle-pg12x64-setup-3.0.1-3.exeが手動で完了する.
    2.3 psycopg2
    psycopg 2はpythonモジュールが提供するPythonとPostgreSQLデータベース間のインタフェースであり、実行するpip install psycopg2
    2.4 PROJ.4,GDALとGEOS
    OSGeo 4 WインストーラはGeoDjangoのインストールに必要なPROJを支援する.4,GDALとGEOSライブラリ.
  • OSGeo 4 Wインストーラをダウンロードし、
  • を実行
  • Express Web GISインストールを選択し、「次へ」をクリックします.
  • selectpackagesリストでGDALが選択されていることを確認し、「次へ」をクリックすると
  • になります.
  • パッケージは自動的にダウンロードしてインストールされ、インストールプログラムを終了することができます.

  • 2.5環境変数の構成OSGEO4W_ROOTおよびPYTHON_ROOTは、コンピュータの実際の位置を基準として、コマンドラインの下で実行される
    set OSGEO4W_ROOT=C:\OSGeo4W
    set PYTHON_ROOT=C:\Python3X
    set GDAL_DATA=%OSGEO4W_ROOT%\share\gdal
    set PROJ_LIB=%OSGEO4W_ROOT%\share\proj
    set PATH=%PATH%;%PYTHON_ROOT%;%OSGEO4W_ROOT%\bin
    reg ADD "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v Path /t REG_EXPAND_SZ /f /d "%PATH%"
    reg ADD "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v GDAL_DATA /t REG_EXPAND_SZ /f /d "%GDAL_DATA%"
    reg ADD "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PROJ_LIB /t REG_EXPAND_SZ /f /d "%PROJ_LIB%"
    

    3.GeoDjangoのテスト
    3.1準備
  • プロジェクトおよび仮想環境ディレクトリの作成
  • D:\>cd geodj
    D:\geodj>mkdir venv
    
  • 仮想環境の作成
  • D:\geodj>virtualenv -p python.\ venv
    created virtual environment CPython3.7.6.final.0-64 in 16109ms
      creator CPython3Windows(dest=D:\geodj\venv, clear=False, global=False)
      seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=C:\Users\xxx\AppData\Local\pypa\virtualenv)
        added seed packages: pip==20.1.1, setuptools==49.2.0, wheel==0.34.2
      activators BashActivator,BatchActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator
    
  • 仮想環境をアクティブ化
  • D:\geodj>.\venv\scripts\activate
    
  • 仮想環境に入り、Django
  • をインストールします.
    (venv) D:\geodj>pip install django
    Collecting django
      Using cached Django-3.0.8-py3-none-any.whl (7.5 MB)
    Collecting pytz
      Using cached pytz-2020.1-py2.py3-none-any.whl (510 kB)
    Collecting sqlparse>=0.2.2
      Using cached sqlparse-0.3.1-py2.py3-none-any.whl (40 kB)
    Collecting asgiref~=3.2
      Using cached asgiref-3.2.10-py3-none-any.whl (19 kB)
    Installing collected packages: pytz, sqlparse, asgiref, django
    Successfully installed asgiref-3.2.10 django-3.0.8 pytz-2020.1 sqlparse-0.3.1
    

    3.2新規プロジェクトの作成
  • プロジェクトの作成、新規アプリケーション
  • (venv) D:\geodj>django-admin startproject geodjango
    
    (venv) D:\geodj>cd geodjango
    
    (venv) D:\geodj\geodjango>python manage.py startapp world
    
  • プロジェクトデータベースおよびアプリケーションの構成
  • # geodjango/settings.py
    DATABASES = {
        'default': {
            'ENGINE': 'django.contrib.gis.db.backends.postgis',
            'NAME': '    ',                      
            'USER': '   ',
            'PASSWORD': '  ',
            'HOST': '127.0.0.1',
            'PORT': '5432',
        },
    }
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'django.contrib.gis',   #   
        'world',   #   
    ]
    

    3.2地理データの表示
  • はサンプルshpをダウンロードし、コマンドラインが正常にダウンロードされずに下ディレクトリに解凍し、プロジェクトディレクトリ
  • に戻る.
    (venv) D:\geodj\geodjango>mkdir world\data
    
    (venv) D:\geodj\geodjango>cd world\data
    
    (venv) D:\geodj\geodjango\world\data>wget https://thematicmapping.org/downloads/TM_WORLD_BORDERS-0.3.zip
    'wget'          ,         
          。
    (venv) D:\geodj\geodjango\world\data>cd ..\..\
    
  • shp情報を表示
  • (venv) D:\geodj\geodjango>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)
    
    (venv) D:\geodj\geodjango>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
    Metadata:
      DBF_DATE_LAST_UPDATE=2008-07-30
    Geometry: Polygon
    Feature Count: 246
    Extent: (-180.000000, -90.000000) - (180.000000, 83.623596)
    Layer SRS WKT:
    GEOGCRS["WGS 84",
        DATUM["World Geodetic System 1984",
            ELLIPSOID["WGS 84",6378137,298.257223563,
                LENGTHUNIT["metre",1]]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["degree",0.0174532925199433]],
        CS[ellipsoidal,2],
            AXIS["latitude",north,
                ORDER[1],
                ANGLEUNIT["degree",0.0174532925199433]],
            AXIS["longitude",east,
                ORDER[2],
                ANGLEUNIT["degree",0.0174532925199433]],
        ID["EPSG",4326]]
    Data axis to CRS axis mapping: 2,1
    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: Integer64 (10.0)
    REGION: Integer (3.0)
    SUBREGION: Integer (3.0)
    LON: Real (8.3)
    LAT: Real (7.3)
    

    3.3地理図形モデルの定義

  • # geodjango/world/models.py
    
    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
    
  • データ移行エラー最終
  • (venv) D:\geodj\geodjango>python manage.py makemigrations
    Migrations for 'world':
      world\migrations\0001_initial.py
        - Create model WorldBorder
    
    (venv) D:\geodj\geodjango>python manage.py sqlmigrate world 0001
    BEGIN;
    --
    -- Create model WorldBorder
    --
    CREATE TABLE "world_worldborder" ("id" serial NOT NULL PRIMARY KEY, "name" varchar(50) NOT NULL, "area" integer NOT NULL, "pop2005" integer NOT NULL, "fips" varchar(2) 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;
    
    (venv) D:\geodj\geodjango>python manage.py migrate
    Operations to perform:
      Apply all migrations: admin, auth, contenttypes, sessions, world
    Running migrations:
      Applying world.0001_initial... OK
    

    3.4 GDALインタフェースShapefileデータを読む
  • オープンPython
  • (venv) D:\geodj\geodjango>python manage.py shell
    Python 3.7.6 (default, Jan  8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    (InteractiveConsole)
    
  • Shapefileを開き、表
  • をインポート
    >>> import os
    >>> import world
    >>> world_shp = os.path.abspath(os.path.join(os.path.dirname(world.__file__),'data', 'TM_WORLD_BORDERS-0.3.shp'))
    >>> from django.contrib.gis.gdal import DataSource
    >>> ds = DataSource(world_shp)
    >>> print(ds)
    D:\geodj\geodjango\world\data\TM_WORLD_BORDERS-0.3.shp (ESRI Shapefile)
    
  • データを表示
  • >>> print(len(ds))
    1
    >>> lyr = ds[0]
    >>> print(lyr)
    TM_WORLD_BORDERS-0.3
    >>> print(lyr.geom_type)
    Polygon
    >>> print(len(lyr))
    246
    >>> 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.proj4
    '+proj=longlat +datum=WGS84 +no_defs'
    >>> print(lyr.fields)
    ['FIPS', 'ISO2', 'ISO3', 'UN', 'NAME', 'AREA', 'POP2005', 'REGION', 'SUBREGION', 'LON', 'LAT']
    >>> [fld.__name__ for fld in lyr.field_types]
    ['OFTString', 'OFTString', 'OFTString', 'OFTInteger', 'OFTString', 'OFTInteger', 'OFTInteger64', 'OFTInteger', 'OFTInteger', 'OFTReal', 'OFTReal']
    >>> for feat in lyr:
    ...     print(feat.get('NAME'), feat.geom.num_points)
    ...
    Antigua and Barbuda 48
    Algeria 1241
    Azerbaijan 871
    Albania 337
    ......
    Saint Barthelemy 14
    Guernsey 18
    Jersey 26
    South Georgia South Sandwich Islands 338
    Taiwan 363
    >>> lyr[0:2]
    [, 
    ]
    >>> feat = lyr[234]
    >>> print(feat.get('NAME'))
    San Marino
    >>> geom = feat.go
    Traceback (most recent call last):
      File "", line 1, in 
    AttributeError: 'Feature' object has no attribute 'go'
    >>> geom = feat.geom
    >>> print(geom.wkt)
    POLYGON ((12.415798 43.957954,12.450554 43.979721,12.453888 43.981667,12.4625 43.984718,12.471666 43.986938,
    12.492777 43.989166,12.505554 43.988609,12.509998 43.986938,12.510277 43.982773,12.511665 43.943329,
    12.510555 43.939163,12.496387 43.923332,12.494999 43.914719,12.487778 43.90583,12.474443 43.897217,
    12.464722 43.895554,12.459166 43.896111,12.416388 43.904716,12.412222 43.906105,12.407822 43.913658,
    12.403889 43.926666,12.404999 43.948326,12.408888 43.954994,12.415798 43.957954))
    

    3.5データのインポート
  • 作成world/load.py
  • # world/load.py
    import os
    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 = os.path.abspath(
        os.path.join(os.path.dirname(__file__), '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)
    
  • 実行インポート
  • (venv) D:\geodj\geodjango>python manage.py shell
    Python 3.7.6 (default, Jan  8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    (InteractiveConsole)
    >>> from world import load
    >>> load.run()
    Saved: Antigua and Barbuda
    Saved: Algeria
    Saved: Azerbaijan
    Saved: Albania
    Saved: Armenia
    Saved: Angola
    ......
    Saved: South Georgia South Sandwich Islands
    Saved: Taiwan
    
    (venv) D:\geodj\geodjango>python manage.py ogrinspect world\data\TM_WORLD_BORDERS-0.3.shp WorldBorder --srid=4326 --mapping --multi
    # 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.BigIntegerField()
        region = models.IntegerField()
        subregion = models.IntegerField()
        lon = models.FloatField()
        lat = models.FloatField()
        geom = models.MultiPolygonField(srid=4326)
    
    
    # Auto-generated `LayerMapping` dictionary for WorldBorder model
    worldborder_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',
    }
    
  • 空間クエリ
  • (venv) D:\geodj\geodjango>python manage.py shell
    Python 3.7.6 (default, Jan  8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    (InteractiveConsole)
    >>> pnt_wkt = 'POINT(-95.3385 29.7245)'
    >>> from world.models import WorldBorder
    >>> WorldBorder.objects.filter(mpoly__contains=pnt_wkt)
    GDAL_ERROR 4: b'POINT(-95.3385 29.7245): No such file or directory'
    GDAL_ERROR 10: b"Pointer 'hObject' is NULL in 'GDALGetDescription'.
    " ]> >>> from django.contrib.gis.geos import Point >>> pnt = Point(12.4604, 43.9420) >>> WorldBorder.objects.get(mpoly__intersects=pnt) >>> from django.contrib.gis.geos import GEOSGeometry, Point >>> pnt = Point(954158.1, 4215137.1, srid=32140) >>> pnt = GEOSGeometry('SRID=32140;POINT(954158.1 4215137.1)') >>> qs = WorldBorder.objects.filter(mpoly__intersects=pnt) >>> print(qs.query) 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"::bytea FROM "world_worldborder" WHERE ST_Intersects("world_worldborder"."mpoly", ST_Transform(ST_GeomFromEWKB('\001\001\000\000 \214}\000\0003333\\\036-AfffFX\024PA'::bytea), 4326)) >>> qs ]> >>> sm = WorldBorder.objects.get(name='San Marino') >>> sm.mpoly >>> sm.mpoly.wkt 'MULTIPOLYGON (((12.415798 43.957954, 12.450554 43.979721, 12.453888 43.981667, 12.4625 43.984718, 12.471666 43.986938, 12.492777 43.989166, 12.505554 43.988609, 12.509998 43.986938, 12.510277 43.982773, 12.511665 43.943329, 12.510555 43.939163, 12.496387 43.923332, 12.494999 43.914719, 12.487778 43.90583, 12.474443 43.897217, 12.464722 43.895554, 12.459166 43.896111, 12.416388 43.904716, 12.412222 43.906105, 12.407822 43.913658, 12.403889 43.926666, 12.404999 43.948326, 12.408888 43.954994, 12.415798 43.957954)))' >>> sm.mpoly.wkb >>> sm.mpoly.geojson '{ "type": "MultiPolygon", "coordinates": [ [ [ [ 12.415798, 43.957954 ], [ 12.450554, 43.979721 ], [ 12.453888, 43.981667 ], [ 12.4625, 43.984718 ], [ 12.471666, 43.986938 ], [ 12.492777, 43.989166 ], [ 12.505554, 43.988609 ], [ 12.509998, 43.986938 ], [ 12.510277, 43.982773 ], [ 12.511665, 43.943329 ], [ 12.510555, 43.939163 ], [ 12.496387, 43.923332 ], [ 12.494999, 43.914719 ], [ 12.487778, 43.90583 ], [ 12.474443, 43.897217 ], [ 12.464722, 43.895554 ], [ 12.459166, 43.896111 ], [ 12.416388, 43.904716 ], [ 12.412222, 43.906105 ], [ 12.407822, 43.913658 ], [ 12.403889, 43.926666 ], [ 12.404999, 43.948326 ], [ 12.408888, 43.954994 ], [ 12.415798, 43.957954 ] ] ] ] }' >>> pnt = Point(12.4604, 43.9420) >>> sm.mpoly.contains(pnt) True >>> pnt.contains(sm.mpoly) False >>> quit()
  • Django地図表示データ
  • 編集world/admin.py
    from django.contrib.gis import admin
    from .models import WorldBorder
    
    admin.site.register(WorldBorder, admin.OSMGeoAdmin)
    

    編集url.py
    from django.contrib.gis import admin
    from django.urls import include, path
    
    urlpatterns = [
        path('admin/', admin.site.urls),
    ]
    

    実行
    (venv) D:\geodj\geodjango>python manage.py createsuperuser
    Username (leave blank to use 'xxx'): xxx
    Email address: 
    Error: Enter a valid email address.
    Email address:
    Password:
    Password (again):
    Superuser created successfully.
    
    (venv) D:\geodj\geodjango>python manage.py runserver
    Watching for file changes with StatReloader
    Performing system checks...
    
    System check identified no issues (0 silenced).
    July 22, 2020 - 15:03:26
    Django version 3.0.8, using settings 'geodjango.settings'
    Starting development server at http://127.0.0.1:8000/
    Quit the server with CTRL-BREAK.
    

    アクセスhttp://localhost:8000/admin/
    . . . . . .
    桃花仙人种桃树,又摘桃花换酒钱_