Merge branch 'location'

This commit is contained in:
Isaac Connor 2020-09-28 09:33:28 -04:00
commit 0a4a144bbc
8 changed files with 153 additions and 2 deletions

View File

@ -536,6 +536,8 @@ CREATE TABLE `Monitors` (
`ArchivedEventDiskSpace` bigint default NULL,
`ZoneCount` TINYINT NOT NULL DEFAULT 0,
`Refresh` int(10) unsigned default NULL,
`Latitude` DECIMAL(10,8),
`Longitude` DECIMAL(10,8),
PRIMARY KEY (`Id`)
) ENGINE=@ZM_MYSQL_ENGINE@;

23
db/zm_update-1.35.7.sql Normal file
View File

@ -0,0 +1,23 @@
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Monitors'
AND column_name = 'Latitude'
) > 0,
"SELECT 'Column Latitude already exists in Monitors'",
"ALTER TABLE `Monitors` ADD `Latitude` DECIMAL(10,8) AFTER `Refresh`"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Monitors'
AND column_name = 'Longitude'
) > 0,
"SELECT 'Column Longitude already exists in Monitors'",
"ALTER TABLE `Monitors` ADD `Longitude` DECIMAL(10,8) AFTER `Latitude`"
));
PREPARE stmt FROM @s;
EXECUTE stmt;

View File

