GeoPHPについて

# GeoPHPの紹介
　GeoPHPはPHPの空間情報処理（GIS）を実現するライブラリです。DrupalというオープンソースのCMSで採用されており、日本語の情報としてはこれに関連する情報が多く見受けられます。

 - github： https://github.com/phayes/geoPHP
 - Webサイト： https://geophp.net

ライセンスについては、下記の記載があります。
>This program is dual-licensed under both the GPL version 2 (or later) and  Modified BSD License. Either license may be used at your option. 

「GPL バージョン２」 と 「修正BSDライセンス」の両方を採用しており、どちらのライセンスかを自由に採用することが出来ると読み取れますが、ご利用の際には配布元のライセンス条項をご自身でご確認下さい。

#### GeoPHPのクラス構造 

GeoPHPは、大きく分けて３つの構造に分かれています。

1. 静的クラス ：　基礎的な機能を提供します
2. アダプタクラス ：　様々なフォーマットの読み込み、書き出しを実現します
3. ジオメトリクラス　：　本格的な空間情報処理を実現します

　また、GEOSライブラリを導入すると、ジオメトリクラスでは更に多くの空間情報処理が提供されます。

下図に各クラスと機能の役割についてまとめました。
複数のクラスが入力、出力に対応している事がわかります。

![gphp.png](https://qiita-image-store.s3.amazonaws.com/0/53918/921e68e9-cab8-d5ae-171e-09d1a54e2c88.png)

　基本的な利用方法としましては、アダプタクラスを用いてデータの読み込みを行い、得られたジオメトリクラスで空間情報処理を行い、その結果をアダプタクラスのwrite関数か、ジオメトリクラスのout関数を用いて、任意のフォーマットに変換して出力するという方法が挙げられます。

#### 対応フォーマット

 - WKT (EWKT を含む)
 - WKB (EWKB を含む)
 - GeoJSON
 - KML
 - GPX
 - GeoRSS
 
　多くのGISフォーマットの入出力に対応しているため、WebAPIでフォーマット変換だけでも非常に有用であると思われます。簡単なGIS処理を行うために態々PostGISを導入するというこというケースも減らせる可能性があります。

　注目は、WKBに対応している事です。PostGISで利用されているデータ形式であり、ビジネスロジックとデータベース間でフォーマット変換が不要になります。データベースのCPU負荷の軽減・SQLの簡素化が期待できます。

#### 利用方法
　方法は２つ。配布先から圧縮ファイルをダウンロードして利用する方法と、composerを利用する方法があります。
　ダウンロードして利用する場合は、配布サイトからダウンロードしインクルードすれば動作いたします。

#### ダウンロード先
 zip: https://github.com/phayes/geoPHP/zipball/master
 tar.gz: https://github.com/phayes/geoPHP/tarball/master

#### ライブラリのインクルード
　ライブラリを利用する際は、`include_once();`関数を用いて、geoPHP.incまでのパスを記載します。


# API（ざっくり日本語訳）
　本家サイト https://geophp.net/api.html に英語のドキュメントが御座います。また、私個人の解説を加えたものには、`［解説］`と
## 静的Class
　GeoPHPでは静的Classの中に有用な機能を提供しています。これらの関数を利用する際は静的なコールをしなければなりません。

［解説］ 具体的には、new によるインスタンスの生成ではなく、スコープ演算子（::)を用いてクラス名にアクセスします。

```php:静的Classの利用例
<?php
include_once("geoPHP.inc"); //geoPHPのインクルード
$geometry = geoPHP::load('MULTILINESTRING((10 10,20 20,10 40))','wkt'); //WKT形式をロードし、ジオメトリ
$reduced_geometry = geoPHP::geometryReduce($geometry);

```

