Commit version 24.12.13800

This commit is contained in:
2025-01-06 17:35:06 -05:00
parent b7f6a79c2c
commit 55d9218816
6133 changed files with 4239740 additions and 1374287 deletions

View File

@ -5,233 +5,226 @@
*
* This file is part of Observium.
*
* @package observium
* @subpackage map
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2019 Observium Limited
* @package observium
* @subpackage map
* @copyright (C) Adam Armstrong
*
*/
// Detect map center and zoom
$where = ' WHERE 1 ';
$where .= generate_query_permitted(array('device'), array('hide_ignored' => TRUE));
// Detect map center and zoom
$where = ' WHERE 1 ';
$where .= generate_query_permitted(['device'], ['hide_ignored' => TRUE]);
if (!is_numeric($config['frontpage']['map']['center']['lat']) || !is_numeric($config['frontpage']['map']['center']['lng']))
{
$map_center = dbFetchRow('SELECT MAX(`location_lon`) AS `lng_max`, MIN(`location_lon`) AS `lng_min`,
if (!is_numeric($config['frontpage']['map']['center']['lat']) || !is_numeric($config['frontpage']['map']['center']['lng'])) {
$map_center = dbFetchRow('SELECT MAX(`location_lon`) AS `lng_max`, MIN(`location_lon`) AS `lng_min`,
MAX(`location_lat`) AS `lat_max`, MIN(`location_lat`) AS `lat_min`
FROM `devices_locations` '.$where);
$map_center['lat'] = ($map_center['lat_max'] + $map_center['lat_min']) / 2;
$map_center['lng'] = ($map_center['lng_max'] + $map_center['lng_min']) / 2;
FROM `devices_locations` ' . $where);
$map_center['lat'] = ($map_center['lat_max'] + $map_center['lat_min']) / 2;
$map_center['lng'] = ($map_center['lng_max'] + $map_center['lng_min']) / 2;
$config['frontpage']['map']['center']['lat'] = $map_center['lat'];
$config['frontpage']['map']['center']['lng'] = $map_center['lng'];
// Auto-zoom
if (!is_numeric($config['frontpage']['map']['zoom']))
{
$map_center['lat_size'] = abs($map_center['lat_max'] - $map_center['lat_min']);
$map_center['lng_size'] = abs($map_center['lng_max'] - $map_center['lng_min']);
$l_max = max($map_center['lng_size'], $map_center['lat_size'] * 2);
// This is the magic array (2: min zoom, 10: max zoom).
foreach (array(1 => 10, 2 => 9, 4 => 8, 6 => 7, 15 => 5, 45 => 4, 90 => 3, 360 => 2) as $g => $z)
{
if ($l_max <= $g)
{
$config['frontpage']['map']['zoom'] = $z;
break;
if (!is_numeric($config['frontpage']['map']['zoom'])) {
$map_center['lat_size'] = abs($map_center['lat_max'] - $map_center['lat_min']);
$map_center['lng_size'] = abs($map_center['lng_max'] - $map_center['lng_min']);
$l_max = max($map_center['lng_size'], $map_center['lat_size'] * 2);
// This is the magic array (2: min zoom, 10: max zoom).
foreach ([1 => 10, 2 => 9, 4 => 8, 6 => 7, 15 => 5, 45 => 4, 90 => 3, 360 => 2] as $g => $z) {
if ($l_max <= $g) {
$config['frontpage']['map']['zoom'] = $z;
break;
}
}
}
}
//r($map_center);
} else {
if (!is_numeric($config['frontpage']['map']['zoom'])) { $config['frontpage']['map']['zoom'] = 4; }
}
} else {
if (!is_numeric($config['frontpage']['map']['zoom'])) {
$config['frontpage']['map']['zoom'] = 4;
}
}
?>
<script type='text/javascript' src='//www.google.com/jsapi'></script>
<script type="text/javascript" src="js/google/markerclusterer.js"></script>
<script type='text/javascript' src='//www.google.com/jsapi'></script>
<script type="text/javascript" src="js/google/markerclusterer.js"></script>
<?php
if ($config['frontpage']['map']['clouds'])
{
echo '<script src="//maps.googleapis.com/maps/api/js?v=3.exp&libraries=weather&key='.$config['geo_api']['google']['key'].'"></script>';
} else {
echo '<script src="//maps.google.com/maps/api/js?key='.$config['geo_api']['google']['key'].'"></script>';
}
?>
<script type="text/javascript">
google.load('visualization', '1.1', {'packages': ['geochart']});
function getMapData() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'Latitude');
data.addColumn('number', 'Longitude');
data.addColumn('number', 'Number up');
data.addColumn('number', 'Number down');
data.addColumn({type: 'string', role: 'tooltip'});
data.addColumn('string', 'Location');
data.addColumn('string', 'url');
data.addRows([
<?php
$locations = array();
foreach ($GLOBALS['cache']['devices']['id'] as $device)
{
if (!$config['web_show_disabled'] && $device["disabled"]) { continue; }
$lat = (is_numeric($device['location_lat']) ? $device['location_lat'] : $config['geocoding']['default']['lat']);
$lon = (is_numeric($device['location_lon']) ? $device['location_lon'] : $config['geocoding']['default']['lon']);
if ($device["status"] == "0")
{
if ($device["ignore"] == "0")
{
$locations[$lat][$lon]["down_hosts"][] = $device;
}
} else {
$locations[$lat][$lon]["up_hosts"][] = $device;
}
}
foreach ($locations as $la => $lat)
{
foreach ($lat as $lo => $lon)
{
$num_up = count($lon["up_hosts"]);
$num_down = count($lon["down_hosts"]);
$total_hosts = $num_up + $num_down;
$tooltip = "$total_hosts Hosts";
$location_name = "";
if ($num_down > 0)
{
$location_name = ($lon['down_hosts'][0]['location'] === '' ? OBS_VAR_UNSET : $lon['down_hosts'][0]['location']);
$location_url = generate_location_url($lon['down_hosts'][0]['location']);
$tooltip .= "\\n\\nDown hosts:";
foreach ($lon["down_hosts"] as $down_host) {
$tooltip .= "\\n" . escape_html($down_host['hostname']);
}
}
elseif ($num_up > 0)
{
$location_name = ($lon['up_hosts'][0]['location'] === '' ? OBS_VAR_UNSET : $lon['up_hosts'][0]['location']);
$location_url = generate_location_url($lon['up_hosts'][0]['location']);
}
// Google Map JS not allowed chars: ', \
$location_name = strtr(escape_html($location_name), "'\\", "`/");
echo "[$la, $lo, $num_up, $num_down, \"$tooltip\", '$location_name', '$location_url'],\n ";
}
}
<?php
if ($config['frontpage']['map']['clouds']) {
echo '<script src="//maps.googleapis.com/maps/api/js?v=3.exp&libraries=weather&key=' . $config['geo_api']['google']['key'] . '"></script>';
} else {
echo '<script src="//maps.google.com/maps/api/js?key=' . $config['geo_api']['google']['key'] . '"></script>';
}
?>
]);
return data;
}
<script type="text/javascript">
google.load('visualization', '1.1', {'packages': ['geochart']});
function initialize() {
var data = getMapData();
var markers = [];
var base_link = '<?php echo generate_url(array("page" => "devices")); ?>';
for (var i = 0; i < data.getNumberOfRows(); i++) {
var latLng = new google.maps.LatLng(data.getValue(i, 0), data.getValue(i, 1));
icon_ = '//maps.gstatic.com/mapfiles/ridefinder-images/mm_20_green.png';
function getMapData() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'Latitude');
data.addColumn('number', 'Longitude');
data.addColumn('number', 'Number up');
data.addColumn('number', 'Number down');
data.addColumn({type: 'string', role: 'tooltip'});
data.addColumn('string', 'Location');
data.addColumn('string', 'url');
data.addRows([
<?php
$locations = [];
foreach ($GLOBALS['cache']['devices']['id'] as $device) {
if (!$config['web_show_disabled'] && $device["disabled"]) {
continue;
}
$lat = (is_numeric($device['location_lat']) ? $device['location_lat'] : $config['geocoding']['default']['lat']);
$lon = (is_numeric($device['location_lon']) ? $device['location_lon'] : $config['geocoding']['default']['lon']);
if ($device["status"] == "0") {
if ($device["ignore"] == "0") {
$locations[$lat][$lon]["down_hosts"][] = $device;
}
} else {
$locations[$lat][$lon]["up_hosts"][] = $device;
}
}
var num_up = data.getValue(i, 2);
var num_down = data.getValue(i, 3);
var location = data.getValue(i, 5);
var ratio_up = num_up / (num_up + num_down);
foreach ($locations as $la => $lat) {
foreach ($lat as $lo => $lon) {
$num_up = count($lon["up_hosts"]);
$num_down = count($lon["down_hosts"]);
$total_hosts = $num_up + $num_down;
$tooltip = "$total_hosts Hosts";
if (ratio_up < 0.9999) {
icon_ = '//maps.gstatic.com/mapfiles/ridefinder-images/mm_20_red.png';
}
$location_name = "";
if ($num_down > 0) {
$location_name = ($lon['down_hosts'][0]['location'] === '' ? OBS_VAR_UNSET : $lon['down_hosts'][0]['location']);
$location_url = generate_location_url($lon['down_hosts'][0]['location']);
$tooltip .= "\\n\\nDown hosts:";
var marker = new google.maps.Marker({
position: latLng,
icon: icon_,
title: data.getValue(i, 4),
location: location,
num_up: num_up,
num_down: num_down,
url: data.getValue(i, 6)
});
foreach ($lon["down_hosts"] as $down_host) {
$tooltip .= "\\n" . escape_html($down_host['hostname']);
}
} elseif ($num_up > 0) {
$location_name = ($lon['up_hosts'][0]['location'] === '' ? OBS_VAR_UNSET : $lon['up_hosts'][0]['location']);
$location_url = generate_location_url($lon['up_hosts'][0]['location']);
}
// Google Map JS not allowed chars: ', \
$location_name = strtr(escape_html($location_name), "'\\", "`/");
echo "[$la, $lo, $num_up, $num_down, \"$tooltip\", '$location_name', '$location_url'],\n ";
}
}
?>
]);
return data;
}
function initialize() {
var data = getMapData();
var markers = [];
var base_link = '<?php echo generate_url(["page" => "devices"]); ?>';
for (var i = 0; i < data.getNumberOfRows(); i++) {
var latLng = new google.maps.LatLng(data.getValue(i, 0), data.getValue(i, 1));
icon_ = '//maps.gstatic.com/mapfiles/ridefinder-images/mm_20_green.png';
var num_up = data.getValue(i, 2);
var num_down = data.getValue(i, 3);
var location = data.getValue(i, 5);
var ratio_up = num_up / (num_up + num_down);
if (ratio_up < 0.9999) {
icon_ = '//maps.gstatic.com/mapfiles/ridefinder-images/mm_20_red.png';
}
var marker = new google.maps.Marker({
position: latLng,
icon: icon_,
title: data.getValue(i, 4),
location: location,
num_up: num_up,
num_down: num_down,
url: data.getValue(i, 6)
});
// marker.num_up = num_up;
// marker.num_down = num_down;
markers.push(marker);
markers.push(marker);
google.maps.event.addDomListener(marker, 'click', function() {
window.location.href = this.url;
});
}
var styles = [];
for (var i = 0; i < 4; i++) {
image_path = "/images/mapclusterer/";
image_ext = ".png";
styles.push({
url: image_path + i + image_ext,
height: 52,
width: 53
});
}
google.maps.event.addDomListener(marker, 'click', function () {
window.location.href = this.url;
});
}
var styles = [];
for (var i = 0; i < 4; i++) {
image_path = "/images/mapclusterer/";
image_ext = ".png";
styles.push({
url: image_path + i + image_ext,
height: 52,
width: 53
});
}
var mcOptions = {gridSize: 30,
maxZoom: 15,
zoomOnClick: false,
styles: styles
};
var markerClusterer = new MarkerClusterer(map, markers, mcOptions);
var mcOptions = {
gridSize: 30,
maxZoom: 15,
zoomOnClick: false,
styles: styles
};
var markerClusterer = new MarkerClusterer(map, markers, mcOptions);
var iconCalculator = function(markers, numStyles) {
var total_up = 0;
var total_down = 0;
for (var i = 0; i < markers.length; i++) {
total_up += markers[i].num_up;
total_down += markers[i].num_down;
}
var iconCalculator = function (markers, numStyles) {
var total_up = 0;
var total_down = 0;
for (var i = 0; i < markers.length; i++) {
total_up += markers[i].num_up;
total_down += markers[i].num_down;
}
var ratio_up = total_up / (total_up + total_down);
var ratio_up = total_up / (total_up + total_down);
//The map clusterer really does seem to use index-1...
index_ = 1;
if (ratio_up < 0.9999) {
index_ = 4; // Could be 2, and then more code to use all 4 images
}
//The map clusterer really does seem to use index-1...
index_ = 1;
if (ratio_up < 0.9999) {
index_ = 4; // Could be 2, and then more code to use all 4 images
}
return {
text: (total_up + total_down),
index: index_
};
}
return {
text: (total_up + total_down),
index: index_
};
}
markerClusterer.setCalculator(iconCalculator);
}
markerClusterer.setCalculator(iconCalculator);
}
var center_ = new google.maps.LatLng(<?php echo $config['frontpage']['map']['center']['lat']; ?>, <?php echo $config['frontpage']['map']['center']['lng']; ?>);
var map = new google.maps.Map(document.getElementById('map'), {
zoom: <?php echo $config['frontpage']['map']['zoom']?>,
scrollwheel: false,
streetViewControl: false,
center: center_,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var center_ = new google.maps.LatLng(<?php echo $config['frontpage']['map']['center']['lat']; ?>, <?php echo $config['frontpage']['map']['center']['lng']; ?>);
var map = new google.maps.Map(document.getElementById('map'), {
zoom: <?php echo $config['frontpage']['map']['zoom']?>,
scrollwheel: false,
streetViewControl: false,
center: center_,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
<?php if ($config['frontpage']['map']['clouds']) { ?>
var cloudLayer = new google.maps.weather.CloudLayer();
cloudLayer.setMap(map);
<?php } ?>
<?php if ($config['frontpage']['map']['clouds']) { ?>
var cloudLayer = new google.maps.weather.CloudLayer();
cloudLayer.setMap(map);
<?php } ?>
function resetMap() {
map.setZoom(4);
map.panTo(center_);
}
function resetMap() {
map.setZoom(4);
map.panTo(center_);
}
google.maps.event.addListener(map, 'click', function(event) {
map.setZoom(map.getZoom() + <?php echo $config['frontpage']['map']['zooms_per_click']; ?>);
map.panTo(event.latLng);
});
google.maps.event.addDomListener(window, 'load', initialize);
google.maps.event.addListener(map, 'click', function (event) {
map.setZoom(map.getZoom() + <?php echo $config['frontpage']['map']['zooms_per_click']; ?>);
map.panTo(event.latLng);
});
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</script>
<?php
// EOF

View File

@ -5,104 +5,106 @@
*
* This file is part of Observium.
*
* @package observium
* @subpackage map
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2019 Observium Limited
* @package observium
* @subpackage map
* @copyright (C) Adam Armstrong
*
*/
?>
<script type='text/javascript' src='//www.google.com/jsapi'></script>
<script type='text/javascript'>
google.load('visualization', '1.1', {'packages': ['geochart']});
google.setOnLoadCallback(drawRegionsMap);
function drawRegionsMap() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'Latitude');
data.addColumn('number', 'Longitude');
data.addColumn('string', 'Location');
data.addColumn('number', 'Status');
data.addColumn('number', 'Devices');
data.addColumn({type: 'string', role: 'tooltip'});
data.addColumn('string', 'url');
data.addRows([
<?php
$locations_up = array();
$locations_down = array();
foreach (get_locations() as $location)
{
$location_name = ($location === '' ? OBS_VAR_UNSET : strtr(escape_html($location), "'\\", "`/"));
$location_url = generate_location_url($location);
$devices_down = array();
$devices_up = array();
$count = $GLOBALS['cache']['device_locations'][$location];
$down = 0;
foreach ($GLOBALS['cache']['devices']['id'] as $device)
{
if ($device['location'] == $location)
{
if ($device['status'] == "0" && $device['ignore'] == "0")
{
$down++;
$devices_down[] = $device['hostname'];
$lat = (is_numeric($device['location_lat']) ? $device['location_lat'] : $config['geocoding']['default']['lat']);
$lon = (is_numeric($device['location_lon']) ? $device['location_lon'] : $config['geocoding']['default']['lon']);
}
else if ($device['status'] == "1")
{
$devices_up[] = $device['hostname'];
$lat = (is_numeric($device['location_lat']) ? $device['location_lat'] : $config['geocoding']['default']['lat']);
$lon = (is_numeric($device['location_lon']) ? $device['location_lon'] : $config['geocoding']['default']['lon']);
}
<script type='text/javascript' src='//www.google.com/jsapi'></script>
<script type='text/javascript'>
google.load('visualization', '1.1', {'packages': ['geochart']});
google.setOnLoadCallback(drawRegionsMap);
function drawRegionsMap() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'Latitude');
data.addColumn('number', 'Longitude');
data.addColumn('string', 'Location');
data.addColumn('number', 'Status');
data.addColumn('number', 'Devices');
data.addColumn({type: 'string', role: 'tooltip'});
data.addColumn('string', 'url');
data.addRows([
<?php
$locations_up = [];
$locations_down = [];
foreach (get_locations() as $location) {
$location_name = ($location === '' ? OBS_VAR_UNSET : strtr(escape_html($location), "'\\", "`/"));
$location_url = generate_location_url($location);
$devices_down = [];
$devices_up = [];
$count = $GLOBALS['cache']['device_locations'][$location];
$down = 0;
foreach ($GLOBALS['cache']['devices']['id'] as $device) {
if ($device['location'] == $location) {
if ($device['status'] == "0" && $device['ignore'] == "0") {
$down++;
$devices_down[] = $device['hostname'];
$lat = (is_numeric($device['location_lat']) ? $device['location_lat'] : $config['geocoding']['default']['lat']);
$lon = (is_numeric($device['location_lon']) ? $device['location_lon'] : $config['geocoding']['default']['lon']);
} elseif ($device['status'] == "1") {
$devices_up[] = $device['hostname'];
$lat = (is_numeric($device['location_lat']) ? $device['location_lat'] : $config['geocoding']['default']['lat']);
$lon = (is_numeric($device['location_lon']) ? $device['location_lon'] : $config['geocoding']['default']['lon']);
}
}
$count = (($count < 100) ? $count : 100);
if ($down > 0)
{
$locations_down[] = "[$lat, $lon, '$location_name', $down, ".$count*$down.", '".count($devices_up). " Devices UP, " . count($devices_down). " Devices DOWN: (". implode(", ", $devices_down).")', '$location_url']";
} else if ($count) {
$locations_up[] = "[".$lat.", ".$lon.", '".$location_name."', 0, ".$count.", '".count($devices_up). " Devices UP: (". implode(", ", $devices_up).")', '$location_url']";
}
}
echo(implode(",\n ", array_merge($locations_up, $locations_down)));
$count = (($count < 100) ? $count : 100);
if ($down > 0) {
$locations_down[] = "[$lat, $lon, '$location_name', $down, " . $count * $down . ", '" . count($devices_up) . " Devices UP, " . count($devices_down) . " Devices DOWN: (" . implode(", ", $devices_down) . ")', '$location_url']";
} elseif ($count) {
$locations_up[] = "[" . $lat . ", " . $lon . ", '" . $location_name . "', 0, " . $count . ", '" . count($devices_up) . " Devices UP: (" . implode(", ", $devices_up) . ")', '$location_url']";
}
}
echo(implode(",\n ", array_merge($locations_up, $locations_down)));
?>
]);
]);
var options = {
region: '<?php echo $config['frontpage']['map']['region']; ?>',
resolution: '<?php echo $config['frontpage']['map']['resolution']; ?>',
displayMode: 'markers',
keepAspectRatio: 0,
//width: 1240,
//height: 480,
is3D: true,
legend: 'none',
enableRegionInteractivity: true,
<?php if ($config['frontpage']['map']['realworld']) { echo "\t\t datalessRegionColor: '#93CA76',"; }
else { echo "\t\t datalessRegionColor: '#d5d5d5',"; }
if ($config['frontpage']['map']['realworld']) { echo "\t\t backgroundColor: {fill: '#000000'},"; } ?>
backgroundColor: {fill: 'transparent'},
magnifyingGlass: {enable: true, zoomFactor: 5},
colorAxis: {values: [0, 1, 2, 3], colors: ['darkgreen', 'orange', 'orangered', 'red']},
markerOpacity: 0.75,
sizeAxis: {minValue: 1, maxValue: 10, minSize: 10, maxSize: 40}
};
var view = new google.visualization.DataView(data);
// exclude last url column in the GeoChart
view.setColumns([0, 1, 2, 3, 4, 5]);
var chart = new google.visualization.GeoChart(document.getElementById('map'));
google.visualization.events.addListener(chart, 'ready', onReady);
function onReady() {
google.visualization.events.addListener(chart, 'select', gotoLocation);
var options = {
region: '<?php echo $config['frontpage']['map']['region']; ?>',
resolution: '<?php echo $config['frontpage']['map']['resolution']; ?>',
displayMode: 'markers',
keepAspectRatio: 0,
//width: 1240,
//height: 480,
is3D: true,
legend: 'none',
enableRegionInteractivity: true,
<?php if ($config['frontpage']['map']['realworld']) {
echo "\t\t datalessRegionColor: '#93CA76',";
} else {
echo "\t\t datalessRegionColor: '#d5d5d5',";
}
function gotoLocation() {
var selection = chart.getSelection();
var item = selection[0];
var url = data.getValue(item.row, 6);
window.location = url;
}
chart.draw(view, options);
if ($config['frontpage']['map']['realworld']) {
echo "\t\t backgroundColor: {fill: '#000000'},";
} ?>
backgroundColor: {fill: 'transparent'},
magnifyingGlass: {enable: true, zoomFactor: 5},
colorAxis: {values: [0, 1, 2, 3], colors: ['darkgreen', 'orange', 'orangered', 'red']},
markerOpacity: 0.75,
sizeAxis: {minValue: 1, maxValue: 10, minSize: 10, maxSize: 40}
};
var view = new google.visualization.DataView(data);
// exclude last url column in the GeoChart
view.setColumns([0, 1, 2, 3, 4, 5]);
var chart = new google.visualization.GeoChart(document.getElementById('map'));
google.visualization.events.addListener(chart, 'ready', onReady);
function onReady() {
google.visualization.events.addListener(chart, 'select', gotoLocation);
}
</script>
function gotoLocation() {
var selection = chart.getSelection();
var item = selection[0];
var url = data.getValue(item.row, 6);
window.location = url;
}
chart.draw(view, options);
}
</script>

View File

@ -1,13 +1,12 @@
<?php
/**
* Observium
*
* This file is part of Observium.
*
* @package observium
* @subpackage map
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2019 Observium Limited
* @package observium
* @subpackage ajax
* @copyright (C) Adam Armstrong
*
*/
@ -36,6 +35,7 @@ register_html_resource('css', 'MarkerCluster.Default.css');
*/
/* old
// [lat, lng], zoom
if (is_numeric($config['frontpage']['map']['zoom']) &&
is_numeric($config['frontpage']['map']['center']['lat']) &&
@ -51,7 +51,7 @@ else
{
// Auto zoom
$leaflet_init = '[0, -0], 2';
$leaflet_bounds = 'map'.$vars['widget_id'].'.fitBounds(realtime.getBounds(), { padding: [30, 30] });';
$leaflet_bounds = 'map'.$mod['widget_id'].'.fitBounds(realtime.getBounds(), { padding: [30, 30] });';
}
switch ($config['frontpage']['map']['tiles'])
@ -110,7 +110,6 @@ switch ($config['frontpage']['map']['tiles'])
?>
<script type="text/javascript">
var icons = {
ok: L.icon({
@ -126,9 +125,12 @@ switch ($config['frontpage']['map']['tiles'])
})
};
var map<?php echo $vars['widget_id']; ?> = L.map('map<?php echo $vars['widget_id']; ?>'),
var url = 'geojson.php?<?php http_build_query($vars['geojson_query']); ?>';
var map<?php echo $mod['widget_id']; ?> = L.map('map<?php echo $mod['widget_id']; ?>'),
realtime = L.realtime({
url: 'geojson.php',
url: url,
method: 'POST',
crossOrigin: true,
type: 'json',
getFeatureId: function (feature) {
@ -193,31 +195,27 @@ switch ($config['frontpage']['map']['tiles'])
return layer;
}
}).addTo(map<?php echo $vars['widget_id']; ?>);
}).addTo(map<?php echo $mod['widget_id']; ?>);
map<?php echo $vars['widget_id']; ?>.setView(<?php echo $leaflet_init; ?>);
map<?php echo $mod['widget_id']; ?>.setView(<?php echo $leaflet_init; ?>);
<?php
// echo $leaflet_bounds;
?>
/* disable scroll wheel by default, toggle by click on map */
map<?php echo $vars['widget_id']; ?>.scrollWheelZoom.disable();
map<?php echo $vars['widget_id']; ?>.on('click', function () {
if (map<?php echo $vars['widget_id']; ?>.scrollWheelZoom.enabled()) {
map<?php echo $vars['widget_id']; ?>.scrollWheelZoom.disable();
// disable scroll wheel by default, toggle by click on map
map<?php echo $mod['widget_id']; ?>.scrollWheelZoom.disable();
map<?php echo $mod['widget_id']; ?>.on('click', function () {
if (map<?php echo $mod['widget_id']; ?>.scrollWheelZoom.enabled()) {
map<?php echo $mod['widget_id']; ?>.scrollWheelZoom.disable();
} else {
map<?php echo $vars['widget_id']; ?>.scrollWheelZoom.enable();
map<?php echo $mod['widget_id']; ?>.scrollWheelZoom.enable();
}
});
map<?php echo $vars['widget_id']; ?>.on('mouseover', function () {
map<?php echo $mod['widget_id']; ?>.on('mouseover', function () {
//console.log('STOPPING');
realtime.stop();
//console.log(realtime.isRunning());
});
map<?php echo $vars['widget_id']; ?>.on('mouseout', function () {
map<?php echo $mod['widget_id']; ?>.on('mouseout', function () {
//console.log('STARTING');
realtime.start();
//console.log(realtime.isRunning());
@ -238,7 +236,7 @@ switch ($config['frontpage']['map']['tiles'])
echo "format: '" . $leaflet_format . "',";
} ?>
attribution: '<?php echo $leaflet_copy; ?>'
}).addTo(map<?php echo $vars['widget_id']; ?>);
}).addTo(map<?php echo $mod['widget_id']; ?>);
realtime.on('update', function () {
@ -256,4 +254,218 @@ switch ($config['frontpage']['map']['tiles'])
<?php
// EOF
*/
function get_leaflet_init_and_bounds($config)
{
if (is_numeric($config['frontpage']['map']['zoom']) &&
is_numeric($config['frontpage']['map']['center']['lat']) &&
is_numeric($config['frontpage']['map']['center']['lng'])) {
$leaflet_init = '[' . $config['frontpage']['map']['center']['lat'] . ', ' . $config['frontpage']['map']['center']['lng'] . '], ' . $config['frontpage']['map']['zoom'];
$leaflet_bounds = '';
} else {
$leaflet_init = '[0, -0], 2';
$leaflet_bounds = 'map' . $mod['widget_id'] . '.fitBounds(realtime.getBounds(), { padding: [30, 30] });';
}
return [$leaflet_init, $leaflet_bounds];
}
function get_ssl_prefixed_url($url)
{
return is_ssl() ? str_replace('http://', 'https://', $url) : $url;
}
function get_map_tiles_config($config)
{
$tile_configs = [
'esri-worldgraycanvas' => [
'url' => 'https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}',
'attribution' => 'Tiles &copy; Esri &mdash; Esri, DeLorme, NAVTEQ'
],
'opentopomap' => [
'url' => 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png',
'attribution' => 'Map data: &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: &copy; <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'
],
'osm-mapnik' => [
'url' => 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
'attribution' => '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
],
'nasa-night' => [
'url' => 'https://map1.vis.earthdata.nasa.gov/wmts-webmerc/VIIRS_CityLights_2012/default//GoogleMapsCompatible_Level8/{z}/{y}/{x}.jpg',
'attribution' => 'Imagery provided by GIBS, operated by <a href="https://earthdata.nasa.gov">ESDIS</a>, funding by NASA/HQ.',
'format' => 'jpg',
],
'wikimedia' => [
'url' => 'https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}{r}.png',
'attribution' => '<a href="https://wikimediafoundation.org/wiki/Maps_Terms_of_Use">Wikimedia</a>',
]
];
$tiles = $config['frontpage']['map']['tiles'];
if (!isset($tile_configs[$tiles])) {
$tiles = 'carto-base-auto';
}
if ($tiles === 'carto-base-auto') {
$tiles = ($config['themes'][$_SESSION['theme']]['type'] === 'dark') ? "carto-base-dark" : "carto-base-light";
}
if (isset($tile_configs[$tiles])) {
return $tile_configs[$tiles];
}
// Fallback to carto-base-dark or carto-base-light
$leaflet_variant = ($tiles === "carto-base-dark") ? "dark_all" : "light_all";
$url_base = 'http://{s}.basemaps.cartocdn.com/' . $leaflet_variant . '/{z}/{x}/{y}';
$url = get_ssl_prefixed_url($url_base . '.png');
$hqurl = get_ssl_prefixed_url($url_base . '@2x.png');
return [
'url' => $url,
'hqurl' => $hqurl,
'attribution' => 'Map data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, &copy; <a href="https://carto.com/attributions">CARTO</a>'
];
}
[$leaflet_init, $leaflet_bounds] = get_leaflet_init_and_bounds($config);
$map_tiles = get_map_tiles_config($config);
//FIXME. Urgent! need escaping!
$vars['geojson_query_str'] = isset($vars['geojson_query']) ? http_build_query($vars['geojson_query']) : '';
?>
<script type="text/javascript">
function initMap(widgetId) {
const icons = {
ok: L.icon({
iconUrl: 'images/svg/ok.svg',
popupAnchor: [0, 16],
iconSize: [<?php echo $config['frontpage']['map']['okmarkersize']; ?>, <?php echo $config['frontpage']['map']['okmarkersize']; ?>]
}),
alert: L.icon({
iconUrl: 'images/svg/high_priority.svg',
popupAnchor: [0, 12],
iconSize: [<?php echo $config['frontpage']['map']['alertmarkersize']; ?>, <?php echo $config['frontpage']['map']['alertmarkersize']; ?>]
})
};
const url = 'ajax/geojson.php?<?php echo $vars['geojson_query_str']; ?>';
const map = L.map(`map${widgetId}`);
const realtime = createRealtimeLayer(url).addTo(map);
map.setView(<?php echo $leaflet_init; ?>);
map.scrollWheelZoom.disable();
map.on('click', () => map.scrollWheelZoom.toggle());
map.on('mouseover', () => realtime.stop());
map.on('mouseout', () => realtime.start());
const tileUrl = <?php echo(isset($map_tiles['hqurl']) ? "L.Browser.retina ? '{$map_tiles['hqurl']}' : '{$map_tiles['url']}'" : "'{$map_tiles['url']}'"); ?>;
L.tileLayer(tileUrl, {
detectRetina: true,
tilematrixset: 'GoogleMapsCompatible_Level',
attribution: '<?php echo $map_tiles['attribution']; ?>'
}).addTo(map);
realtime.on('update', () => {
if (realtime.isRunning()) {
<?php echo $leaflet_bounds; ?>
}
});
function createRealtimeLayer(url) {
const onEachFeature = (feature, layer) => {
layer.on({
mouseover: showTooltip,
mouseout: hideTooltip
});
layer.on('click', () => window.open(feature.properties.url, "_self"));
layer.setIcon(icons[feature.properties.state === "up" ? 'ok' : 'alert']);
};
const updateFeature = (feature, layer) => {
if (!layer) {
return;
}
onEachFeature(feature, layer);
return layer;
};
return L.realtime({
url: url,
method: 'POST',
crossOrigin: true,
type: 'json',
getFeatureId: feature => feature.properties.id + feature.properties.state
}, {
interval: 10 * 1000,
onEachFeature: onEachFeature,
updateFeature: updateFeature
});
}
}
// Function to show the tooltip on 'mouseover'
function showTooltip(e) {
var layer = e.target;
var lat = layer.feature.geometry.coordinates[1]; // Get latitude from GeoJSON
var lon = layer.feature.geometry.coordinates[0]; // Get longitude from GeoJSON
// Fetch the external HTML content using AJAX
$.ajax({
url: 'ajax/entity_popup.php', // Replace with your AJAX endpoint
data: {
entity_type: 'latlon',
lat: lat,
lon: lon
},
success: function (response) {
// Create and show the qTip2 tooltip with the fetched HTML content
$('body').qtip({
content: {
text: response
},
show: {
event: false, // Don't show on a regular event
ready: true // Show immediately upon creation
},
hide: {
event: 'mouseout'
},
style: {
classes: 'qtip-bootstrap',
},
position: {
target: [e.originalEvent.pageX, e.originalEvent.pageY],
adjust: {
x: 10, // Horizontal offset
y: 10 // Vertical offset
}
},
events: {
hidden: function (event, api) {
api.destroy(true); // Destroy the tooltip when hidden
}
}
});
},
error: function (xhr, status, error) {
console.log('Error fetching tooltip content:', error);
}
});
}
// Function to hide the tooltip on 'mouseout'
function hideTooltip(e) {
var layer = e.target;
// Hide the qTip2 tooltip
$(layer).qtip('hide');
}
initMap('<?php echo $mod['widget_id']; ?>');
</script>