mirror of
https://github.com/salesagility/SuiteCRM.git
synced 2024-11-21 23:47:57 +00:00
387 lines
11 KiB
PHP
Executable File
387 lines
11 KiB
PHP
Executable File
<?php
|
|
|
|
if (!defined('sugarEntry') || !sugarEntry) {
|
|
die('Not A Valid Entry Point');
|
|
}
|
|
|
|
require_once('modules/jjwg_Areas/jjwg_Areas_sugar.php');
|
|
require_once('modules/jjwg_Maps/jjwg_Maps.php');
|
|
|
|
#[\AllowDynamicProperties]
|
|
class jjwg_Areas extends jjwg_Areas_sugar
|
|
{
|
|
|
|
/**
|
|
* @var settings array
|
|
*/
|
|
public $settings = array();
|
|
/**
|
|
* coords processed from coordinates string
|
|
* @var array of strings ('lng,lat,elv')
|
|
*/
|
|
public $coords = array();
|
|
/**
|
|
* polygon processed from coordinates strings
|
|
* @var array of arrays (keys: lng, lat, elv)
|
|
*/
|
|
public $polygon = null;
|
|
/**
|
|
* Point in Area/Polygon check on vertices
|
|
* @var boolean
|
|
*/
|
|
public $point_on_vertex = true;
|
|
/**
|
|
* @area Polygon Area
|
|
*/
|
|
public $area = 0;
|
|
/**
|
|
* Polygon Centroid (Area Balance Center)
|
|
* @var array (keys: lng, lat, elv)
|
|
*/
|
|
public $centroid = null;
|
|
|
|
public function __construct($init=true)
|
|
{
|
|
parent::__construct();
|
|
// Admin Config Setting
|
|
if ($init) {
|
|
$this->configuration();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load Configuration Settings using Administration Module
|
|
* See jjwg_Maps module for setting config
|
|
* $GLOBALS['jjwg_config_defaults']
|
|
* $GLOBALS['jjwg_config']
|
|
*/
|
|
public function configuration()
|
|
{
|
|
$this->jjwg_Maps = BeanFactory::newBean('jjwg_Maps');
|
|
$this->settings = $GLOBALS['jjwg_config'];
|
|
}
|
|
|
|
/**
|
|
* Retrieve object by id
|
|
*/
|
|
public function retrieve($id = -1, $encode = true, $deleted = true)
|
|
{
|
|
parent::retrieve($id, $encode, $deleted);
|
|
|
|
$this->polygon = $this->define_polygon();
|
|
$this->area = $this->define_area();
|
|
$this->centroid = $this->define_centroid();
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Define polygon coordinates
|
|
*/
|
|
public function define_polygon()
|
|
{
|
|
if (!empty($this->polygon)) {
|
|
return $this->polygon;
|
|
}
|
|
|
|
if (preg_match('/[\n\r]/', (string) $this->coordinates)) {
|
|
$this->coords = preg_split("/[\n\r\s]+/", (string) $this->coordinates, null, PREG_SPLIT_NO_EMPTY);
|
|
} else {
|
|
$this->coords = preg_split("/[\s]+/", (string) $this->coordinates, null, PREG_SPLIT_NO_EMPTY);
|
|
}
|
|
if (count($this->coords) > 0) {
|
|
foreach ($this->coords as $coord) {
|
|
$p = preg_split("/[\s\(\)]*,[\s\(\)]*/", (string) $coord, null, PREG_SPLIT_NO_EMPTY);
|
|
if ($this->is_valid_lng($p[0]) && $this->is_valid_lat($p[1])) {
|
|
$this->polygon[] = array(
|
|
'lng' => $p[0],
|
|
'lat' => $p[1],
|
|
'elv' => $p[2],
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!is_array($this->polygon)) {
|
|
LoggerManager::getLogger()->warn('Parameter must be an array or an object that implements Countable');
|
|
}
|
|
|
|
if (count((array)$this->polygon) > 0) {
|
|
return $this->polygon;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Define Area Location based on Centroid
|
|
* (Center of Gravity or Balance Point)
|
|
*
|
|
*/
|
|
public function define_area_loc()
|
|
{
|
|
$loc = array();
|
|
$loc['name'] = $this->name;
|
|
if (!is_null($this->centroid)) {
|
|
$loc['lng'] = $this->centroid['lng'];
|
|
$loc['lat'] = $this->centroid['lat'];
|
|
} else {
|
|
$loc['lng'] = null;
|
|
$loc['lat'] = null;
|
|
}
|
|
$loc = $this->define_loc($loc);
|
|
|
|
return $loc;
|
|
}
|
|
|
|
/**
|
|
* Define Centroid - Point
|
|
* @return type
|
|
*/
|
|
public function define_centroid()
|
|
{
|
|
if (!empty($this->centroid)) {
|
|
return $this->centroid;
|
|
}
|
|
|
|
if (empty($this->polygon)) {
|
|
$this->polygon = $this->define_polygon();
|
|
}
|
|
|
|
$n = is_countable($this->polygon) ? count($this->polygon) : 0;
|
|
$a = $this->define_area($this->polygon);
|
|
if (empty($a)) {
|
|
return $this->centroid;
|
|
}
|
|
$cx = 0.0;
|
|
$cy = 0.0;
|
|
// Set $p as Polygon and Add Closing Point
|
|
$p = $this->polygon;
|
|
$p[] = $p[0];
|
|
|
|
for ($i = 0; $i < $n; $i++) {
|
|
$cx += ($p[$i]['lng'] + $p[$i+1]['lng']) * (($p[$i]['lng'] * $p[$i+1]['lat']) - ($p[$i+1]['lng'] * $p[$i]['lat']));
|
|
$cy += ($p[$i]['lat'] + $p[$i+1]['lat']) * (($p[$i]['lng'] * $p[$i+1]['lat']) - ($p[$i+1]['lng'] * $p[$i]['lat']));
|
|
}
|
|
$centroid_lng = -(1/(6*$a))*$cx;
|
|
$centroid_lat = -(1/(6*$a))*$cy;
|
|
|
|
if ($centroid_lng != 0 && $centroid_lat != 0) {
|
|
$this->centroid = array(
|
|
'lng' => $centroid_lng,
|
|
'lat' => $centroid_lat,
|
|
'elv' => 0
|
|
);
|
|
}
|
|
|
|
return $this->centroid;
|
|
}
|
|
|
|
/**
|
|
* Define Polygon Area
|
|
* @return type
|
|
*/
|
|
public function define_area()
|
|
{
|
|
if (!empty($this->area)) {
|
|
return $this->area;
|
|
}
|
|
|
|
if (empty($this->polygon)) {
|
|
$this->polygon = $this->define_polygon();
|
|
}
|
|
|
|
// Based on: http://forums.devnetwork.net/viewtopic.php?f=1&t=44074
|
|
$n = is_countable($this->polygon) ? count($this->polygon) : 0;
|
|
$area = 0.0;
|
|
// Set $p as Polygon and Add Closing Point
|
|
$p = $this->polygon;
|
|
$p[] = $p[0];
|
|
|
|
for ($i = 0; $i < $n; $i++) {
|
|
$j = ($i + 1);
|
|
$area += $p[$i]['lng'] * $p[$j]['lat'];
|
|
$area -= $p[$i]['lat'] * $p[$j]['lng'];
|
|
}
|
|
$area /= 2;
|
|
$this->area = abs($area);
|
|
|
|
return $this->area;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Define Marker Location
|
|
* @param $marker mixed (array or object)
|
|
*/
|
|
public function define_loc($marker = array())
|
|
{
|
|
$loc = array();
|
|
if (is_object($marker)) {
|
|
$loc['name'] = $marker->name;
|
|
$loc['lat'] = $marker->jjwg_maps_lat;
|
|
$loc['lng'] = $marker->jjwg_maps_lng;
|
|
} elseif (is_array($marker) && !empty($marker)) {
|
|
$loc['name'] = $marker['name'];
|
|
$loc['lat'] = $marker['lat'];
|
|
$loc['lng'] = $marker['lng'];
|
|
} else {
|
|
$loc['name'] = '';
|
|
if (is_null($this->centroid)) {
|
|
$loc['lat'] = null;
|
|
$loc['lng'] = null;
|
|
} else {
|
|
$loc['lat'] = $this->centroid['lat'];
|
|
$loc['lng'] = $this->centroid['lng'];
|
|
}
|
|
}
|
|
|
|
if (empty($loc['name'])) {
|
|
$loc['name'] = 'N/A';
|
|
}
|
|
if (!$this->is_valid_lat($loc['lat'])) {
|
|
$loc['lat'] = $this->settings['map_default_center_latitude'];
|
|
}
|
|
if (!$this->is_valid_lng($loc['lng'])) {
|
|
$loc['lng'] = $this->settings['map_default_center_longitude'];
|
|
}
|
|
return $loc;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Check for valid longitude
|
|
* @param $lng float
|
|
*/
|
|
public function is_valid_lng($lng)
|
|
{
|
|
return (is_numeric($lng) && $lng >= -180 && $lng <= 180);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Check for valid latitude
|
|
* @param $lat float
|
|
*/
|
|
public function is_valid_lat($lat)
|
|
{
|
|
return (is_numeric($lat) && $lat >= -90 && $lat <= 90);
|
|
}
|
|
|
|
/**
|
|
* Determine if Marker Object is in Area (Polygon)
|
|
* @param object $marker
|
|
*/
|
|
public function is_marker_in_area($marker)
|
|
{
|
|
$loc = array();
|
|
if (is_object($marker)) {
|
|
$loc['lat'] = $marker->jjwg_maps_lat;
|
|
$loc['lng'] = $marker->jjwg_maps_lng;
|
|
} elseif (is_array($marker)) {
|
|
$loc['lat'] = $marker['lat'];
|
|
$loc['lng'] = $marker['lng'];
|
|
}
|
|
|
|
return $this->is_point_in_area($loc['lng'], $loc['lat']);
|
|
}
|
|
|
|
/**
|
|
* Determine if lng/lat point is in Area Polygon
|
|
*
|
|
* @param float $lng
|
|
* @param float $lat
|
|
*/
|
|
public function is_point_in_area($lng, $lat)
|
|
{
|
|
|
|
// lng,lat,elv
|
|
$point = $lng.','.$lat.',0.0';
|
|
|
|
return $this->point_in_polygon($point);
|
|
}
|
|
|
|
/**
|
|
* Determine if Point lies within Polygon
|
|
*
|
|
* Polygon Algorithm: http://assemblysys.com/php-point-in-polygon-algorithm/
|
|
* Modified by JJWDesign 07/16/2013
|
|
*
|
|
* @param string $point
|
|
* @param boolean $point_on_vertex
|
|
* @return boolean
|
|
*/
|
|
public function point_in_polygon($point, $point_on_vertex = true)
|
|
{
|
|
$this->point_on_vertex = $point_on_vertex;
|
|
$polygon = preg_split('/[\s]+/', (string) $this->coordinates);
|
|
|
|
// Chek $polygon count
|
|
if (!((is_countable($polygon) ? count($polygon) : 0) > 1)) {
|
|
return false;
|
|
}
|
|
// Add the first point to the end, in order to properly close the loop completely
|
|
if ($polygon[(is_countable($polygon) ? count($polygon) : 0)-1] !== $polygon[0]) {
|
|
$polygon[] = $polygon[0];
|
|
}
|
|
|
|
// Transform string coordinates into arrays with x and y values
|
|
$point = $this->point_string_to_coordinates($point);
|
|
$vertices = array();
|
|
foreach ($polygon as $vertex) {
|
|
$vertices[] = $this->point_string_to_coordinates($vertex);
|
|
}
|
|
|
|
// Check if the point sits exactly on a vertex
|
|
if ($this->point_on_vertex == true && $this->point_on_vertex($point, $vertices) == true) {
|
|
return true;
|
|
}
|
|
|
|
// 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 true;
|
|
}
|
|
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 true;
|
|
}
|
|
if ($vertex1['x'] == $vertex2['x'] || $point['x'] <= $xinters) {
|
|
$intersections++;
|
|
}
|
|
}
|
|
}
|
|
// If the number of edges we passed through is odd, then it's in the polygon.
|
|
if ($intersections % 2 != 0) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public function point_on_vertex($point, $vertices)
|
|
{
|
|
foreach ($vertices as $vertex) {
|
|
if ($point == $vertex) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
public function point_string_to_coordinates($pointString)
|
|
{
|
|
|
|
// Coordinate Results (lng,lat,elv)
|
|
$coordinates = preg_split('/[,]+/', (string) $pointString);
|
|
return array("x" => $coordinates[0], "y" => $coordinates[1]);
|
|
}
|
|
}
|