1[![Build Status](https://travis-ci.org/funiq/geoPHP.svg?branch=master)](https://travis-ci.org/funiq/geoPHP)
2
3GeoPHP is a open-source native PHP library for doing geometry operations. It is a fork of famous [geoPHP](https://github.com/phayes/geoPHP) library by Patrick Hayes.
4
5It is written entirely in PHP and can therefore run on shared hosts. It can read and write a wide variety of formats: WKT (EWKT), WKB (EWKB), TWKB, GeoJSON,
6KML, GPX, and GeoRSS. It works with all Simple-Feature geometries (Point, LineString, Polygon, GeometryCollection etc.)
7and can be used to get centroids, bounding-boxes, area, and a wide variety of other useful information.
8
9GeoPHP also helpfully wraps the GEOS php extension so that applications can get a transparent performance
10increase when GEOS is installed on the server. When GEOS is installed, geoPHP also becomes
11fully compliant with the OpenGIS® Implementation Standard for Geographic information. With GEOS you get the
12full-set of openGIS functions in PHP like Union, IsWithin, Touches etc. This means that applications
13get a useful "core-set" of geometry operations that work in all environments, and an "extended-set"of operations
14for environments that have GEOS installed.
15
16See the _getting started_ section below for references and examples of everything that geoPHP can do.
17
18Forks and contributions are welcome. Please open [issues](https://github.com/funiq/geoPHP/issues), send [pull](https://github.com/funiq/geoPHP/pulls) requests and I will merge them into the main branch.
19
20## Getting Started
21
22### Example usage
23
24```php
25<?php
26use \geoPHP\geoPHP;
27
28// Polygon WKT example
29$polygon = geoPHP::load('POLYGON((1 1,5 1,5 5,1 5,1 1),(2 2,2 3,3 3,3 2,2 2))','wkt');
30$area = $polygon->getArea();
31$centroid = $polygon->getCentroid();
32$centX = $centroid->getX();
33$centY = $centroid->getY();
34
35print "This polygon has an area of ".$area." and a centroid with X=".$centX." and Y=".$centY;
36
37// MultiPoint json example
38print "<br/>";
39$json =
40'{
41   "type": "MultiPoint",
42   "coordinates": [
43       [100.0, 0.0], [101.0, 1.0]
44   ]
45}';
46
47$multipoint = geoPHP::load($json, 'json');
48$multipoint_points = $multipoint->getComponents();
49$first_wkt = $multipoint_points[0]->out('wkt');
50
51print "This multipoint has ".$multipoint->numGeometries()." points. The first point has a wkt representation of ".$first_wkt;
52```
53
54### More Examples
55
56The Well Known Text (WKT) and Well Known Binary (WKB) support is ideal for integrating with MySQL's or PostGIS's spatial capability.
57Once you have SELECTed your data with `'AsText('geo_field')'` or `'AsBinary('geo_field')'`, you can put it straight into
58geoPHP (can be wkt or wkb, but must be the same as how you extracted it from your database):
59
60    $geom = geoPHP::load($dbRow,'wkt');
61
62You can collect multiple geometries into one (note that you must use wkt for this):
63
64    $geom = geoPHP::load("GEOMETRYCOLLECTION(".$dbString1.",".$dbString2.")",'wkt');
65
66Calling get components returns the sub-geometries within a geometry as an array.
67
68    $geom2 = geoPHP::load("GEOMETRYCOLLECTION(LINESTRING(1 1,5 1,5 5,1 5,1 1),LINESTRING(2 2,2 3,3 3,3 2,2 2))");
69    $geomComponents = $geom2->getComponents();    //an array of the two linestring geometries
70    $linestring1 = $geomComponents[0]->getComponents();	//an array of the first linestring's point geometries
71    $linestring2 = $geomComponents[1]->getComponents();
72    echo $linestring1[0]->x() . ", " . $linestring1[0]->y();    //outputs '1, 1'
73
74An alternative is to use the `asArray()` method. Using the above geometry collection of two linestrings,
75
76	$geometryArray = $geom2->asArray();
77	echo $geometryArray[0][0][0] . ", " . $geometryArray[0][0][1];    //outputs '1, 1'
78
79Clearly, more complex analysis is possible.
80
81	echo $geom2->envelope()->area();
82
83
84### Working with PostGIS
85
86geoPHP, through it's EWKB adapter, has good integration with postGIS. Here's an example of reading and writing postGIS geometries
87
88```php
89<?php
90use \geoPHP\geoPHP;
91$host =     'localhost';
92$database = 'phayes';
93$table =    'test';
94$column =   'geom';
95$user =     'phayes';
96$pass =     'supersecret';
97
98$connection = pg_connect("host=$host dbname=$database user=$user password=$pass");
99
100// Working with PostGIS and Extended-WKB
101// ----------------------------
102
103// Using asBinary and GeomFromWKB in PostGIS
104$result = pg_fetch_all(pg_query($connection, "SELECT asBinary($column) as geom FROM $table"));
105foreach ($result as $item) {
106  $wkb = pg_unescape_bytea($item['geom']); // Make sure to unescape the hex blob
107  $geom = geoPHP::load($wkb, 'ewkb'); // We now a full geoPHP Geometry object
108
109  // Let's insert it back into the database
110  $insert_string = pg_escape_bytea($geom->out('ewkb'));
111  pg_query($connection, "INSERT INTO $table ($column) values (GeomFromWKB('$insert_string'))");
112}
113
114// Using a direct SELECT and INSERTs in PostGIS without using wrapping functions
115$result = pg_fetch_all(pg_query($connection, "SELECT $column as geom FROM $table"));
116foreach ($result as $item) {
117  $wkb = pack('H*',$item['geom']);   // Unpacking the hex blob
118  $geom = geoPHP::load($wkb, 'ewkb'); // We now have a geoPHP Geometry
119
120  // To insert directly into postGIS we need to unpack the WKB
121  $unpacked = unpack('H*', $geom->out('ewkb'));
122  $insert_string = $unpacked[1];
123  pg_query($connection, "INSERT INTO $table ($column) values ('$insert_string')");
124}
125```
126
127## Documentation
128
129In progress… You can read the doc for original phayes/geoPHP at [geophp.net](https://geophp.net "GeoPHP homepage")
130
131## Credit
132
133- Maintainer: Péter Báthory
134- Original author: Patrick Hayes
135
136Additional Contributors:
137 * GeoMemes Research (<http://www.geomemes.com>)
138 * HighWire Press (<http://www.highwire.org>) and GeoScienceWorld (<http://www.geoscienceworld.org>)
139 * Arnaud Renevier (gisconverter.php) <https://github.com/arenevier/gisconverter.php>
140 * Dave Tarc <https://github.com/dtarc>
141 * Elliott Hunston (documentation) <https://github.com/ejh>
142
143This library is open-source and dual-licensed under both the Modified BSD License and GPLv2. Either license may be used at your option.
144