| 関数 | 説明 | 戻り値 |
|:--|:--|:--|
| version | geoPHPのバージョンを返却します。互換性チェックに便利です。 | Numeric String |
| load | WKT形式のような変換可能な形式を読み込み、ジオメトリに変換します。 第1引数はデータ、第2引数はフォーマット('wkt','wkb','json','kml','gpx','google_geocode')の何れかを指定します。 全ての追加的な引数は、フォーマット変換に渡されます。 | Geometry |
| getAdapterMap | geoPHP::load関数で変換可能なアダプタ形式について、キー・バリュー形式の配列を返却します。 | Array |
| geometryList | 全ての空間形式のリストを返却します。 | Array |
| geosToGeometry | GEOS形式のジオメトリ（地物）を入力すると、geoPHP形式のジオメトリ（地物）が返却されます。 | Geometry |
| geometryReduce |ジオメトリまたはジオメトリ配列を、使用可能な共通ジオメトリに縮小します。たとえば、ポイントのみのGeometryCollectionはMultiPointになります。また、単一ポイントを含むマルチポイントはポイントを返します。ジオメトリの配列を渡すことができ、それらは単一のジオメトリにコンパイルされます。| Geometry |
| geosInstalled | GEOSがインストールされており、geoPHPのgeos拡張関数が利用可能の可否について返却します。 | Boolean |

## アダプタ
　アダプタは、geoPHPジオメトリにデータを入出力する役割を担います。一般に、アダプタを使用してgeoPHPジオメトリにデータをロードし、ジオメトリに対してさまざまな操作を行い、別のアダプタを使用して別の（または同じ）フォーマットに書き出します。アダプタは、インスタンスを生成して利用し、静的な呼出では利用できません。

#### アダプタクラスの階層構造

- **WKT**  WKT (Well Known Text)形式の読み込み・書き出し
  - **EWKT** Extended-WKT形式の読み込み・書き出し
- **WKB** WKB (Well Known Binary)形式の読み込み・書き出し。非常に高速に動作します。
 - **EWKB** Extended-WKB形式の読み込み・書き出し (PostGIS利用時に用います)
- **GeoJSON** GeoJSON形式の読み込み・書き出し
- **KML**  KML (Google Earth)形式の読み込み・書き出し
- **GoogleGeocode** google geocoding APIのジオコーディング・逆ジオコーディングを可能にします。
- **GPX** GPX (多くのGPSデバイスで採用されている形式)形式の読み込み・書き出し
- **GeoRSS** GeoRSS形式の読み込み・書き出し

［ 解説 ］　各フォーマット毎にクラスが設置されていますが、WKTとWKBの拡張形式であるEWKTとEWKBはそれぞれのサブクラスとして宣言されているようです。

#### 実装例

```php:アダプタ利用例
<?php
include_once("geoPHP.inc"); //geoPHPのインクルード
$wkb_reader = new WKB(); //newキーワードにより、WKBクラスのインスタンスを作成
$geometry = $wkb_reader->read('0101000000000000000000f03f000000000000f03f',TRUE);
$wkt_writer = new wkt();　//newキーワードにより、WKTクラスのインスタンスを作成
$wkt = $wkt_writer->write($geometry); //ジオメトリ（地物）をWKT形式に変換して出力
echo $wkt; // POINT(1 1)　
```
### アダプタクラスの関数

| 関数名 | 説明 | 戻り値 |
|:--|:--|:--|
| read | 通常テキスト型のデータを読み込み、ジオメトリを返却します。 | Geometry |
| write | ジオメトリデータを入力すると、アダプタのフォーマットに従った文字列を出力します。 | String |

## ジオメトリ

ジオメトリクラスは、geoPHPの中心となるクラスであり、
ジオメトリオブジェクトにデータをロードしたら、変換、変形、および操作等の以下で説明するさまざまなメソッドにアクセスできます。一般的に、ジオメトリオブジェクトを取得するにはアダプタを使用しますが、手動で作成することもできます。これを行う方法については、クラスのコンストラクタメソッドを参照してください。 GEOS-php拡張モジュールを利用するには、GEOSのインストールが必要です（詳細は後述）。

### ジオメトリクラス構造

Geometry

- Point
- Collection
 - LineString
 - Polygon
 - MultiLineString
 - MultiPoint
 - MultiPolygon
 - GeometryCollection

