2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【GIS】Pythonでラスタ画像上の任意地点の値を拾う

Posted at

やりたいこと

ラスタ画像上で任意地点の座標を指定して,値を拾うってのをやります.多少語弊があるかもしれませんが,QGISでいうところのPoint Sampling Toolみたいなやつですね.
今回は,国土数値情報の土地利用細分メッシュを用いて,指定した座標の土地利用の画素値をサンプリングしてみます.

使用ライブラリ

今回使うデータがGeoTiff形式のラスタデータなので,読み込みにみんな大好きGdalを使います.
インストールは以下のコマンドでできます.

pipの人

pip install GDAL

condaの人

conda install -c conda-forge gdal

使用データ

繰り返しになりますが,国土数値情報の土地利用細分メッシュを使います.今回は四国周辺の2014年度版のものを使ってます.
以下のリンクからダウンロードできます.

国土数値情報>土地利用細分メッシュ(ラスタ版)

プログラム全体

from osgeo import gdal
import numpy as np

file_path = './input/landuse.tif'

ds = gdal.Open(file_path)

lu = ds.ReadAsArray()

Xsize = ds.RasterXSize
Ysize = ds.RasterYSize

x_min, x_res, rtn_x, y_max, rtn_y, y_res = ds.GetGeoTransform()

x_max = x_min + Xsize * x_res
y_min = y_max + Ysize * y_res

lon_tick = np.arange( x_min, x_max, x_res )
lat_tick = np.arange( y_max, y_min, y_res )

lon, lat = np.meshgrid(lon_tick, lat_tick)


p_lon = 133. + 32.9/60
p_lat = 33. + 34./60

dist = ( lon - p_lon )**2 + ( lat - p_lat )**2

mindist = np.min(dist)

p_index = np.where( dist == mindist )
p_lu = lu[p_index]

print(p_lu)

説明

値の拾い方

任意地点の座標値を起点に,全画素までの距離を測り,その大きさが最小になる地点の画素値を拾うというアイデアです.

ライブラリのインポート

from osgeo import gdal
import numpy as np

データの読み込み,必要な情報の取得

file_path = './input/landuse.tif'

ds = gdal.Open(file_path)

まず,gdalのOpenでGeoTiff画像を読み込みます.

lu = ds.ReadAsArray()

Xsize = ds.RasterXSize
Ysize = ds.RasterYSize

x_min, x_res, rtn_x, y_max, rtn_y, y_res = ds.GetGeoTransform()

上から順に,データの配列化,水平・鉛直方向の画素数,各種座標値を取得します.
GetGeoTransformでは,左から順に,始点端経度(最小経度),水平解像度,回転,始点端緯度(最大緯度),回転,鉛直解像度を取得できます.この時,鉛直解像度は負の値になることに注意してください.

x_max = x_min + Xsize * x_res
y_min = y_max + Ysize * y_res

lon_tick = np.arange( x_min, x_max, x_res )
lat_tick = np.arange( y_max, y_min, y_res )

lon, lat = np.meshgrid(lon_tick, lat_tick)

取得した座標値から,最大緯度,最小経度を求めます.
画像の4隅の座標がわかったので,これと縦横の解像度から,緯度,経度のメッシュを作成します.

値を拾う

座標の入力

p_lon = 133. + 32.9/60
p_lat = 33. + 34./60

任意地点から全画素までの距離を測る

dist = ( lon - p_lon )**2 + ( lat - p_lat )**2

中学数学でやる距離の公式です.ほんとは平方根取らないとちゃんとした距離にならないですが,大きさを比較するだけなので今回は平方根取ってません.

mindist = np.min(dist)

p_index = np.where( dist == mindist )
p_lu = lu[p_index]

print(p_lu)

>>> [70]

距離の最小値を求め,それに当たるインデックスを取得します.最後に,土地利用の画像上で取得したインデックスを指定することで,指定した座標の画素値を取得できます.
ちなみに今回は画素値として70という値が取得できました.対応表でチェックしてみると,「建物用地」みたいです.

注意点

指定した地点が隣り合う画素のど真ん中にある時など,距離の最小値が2つ以上ある時は困ります.特に今回のように画素値が離散的な値の時は,どの値を選べばいいか問題が発生することもあります.(なかなかそんなことは起きないけど)
ぼくの場合は画素値が連続値(気温とか標高値とか)の場合は,平均とったりしています.理屈上あり得る問題なので注意してください.

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?