Skip to content

Commit b60e71f

Browse files
committed
Proper autoloading for composer, PSR-4 compliant, Cleanup
1 parent bb6d793 commit b60e71f

22 files changed

+3867
-8
lines changed

composer.json

+18-8
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
11
{
22
"name": "phayes/geophp",
3-
"license": "GPL-2 or New-BSD",
4-
"type": "library",
53
"description": "GeoPHP is a open-source native PHP library for doing geometry operations. It is written entirely in PHP and can therefore run on shared hosts. It can read and write a wide variety of formats: WKT (including EWKT), WKB (including EWKB), GeoJSON, KML, GPX, GeoRSS). It works with all Simple-Feature geometries (Point, LineString, Polygon, GeometryCollection etc.) and can be used to get centroids, bounding-boxes, area, and a wide variety of other useful information.",
4+
"type": "library",
5+
"keywords": ["geojson", "wkt", "geophp", "converter", "geometry"],
66
"homepage": "https://github.com/phayes/geoPHP",
7-
"autoload": {
8-
"classmap": ["geoPHP.inc"]
9-
},
10-
"authors":[
7+
"license": "GPL-2 or New-BSD",
8+
"authors": [
119
{
12-
"name":"Patrick Hayes"
10+
"name": "Patrick Hayes",
11+
"email": "[email protected]",
12+
"homepage": "https://benramsey.com"
1313
}
1414
],
15+
"support": {
16+
"issues": "https://github.com/phayes/geoPHP/issues",
17+
"source": "https://github.com/phayes/geoPHP"
18+
},
19+
"require": {
20+
"php": ">=5.3"
21+
},
1522
"require-dev": {
16-
"phpunit/phpunit": "4.1.*"
23+
"phpunit/phpunit": "4.1.*"
24+
},
25+
"autoload": {
26+
"psr-4": {"Phayes\\GeoPHP\\": "src/"}
1727
}
1828
}

src/Adapters/EWKB.php

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<?php
2+
3+
namespace Phayes\GeoPHP\Adapters;
4+
5+
use Phayes\GeoPHP\GeoPHP;
6+
use Phayes\GeoPHP\Adapters\GeoAdapter;
7+
use Phayes\GeoPHP\Adapters\WKB;
8+
use Phayes\GeoPHP\Geometry\Point;
9+
use Phayes\GeoPHP\Geometry\Polygon;
10+
use Phayes\GeoPHP\Geometry\LineString;
11+
use Phayes\GeoPHP\Geometry\MultiPoint;
12+
use Phayes\GeoPHP\Geometry\MultiPolygon;
13+
use Phayes\GeoPHP\Geometry\MultiLineString;
14+
use Phayes\GeoPHP\Geometry\Geometry;
15+
use Phayes\GeoPHP\Geometry\GeometryCollection;
16+
use Exception;
17+
18+
class EWKB extends WKB
19+
{
20+
21+
/**
22+
* Read WKB binary string into geometry objects
23+
*
24+
* @param string $wkb An Extended-WKB binary string
25+
*
26+
* @return Geometry
27+
*/
28+
public function read($wkb, $is_hex_string = false)
29+
{
30+
if ($is_hex_string) {
31+
$wkb = pack('H*',$wkb);
32+
}
33+
34+
// Open the wkb up in memory so we can examine the SRID
35+
$mem = fopen('php://memory', 'r+');
36+
fwrite($mem, $wkb);
37+
fseek($mem, 0);
38+
$base_info = unpack("corder/ctype/cz/cm/cs", fread($mem, 5));
39+
if ($base_info['s']) {
40+
$srid = current(unpack("Lsrid", fread($mem, 4)));
41+
}
42+
else {
43+
$srid = NULL;
44+
}
45+
fclose($mem);
46+
47+
// Run the wkb through the normal WKB reader to get the geometry
48+
$wkb_reader = new WKB();
49+
$geom = $wkb_reader->read($wkb);
50+
51+
// If there is an SRID, add it to the geometry
52+
if ($srid) {
53+
$geom->setSRID($srid);
54+
}
55+
56+
return $geom;
57+
}
58+
59+
/**
60+
* Serialize geometries into an EWKB binary string.
61+
*
62+
* @param Geometry $geometry
63+
*
64+
* @return string The Extended-WKB binary string representation of the input geometries
65+
*/
66+
public function write(Geometry $geometry, $write_as_hex = false)
67+
{
68+
// We always write into NDR (little endian)
69+
$wkb = pack('c',1);
70+
71+
switch ($geometry->getGeomType()) {
72+
case 'Point';
73+
$wkb .= pack('L',1);
74+
$wkb .= $this->writePoint($geometry);
75+
break;
76+
case 'LineString';
77+
$wkb .= pack('L',2);
78+
$wkb .= $this->writeLineString($geometry);
79+
break;
80+
case 'Polygon';
81+
$wkb .= pack('L',3);
82+
$wkb .= $this->writePolygon($geometry);
83+
break;
84+
case 'MultiPoint';
85+
$wkb .= pack('L',4);
86+
$wkb .= $this->writeMulti($geometry);
87+
break;
88+
case 'MultiLineString';
89+
$wkb .= pack('L',5);
90+
$wkb .= $this->writeMulti($geometry);
91+
break;
92+
case 'MultiPolygon';
93+
$wkb .= pack('L',6);
94+
$wkb .= $this->writeMulti($geometry);
95+
break;
96+
case 'GeometryCollection';
97+
$wkb .= pack('L',7);
98+
$wkb .= $this->writeMulti($geometry);
99+
break;
100+
}
101+
102+
if ($write_as_hex) {
103+
$unpacked = unpack('H*',$wkb);
104+
return $unpacked[1];
105+
} else {
106+
return $wkb;
107+
}
108+
}
109+
}

src/Adapters/EWKT.php

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Phayes\GeoPHP\Adapters;
4+
5+
use Phayes\GeoPHP\Adapters\WKT;
6+
7+
class EWKT extends WKT
8+
{
9+
10+
/**
11+
* Serialize geometries into an EWKT string.
12+
*
13+
* @param Geometry $geometry
14+
*
15+
* @return string The Extended-WKT string representation of the input geometries
16+
*/
17+
public function write(Geometry $geometry)
18+
{
19+
$srid = $geometry->SRID();
20+
$wkt = '';
21+
if ($srid) {
22+
$wkt = 'SRID=' . $srid . ';';
23+
$wkt .= $geometry->out('wkt');
24+
return $wkt;
25+
}
26+
else {
27+
return $geometry->out('wkt');
28+
}
29+
}
30+
}

src/Adapters/GPX.php

+209
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
<?php
2+
3+
namespace Phayes\GeoPHP\Adapters;
4+
5+
use Phayes\GeoPHP\GeoPHP;
6+
use Phayes\GeoPHP\Adapters\GeoAdapter;
7+
use Phayes\GeoPHP\Geometry\Point;
8+
use Phayes\GeoPHP\Geometry\Polygon;
9+
use Phayes\GeoPHP\Geometry\LineString;
10+
use Phayes\GeoPHP\Geometry\MultiPoint;
11+
use Phayes\GeoPHP\Geometry\MultiPolygon;
12+
use Phayes\GeoPHP\Geometry\MultiLineString;
13+
use Phayes\GeoPHP\Geometry\Geometry;
14+
use Phayes\GeoPHP\Geometry\GeometryCollection;
15+
use Exception;
16+
17+
/**
18+
* PHP Geometry/GPX encoder/decoder
19+
*/
20+
class GPX extends GeoAdapter
21+
{
22+
private $namespace = false;
23+
private $nss = ''; // Name-space string. eg 'georss:'
24+
25+
/**
26+
* Read GPX string into geometry objects
27+
*
28+
* @param string $gpx A GPX string
29+
*
30+
* @return Geometry|GeometryCollection
31+
*/
32+
public function read($gpx)
33+
{
34+
return $this->geomFromText($gpx);
35+
}
36+
37+
/**
38+
* Serialize geometries into a GPX string.
39+
*
40+
* @param Geometry $geometry
41+
*
42+
* @return string The GPX string representation of the input geometries
43+
*/
44+
public function write(Geometry $geometry, $namespace = false)
45+
{
46+
if ($geometry->isEmpty()) {
47+
return null;
48+
}
49+
if ($namespace) {
50+
$this->namespace = $namespace;
51+
$this->nss = $namespace.':';
52+
}
53+
54+
return '<'.$this->nss.'gpx creator="geoPHP" version="1.0">'.$this->geometryToGPX($geometry).'</'.$this->nss.'gpx>';
55+
}
56+
57+
public function geomFromText($text)
58+
{
59+
// Change to lower-case and strip all CDATA
60+
$text = strtolower($text);
61+
$text = preg_replace('/<!\[cdata\[(.*?)\]\]>/s','',$text);
62+
63+
// Load into DOMDocument
64+
$xmlobj = new DOMDocument();
65+
@$xmlobj->loadXML($text);
66+
if ($xmlobj === false) {
67+
throw new Exception("Invalid GPX: ". $text);
68+
}
69+
70+
$this->xmlobj = $xmlobj;
71+
try {
72+
$geom = $this->geomFromXML();
73+
} catch(InvalidText $e) {
74+
throw new Exception("Cannot Read Geometry From GPX: ". $text);
75+
} catch(Exception $e) {
76+
throw $e;
77+
}
78+
79+
return $geom;
80+
}
81+
82+
protected function geomFromXML()
83+
{
84+
$geometries = [];
85+
$geometries = array_merge($geometries, $this->parseWaypoints());
86+
$geometries = array_merge($geometries, $this->parseTracks());
87+
$geometries = array_merge($geometries, $this->parseRoutes());
88+
89+
if (empty($geometries)) {
90+
throw new Exception("Invalid / Empty GPX");
91+
}
92+
93+
return geoPHP::geometryReduce($geometries);
94+
}
95+
96+
protected function childElements($xml, $nodename = '')
97+
{
98+
$children = [];
99+
foreach ($xml->childNodes as $child) {
100+
if ($child->nodeName == $nodename) {
101+
$children[] = $child;
102+
}
103+
}
104+
105+
return $children;
106+
}
107+
108+
protected function parseWaypoints()
109+
{
110+
$points = [];
111+
$wpt_elements = $this->xmlobj->getElementsByTagName('wpt');
112+
113+
foreach ($wpt_elements as $wpt) {
114+
$lat = $wpt->attributes->getNamedItem("lat")->nodeValue;
115+
$lon = $wpt->attributes->getNamedItem("lon")->nodeValue;
116+
$points[] = new Point($lon, $lat);
117+
}
118+
119+
return $points;
120+
}
121+
122+
protected function parseTracks()
123+
{
124+
$lines = [];
125+
$trk_elements = $this->xmlobj->getElementsByTagName('trk');
126+
127+
foreach ($trk_elements as $trk) {
128+
$components = array();
129+
foreach ($this->childElements($trk, 'trkseg') as $trkseg) {
130+
foreach ($this->childElements($trkseg, 'trkpt') as $trkpt) {
131+
$lat = $trkpt->attributes->getNamedItem("lat")->nodeValue;
132+
$lon = $trkpt->attributes->getNamedItem("lon")->nodeValue;
133+
$components[] = new Point($lon, $lat);
134+
}
135+
}
136+
if ($components) {$lines[] = new LineString($components);}
137+
}
138+
139+
return $lines;
140+
}
141+
142+
protected function parseRoutes()
143+
{
144+
$lines = [];
145+
$rte_elements = $this->xmlobj->getElementsByTagName('rte');
146+
147+
foreach ($rte_elements as $rte) {
148+
$components = [];
149+
foreach ($this->childElements($rte, 'rtept') as $rtept) {
150+
$lat = $rtept->attributes->getNamedItem("lat")->nodeValue;
151+
$lon = $rtept->attributes->getNamedItem("lon")->nodeValue;
152+
$components[] = new Point($lon, $lat);
153+
}
154+
$lines[] = new LineString($components);
155+
}
156+
157+
return $lines;
158+
}
159+
160+
protected function geometryToGPX($geom)
161+
{
162+
$type = strtolower($geom->getGeomType());
163+
164+
switch ($type) {
165+
case 'point':
166+
return $this->pointToGPX($geom);
167+
break;
168+
case 'linestring':
169+
return $this->linestringToGPX($geom);
170+
break;
171+
case 'polygon':
172+
case 'multipoint':
173+
case 'multilinestring':
174+
case 'multipolygon':
175+
case 'geometrycollection':
176+
return $this->collectionToGPX($geom);
177+
break;
178+
}
179+
}
180+
181+
private function pointToGPX($geom)
182+
{
183+
return '<'.$this->nss.'wpt lat="'.$geom->getY().'" lon="'.$geom->getX().'" />';
184+
}
185+
186+
private function linestringToGPX($geom)
187+
{
188+
$gpx = '<'.$this->nss.'trk><'.$this->nss.'trkseg>';
189+
190+
foreach ($geom->getComponents() as $comp) {
191+
$gpx .= '<'.$this->nss.'trkpt lat="'.$comp->getY().'" lon="'.$comp->getX().'" />';
192+
}
193+
194+
$gpx .= '</'.$this->nss.'trkseg></'.$this->nss.'trk>';
195+
196+
return $gpx;
197+
}
198+
199+
public function collectionToGPX($geom)
200+
{
201+
$gpx = '';
202+
$components = $geom->getComponents();
203+
foreach ($geom->getComponents() as $comp) {
204+
$gpx .= $this->geometryToGPX($comp);
205+
}
206+
207+
return $gpx;
208+
}
209+
}

0 commit comments

Comments
 (0)