View source
<?php
class WKT extends GeoAdapter {
public function read($wkt) {
$wkt = trim($wkt);
if (strpos($wkt, ';')) {
$parts = explode(';', $wkt);
$wkt = $parts[1];
$eparts = explode('=', $parts[0]);
$srid = $eparts[1];
}
else {
$srid = NULL;
}
if (geoPHP::geosInstalled()) {
$reader = new GEOSWKTReader();
if ($srid) {
$geom = geoPHP::geosToGeometry($reader
->read($wkt));
$geom
->setSRID($srid);
return $geom;
}
else {
return geoPHP::geosToGeometry($reader
->read($wkt));
}
}
$wkt = str_replace(', ', ',', $wkt);
foreach (geoPHP::geometryList() as $geom_type) {
$wkt_geom = strtoupper($geom_type);
if (strtoupper(substr($wkt, 0, strlen($wkt_geom))) == $wkt_geom) {
$data_string = $this
->getDataString($wkt);
$method = 'parse' . $geom_type;
if ($srid) {
$geom = $this
->{$method}($data_string);
$geom
->setSRID($srid);
return $geom;
}
else {
return $this
->{$method}($data_string);
}
}
}
}
private function parsePoint($data_string) {
$data_string = $this
->trimParens($data_string);
if ($data_string == 'EMPTY') {
return new Point();
}
$parts = explode(' ', $data_string);
return new Point($parts[0], $parts[1]);
}
private function parseLineString($data_string) {
$data_string = $this
->trimParens($data_string);
if ($data_string == 'EMPTY') {
return new LineString();
}
$parts = explode(',', $data_string);
$points = array();
foreach ($parts as $part) {
$points[] = $this
->parsePoint($part);
}
return new LineString($points);
}
private function parsePolygon($data_string) {
$data_string = $this
->trimParens($data_string);
if ($data_string == 'EMPTY') {
return new Polygon();
}
$parts = explode('),(', $data_string);
$lines = array();
foreach ($parts as $part) {
if (!$this
->beginsWith($part, '(')) {
$part = '(' . $part;
}
if (!$this
->endsWith($part, ')')) {
$part = $part . ')';
}
$lines[] = $this
->parseLineString($part);
}
return new Polygon($lines);
}
private function parseMultiPoint($data_string) {
$data_string = $this
->trimParens($data_string);
if ($data_string == 'EMPTY') {
return new MultiPoint();
}
$parts = explode(',', $data_string);
$points = array();
foreach ($parts as $part) {
$points[] = $this
->parsePoint($part);
}
return new MultiPoint($points);
}
private function parseMultiLineString($data_string) {
$data_string = $this
->trimParens($data_string);
if ($data_string == 'EMPTY') {
return new MultiLineString();
}
$parts = explode('),(', $data_string);
$lines = array();
foreach ($parts as $part) {
if (!$this
->beginsWith($part, '(')) {
$part = '(' . $part;
}
if (!$this
->endsWith($part, ')')) {
$part = $part . ')';
}
$lines[] = $this
->parseLineString($part);
}
return new MultiLineString($lines);
}
private function parseMultiPolygon($data_string) {
$data_string = $this
->trimParens($data_string);
if ($data_string == 'EMPTY') {
return new MultiPolygon();
}
$parts = explode(')),((', $data_string);
$polys = array();
foreach ($parts as $part) {
if (!$this
->beginsWith($part, '((')) {
$part = '((' . $part;
}
if (!$this
->endsWith($part, '))')) {
$part = $part . '))';
}
$polys[] = $this
->parsePolygon($part);
}
return new MultiPolygon($polys);
}
private function parseGeometryCollection($data_string) {
$data_string = $this
->trimParens($data_string);
if ($data_string == 'EMPTY') {
return new GeometryCollection();
}
$geometries = array();
$matches = array();
$str = preg_replace('/,\\s*([A-Za-z])/', '|$1', $data_string);
$components = explode('|', trim($str));
foreach ($components as $component) {
$geometries[] = $this
->read($component);
}
return new GeometryCollection($geometries);
}
protected function getDataString($wkt) {
$first_paren = strpos($wkt, '(');
if ($first_paren !== FALSE) {
return substr($wkt, $first_paren);
}
elseif (strstr($wkt, 'EMPTY')) {
return 'EMPTY';
}
else {
return FALSE;
}
}
protected function trimParens($str) {
$str = trim($str);
if ($this
->beginsWith($str, '(')) {
return substr($str, 1, -1);
}
else {
return $str;
}
}
protected function beginsWith($str, $char) {
if (substr($str, 0, strlen($char)) == $char) {
return TRUE;
}
else {
return FALSE;
}
}
protected function endsWith($str, $char) {
if (substr($str, 0 - strlen($char)) == $char) {
return TRUE;
}
else {
return FALSE;
}
}
public function write(Geometry $geometry) {
if (geoPHP::geosInstalled()) {
$writer = new GEOSWKTWriter();
$writer
->setTrim(TRUE);
return $writer
->write($geometry
->geos());
}
if ($geometry
->isEmpty()) {
return strtoupper($geometry
->geometryType()) . ' EMPTY';
}
else {
if ($data = $this
->extractData($geometry)) {
return strtoupper($geometry
->geometryType()) . ' (' . $data . ')';
}
}
}
public function extractData($geometry) {
$parts = array();
switch ($geometry
->geometryType()) {
case 'Point':
return $geometry
->getX() . ' ' . $geometry
->getY();
case 'LineString':
foreach ($geometry
->getComponents() as $component) {
$parts[] = $this
->extractData($component);
}
return implode(', ', $parts);
case 'Polygon':
case 'MultiPoint':
case 'MultiLineString':
case 'MultiPolygon':
foreach ($geometry
->getComponents() as $component) {
$parts[] = '(' . $this
->extractData($component) . ')';
}
return implode(', ', $parts);
case 'GeometryCollection':
foreach ($geometry
->getComponents() as $component) {
$parts[] = strtoupper($component
->geometryType()) . ' (' . $this
->extractData($component) . ')';
}
return implode(', ', $parts);
}
}
}