Merge branch 'map'
commit
b0413f330e
|
@ -215,6 +215,8 @@ CREATE TABLE `Events` (
|
||||||
`DiskSpace` bigint unsigned default NULL,
|
`DiskSpace` bigint unsigned default NULL,
|
||||||
`Scheme` enum('Deep','Medium','Shallow') NOT NULL default 'Medium',
|
`Scheme` enum('Deep','Medium','Shallow') NOT NULL default 'Medium',
|
||||||
`Locked` BOOLEAN NOT NULL DEFAULT False,
|
`Locked` BOOLEAN NOT NULL DEFAULT False,
|
||||||
|
`Latitude` DECIMAL(10,8),
|
||||||
|
`Longitude` DECIMAL(11,8),
|
||||||
PRIMARY KEY (`Id`),
|
PRIMARY KEY (`Id`),
|
||||||
KEY `Events_MonitorId_idx` (`MonitorId`),
|
KEY `Events_MonitorId_idx` (`MonitorId`),
|
||||||
KEY `Events_StorageId_idx` (`StorageId`),
|
KEY `Events_StorageId_idx` (`StorageId`),
|
||||||
|
@ -683,6 +685,8 @@ CREATE TABLE `Servers` (
|
||||||
`zmaudit` BOOLEAN NOT NULL DEFAULT FALSE,
|
`zmaudit` BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
`zmtrigger` BOOLEAN NOT NULL DEFAULT FALSE,
|
`zmtrigger` BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
`zmeventnotification` BOOLEAN NOT NULL DEFAULT FALSE,
|
`zmeventnotification` BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
|
`Latitude` DECIMAL(10,8),
|
||||||
|
`Longitude` DECIMAL(11,8),
|
||||||
PRIMARY KEY (`Id`)
|
PRIMARY KEY (`Id`)
|
||||||
) ENGINE=@ZM_MYSQL_ENGINE@;
|
) ENGINE=@ZM_MYSQL_ENGINE@;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Servers'
|
||||||
|
AND column_name = 'Latitude'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column Latitude already exists in Servers'",
|
||||||
|
"ALTER TABLE `Servers` ADD `Latitude` DECIMAL(10,8) AFTER `zmeventnotification`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Servers'
|
||||||
|
AND column_name = 'Longitude'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column Longitude already exists in Servers'",
|
||||||
|
"ALTER TABLE `Servers` ADD `Longitude` DECIMAL(10,8) AFTER `Latitude`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Events'
|
||||||
|
AND column_name = 'Latitude'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column Latitude already exists in Events'",
|
||||||
|
"ALTER TABLE `Events` ADD `Latitude` DECIMAL(10,8) AFTER `Locked`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Events'
|
||||||
|
AND column_name = 'Longitude'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column Longitude already exists in Events'",
|
||||||
|
"ALTER TABLE `Events` ADD `Longitude` DECIMAL(10,8) AFTER `Latitude`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
|
@ -0,0 +1,5 @@
|
||||||
|
#map-template {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
position: fixed;
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
* En la variable map esta inicialiando el mapa para ellos usamos la constante L que instancia leaflet para el manejo de mapas.
|
||||||
|
* el setView se usa para decirle a leaflet donde se centrar nuestro mapa y le pasamos lo valores de latitud y longitud, el valor de 10 indica el nivel de zoom por defecto.
|
||||||
|
*/
|
||||||
|
const map = L.map('map-template', {
|
||||||
|
center: L.latLng(44.30597010, -80.39925430),
|
||||||
|
zoom : 8 });
|
||||||
|
|
||||||
|
L.tileLayer(ZM_OPT_GEOLOCATION_TILE_PROVIDER, {
|
||||||
|
attribution: 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
|
||||||
|
maxZoom: 18,
|
||||||
|
id: 'mapbox/streets-v11',
|
||||||
|
tileSize: 512,
|
||||||
|
zoomOffset: -1,
|
||||||
|
accessToken: ZM_OPT_GEOLOCATION_ACCESS_TOKEN,
|
||||||
|
detectRetina: true
|
||||||
|
}).addTo(map);
|
||||||
|
map.invalidateSize();
|
||||||
|
|
||||||
|
//L.Control.geocoder().addTo(map);
|
||||||
|
|
||||||
|
var iconoDesconectada = L.icon({
|
||||||
|
iconUrl: 'skins/classic/graphics/icon-disconnected.png',
|
||||||
|
iconSize: [25, 41], // size of the icon
|
||||||
|
iconAnchor: [13, 41], // point of the icon which will correspond to marker's location
|
||||||
|
});
|
||||||
|
|
||||||
|
var iconoConectada = L.icon({
|
||||||
|
iconUrl: 'skins/classic/graphics/icon-connected.png',
|
||||||
|
iconSize: [25, 41], // size of the icon
|
||||||
|
iconAnchor: [13, 41], // point of the icon which will correspond to marker's location
|
||||||
|
});
|
||||||
|
|
||||||
|
var iconoError = L.icon({
|
||||||
|
iconUrl: 'skins/classic/graphics/icon-error.png',
|
||||||
|
iconSize: [25, 41], // size of the icon
|
||||||
|
iconAnchor: [13, 41], // point of the icon which will correspond to marker's location
|
||||||
|
});
|
||||||
|
|
||||||
|
//-------------Agregado por Matias Figueroa ------------
|
||||||
|
//Funcion para obtener direccion del servidor
|
||||||
|
var wwwUrlPath = window.document.location.href;
|
||||||
|
// Obtengo el directorio después de la dirección del host,
|
||||||
|
var pathName = window.document.location.pathname;
|
||||||
|
var pos = wwwUrlPath.indexOf(pathName);
|
||||||
|
// Dirección del servidor
|
||||||
|
var localhostPath = wwwUrlPath.substring(0, pos);
|
||||||
|
//-------------------Fin agregado------------------
|
||||||
|
|
||||||
|
const server = new Server(Servers[serverId]);
|
||||||
|
|
||||||
|
//const requestURL = server.UrlToApi()+'/monitors.json'+(auth_hash ? '?auth=' + auth_hash : '');
|
||||||
|
const requestURL = 'https://zm.connortechnology.com/api/monitors.json'+(auth_hash ? '?auth=' + auth_hash : '');
|
||||||
|
const request = new XMLHttpRequest();
|
||||||
|
var monitors = {};
|
||||||
|
request.open('GET', requestURL, open);
|
||||||
|
request.responseType = 'json';
|
||||||
|
request.send();
|
||||||
|
|
||||||
|
request.onload = function() {
|
||||||
|
if (!request.response) {
|
||||||
|
alert("Error gettings monitor data");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
monitors = request.response;
|
||||||
|
|
||||||
|
console.log(monitors);
|
||||||
|
|
||||||
|
var cantidadMonitors = monitors.monitors.length;
|
||||||
|
var lat;
|
||||||
|
var long;
|
||||||
|
var nombre;
|
||||||
|
var estado;
|
||||||
|
var fps;
|
||||||
|
var res;
|
||||||
|
var id;
|
||||||
|
var events;
|
||||||
|
var cant_conectadas = 0;
|
||||||
|
var cant_desconectadas = 0;
|
||||||
|
var cant_error = 0;
|
||||||
|
let total_cameras = 0;
|
||||||
|
var div_conectadas = document.getElementById("progress-conectadas");
|
||||||
|
var div_desconectadas = document.getElementById("progress-desconectadas");
|
||||||
|
var div_error = document.getElementById("progress-error");
|
||||||
|
|
||||||
|
for (let i=0, len = monitors.monitors.length; i < len; i++) {
|
||||||
|
const monitor = monitors["monitors"][i]["Monitor"];
|
||||||
|
console.log(monitor);
|
||||||
|
const monitor_status = monitors["monitors"][i]["Monitor_Status"];
|
||||||
|
const event_summary = monitors["monitors"][i]["Event_Summary"];
|
||||||
|
const server = new Server(Servers[monitor.ServerId]);
|
||||||
|
|
||||||
|
id = monitor["Id"];
|
||||||
|
nombre = monitors["monitors"][i]["Monitor"]["Name"];
|
||||||
|
estado = monitors["monitors"][i]["Monitor_Status"]["Status"];
|
||||||
|
fps = monitors["monitors"][i]["Monitor_Status"]["CaptureFPS"];
|
||||||
|
res = monitors["monitors"][i]["Monitor"]["Width"]+"x"+monitors["monitors"][i]["Monitor"]["Height"];
|
||||||
|
events = monitors["monitors"][i]["Event_Summary"]["TotalEvents"];
|
||||||
|
|
||||||
|
if (!(monitor.Latitude && monitor.Longitude)) {
|
||||||
|
console.log("Monitor", monitor.Name, "Has no latitude or longitude");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const url_to_zms = server.UrlToZMS()+'?scale=60&mode=single&monitor='+id+(auth_relay?'&'+auth_relay:'');
|
||||||
|
const popup = monitor.Name+'<br>Resolution: '+res+'<br>FPS: '+fps+'<br><a href="?view=watch&mid='+id+'"><img style="width: 100%;" src="'+url_to_zms+'"/></a><br/>Events: '+events;
|
||||||
|
if (event_summary.TotalEvents > 0) {
|
||||||
|
if (monitor_status.Status == 'Connected') {
|
||||||
|
L.marker([monitor.Latitude, monitor.Longitude], {icon: iconoConectada})
|
||||||
|
.addTo(map).bindPopup(popup);
|
||||||
|
cant_conectadas += 1;
|
||||||
|
} else {
|
||||||
|
L.marker([monitor.Latitude, monitor.Longitude], {icon: iconoDesconectada})
|
||||||
|
.addTo(map).bindPopup(popup);
|
||||||
|
cant_desconectadas += 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
L.marker([monitor.Latitude, monitor.Longitude], {icon: iconoError})
|
||||||
|
.addTo(map).bindPopup(popup);
|
||||||
|
cant_error += 1;
|
||||||
|
}
|
||||||
|
total_cameras += 1;
|
||||||
|
} // end foreach monitor
|
||||||
|
var percent_conectadas = Number.parseFloat(((cant_conectadas*100)/total_cameras)).toFixed(2);
|
||||||
|
var percent_desconectadas = Number.parseFloat(((cant_desconectadas*100)/total_cameras)).toFixed(2);
|
||||||
|
var percent_error = Number.parseFloat(((cant_error*100)/total_cameras)).toFixed(2);
|
||||||
|
|
||||||
|
div_conectadas.style.width = percent_conectadas+"%";
|
||||||
|
div_conectadas.innerHTML = percent_conectadas+"%";
|
||||||
|
document.getElementById("progress-conectadas-titulo").style.width = percent_conectadas+"%";
|
||||||
|
document.getElementById("progress-conectadas-titulo").innerHTML = "CONECTADAS";
|
||||||
|
|
||||||
|
div_desconectadas.style.width = percent_desconectadas+"%";
|
||||||
|
div_desconectadas.innerHTML = percent_desconectadas+"%";
|
||||||
|
document.getElementById("progress-desconectadas-titulo").style.width = percent_desconectadas+"%";
|
||||||
|
document.getElementById("progress-desconectadas-titulo").innerHTML = "DESCONECTADAS";
|
||||||
|
|
||||||
|
div_error.style.width = percent_error+"%";
|
||||||
|
div_error.innerHTML = percent_error+"%";
|
||||||
|
document.getElementById("progress-error-titulo").style.width = percent_error+"%";
|
||||||
|
document.getElementById("progress-error-titulo").innerHTML = "ERROR";
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
//
|
||||||
|
// ZoneMinder map view
|
||||||
|
// Copyright (C) 2022 ZoneMinder Inc
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
//
|
||||||
|
xhtmlHeaders(__FILE__, translate('Console'));
|
||||||
|
getBodyTopHTML();
|
||||||
|
$navbar = getNavBarHTML();
|
||||||
|
echo $navbar ?>
|
||||||
|
<div id="content">
|
||||||
|
<div id="statistics">
|
||||||
|
<div class="progress">
|
||||||
|
<div id="progress-connected-title" class="progress-bar" role="progressbar" style="width: 0%; background: #15ad10 !important; font-weight: bold; " aria-valuenow="15" aria-valuemin="0" aria-valuemax="100" title="Connected"></div>
|
||||||
|
<div id="progress-disconnected-title" class="progress-bar bg-success" role="progressbar" style="width: 0%; background: #dd4042 !important; font-weight: bold; " aria-valuenow="30" aria-valuemin="0" aria-valuemax="100" title="Disconnected"></div>
|
||||||
|
<div id="progress-error-title" class="progress-bar bg-info" role="progressbar" style="width: 0%; background: #797979 !important; font-weight: bold; " aria-valuenow="20" aria-valuemin="0" aria-valuemax="100" title="No Connection"></div>
|
||||||
|
</div>
|
||||||
|
<div class="progress">
|
||||||
|
<div id="progress-connected" class="progress-bar" role="progressbar" style="width: 0%; background: #15ad10 !important; font-weight: bold; font-size: medium;" aria-valuenow="15" aria-valuemin="0" aria-valuemax="100" title="Connected"></div>
|
||||||
|
<div id="progress-disconnected" class="progress-bar bg-success" role="progressbar" style="width: 0%; background: #dd4042 !important; font-weight: bold; font-size: medium;" aria-valuenow="30" aria-valuemin="0" aria-valuemax="100" title="Disconnected"></div>
|
||||||
|
<div id="progress-error" class="progress-bar bg-info" role="progressbar" style="width: 0%; background: #797979 !important; font-weight: bold; font-size: medium;" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100" title="No Connection"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="map-template"></div>
|
||||||
|
<?php
|
||||||
|
echo output_script_if_exists(array('js/leaflet/leaflet.js'), false);
|
||||||
|
echo output_link_if_exists(array('js/leaflet/leaflet.css'), false);
|
||||||
|
xhtmlFooter()
|
||||||
|
?>
|
Loading…
Reference in New Issue