function ip_geoloc_center_of_locations in IP Geolocation Views & Maps 7
Same name and namespace in other branches
- 8 ip_geoloc_api.inc \ip_geoloc_center_of_locations()
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
3 calls to ip_geoloc_center_of_locations()
- ip_geoloc_plugin_style_leaflet::render in views/
ip_geoloc_plugin_style_leaflet.inc - Transform the View result in a list of marker locations and render on map.
- ip_geoloc_plugin_style_map::render in views/
ip_geoloc_plugin_style_map.inc - Transform the View result in a list of markers and render these on a map.
- ip_geoloc_plugin_style_openlayers::render in views/
ip_geoloc_plugin_style_openlayers.inc - Transform the View result in a list of markers and render these on a map.
File
- ./
ip_geoloc_api.inc, line 592 - API functions of IP geolocation module
Code
function ip_geoloc_center_of_locations($locations, $center_of_gravity = FALSE) {
if (empty($locations)) {
return array(
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 array(
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 array(
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 array(
$center_lat,
$center_lng,
);
}