forked from lino/radar-wp
Initial import.
This commit is contained in:
commit
86383280c9
428 changed files with 68738 additions and 0 deletions
294
vendor/phayes/geophp/lib/geometry/Collection.class.php
vendored
Normal file
294
vendor/phayes/geophp/lib/geometry/Collection.class.php
vendored
Normal file
|
@ -0,0 +1,294 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Collection: Abstract class for compound geometries
|
||||
*
|
||||
* A geometry is a collection if it is made up of other
|
||||
* component geometries. Therefore everything but a Point
|
||||
* is a Collection. For example a LingString is a collection
|
||||
* of Points. A Polygon is a collection of LineStrings etc.
|
||||
*/
|
||||
abstract class Collection extends Geometry
|
||||
{
|
||||
public $components = array();
|
||||
|
||||
/**
|
||||
* Constructor: Checks and sets component geometries
|
||||
*
|
||||
* @param array $components array of geometries
|
||||
*/
|
||||
public function __construct($components = array()) {
|
||||
if (!is_array($components)) {
|
||||
throw new Exception("Component geometries must be passed as an array");
|
||||
}
|
||||
foreach ($components as $component) {
|
||||
if ($component instanceof Geometry) {
|
||||
$this->components[] = $component;
|
||||
}
|
||||
else {
|
||||
throw new Exception("Cannot create a collection with non-geometries");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Collection component geometries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getComponents() {
|
||||
return $this->components;
|
||||
}
|
||||
|
||||
public function centroid() {
|
||||
if ($this->isEmpty()) return NULL;
|
||||
|
||||
if ($this->geos()) {
|
||||
$geos_centroid = $this->geos()->centroid();
|
||||
if ($geos_centroid->typeName() == 'Point') {
|
||||
return geoPHP::geosToGeometry($this->geos()->centroid());
|
||||
}
|
||||
}
|
||||
|
||||
// As a rough estimate, we say that the centroid of a colletion is the centroid of it's envelope
|
||||
// @@TODO: Make this the centroid of the convexHull
|
||||
// Note: Outside of polygons, geometryCollections and the trivial case of points, there is no standard on what a "centroid" is
|
||||
$centroid = $this->envelope()->centroid();
|
||||
|
||||
return $centroid;
|
||||
}
|
||||
|
||||
public function getBBox() {
|
||||
if ($this->isEmpty()) return NULL;
|
||||
|
||||
if ($this->geos()) {
|
||||
$envelope = $this->geos()->envelope();
|
||||
if ($envelope->typeName() == 'Point') {
|
||||
return geoPHP::geosToGeometry($envelope)->getBBOX();
|
||||
}
|
||||
|
||||
$geos_ring = $envelope->exteriorRing();
|
||||
return array(
|
||||
'maxy' => $geos_ring->pointN(3)->getY(),
|
||||
'miny' => $geos_ring->pointN(1)->getY(),
|
||||
'maxx' => $geos_ring->pointN(1)->getX(),
|
||||
'minx' => $geos_ring->pointN(3)->getX(),
|
||||
);
|
||||
}
|
||||
|
||||
// Go through each component and get the max and min x and y
|
||||
$i = 0;
|
||||
foreach ($this->components as $component) {
|
||||
$component_bbox = $component->getBBox();
|
||||
|
||||
// On the first run through, set the bbox to the component bbox
|
||||
if ($i == 0) {
|
||||
$maxx = $component_bbox['maxx'];
|
||||
$maxy = $component_bbox['maxy'];
|
||||
$minx = $component_bbox['minx'];
|
||||
$miny = $component_bbox['miny'];
|
||||
}
|
||||
|
||||
// Do a check and replace on each boundary, slowly growing the bbox
|
||||
$maxx = $component_bbox['maxx'] > $maxx ? $component_bbox['maxx'] : $maxx;
|
||||
$maxy = $component_bbox['maxy'] > $maxy ? $component_bbox['maxy'] : $maxy;
|
||||
$minx = $component_bbox['minx'] < $minx ? $component_bbox['minx'] : $minx;
|
||||
$miny = $component_bbox['miny'] < $miny ? $component_bbox['miny'] : $miny;
|
||||
$i++;
|
||||
}
|
||||
|
||||
return array(
|
||||
'maxy' => $maxy,
|
||||
'miny' => $miny,
|
||||
'maxx' => $maxx,
|
||||
'minx' => $minx,
|
||||
);
|
||||
}
|
||||
|
||||
public function asArray() {
|
||||
$array = array();
|
||||
foreach ($this->components as $component) {
|
||||
$array[] = $component->asArray();
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
|
||||
public function area() {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->area();
|
||||
}
|
||||
|
||||
$area = 0;
|
||||
foreach ($this->components as $component) {
|
||||
$area += $component->area();
|
||||
}
|
||||
return $area;
|
||||
}
|
||||
|
||||
// By default, the boundary of a collection is the boundary of it's components
|
||||
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 numGeometries() {
|
||||
return count($this->components);
|
||||
}
|
||||
|
||||
// Note that the standard is 1 based indexing
|
||||
public function geometryN($n) {
|
||||
$n = intval($n);
|
||||
if (array_key_exists($n-1, $this->components)) {
|
||||
return $this->components[$n-1];
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
public function length() {
|
||||
$length = 0;
|
||||
foreach ($this->components as $delta => $component) {
|
||||
$length += $component->length();
|
||||
}
|
||||
return $length;
|
||||
}
|
||||
|
||||
public function greatCircleLength($radius = 6378137) {
|
||||
$length = 0;
|
||||
foreach ($this->components as $component) {
|
||||
$length += $component->greatCircleLength($radius);
|
||||
}
|
||||
return $length;
|
||||
}
|
||||
|
||||
public function haversineLength() {
|
||||
$length = 0;
|
||||
foreach ($this->components as $component) {
|
||||
$length += $component->haversineLength();
|
||||
}
|
||||
return $length;
|
||||
}
|
||||
|
||||
public function dimension() {
|
||||
$dimension = 0;
|
||||
foreach ($this->components as $component) {
|
||||
if ($component->dimension() > $dimension) {
|
||||
$dimension = $component->dimension();
|
||||
}
|
||||
}
|
||||
return $dimension;
|
||||
}
|
||||
|
||||
// A collection is empty if it has no components OR all it's components are empty
|
||||
public function isEmpty() {
|
||||
if (!count($this->components)) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
foreach ($this->components as $component) {
|
||||
if (!$component->isEmpty()) return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
public function numPoints() {
|
||||
$num = 0;
|
||||
foreach ($this->components as $component) {
|
||||
$num += $component->numPoints();
|
||||
}
|
||||
return $num;
|
||||
}
|
||||
|
||||
public function getPoints() {
|
||||
$points = array();
|
||||
foreach ($this->components as $component) {
|
||||
$points = array_merge($points, $component->getPoints());
|
||||
}
|
||||
return $points;
|
||||
}
|
||||
|
||||
public function equals($geometry) {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->equals($geometry->geos());
|
||||
}
|
||||
|
||||
// To test for equality we check to make sure that there is a matching point
|
||||
// in the other geometry for every point in this geometry.
|
||||
// This is slightly more strict than the standard, which
|
||||
// uses Within(A,B) = true and Within(B,A) = true
|
||||
// @@TODO: Eventually we could fix this by using some sort of simplification
|
||||
// method that strips redundant vertices (that are all in a row)
|
||||
|
||||
$this_points = $this->getPoints();
|
||||
$other_points = $geometry->getPoints();
|
||||
|
||||
// First do a check to make sure they have the same number of vertices
|
||||
if (count($this_points) != count($other_points)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
foreach ($this_points as $point) {
|
||||
$found_match = FALSE;
|
||||
foreach ($other_points as $key => $test_point) {
|
||||
if ($point->equals($test_point)) {
|
||||
$found_match = TRUE;
|
||||
unset($other_points[$key]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$found_match) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// All points match, return TRUE
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function isSimple() {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->isSimple();
|
||||
}
|
||||
|
||||
// A collection is simple if all it's components are simple
|
||||
foreach ($this->components as $component) {
|
||||
if (!$component->isSimple()) return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function explode() {
|
||||
$parts = array();
|
||||
foreach ($this->components as $component) {
|
||||
$parts = array_merge($parts, $component->explode());
|
||||
}
|
||||
return $parts;
|
||||
}
|
||||
|
||||
// Not valid for this geometry type
|
||||
// --------------------------------
|
||||
public function x() { return NULL; }
|
||||
public function y() { return NULL; }
|
||||
public function startPoint() { return NULL; }
|
||||
public function endPoint() { return NULL; }
|
||||
public function isRing() { return NULL; }
|
||||
public function isClosed() { return NULL; }
|
||||
public function pointN($n) { return NULL; }
|
||||
public function exteriorRing() { return NULL; }
|
||||
public function numInteriorRings() { return NULL; }
|
||||
public function interiorRingN($n) { return NULL; }
|
||||
public function pointOnSurface() { return NULL; }
|
||||
}
|
||||
|
347
vendor/phayes/geophp/lib/geometry/Geometry.class.php
vendored
Normal file
347
vendor/phayes/geophp/lib/geometry/Geometry.class.php
vendored
Normal file
|
@ -0,0 +1,347 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Geometry abstract class
|
||||
*/
|
||||
abstract class Geometry
|
||||
{
|
||||
private $geos = NULL;
|
||||
protected $srid = NULL;
|
||||
protected $geom_type;
|
||||
|
||||
// Abtract: Standard
|
||||
// -----------------
|
||||
abstract public function area();
|
||||
abstract public function boundary();
|
||||
abstract public function centroid();
|
||||
abstract public function length();
|
||||
abstract public function y();
|
||||
abstract public function x();
|
||||
abstract public function numGeometries();
|
||||
abstract public function geometryN($n);
|
||||
abstract public function startPoint();
|
||||
abstract public function endPoint();
|
||||
abstract public function isRing(); // Mssing dependancy
|
||||
abstract public function isClosed(); // Missing dependancy
|
||||
abstract public function numPoints();
|
||||
abstract public function pointN($n);
|
||||
abstract public function exteriorRing();
|
||||
abstract public function numInteriorRings();
|
||||
abstract public function interiorRingN($n);
|
||||
abstract public function dimension();
|
||||
abstract public function equals($geom);
|
||||
abstract public function isEmpty();
|
||||
abstract public function isSimple();
|
||||
|
||||
// Abtract: Non-Standard
|
||||
// ---------------------
|
||||
abstract public function getBBox();
|
||||
abstract public function asArray();
|
||||
abstract public function getPoints();
|
||||
abstract public function explode();
|
||||
abstract public function greatCircleLength(); //meters
|
||||
abstract public function haversineLength(); //degrees
|
||||
|
||||
|
||||
// Public: Standard -- Common to all geometries
|
||||
// --------------------------------------------
|
||||
public function SRID() {
|
||||
return $this->srid;
|
||||
}
|
||||
|
||||
public function setSRID($srid) {
|
||||
if ($this->geos()) {
|
||||
$this->geos()->setSRID($srid);
|
||||
}
|
||||
$this->srid = $srid;
|
||||
}
|
||||
|
||||
public function envelope() {
|
||||
if ($this->isEmpty()) return new Polygon();
|
||||
|
||||
if ($this->geos()) {
|
||||
return geoPHP::geosToGeometry($this->geos()->envelope());
|
||||
}
|
||||
|
||||
$bbox = $this->getBBox();
|
||||
$points = array (
|
||||
new Point($bbox['maxx'],$bbox['miny']),
|
||||
new Point($bbox['maxx'],$bbox['maxy']),
|
||||
new Point($bbox['minx'],$bbox['maxy']),
|
||||
new Point($bbox['minx'],$bbox['miny']),
|
||||
new Point($bbox['maxx'],$bbox['miny']),
|
||||
);
|
||||
|
||||
$outer_boundary = new LineString($points);
|
||||
return new Polygon(array($outer_boundary));
|
||||
}
|
||||
|
||||
public function geometryType() {
|
||||
return $this->geom_type;
|
||||
}
|
||||
|
||||
// Public: Non-Standard -- Common to all geometries
|
||||
// ------------------------------------------------
|
||||
|
||||
// $this->out($format, $other_args);
|
||||
public function out() {
|
||||
$args = func_get_args();
|
||||
|
||||
$format = array_shift($args);
|
||||
$type_map = geoPHP::getAdapterMap();
|
||||
$processor_type = $type_map[$format];
|
||||
$processor = new $processor_type();
|
||||
|
||||
array_unshift($args, $this);
|
||||
$result = call_user_func_array(array($processor, 'write'), $args);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
// Public: Aliases
|
||||
// ---------------
|
||||
public function getCentroid() {
|
||||
return $this->centroid();
|
||||
}
|
||||
|
||||
public function getArea() {
|
||||
return $this->area();
|
||||
}
|
||||
|
||||
public function getX() {
|
||||
return $this->x();
|
||||
}
|
||||
|
||||
public function getY() {
|
||||
return $this->y();
|
||||
}
|
||||
|
||||
public function getGeos() {
|
||||
return $this->geos();
|
||||
}
|
||||
|
||||
public function getGeomType() {
|
||||
return $this->geometryType();
|
||||
}
|
||||
|
||||
public function getSRID() {
|
||||
return $this->SRID();
|
||||
}
|
||||
|
||||
public function asText() {
|
||||
return $this->out('wkt');
|
||||
}
|
||||
|
||||
public function asBinary() {
|
||||
return $this->out('wkb');
|
||||
}
|
||||
|
||||
// Public: GEOS Only Functions
|
||||
// ---------------------------
|
||||
public function geos() {
|
||||
// If it's already been set, just return it
|
||||
if ($this->geos && geoPHP::geosInstalled()) {
|
||||
return $this->geos;
|
||||
}
|
||||
// It hasn't been set yet, generate it
|
||||
if (geoPHP::geosInstalled()) {
|
||||
$reader = new GEOSWKBReader();
|
||||
$this->geos = $reader->readHEX($this->out('wkb',TRUE));
|
||||
}
|
||||
else {
|
||||
$this->geos = FALSE;
|
||||
}
|
||||
return $this->geos;
|
||||
}
|
||||
|
||||
public function setGeos($geos) {
|
||||
$this->geos = $geos;
|
||||
}
|
||||
|
||||
public function pointOnSurface() {
|
||||
if ($this->geos()) {
|
||||
return geoPHP::geosToGeometry($this->geos()->pointOnSurface());
|
||||
}
|
||||
}
|
||||
|
||||
public function equalsExact(Geometry $geometry) {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->equalsExact($geometry->geos());
|
||||
}
|
||||
}
|
||||
|
||||
public function relate(Geometry $geometry, $pattern = NULL) {
|
||||
if ($this->geos()) {
|
||||
if ($pattern) {
|
||||
return $this->geos()->relate($geometry->geos(), $pattern);
|
||||
}
|
||||
else {
|
||||
return $this->geos()->relate($geometry->geos());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function checkValidity() {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->checkValidity();
|
||||
}
|
||||
}
|
||||
|
||||
public function buffer($distance) {
|
||||
if ($this->geos()) {
|
||||
return geoPHP::geosToGeometry($this->geos()->buffer($distance));
|
||||
}
|
||||
}
|
||||
|
||||
public function intersection(Geometry $geometry) {
|
||||
if ($this->geos()) {
|
||||
return geoPHP::geosToGeometry($this->geos()->intersection($geometry->geos()));
|
||||
}
|
||||
}
|
||||
|
||||
public function convexHull() {
|
||||
if ($this->geos()) {
|
||||
return geoPHP::geosToGeometry($this->geos()->convexHull());
|
||||
}
|
||||
}
|
||||
|
||||
public function difference(Geometry $geometry) {
|
||||
if ($this->geos()) {
|
||||
return geoPHP::geosToGeometry($this->geos()->difference($geometry->geos()));
|
||||
}
|
||||
}
|
||||
|
||||
public function symDifference(Geometry $geometry) {
|
||||
if ($this->geos()) {
|
||||
return geoPHP::geosToGeometry($this->geos()->symDifference($geometry->geos()));
|
||||
}
|
||||
}
|
||||
|
||||
// Can pass in a geometry or an array of geometries
|
||||
public function union(Geometry $geometry) {
|
||||
if ($this->geos()) {
|
||||
if (is_array($geometry)) {
|
||||
$geom = $this->geos();
|
||||
foreach ($geometry as $item) {
|
||||
$geom = $geom->union($item->geos());
|
||||
}
|
||||
return geoPHP::geosToGeometry($geom);
|
||||
}
|
||||
else {
|
||||
return geoPHP::geosToGeometry($this->geos()->union($geometry->geos()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function simplify($tolerance, $preserveTopology = FALSE) {
|
||||
if ($this->geos()) {
|
||||
return geoPHP::geosToGeometry($this->geos()->simplify($tolerance, $preserveTopology));
|
||||
}
|
||||
}
|
||||
|
||||
public function disjoint(Geometry $geometry) {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->disjoint($geometry->geos());
|
||||
}
|
||||
}
|
||||
|
||||
public function touches(Geometry $geometry) {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->touches($geometry->geos());
|
||||
}
|
||||
}
|
||||
|
||||
public function intersects(Geometry $geometry) {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->intersects($geometry->geos());
|
||||
}
|
||||
}
|
||||
|
||||
public function crosses(Geometry $geometry) {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->crosses($geometry->geos());
|
||||
}
|
||||
}
|
||||
|
||||
public function within(Geometry $geometry) {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->within($geometry->geos());
|
||||
}
|
||||
}
|
||||
|
||||
public function contains(Geometry $geometry) {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->contains($geometry->geos());
|
||||
}
|
||||
}
|
||||
|
||||
public function overlaps(Geometry $geometry) {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->overlaps($geometry->geos());
|
||||
}
|
||||
}
|
||||
|
||||
public function covers(Geometry $geometry) {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->covers($geometry->geos());
|
||||
}
|
||||
}
|
||||
|
||||
public function coveredBy(Geometry $geometry) {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->coveredBy($geometry->geos());
|
||||
}
|
||||
}
|
||||
|
||||
public function distance(Geometry $geometry) {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->distance($geometry->geos());
|
||||
}
|
||||
}
|
||||
|
||||
public function hausdorffDistance(Geometry $geometry) {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->hausdorffDistance($geometry->geos());
|
||||
}
|
||||
}
|
||||
|
||||
public function project(Geometry $point, $normalized = NULL) {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->project($point->geos(), $normalized);
|
||||
}
|
||||
}
|
||||
|
||||
// Public - Placeholders
|
||||
// ---------------------
|
||||
public function hasZ() {
|
||||
// geoPHP does not support Z values at the moment
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public function is3D() {
|
||||
// geoPHP does not support 3D geometries at the moment
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public function isMeasured() {
|
||||
// geoPHP does not yet support M values
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public function coordinateDimension() {
|
||||
// geoPHP only supports 2-dimensional space
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function z() {
|
||||
// geoPHP only supports 2-dimensional space
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public function m() {
|
||||
// geoPHP only supports 2-dimensional space
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
29
vendor/phayes/geophp/lib/geometry/GeometryCollection.class.php
vendored
Normal file
29
vendor/phayes/geophp/lib/geometry/GeometryCollection.class.php
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
/**
|
||||
* GeometryCollection: A heterogenous collection of geometries
|
||||
*/
|
||||
class GeometryCollection extends Collection
|
||||
{
|
||||
protected $geom_type = 'GeometryCollection';
|
||||
|
||||
// We need to override asArray. Because geometryCollections are heterogeneous
|
||||
// we need to specify which type of geometries they contain. We need to do this
|
||||
// because, for example, there would be no way to tell the difference between a
|
||||
// MultiPoint or a LineString, since they share the same structure (collection
|
||||
// of points). So we need to call out the type explicitly.
|
||||
public function asArray() {
|
||||
$array = array();
|
||||
foreach ($this->components as $component) {
|
||||
$array[] = array(
|
||||
'type' => $component->geometryType(),
|
||||
'components' => $component->asArray(),
|
||||
);
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
|
||||
// Not valid for this geomettry
|
||||
public function boundary() { return NULL; }
|
||||
public function isSimple() { return NULL; }
|
||||
}
|
||||
|
190
vendor/phayes/geophp/lib/geometry/LineString.class.php
vendored
Normal file
190
vendor/phayes/geophp/lib/geometry/LineString.class.php
vendored
Normal file
|
@ -0,0 +1,190 @@
|
|||
<?php
|
||||
/**
|
||||
* LineString. A collection of Points representing a line.
|
||||
* A line can have more than one segment.
|
||||
*/
|
||||
class LineString extends Collection
|
||||
{
|
||||
protected $geom_type = 'LineString';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $points An array of at least two points with
|
||||
* which to build the LineString
|
||||
*/
|
||||
public function __construct($points = array()) {
|
||||
if (count($points) == 1) {
|
||||
throw new Exception("Cannot construct a LineString with a single point");
|
||||
}
|
||||
|
||||
// Call the Collection constructor to build the LineString
|
||||
parent::__construct($points);
|
||||
}
|
||||
|
||||
// The boundary of a linestring is itself
|
||||
public function boundary() {
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function startPoint() {
|
||||
return $this->pointN(1);
|
||||
}
|
||||
|
||||
public function endPoint() {
|
||||
$last_n = $this->numPoints();
|
||||
return $this->pointN($last_n);
|
||||
}
|
||||
|
||||
public function isClosed() {
|
||||
return ($this->startPoint()->equals($this->endPoint()));
|
||||
}
|
||||
|
||||
public function isRing() {
|
||||
return ($this->isClosed() && $this->isSimple());
|
||||
}
|
||||
|
||||
public function numPoints() {
|
||||
return $this->numGeometries();
|
||||
}
|
||||
|
||||
public function pointN($n) {
|
||||
return $this->geometryN($n);
|
||||
}
|
||||
|
||||
public function dimension() {
|
||||
if ($this->isEmpty()) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function area() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function length() {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->length();
|
||||
}
|
||||
$length = 0;
|
||||
foreach ($this->getPoints() as $delta => $point) {
|
||||
$previous_point = $this->geometryN($delta);
|
||||
if ($previous_point) {
|
||||
$length += sqrt(pow(($previous_point->getX() - $point->getX()), 2) + pow(($previous_point->getY()- $point->getY()), 2));
|
||||
}
|
||||
}
|
||||
return $length;
|
||||
}
|
||||
|
||||
public function greatCircleLength($radius = 6378137) {
|
||||
$length = 0;
|
||||
$points = $this->getPoints();
|
||||
for($i=0; $i<$this->numPoints()-1; $i++) {
|
||||
$point = $points[$i];
|
||||
$next_point = $points[$i+1];
|
||||
if (!is_object($next_point)) {continue;}
|
||||
// Great circle method
|
||||
$lat1 = deg2rad($point->getY());
|
||||
$lat2 = deg2rad($next_point->getY());
|
||||
$lon1 = deg2rad($point->getX());
|
||||
$lon2 = deg2rad($next_point->getX());
|
||||
$dlon = $lon2 - $lon1;
|
||||
$length +=
|
||||
$radius *
|
||||
atan2(
|
||||
sqrt(
|
||||
pow(cos($lat2) * sin($dlon), 2) +
|
||||
pow(cos($lat1) * sin($lat2) - sin($lat1) * cos($lat2) * cos($dlon), 2)
|
||||
)
|
||||
,
|
||||
sin($lat1) * sin($lat2) +
|
||||
cos($lat1) * cos($lat2) * cos($dlon)
|
||||
);
|
||||
}
|
||||
// Returns length in meters.
|
||||
return $length;
|
||||
}
|
||||
|
||||
public function haversineLength() {
|
||||
$degrees = 0;
|
||||
$points = $this->getPoints();
|
||||
for($i=0; $i<$this->numPoints()-1; $i++) {
|
||||
$point = $points[$i];
|
||||
$next_point = $points[$i+1];
|
||||
if (!is_object($next_point)) {continue;}
|
||||
$degree = rad2deg(
|
||||
acos(
|
||||
sin(deg2rad($point->getY())) * sin(deg2rad($next_point->getY())) +
|
||||
cos(deg2rad($point->getY())) * cos(deg2rad($next_point->getY())) *
|
||||
cos(deg2rad(abs($point->getX() - $next_point->getX())))
|
||||
)
|
||||
);
|
||||
$degrees += $degree;
|
||||
}
|
||||
// Returns degrees
|
||||
return $degrees;
|
||||
}
|
||||
|
||||
public function explode() {
|
||||
$parts = array();
|
||||
$points = $this->getPoints();
|
||||
|
||||
foreach ($points as $i => $point) {
|
||||
if (isset($points[$i+1])) {
|
||||
$parts[] = new LineString(array($point, $points[$i+1]));
|
||||
}
|
||||
}
|
||||
return $parts;
|
||||
}
|
||||
|
||||
public function isSimple() {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->isSimple();
|
||||
}
|
||||
|
||||
$segments = $this->explode();
|
||||
|
||||
foreach ($segments as $i => $segment) {
|
||||
foreach ($segments as $j => $check_segment) {
|
||||
if ($i != $j) {
|
||||
if ($segment->lineSegmentIntersect($check_segment)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Utility function to check if any line sigments intersect
|
||||
// Derived from http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect
|
||||
public function lineSegmentIntersect($segment) {
|
||||
$p0_x = $this->startPoint()->x();
|
||||
$p0_y = $this->startPoint()->y();
|
||||
$p1_x = $this->endPoint()->x();
|
||||
$p1_y = $this->endPoint()->y();
|
||||
$p2_x = $segment->startPoint()->x();
|
||||
$p2_y = $segment->startPoint()->y();
|
||||
$p3_x = $segment->endPoint()->x();
|
||||
$p3_y = $segment->endPoint()->y();
|
||||
|
||||
$s1_x = $p1_x - $p0_x; $s1_y = $p1_y - $p0_y;
|
||||
$s2_x = $p3_x - $p2_x; $s2_y = $p3_y - $p2_y;
|
||||
|
||||
$fps = (-$s2_x * $s1_y) + ($s1_x * $s2_y);
|
||||
$fpt = (-$s2_x * $s1_y) + ($s1_x * $s2_y);
|
||||
|
||||
if ($fps == 0 || $fpt == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$s = (-$s1_y * ($p0_x - $p2_x) + $s1_x * ($p0_y - $p2_y)) / $fps;
|
||||
$t = ( $s2_x * ($p0_y - $p2_y) - $s2_y * ($p0_x - $p2_x)) / $fpt;
|
||||
|
||||
if ($s > 0 && $s < 1 && $t > 0 && $t < 1) {
|
||||
// Collision detected
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
20
vendor/phayes/geophp/lib/geometry/MultiLineString.class.php
vendored
Normal file
20
vendor/phayes/geophp/lib/geometry/MultiLineString.class.php
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
/**
|
||||
* MultiLineString: A collection of LineStrings
|
||||
*/
|
||||
class MultiLineString extends Collection
|
||||
{
|
||||
protected $geom_type = 'MultiLineString';
|
||||
|
||||
// MultiLineString is closed if all it's components are closed
|
||||
public function isClosed() {
|
||||
foreach ($this->components as $line) {
|
||||
if (!$line->isClosed()) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
21
vendor/phayes/geophp/lib/geometry/MultiPoint.class.php
vendored
Normal file
21
vendor/phayes/geophp/lib/geometry/MultiPoint.class.php
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
/**
|
||||
* MultiPoint: A collection Points
|
||||
*/
|
||||
class MultiPoint extends Collection
|
||||
{
|
||||
protected $geom_type = 'MultiPoint';
|
||||
|
||||
public function numPoints() {
|
||||
return $this->numGeometries();
|
||||
}
|
||||
|
||||
public function isSimple() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Not valid for this geometry type
|
||||
// --------------------------------
|
||||
public function explode() { return NULL; }
|
||||
}
|
||||
|
8
vendor/phayes/geophp/lib/geometry/MultiPolygon.class.php
vendored
Normal file
8
vendor/phayes/geophp/lib/geometry/MultiPolygon.class.php
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
/**
|
||||
* MultiPolygon: A collection of Polygons
|
||||
*/
|
||||
class MultiPolygon extends Collection
|
||||
{
|
||||
protected $geom_type = 'MultiPolygon';
|
||||
}
|
179
vendor/phayes/geophp/lib/geometry/Point.class.php
vendored
Normal file
179
vendor/phayes/geophp/lib/geometry/Point.class.php
vendored
Normal file
|
@ -0,0 +1,179 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Point: The most basic geometry type. All other geometries
|
||||
* are built out of Points.
|
||||
*/
|
||||
class Point extends Geometry
|
||||
{
|
||||
public $coords = array(2);
|
||||
protected $geom_type = 'Point';
|
||||
protected $dimension = 2;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param numeric $x The x coordinate (or longitude)
|
||||
* @param numeric $y The y coordinate (or latitude)
|
||||
* @param numeric $z The z coordinate (or altitude) - optional
|
||||
*/
|
||||
public function __construct($x = NULL, $y = NULL, $z = NULL) {
|
||||
|
||||
// Check if it's an empty point
|
||||
if ($x === NULL && $y === NULL) {
|
||||
$this->coords = array(NULL, NULL);
|
||||
$this->dimension = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Basic validation on x and y
|
||||
if (!is_numeric($x) || !is_numeric($y)) {
|
||||
throw new Exception("Cannot construct Point. x and y should be numeric");
|
||||
}
|
||||
|
||||
// Check to see if this is a 3D point
|
||||
if ($z !== NULL) {
|
||||
if (!is_numeric($z)) {
|
||||
throw new Exception("Cannot construct Point. z should be numeric");
|
||||
}
|
||||
$this->dimension = 3;
|
||||
}
|
||||
|
||||
// Convert to floatval in case they are passed in as a string or integer etc.
|
||||
$x = floatval($x);
|
||||
$y = floatval($y);
|
||||
$z = floatval($z);
|
||||
|
||||
// Add poitional elements
|
||||
if ($this->dimension == 2) {
|
||||
$this->coords = array($x, $y);
|
||||
}
|
||||
if ($this->dimension == 3) {
|
||||
$this->coords = array($x, $y, $z);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get X (longitude) coordinate
|
||||
*
|
||||
* @return float The X coordinate
|
||||
*/
|
||||
public function x() {
|
||||
return $this->coords[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Y (latitude) coordinate
|
||||
*
|
||||
* @return float The Y coordinate
|
||||
*/
|
||||
public function y() {
|
||||
return $this->coords[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Z (altitude) coordinate
|
||||
*
|
||||
* @return float The Z coordinate or NULL is not a 3D point
|
||||
*/
|
||||
public function z() {
|
||||
if ($this->dimension == 3) {
|
||||
return $this->coords[2];
|
||||
}
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
// A point's centroid is itself
|
||||
public function centroid() {
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBBox() {
|
||||
return array(
|
||||
'maxy' => $this->getY(),
|
||||
'miny' => $this->getY(),
|
||||
'maxx' => $this->getX(),
|
||||
'minx' => $this->getX(),
|
||||
);
|
||||
}
|
||||
|
||||
public function asArray($assoc = FALSE) {
|
||||
return $this->coords;
|
||||
}
|
||||
|
||||
public function area() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function length() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function greatCircleLength() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function haversineLength() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The boundary of a point is itself
|
||||
public function boundary() {
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function dimension() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function isEmpty() {
|
||||
if ($this->dimension == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
public function numPoints() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function getPoints() {
|
||||
return array($this);
|
||||
}
|
||||
|
||||
public function equals($geometry) {
|
||||
if (get_class($geometry) != 'Point') {
|
||||
return FALSE;
|
||||
}
|
||||
if (!$this->isEmpty() && !$geometry->isEmpty()) {
|
||||
return ($this->x() == $geometry->x() && $this->y() == $geometry->y());
|
||||
}
|
||||
else if ($this->isEmpty() && $geometry->isEmpty()) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
public function isSimple() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Not valid for this geometry type
|
||||
public function numGeometries() { return NULL; }
|
||||
public function geometryN($n) { return NULL; }
|
||||
public function startPoint() { return NULL; }
|
||||
public function endPoint() { return NULL; }
|
||||
public function isRing() { return NULL; }
|
||||
public function isClosed() { return NULL; }
|
||||
public function pointN($n) { return NULL; }
|
||||
public function exteriorRing() { return NULL; }
|
||||
public function numInteriorRings() { return NULL; }
|
||||
public function interiorRingN($n) { return NULL; }
|
||||
public function pointOnSurface() { return NULL; }
|
||||
public function explode() { return NULL; }
|
||||
}
|
||||
|
215
vendor/phayes/geophp/lib/geometry/Polygon.class.php
vendored
Normal file
215
vendor/phayes/geophp/lib/geometry/Polygon.class.php
vendored
Normal file
|
@ -0,0 +1,215 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Polygon: A polygon is a plane figure that is bounded by a closed path,
|
||||
* composed of a finite sequence of straight line segments
|
||||
*/
|
||||
class Polygon extends Collection
|
||||
{
|
||||
protected $geom_type = 'Polygon';
|
||||
|
||||
// The boundary of a polygin is it's outer ring
|
||||
public function boundary() {
|
||||
return $this->exteriorRing();
|
||||
}
|
||||
|
||||
public function area($exterior_only = FALSE, $signed = FALSE) {
|
||||
if ($this->isEmpty()) return 0;
|
||||
|
||||
if ($this->geos() && $exterior_only == FALSE) {
|
||||
return $this->geos()->area();
|
||||
}
|
||||
|
||||
$exterior_ring = $this->components[0];
|
||||
$pts = $exterior_ring->getComponents();
|
||||
|
||||
$c = count($pts);
|
||||
if((int)$c == '0') return NULL;
|
||||
$a = '0';
|
||||
foreach($pts as $k => $p){
|
||||
$j = ($k + 1) % $c;
|
||||
$a = $a + ($p->getX() * $pts[$j]->getY()) - ($p->getY() * $pts[$j]->getX());
|
||||
}
|
||||
|
||||
if ($signed) $area = ($a / 2);
|
||||
else $area = abs(($a / 2));
|
||||
|
||||
if ($exterior_only == TRUE) {
|
||||
return $area;
|
||||
}
|
||||
foreach ($this->components as $delta => $component) {
|
||||
if ($delta != 0) {
|
||||
$inner_poly = new Polygon(array($component));
|
||||
$area -= $inner_poly->area();
|
||||
}
|
||||
}
|
||||
return $area;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the outermost point from the centroid
|
||||
*
|
||||
* @returns Point The outermost point
|
||||
*/
|
||||
public function outermostPoint() {
|
||||
$centroid = $this->getCentroid();
|
||||
|
||||
$max = array('length' => 0, 'point' => null);
|
||||
|
||||
foreach($this->getPoints() as $point) {
|
||||
$lineString = new LineString(array($centroid, $point));
|
||||
|
||||
if($lineString->length() > $max['length']) {
|
||||
$max['length'] = $lineString->length();
|
||||
$max['point'] = $point;
|
||||
}
|
||||
}
|
||||
|
||||
return $max['point'];
|
||||
}
|
||||
|
||||
public function exteriorRing() {
|
||||
if ($this->isEmpty()) return new LineString();
|
||||
return $this->components[0];
|
||||
}
|
||||
|
||||
public function numInteriorRings() {
|
||||
if ($this->isEmpty()) return 0;
|
||||
return $this->numGeometries()-1;
|
||||
}
|
||||
|
||||
public function interiorRingN($n) {
|
||||
return $this->geometryN($n+1);
|
||||
}
|
||||
|
||||
public function dimension() {
|
||||
if ($this->isEmpty()) return 0;
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function isSimple() {
|
||||
if ($this->geos()) {
|
||||
return $this->geos()->isSimple();
|
||||
}
|
||||
|
||||
$segments = $this->explode();
|
||||
|
||||
foreach ($segments as $i => $segment) {
|
||||
foreach ($segments as $j => $check_segment) {
|
||||
if ($i != $j) {
|
||||
if ($segment->lineSegmentIntersect($check_segment)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given point, determine whether it's bounded by the given polygon.
|
||||
* Adapted from http://www.assemblysys.com/dataServices/php_pointinpolygon.php
|
||||
* @see http://en.wikipedia.org/wiki/Point%5Fin%5Fpolygon
|
||||
*
|
||||
* @param Point $point
|
||||
* @param boolean $pointOnBoundary - whether a boundary should be considered "in" or not
|
||||
* @param boolean $pointOnVertex - whether a vertex should be considered "in" or not
|
||||
* @return boolean
|
||||
*/
|
||||
public function pointInPolygon($point, $pointOnBoundary = true, $pointOnVertex = true) {
|
||||
$vertices = $this->getPoints();
|
||||
|
||||
// Check if the point sits exactly on a vertex
|
||||
if ($this->pointOnVertex($point, $vertices)) {
|
||||
return $pointOnVertex ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
// Check if the point is inside the polygon or on the boundary
|
||||
$intersections = 0;
|
||||
$vertices_count = count($vertices);
|
||||
|
||||
for ($i=1; $i < $vertices_count; $i++) {
|
||||
$vertex1 = $vertices[$i-1];
|
||||
$vertex2 = $vertices[$i];
|
||||
if ($vertex1->y() == $vertex2->y()
|
||||
&& $vertex1->y() == $point->y()
|
||||
&& $point->x() > min($vertex1->x(), $vertex2->x())
|
||||
&& $point->x() < max($vertex1->x(), $vertex2->x())) {
|
||||
// Check if point is on an horizontal polygon boundary
|
||||
return $pointOnBoundary ? TRUE : FALSE;
|
||||
}
|
||||
if ($point->y() > min($vertex1->y(), $vertex2->y())
|
||||
&& $point->y() <= max($vertex1->y(), $vertex2->y())
|
||||
&& $point->x() <= max($vertex1->x(), $vertex2->x())
|
||||
&& $vertex1->y() != $vertex2->y()) {
|
||||
$xinters =
|
||||
($point->y() - $vertex1->y()) * ($vertex2->x() - $vertex1->x())
|
||||
/ ($vertex2->y() - $vertex1->y())
|
||||
+ $vertex1->x();
|
||||
if ($xinters == $point->x()) {
|
||||
// Check if point is on the polygon boundary (other than horizontal)
|
||||
return $pointOnBoundary ? TRUE : FALSE;
|
||||
}
|
||||
if ($vertex1->x() == $vertex2->x() || $point->x() <= $xinters) {
|
||||
$intersections++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If the number of edges we passed through is even, then it's in the polygon.
|
||||
if ($intersections % 2 != 0) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
public function pointOnVertex($point) {
|
||||
foreach($this->getPoints() as $vertex) {
|
||||
if ($point->equals($vertex)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Not valid for this geometry type
|
||||
// --------------------------------
|
||||
public function length() { return NULL; }
|
||||
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue