/** * Given an object or a string, return a Geometry * * @param mixed $input The GeoJSON string or object * * @return object Geometry */ public function read($input) { if (is_string($input)) { $input = json_decode($input); } if (!is_object($input)) { throw new Exception('Invalid JSON'); } if (!is_string($input->type)) { throw new Exception('Invalid JSON'); } // Check to see if it's a FeatureCollection if ($input->type == 'FeatureCollection') { $geoms = array(); foreach ($input->features as $feature) { $geoms[] = $this->read($feature); } return GeoPHP::geometryReduce($geoms); } // Check to see if it's a Feature if ($input->type == 'Feature') { return $this->read($input->geometry); } // It's a geometry - process it return $this->objToGeom($input); }
public function centroid() { if ($this->isEmpty()) { return NULL; } if ($this->geos()) { return GeoPHP::geosToGeometry($this->geos()->centroid()); } $exterior_ring = $this->components[0]; $pts = $exterior_ring->getComponents(); $c = count($pts); if ((int) $c == '0') { return NULL; } $cn = array('x' => '0', 'y' => '0'); $a = $this->area(TRUE, TRUE); // If this is a polygon with no area. Just return the first point. if ($a == 0) { return $this->exteriorRing()->pointN(1); } foreach ($pts as $k => $p) { $j = ($k + 1) % $c; $P = $p->getX() * $pts[$j]->getY() - $p->getY() * $pts[$j]->getX(); $cn['x'] = $cn['x'] + ($p->getX() + $pts[$j]->getX()) * $P; $cn['y'] = $cn['y'] + ($p->getY() + $pts[$j]->getY()) * $P; } $cn['x'] = $cn['x'] / (6 * $a); $cn['y'] = $cn['y'] / (6 * $a); $centroid = new Point($cn['x'], $cn['y']); return $centroid; }
/** * Serialize geometries into a WKT string. * * @param Geometry $geometry * * @return string The WKT string representation of the input geometries */ public function write(Geometry $geometry) { // If geos is installed, then we take a shortcut and let it write the WKT 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 . ')'; } } }
protected function geomFromXML() { $geometries = array(); $geometries = array_merge($geometries, $this->parsePoints()); $geometries = array_merge($geometries, $this->parseLines()); $geometries = array_merge($geometries, $this->parsePolygons()); $geometries = array_merge($geometries, $this->parseBoxes()); $geometries = array_merge($geometries, $this->parseCircles()); if (empty($geometries)) { throw new Exception("Invalid / Empty GeoRSS"); } return GeoPHP::geometryReduce($geometries); }
public function boundary() { if ($this->isEmpty()) { return new LineString(); } if ($this->geos()) { return $this->geos()->boundary(); } $components_boundaries = array(); foreach ($this->components as $component) { $components_boundaries[] = $component->boundary(); } return GeoPHP::geometryReduce($components_boundaries); }
public function simplify($tolerance, $preserveTopology = FALSE) { if ($this->geos()) { return GeoPHP::geosToGeometry($this->geos()->simplify($tolerance, $preserveTopology)); } }
static function detectFormat(&$input) { $mem = fopen('php://memory', 'r+'); fwrite($mem, $input, 11); // Write 11 bytes - we can detect the vast majority of formats in the first 11 bytes fseek($mem, 0); $bytes = unpack("c*", fread($mem, 11)); // If bytes is empty, then we were passed empty input if (empty($bytes)) { return FALSE; } // First char is a tab, space or carriage-return. trim it and try again if ($bytes[1] == 9 || $bytes[1] == 10 || $bytes[1] == 32) { $ltinput = ltrim($input); return GeoPHP::detectFormat($ltinput); } // Detect WKB or EWKB -- first byte is 1 (little endian indicator) if ($bytes[1] == 1) { // If SRID byte is TRUE (1), it's EWKB if ($bytes[5]) { return 'ewkb'; } else { return 'wkb'; } } // Detect HEX encoded WKB or EWKB (PostGIS format) -- first byte is 48, second byte is 49 (hex '01' => first-byte = 1) if ($bytes[1] == 48 && $bytes[2] == 49) { // The shortest possible WKB string (LINESTRING EMPTY) is 18 hex-chars (9 encoded bytes) long // This differentiates it from a geohash, which is always shorter than 18 characters. if (strlen($input) >= 18) { //@@TODO: Differentiate between EWKB and WKB -- check hex-char 10 or 11 (SRID bool indicator at encoded byte 5) return 'ewkb:1'; } } // Detect GeoJSON - first char starts with { if ($bytes[1] == 123) { return 'json'; } // Detect EWKT - first char is S if ($bytes[1] == 83) { return 'ewkt'; } // Detect WKT - first char starts with P (80), L (76), M (77), or G (71) $wkt_chars = array(80, 76, 77, 71); if (in_array($bytes[1], $wkt_chars)) { return 'wkt'; } // Detect XML -- first char is < if ($bytes[1] == 60) { // grab the first 256 characters $string = substr($input, 0, 256); if (strpos($string, '<kml') !== FALSE) { return 'kml'; } if (strpos($string, '<coordinate') !== FALSE) { return 'kml'; } if (strpos($string, '<gpx') !== FALSE) { return 'gpx'; } if (strpos($string, '<georss') !== FALSE) { return 'georss'; } if (strpos($string, '<rss') !== FALSE) { return 'georss'; } if (strpos($string, '<feed') !== FALSE) { return 'georss'; } } // We need an 8 byte string for geohash and unpacked WKB / WKT fseek($mem, 0); $string = trim(fread($mem, 8)); // Detect geohash - geohash ONLY contains lowercase chars and numerics preg_match('/[a-z0-9]+/', $string, $matches); if ($matches[0] == $string) { return 'geohash'; } // What do you get when you cross an elephant with a rhino? // http://youtu.be/RCBn5J83Poc return FALSE; }