@ -479,6 +479,33 @@ our @options = (
type => $types{string},
category => 'system',
},
{
name => 'ZM_OPT_USE_GEOLOCATION',
description => 'Add geolocation features to ZoneMinder.',
help => 'Whether or not to enable Latitude/Longitude settings on Monitors and enable mapping options.',
type => $types{boolean},
category => 'system',
},
{
name => 'ZM_OPT_GEOLOCATION_TILE_PROVIDER',
description => 'Tile provider to use for maps.',
help => 'OpenStreetMaps does not itself provide the images to use in the map. There are many to choose from. Mapbox.com is one example that offers free tiles and has been tested during development of this feature.',
requires => [
{name=>'ZM_OPT_USE_GEOLOCATION', value=>'yes'}
],
type => $types{string},
category => 'system',
},
{
name => 'ZM_OPT_GEOLOCATION_ACCESS_TOKEN',
description => 'Access Token for the tile provider used for maps.',
help => 'OpenStreetMaps does not itself provide the images to use in the map. There are many to choose from. Mapbox.com is one example that offers free tiles and has been tested during development of this feature. You must go to mapbox.com and sign up and get an access token and cutnpaste it here.',
requires => [
{name=>'ZM_OPT_USE_GEOLOCATION', value=>'yes'}
],
type => $types{string},
category => 'system',
},
{
name => 'ZM_SYSTEM_SHUTDOWN',
default => 'true',

View File

@ -129,6 +129,8 @@ class Monitor extends ZM_Object {
'Refresh' => null,
'DefaultCodec' => 'auto',
'GroupIds' => array('default'=>array(), 'do_not_update'=>1),
'Latitude' => null,
'Longitude' => null,
);
private $status_fields = array(
'Status' => null,

View File

@ -39,12 +39,29 @@ function xhtmlHeaders($file, $title) {
$baseViewCssPhpFile = getSkinFile('/css/base/views/'.$basename.'.css.php');
$viewCssPhpFile = getSkinFile('/css/'.$css.'/views/'.$basename.'.css.php');
function output_link_if_exists($files) {
function output_link_if_exists($files, $cache_bust=true) {
global $skin;
$html = array();
foreach ( $files as $file ) {
if ( getSkinFile($file) ) {
if ( $cache_bust ) {
$html[] = '<link rel="stylesheet" href="'.cache_bust('skins/'.$skin.'/'.$file).'" type="text/css"/>';
} else {
$html[] = '<link rel="stylesheet" href="skins/'.$skin.'/'.$file.'" type="text/css"/>';
}
}
}
$html[] = ''; // So we ge a trailing \n
return implode(PHP_EOL, $html);
}
function output_script_if_exists($files, $cache_bust=true) {
global $skin;
$html = array();
foreach ( $files as $file ) {
if ( $cache_bust ) {
$html[] = '<script src="'.cache_bust('skins/'.$skin.'/'.$file).'"></script>';
} else {
$html[] = '<script src="skins/'.$skin.'/'.$file.'"></script>';
}
}
$html[] = ''; // So we ge a trailing \n
@ -56,6 +73,9 @@ function xhtmlHeaders($file, $title) {
foreach ( $files as $file ) {
$html[] = '<link rel="stylesheet" href="'.cache_bust($file).'" type="text/css"/>';
}
if ( ! count($html) ) {
ZM\Warning("No files found for $files");
}
$html[] = ''; // So we ge a trailing \n
return implode(PHP_EOL, $html);
}
@ -109,6 +129,8 @@ if ( $css != 'base' )
echo output_link_if_exists(array('/css/base/views/control.css'));
if ( $css != 'base' )
echo output_link_if_exists(array('/css/'.$css.'/views/control.css'));
} else if ( $basename == 'monitor' ) {
echo output_link_if_exists(array('js/leaflet/leaflet.css'), false);
}
?>
<style>
@ -902,7 +924,10 @@ function xhtmlFooter() {
// This is used in the log popup for the export function. Not sure if it's used anywhere else
?>
<script src="<?php echo cache_bust('js/overlay.js') ?>"></script>
<?php } ?>
<?php
} else if ( $basename == 'monitor' ) {
echo output_script_if_exists(array('js/leaflet/leaflet.js'), false);
} ?>
<script nonce="<?php echo $cspNonce; ?>">$j('.chosen').chosen();</script>
</body>
</html>

View File

@ -203,6 +203,33 @@ function initPage() {
evt.preventDefault();
window.location.assign('?view=console');
});
if ( ZM_OPT_USE_GEOLOCATION ) {
if ( window.L ) {
var form = document.getElementById('contentForm');
var latitude = form.elements['newMonitor[Latitude]'].value;
var longitude = form.elements['newMonitor[Longitude]'].value;
console.log("lat: " + latitude + ', long:'+longitude);
map = L.map('LocationMap', {
center: L.latLng(latitude, longitude),
zoom: 13,
onclick: function() {
alert('click');
}
});
L.tileLayer(ZM_OPT_GEOLOCATION_TILE_PROVIDER, {
attribution: 'Map data &copy; <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,
}).addTo(map);
L.marker([latitude, longitude]).addTo(map);
} else {
console.log('Location turned on but leaflet not installed.');
}
} // end if ZM_OPT_USE_GEOLOCATION
} // end function initPage()
function change_WebColour() {
@ -242,4 +269,19 @@ function update_estimated_ram_use() {
document.getElementById('estimated_ram_use').innerHTML = human_filesize(buffer_count * width * height * colours, 0);
}
function updateLatitudeAndLongitude(latitude, longitude) {
var form = document.getElementById('contentForm');
form.elements['newMonitor[Latitude]'].value = latitude;
form.elements['newMonitor[Longitude]'].value = longitude;
}
function getLocation() {
if ('geolocation' in navigator) {
navigator.geolocation.getCurrentPosition((position) => {
updateLatitudeAndLongitude(position.coords.latitude, position.coords.longitude);
});
} else {
console.log("Geolocation not available");
}
}
window.addEventListener('DOMContentLoaded', initPage);

View File

@ -1,3 +1,10 @@
var ZM_OPT_USE_GEOLOCATION = '<?php echo ZM_OPT_USE_GEOLOCATION ?>';
<?php
if ( ZM_OPT_USE_GEOLOCATION ) {
echo 'var ZM_OPT_GEOLOCATION_TILE_PROVIDER=\''.ZM_OPT_GEOLOCATION_TILE_PROVIDER.'\''.PHP_EOL;
echo 'var ZM_OPT_GEOLOCATION_ACCESS_TOKEN=\''.ZM_OPT_GEOLOCATION_ACCESS_TOKEN.'\''.PHP_EOL;
}
?>
var optControl = <?php echo ZM_OPT_CONTROL ?>;
var hasOnvif = <?php echo ZM_HAS_ONVIF ?>;
var defaultAspectRatio = '<?php echo ZM_DEFAULT_ASPECT_RATIO ?>';

View File

@ -404,6 +404,7 @@ if ( $monitor->Type() != 'WebSite' ) {
if ( ZM_OPT_X10 )
$tabs['x10'] = translate('X10');
$tabs['misc'] = translate('Misc');
$tabs['location'] = translate('Location');
}
if ( isset($_REQUEST['tab']) )
@ -1151,6 +1152,28 @@ echo htmlSelect('newMonitor[ReturnLocation]', $return_options, $monitor->ReturnL
<?php
break;
}
case 'location':
?>
<tr>
<td class="text-right pr-3"><?php echo translate('Latitude') ?></td>
<td><input type="number" name="newMonitor[Latitude]" step="any" value="<?php echo $monitor->Latitude() ?>" min="-90" max="90"/></td>
</tr>
<tr>
<td class="text-right pr-3"><?php echo translate('Longitude') ?></td>
<td><input type="number" name="newMonitor[Longitude]" step="any" value="<?php echo $monitor->Longitude() ?>" min="-180" max="180"/></td>
</tr>
<tr>
<td class="text-right pr-3"><?php echo translate('Longitude') ?></td>
<td><button type="button" data-on-click="getLocation"><?php echo translate('GetCurrentLocation') ?></button></td>
</tr>
<tr>
<td colspan="2"><div id="LocationMap" style="height: 500px; width: 500px;"></div></td>
</tr>
<?php
break;
default :
ZM\Error("Unknown tab $tab");
} // end switch tab
?>
</tbody>