QGIS + Python その1

- GIS(QGIS)に関しては勉強を始めたばかりなので、理解に怪しいところが多々あり。

# 実行動作確認環境
- Windows 7 64bit
- QGIS 2.8.11

# 準備
- QGISのメニューバーの「プラグイン」から「Pythonコンソール」を選択
- Pythonコンソールのアイコンから、エディタの表示を選択
![Image.png](https://qiita-image-store.s3.amazonaws.com/0/152805/c3ad7c63-8bf4-e378-8765-85037f97a7fb.png)
- 以降、対話型のコンソールは使用せず、エディタでコードを記述＆実行する前提で記述

# Python バージョンの確認

```Python:test.py
import platform
print(platform.python_version())
```

- 実行結果はコンソールに表示される → `2.7.5`
- 2.x系列のPythonらしい

# Pythonの実行パスの確認
```Python:test.py
import os
print(os.getcwd())
```
- 実行結果→`C:\PROGRA~1\QGIS2~1.18\bin`
    - `C:\Program Files\QGIS 2.18\bin`

# ベクタレイヤの追加

```Python:test.py
filePath='C:/Users/xxxx/Documents/GIS DataBase/PyTest/lay01.shp'
iface.addVectorLayer(filePath,'test','ogr')
```

- 第一引数：ファイルパス
    - ファイルパスは、「￥」ではなく「スラッシュ」を使っても記述可能。
        - 「￥」を使う場合にはエスケープシーケンスに注意
- 第二引数：レイヤにつけたい名前
    - 上記コードの場合、QGIS上でのレイヤ名前は「test lay01 Polygon」となる
    - 第二引数+SP+ファイル名+SP+タイプ
    - ![Image2.png](https://qiita-image-store.s3.amazonaws.com/0/152805/f69abd1d-93a6-db68-65fe-a78c8934a052.png)
- 第三引数：いまのところ不明　`ogr` にしておく。`providerKey`
    - `org`にしないように。

# アクティブレイヤの取得
- あらかじめマウス等でレイヤを選択しておきます。

```Python:test.py
layer=iface.activeLayer()
print('\n'.join(dir(layer)))
```

- `dir(xxx)`で xxx オブジェクトのメンバ一覧（利用できるメソッド等の一覧）を取得可能
- `geometryType()`、`getFeatures()`
- 詳細は、[QgsVectorLayer Class Reference](http://qgis.org/api/2.18/classQgsVectorLayer.html)

# レイヤのジオメトリタイプを調べる
- QGIS?のベクタレイヤには、ポイント（点）、ライン（ポリライン、線）、ポリゴン（面）を混在させることはできない（らしい）。
- よって、ベクタレイヤのタイプは、ポイント、ライン、ポリゴンのいずれかになる（と思われる）。
    - ![Image3.png](https://qiita-image-store.s3.amazonaws.com/0/152805/b38fb76b-4b9d-ce46-7f3e-87b152fcf80e.png)

- ポイント、ライン、ポリゴンを総称してジオメトリという（らしい）。

```Python:test.py
layer=iface.activeLayer()
type = layer.geometryType()
if type == QGis.Point :
    print('Point')
elif type == QGis.Line :
    print('Line')
elif type == QGis.Polygon:
    print('Polygon')
```

# 選択地物（選択ポリゴン）の属性を出力
- 地物には`id`という属性カラムがある前提とします。
    - ![Image4.png](https://qiita-image-store.s3.amazonaws.com/0/152805/42e4832d-e03a-0918-da04-766cf9587917.png)

- 地物が単数または複数選択されている状態であるとします。

```Python:test.py
layer=iface.activeLayer()
features = layer.selectedFeatures()

for feature in features:
    print(feature['id'])
```
- 選択の有無に関わらず、アクティブレイヤ上の全地物を対象とする場合は、`layer.getFeatures()`を使う。

```Python:test.py
layer=iface.activeLayer()
features = layer.getFeatures()

for feature in features:
    print(feature['id'])
```

# 地物（ポリゴン）の頂点座標を出力

```Python:test.py
# -*- coding: utf-8 -*- 

layer=iface.activeLayer()

if layer is None :
    print(u'アクティブなレイヤが存在しません。')

if layer.geometryType() != QGis.Polygon:
    print(u'アクティブレイヤのジオメトリタイプがポリゴンではありません。')

print(u'アクティブレイヤ {0} を対象に処理を実行します。'.format(layer.name()))
print('')

for feature in layer.getFeatures():

    print(u'ID={0}'.format(feature['id']))
    if feature.geometry().isMultipart():
        polygons = feature.geometry().asMultiPolygon()
    else:
        polygons = [ feature.geometry().asPolygon() ]
                
    for polygon in polygons:
        for vertices in polygon:
            for vertex in vertices:
                print('X={0:.9f}  Y={1:.9f}'.format(vertex.x(),vertex.y()))
 
    print('')
```

- 上記 `vertex` は `class 'qgis._core.QgsPoint'` のインスタンス
- 詳細は、[QgsPoint Class Reference](http://qgis.org/api/2.18/classQgsPoint.html)

# レイヤのバウンディングボックスを取得する

- レイヤに存在する全ての地物に対するバウンディングボックスを取得する
- バウンディングボックスは`QgsRectangle`クラス
    - 詳細は、[QgsRectangle Class Reference](http://qgis.org/api/2.18/classQgsRectangle.html)

```Python:test.py
# -*- coding: utf-8 -*- 
layer=iface.activeLayer()

if layer is None :
    print(u'アクティブなレイヤが存在しません。')

box = layer.extent()
print('xMinimum={0:.9f}'.format(box.xMinimum()))
print('xMaximum={0:.9f}'.format(box.xMaximum()))
print('yMinimum={0:.9f}'.format(box.yMinimum()))
print('yMaximum={0:.9f}'.format(box.yMaximum()))
print('width={0:.9f}'.format(box.width()))
print('height={0:.9f}'.format(box.height()))
```

# 参考資料

- [QGISプログラミング入門 2016Osaka編](http://waigani.hatenablog.jp/entry/2016/01/31/133014)
- [GIS Stack Exchange](https://gis.stackexchange.com/)
- [QGIS API Documentation 2.18](http://qgis.org/api/2.18/annotated.html)
- [Getting Started With Python Programming](http://www.qgistutorials.com/en/docs/getting_started_with_pyqgis.html)