［　解説　］
　ジオメトリクラスは、Point（点）以外は全てCollectionとして定義されているようです。
　　基本は空間形状の３形態である、Point（点）、LineString（線）、Polygon（面）であり、その複数型であるMultiPoint(点）、　MultiLineString(線） 、　MultiPolygonが３種類あります。GeometryCollectionは、形態が異なる地物が複合して登録する事が可能（だと思われます［未検証］）。

### 実装例

```php:ジオメトリ実装例
$poly1 = $geoPHP::load('POLYGON((30 10,10 20,20 40,40 40,30 10))','wkt');
$poly2 = $geoPHP::load('POLYGON((35 10,10 20,15 40,45 45,35 10),(20 30, 35 35, 30 20, 20 30))','wkt');
$combined_poly = $poly1->union($poly2);
$kml = $combined_poly->out('kml');
```

|関数名|処理内容|戻り値|
|:--|:--|:--|
| out | geometry型から指定した空間フォーマットに変換し出力します。対応形式( wkt, wkb, json, kml, gpx, google_geocode) | String |
| area | ポリゴンまたはジオメトリコレクションからジオメトリ型の空間参照系に従って面積を算出します。| Float |
| boundary | ジオメトリの全てを包含する外輪（線）を返却します。（凸包か凹包かは使っていないので未検証です。）| LinearRing |
| envelope | ジオメトリを内包する面積最小となる四角形（バンダリボックス）を返却します。| Polygon |
| getBBox | ジオメトリを内包する面積最小となる四角形を配列として返却します。| Array |
| centroid | ジオメトリ（地物）の重心を返却します。 ポリゴンの場合は、重心位置がポリゴン内部に存在することは保証されていません。| Point |
| length | 空間参照系に従って算出された長さを返却します。 | Float |
| greatCircleLength | 地球の曲線に合わせた距離をメートル単位で算出した結果を返却します。 | Float |
| haversineLength | 度単位でHAVERSINE距離を算出した結果を返却します。 | Float |
| y | ジオメトリ（点）のy座標の値 | Float |
| x | ジオメトリ（点）のx座標の値 | Float |
| numGeometries | ジオメトリの数を返却します。 | Integer |
| geometryN | ジオメトリコレクション（地物の集合体）から、N番目のジオメトリ（地物）を返却します。地物の番号は１から始まります。 | Geometry |
| startPoint | 線ジオメトリの始点を返却します。 | Point |
| endPoint | 線ジオメトリの終点を返却します。  | Point |
| isRing | 曲線が closed()［始点と終点が同一］ と isSimple()［同一地点に複数通過しないこと］が同時に満たされる場合に、 1 (TRUE)を返却します。 | Boolean |
| isClosed | 曲線が閉じている場合、 1 (TRUE)を返却します。始点=終点| Boolean |
| getComponents | ジオメトリコレクション（地物の集合体）から、全てのジオメトリ（地物）を取得します。 | Array of geometries |
| numPoints | 線ジオメトリの点の数を返却します。 | Integer |
| pointN | 線ジオメトリのN番目の点を返却します。 番号は1から始まりますのでご注意下さい。 | Point |
| exteriorRing | 面ジオメトリの外輪（線）を返却します。 | LineString |
| numInteriorRings | 面ジオメトリの内輪の数を返却します。 | Integer |
| interiorRingN | 面ジオメトリのN番目の内輪（線）を返却します。番号は1から始まりますのでご注意下さい。 | LineString |
| dimension | ジオメトリ（地物）の次元数を返却します。 ジオメトリコレクション内部で次元数が統一されていない場合、次元数が最大となるジオメトリの値を返却します。 | Integer |
| geometryType | インスタンス化可能なメンバであるジオメトリのインスタンス化可能な空間形式の名前を文字列で返します。 | String |
| SRID | ジオメトリ（地物）の空間参照系識別子（SRID）を返却します。 | integer |
| setSRID | ジオメトリ（地物）に対して、空間参照系識別子（SRID）を指定します。 | NULL |
| asArray | ジオメトリ（地物）を配列型に変換します。 | Array |
| getGeoInterface | 空間形式と座標系を一つの配列として返却します。 | Array |
| isEmpty |１つも頂点が存在しない場合、TRUEを返却します。 | Boolean |

### Alias 別名
［ 解説 ］ geometry関数で、別名で読み出し可能な関数があります。

| 関数名 | 説明 | 戻り値 |
|:--|:--|:--|
| getCentroid |centroid() の別名 | Point |
| getArea | area()の別名  | Float |
| getX | x()の別名  | Float |
| getY | y()の別名  | Float |
| getGeos | geos()の別名  | GEOSGeometry |
| getGeomType | geometryType()の別名  | String |
| getSRID | SRID()の別名  | Integer |
| asText | $this->out('wkt')の別名  | String |
| asBinary | $this->out('wkb')の別名  | String |

## 先進的関数

GEOS-php 拡張関数は、GEOSのインストールが必要です。

[ 解説 ]GEOSの関数については、PostGIS等で導入されておりますので、日本語訳と解説についてはPostGISのドキュメントをご覧頂くと参考になるかと思います。

| 関数名 | 説明 | 戻り値 |
|:--|:--|:--|
| geos | geometryからGEOSGeometryを返却します。  | GEOSGeometry |
| setGeos | 入力したgeometryの代表値をGEOSGeometryに設定します。 | NULL |
| pointOnSurface | ポリゴン内部に存在することを保証した１つのポイント（点）を返却します。 | Point |
| equals |  他の地物と空間的に同一である場合に、1 (TRUE)を返却します。  | Boolean |
| equalsExact | 地物が別の地物と完全に一致している場合に、1を返します（TRUE）。判定には、コンポーネントパーツの順序も含まれます。| Boolean |
| relate | intersectionMatrixPattern結果に従って、ジオメトリが空間的にもう一つのジオメトリと関係している場合に、1 (TRUE)を返却します。 | Boolean |
| checkValidity | 説明文欠損 | Boolean |
| isSimple | ジオメトリが空間の同じポイントを2回以上通過しない場合に、1（TRUE）を返却します。 | Boolean |
| project | ジオメトリを別のSRIDに投影します。 | Geometry |
| buffer | 入力したジオメトリオブジェクトからの距離が、指定した距離であるすべての点を表すジオメトリを返します。距離計算はジオメトリの測地系に従います。線形補間の限界のために、比較的小さな誤差が存在することがよくありますが、使用される座標系の分解能に近いはずです。| Geometry |
| intersection | ２つのジオメトリの交差する範囲を返却します。 http://en.wikipedia.org/wiki/Intersection_(set_theory) を御覧ください。 | Geometry |
| convexHull | 入力したジオメトリの凸包を返却します。 http://en.wikipedia.org/wiki/Convex_hull を御覧ください | Geometry |
| difference | 入力したジオメトリ１が、ジオメトリ２と重なり合わない範囲を返却します。 | Geometry |
| symDifference | 入力した２つのジオメトリがお互いに重ならない範囲を返却します。 http://en.wikipedia.org/wiki/Symmetric_difference を御覧ください。 ジオメトリ１とジオメトリ２を入れ替えても同様の結果が得られます。 | Geometry |
| union | ジオメトリに他のジオメトリを合わせたジオメトリオブジェクトを返却します。 http://en.wikipedia.org/wiki/Union_(set_theory) | Geometry |
| simplify | 指定した許容誤差に従ってジオメトリを単純化します。単純化されたジオメトリのすべての頂点は元のジオメトリの許容距離内にあります。大きすぎる許容値が渡された場合、結果は空のジオメトリになります。| Geometry |
| disjoint | 他のオブジェクトと空間的に触れ合っていない場合、1 (TRUE) を返却します。 | Boolean |
| touches | 他のオブジェクトと空間的に触れ合う場合に、1 (TRUE) を返却します。 | Boolean |
| intersects |  他のオブジェクトと空間的に重なり合う場合に、1 (TRUE) を返却します。 | Boolean |
| crosses |　他のオブジェクトと空間的に交差する場合に、1 (TRUE) を返却します。 | Boolean |
| within | 他のオブジェクトと空間的に重なり合う場合に、1 (TRUE) を返却します。 | Boolean |
| contains | 他のオブジェクトと空間的に内包される場合に、 1 (TRUE) を返却します。 | Boolean |
| overlaps | 他のオブジェクトと空間的に重なる場合に、1 (TRUE) を返却します。 | Boolean |
| covers | contains()の別名 | Boolean |
| coveredBy |  within()　の別名 | Boolean |
| distance | ２つのオブジェクトの最短距離を、測地系の単位で返却します。| Float |
| hausdorffDistance | See http://en.wikipedia.org/wiki/Hausdorff_distance | Float |

# まとめ
GeoPHPの概要とAPIの日本語訳を行いました。
特徴としては、
　強み：多くのフォーマットに対応しており、フォーマット変換に便利である。
　弱み：空間INDEXに未対応など、大規模なデータ処理に不向きである。
というものがあると思います。

これを機に多くの人に関心をもって頂き、沢山のノウハウを共有できたらと思います。