public function IpGeoLocAPI::centerOfLocations in IP Geolocation Views & Maps 8
Calculate the center of the supplied locations using one of two algorithms.
The first algorithm returns the center of the rectangle whose horizontal sides pass through the top and bottom locations in the set, while its vertical sides pass through the left-most and right-most locations.
The second algorithm returns the center of gravity of all supplied locations. The second algorithn is therefore sensitive to location clusters. This may be what you want, or it may be what you want to avoid.
Parameters
array $locations: Array of location objects each with latitude and longitude.
bool $center_of_gravity: If TRUE use the center of gravity algorithm.
Return value
array containing latitude and longitude of the center
File
- src/
Services/ IpGeoLocAPI.php, line 609
Class
- IpGeoLocAPI
- Class IpGeoAPI to interact with other modules.
Namespace
Drupal\ip_geoloc\ServicesCode
public function centerOfLocations(array $locations, $center_of_gravity = FALSE) {
if (empty($locations)) {
return [
NULL,
NULL,
];
}
if ($center_of_gravity) {
// Because longitude turns back on itself, cannot simply average coords.
$count = 0;
$x = $y = $z = 0.0;
foreach ($locations as $location) {
if (isset($location->lon)) {
$lng = $location->lon;
$lat = $location->lat;
}
elseif (isset($location->longitude)) {
$lng = $location->longitude;
$lat = $location->latitude;
}
else {
continue;
}
$lng = deg2rad($lng);
$lat = deg2rad($lat);
// Convert to Cartesian coords and total the 3 dimensions independently.
$x += cos($lat) * cos($lng);
$y += cos($lat) * sin($lng);
$z += sin($lat);
$count++;
}
$x /= $count;
$y /= $count;
$z /= $count;
$center_lat = atan2($z, sqrt($x * $x + $y * $y));
$center_lng = atan2($y, $x);
return [
rad2deg($center_lat),
rad2deg($center_lng),
];
}
// Alternative method based on top & bottom lat and left & right lon.
$top = $bottom = $left = $right = NULL;
foreach ($locations as $location) {
if (isset($location->lon)) {
$lng = $location->lon;
$lat = $location->lat;
}
elseif (isset($location->longitude)) {
$lng = $location->longitude;
$lat = $location->latitude;
}
else {
continue;
}
if (!isset($top) || $lat > $top) {
$top = $lat;
}
if (!isset($bottom) || $lat < $bottom) {
$bottom = $lat;
}
if (!isset($left) || $lng < $left) {
$left = $lng;
}
if (!isset($right) || $lng > $right) {
$right = $lng;
}
}
if (!isset($top) || !isset($left)) {
return [
NULL,
NULL,
];
}
$center_lat = 0.5 * ($top + $bottom);
$center_lng = 0.5 * ($left + $right);
if ($right - $left > 180) {
// If the angle between right and left is greater than 180, then averaging
// is still ok, provided we flip over to the opposite end of the world.
$center_lng = $center_lng > 0.0 ? $center_lng - 180.0 : $center_lng + 180.0;
}
return [
$center_lat,
$center_lng,
];
}