GIS奮闘記

元GISエンジニアの技術紹介ブログ。主にPythonを使用。

スポンサーリンク

Shapelyを使ってみよう

さて、本日はShapelyを使ってみようと思います。

Shapelyとは

Shapelyは、GEOSをベースとしたpythonライブラリで、ジオメトリの操作および分析のために使われます。GIS関係のPythonライブラリではかなり有名だと思います。

特徴
  1. 二点間の距離を計測したり、エリアの面積を計測することができる
  2. プロジェクション(投影法とか座標系)関係の処理はできない
  3. wktやjsonのシリアライズ、デシリアライズができる

要するに地理空間データを計算するためのライブラリですね。

投影法?座標系?という方は以下のエントリーを読んでみてください。
www.gis-py.com

また、以下のエントリーでもShapelyを紹介していますので、興味のある方はぜひ読んでみてください。
www.gis-py.com

Shapelyでのジオメトリの扱い

ジオメトリの主なプロパティ

プロパティ
area 面積
bounds minx, miny, maxx, maxy
length 長さ
geom_type ジオメトリタイプ

ジオメトリの種類

ジオメトリ 特徴
Point Pointはポイントですね。データ上の点です。
LineString ラインですね。ポイントの配列がラインを形成しているイメージでしょうか。
LinearRing リングのようになるラインですね。出発点に最終点のLinsStringを含みます。それぞれのLinearRingは交差または触れることができません。
Polygon ポリゴンですね。穴の開いたポリゴンを作ることもできます。
MultiPoint pointのcollectionです。レコードとしては一つだけど、ジオメトリは複数あるイメージでしょうか。
MultiLineString LineStringのcollectionです。考え方はMultiPointと同じです。
MultiPolygon Polygonのcollectionをです。考え方はMultiPointと同じです。
GeometryCollection Point, Line, LinearRing, Polygonを組み合わせたcollectionです。

各ジオメトリを扱うサンプルコード

Point

ポイントのプロパティを確認してみます。

from shapely.geometry import Point
point = Point(1.0, 2.0)

print point.area
print point.bounds
print point.length
print point.geom_type
point

当たり前ですが、ポイントなので面積と長さは0ですね。

f:id:sanvarie:20181025092304p:plain

バッファ

バッファをとってみます。

from shapely.geometry import Point
point = Point(0.0, 0.0)
polygon = point.buffer(10.0)

print polygon.area
print polygon.bounds
print polygon.length
print polygon.geom_type
polygon

ある地点に配置したポイントのバッファをとるとポリゴンを作ることができます。
f:id:sanvarie:20181025092406p:plain

距離

ジオメトリ間の距離を測ってみます。

from shapely.geometry import Point
point1 = Point(0.0, 0.0)
point2 = Point(1.0, 1.0)

point1.distance(point2)

f:id:sanvarie:20181025092524p:plain

LineString

ラインですね。ポイントの配列がラインを形成します。
f:id:sanvarie:20181024161443p:plain

from shapely.geometry import LineString
line = LineString([(0, 0), (1, 1),(1,0),(2,1)])
line

f:id:sanvarie:20181025092736p:plain

LinearRing

ラインリングは面白い考えですね。出発点に最終点のLinsStringを含みます。それぞれのLinearRingは交差または触れることができません。以下のbはポイントが交差しているので不正なラインリングですね。
f:id:sanvarie:20181024161509p:plain

from shapely.geometry.polygon import LinearRing
ring = LinearRing([(0, 0), (1, 1), (1, 0)])
ring

三点しか指定していないのにリングになりました。これがラインリングの考えですね。
f:id:sanvarie:20181025092905p:plain

Polygon

ポリゴンは通常のポリゴンと以下のように穴の開いたポリゴンも作ることができます。ただし、以下のb,c,dは不正なポリゴンと認識されます。
f:id:sanvarie:20181024161537p:plain
f:id:sanvarie:20181024161713p:plain

from shapely.geometry import Polygon
polygon = Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])
polygon

f:id:sanvarie:20181025093215p:plain

from shapely.geometry import Polygon
ext = [(0, 0), (0, 2), (2, 2), (2, 0), (0, 0)]
int = [(1, 0), (0.5, 0.5), (1, 1), (1.5, 0.5), (1, 0)][::-1]
polygon = Polygon(ext, [int])
polygon

こんな感じで穴の開いたポリゴンを作ることができます。
f:id:sanvarie:20181025102559p:plain

GeometryCollection

コレクションは、Point, Lines, LinearRing, Polygonを組み合わせたcollectionを表します。

f:id:sanvarie:20181024162410p:plain

from shapely.geometry import LineString
a = LineString([(0, 0), (1, 1), (1,2), (2,2)])
b = LineString([(0, 0), (1, 1), (2,1), (2,2)])
x = a.intersection(b)
x

二つのラインリングが交差する箇所を抽出しました。これがコレクションですね。
f:id:sanvarie:20181025093403p:plain

MultiPoint

ポイントのコレクションですね。

from shapely.geometry import MultiPoint
points = MultiPoint([(0.0, 0.0), (1.0, 1.0)])
points

f:id:sanvarie:20181025093625p:plain

MultiLineString

ラインのコレクションですね
f:id:sanvarie:20181024162636p:plain

from shapely.geometry import MultiLineString
coords = [((0, 0), (1, 1)), ((-1, 0), (1, 0))]
lines = MultiLineString(coords)
lines

f:id:sanvarie:20181025093718p:plain

MultiPolygon

ポリゴンのコレクションですね。以下のbのようなマルチポリゴンは不正なものとして扱われます。
f:id:sanvarie:20181024162900p:plain

from shapely.geometry import MultiPolygon

coords = [((0, 0), (0, 1), (1, 1), (1, 0),(, 2), (0, 3), (3, 3), (3, 2))]
polygons= MultiLineString(coords)
polygons

f:id:sanvarie:20181025101406p:plain

以上です。今回紹介したものはShapelyの基本的な考え方だけですが、いかがでしたでしょうか。個人的にはすごく便利で使い勝手のいいライブラリだと思います。興味のある方はぜひ使ってみてください。