forked from kamba4/sunders
moved files into subdirs
This commit is contained in:
parent
bf6ccf5094
commit
10fcf55b10
242 changed files with 23 additions and 0 deletions
457
web/www/sunders/js/leafletembed_functions.js
Normal file
457
web/www/sunders/js/leafletembed_functions.js
Normal file
|
|
@ -0,0 +1,457 @@
|
|||
var ajaxRequest;
|
||||
var map;
|
||||
var osmTiles;
|
||||
var plotList;
|
||||
var plotLayers = [];
|
||||
var footprintPolygon;
|
||||
|
||||
// Returns the value of URL parameter #name.
|
||||
function getUrlParameter(name) {
|
||||
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
|
||||
var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
|
||||
var results = regex.exec(window.location.search);
|
||||
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
|
||||
}
|
||||
|
||||
// Draw the map for the first time.
|
||||
function initMap() {
|
||||
// Set up the AJAX request.
|
||||
ajaxRequest=getXmlHttpRequest();
|
||||
if (ajaxRequest == null) {
|
||||
alert('This browser does not support HTTP requests.');
|
||||
return;
|
||||
}
|
||||
|
||||
// --- URLSearchParams is not supported by all browsers ---
|
||||
// var urlParams = new URLSearchParams(window.location.search);
|
||||
// var embedMode = urlParams.get('emb');
|
||||
var embedMode = getUrlParameter('emb');
|
||||
if (embedMode !== '') {
|
||||
embedMode = '\'' + embedMode + '\'';
|
||||
}
|
||||
|
||||
// Set up the OSM tile layer with correct attribution
|
||||
var osmUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
// var osmUrl = '';
|
||||
var dataAttrib = '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap contributors</a>';
|
||||
var permalink = '<a href="#" onClick="permalink(null, ' + embedMode + ');return false;">Permalink</a>';
|
||||
var mapAttrib = dataAttrib + ' | ' + permalink;
|
||||
osmTiles = new L.TileLayer(osmUrl, {minZoom: 4, maxZoom: 19, attribution: mapAttrib});
|
||||
|
||||
// Set up the map.
|
||||
map = new L.Map('map', {maxZoom: 19});
|
||||
map.zoomControl.setPosition('topleft');
|
||||
map.attributionControl.setPosition('bottomleft');
|
||||
map.setView(new L.LatLng(initialLat, initialLon), initialZoom);
|
||||
map.addLayer(osmTiles);
|
||||
addPlots();
|
||||
map.on('moveend', onMapMoved);
|
||||
}
|
||||
|
||||
// Return XMLHttpRequest.
|
||||
function getXmlHttpRequest() {
|
||||
if (window.XMLHttpRequest) { return new XMLHttpRequest(); }
|
||||
if (window.ActiveXObject) { return new ActiveXObject('Microsoft.XMLHTTP'); }
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create an URL for the current location and use this URL to reload the map.
|
||||
function getPermalink(switchToLanguage, embedMode) {
|
||||
var center = map.getCenter();
|
||||
var lat = Math.round(center.lat * 100000000) / 100000000;
|
||||
var lon = Math.round(center.lng * 100000000) / 100000000;
|
||||
var serverUrl = location.protocol + '//' + location.host + location.pathname;
|
||||
var embQuery = '';
|
||||
|
||||
if (switchToLanguage != null) {
|
||||
var supportedLanguages = [ 'de', 'en', 'es', 'fr', 'it', 'ru' ];
|
||||
var urlLanguage = (serverUrl.slice(-3)).substring(0, 2);
|
||||
|
||||
if ((serverUrl.slice(-4)).substring(0, 1) == '/' && supportedLanguages.includes(urlLanguage)) {
|
||||
serverUrl = serverUrl.substring(0, serverUrl.length - 3);
|
||||
}
|
||||
serverUrl = serverUrl + switchToLanguage;
|
||||
}
|
||||
|
||||
if (embedMode != null) {
|
||||
embQuery = '&emb=' + embedMode;
|
||||
}
|
||||
|
||||
var permalinkUrl = serverUrl + '?lat=' + lat + '&lon=' + lon + '&zoom=' + map.getZoom() + embQuery;
|
||||
|
||||
return permalinkUrl;
|
||||
}
|
||||
|
||||
// Use the permalink URL to reload the map.
|
||||
function permalink(switchToLanguage, embedMode) {
|
||||
window.location = getPermalink(switchToLanguage, embedMode);
|
||||
}
|
||||
|
||||
// Add plots to map.
|
||||
function addPlots() {
|
||||
var bounds = map.getBounds();
|
||||
var boundsSW = bounds.getSouthWest();
|
||||
var boundsNE = bounds.getNorthEast();
|
||||
// extend bounds, to also draw cameras that are located just outside the screen, but whose observation area may be inside
|
||||
boundsSW.lng -= 0.001;
|
||||
boundsSW.lat -= 0.001;
|
||||
boundsNE.lng += 0.001;
|
||||
boundsNE.lat += 0.001;
|
||||
var size = map.getSize();
|
||||
var url = 'camera.php?bbox=' + boundsSW.lng + ',' + boundsSW.lat + ',' + boundsNE.lng + ',' + boundsNE.lat + '&zoom=' + map.getZoom() + '&width=' + size.x + '&height=' + size.y;
|
||||
ajaxRequest.onreadystatechange = onStateChanged;
|
||||
ajaxRequest.open('GET', url, true);
|
||||
ajaxRequest.send(null);
|
||||
}
|
||||
|
||||
// Remove all markers from map.
|
||||
function removeMarkers() {
|
||||
for (i=0; i<plotLayers.length; i++) {
|
||||
map.removeLayer(plotLayers[i]);
|
||||
}
|
||||
if (footprintPolygon != null) {
|
||||
map.removeLayer(footprintPolygon);
|
||||
}
|
||||
plotLayers=[];
|
||||
}
|
||||
|
||||
// Things to do when the map has been moved.
|
||||
function onMapMoved(e) {
|
||||
addPlots();
|
||||
}
|
||||
|
||||
// Things to do when a marker has been clicked.
|
||||
function onClick(e) {
|
||||
e.target.openPopup();
|
||||
}
|
||||
|
||||
// Things to do when the readystatechange event is fired.
|
||||
function onStateChanged() {
|
||||
if (ajaxRequest.readyState == 4) { // 0 = UNSENT, 1 = OPENED, 2 = HEADERS_RECEIVED, 3 = LOADING, 4 = DONE
|
||||
if (ajaxRequest.status == 200) { // 200 = OK, 404 = Page not found
|
||||
plotList = eval('(' + ajaxRequest.responseText + ')');
|
||||
removeMarkers();
|
||||
for (i=0; i<plotList.length; i++) {
|
||||
var plotLatLng;
|
||||
var plotMarker = '';
|
||||
|
||||
if (plotList[i].error) {
|
||||
alert(plotList[i].error);
|
||||
}
|
||||
// Add label with number of composite cameras.
|
||||
else if (plotList[i].multi == 'yes') {
|
||||
plotLatLng = new L.LatLng(plotList[i].lat, plotList[i].lon);
|
||||
plotMarker = getPlotMarkerMulti(plotList[i], plotLatLng);
|
||||
}
|
||||
// Add camera icon.
|
||||
else {
|
||||
try {
|
||||
plotLatLng = new L.LatLng(plotList[i].lat, plotList[i].lon);
|
||||
var plotType = getPlotType(plotList[i]);
|
||||
plotMarker = getPlotMarkerCamera(plotList[i], plotLatLng, plotType);
|
||||
|
||||
// Get camera height to draw camera's field of view.
|
||||
var cameraHeight = getCameraHeight(plotList[i]);
|
||||
// Get camera direction to draw camera's field of view.
|
||||
var cameraDirection = getCameraDirection(plotList[i]);
|
||||
|
||||
// Draw fixed camera's field of view and add it to map.
|
||||
var cameraType = plotList[i]['camera:type'];
|
||||
|
||||
if (cameraType == 'fixed' || cameraType == 'static' || cameraType == 'dome') {
|
||||
var focusColor = getFocusColor(plotType);
|
||||
if (cameraType == 'fixed' || cameraType == 'static') {
|
||||
if (cameraDirection != null) {
|
||||
// Get camera angle to draw camera's field of view.
|
||||
var cameraAngle = getCameraAngle(plotList[i]);
|
||||
var cameraAngleType = getCameraAngleType(cameraAngle);
|
||||
|
||||
if (cameraAngleType == 'sky') {
|
||||
// Draw no focus.
|
||||
} else if (cameraAngleType == 'ground') {
|
||||
// Draw circle focus.
|
||||
var focusRadius = getRadiusForHeight(cameraHeight) / 12;
|
||||
var plotFocus = drawCameraFocusDome(plotLatLng, focusRadius, focusColor);
|
||||
} else {
|
||||
if (cameraAngleType == 'opposite') {
|
||||
cameraDirection = cameraDirection + 180;
|
||||
}
|
||||
var cameraAngleFactor = getCameraAngleFactor(cameraAngle);
|
||||
var focusRadius = getRadiusForHeight(cameraHeight) * cameraAngleFactor;
|
||||
var plotFocus = drawCameraFocusFixed(plotLatLng, cameraDirection, focusRadius, 60, focusColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Draw dome's field of view and add it to map.
|
||||
else if (cameraType == 'dome') {
|
||||
var focusRadius = getRadiusForHeight(cameraHeight);
|
||||
if (isNumeric(cameraDirection)) {
|
||||
var plotFocus = drawCameraFocusFixed(plotLatLng, cameraDirection, focusRadius, 180, focusColor);
|
||||
} else {
|
||||
var plotFocus = drawCameraFocusDome(plotLatLng, focusRadius, focusColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add camera's field of view.
|
||||
map.addLayer(plotFocus);
|
||||
plotLayers.push(plotFocus);
|
||||
|
||||
// Add camera details to camera marker.
|
||||
addCameraDetailsData(plotMarker, plotList[i]);
|
||||
} catch(e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (plotMarker !== '') {
|
||||
map.addLayer(plotMarker);
|
||||
plotLayers.push(plotMarker);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get label with number of composite cameras.
|
||||
function getPlotMarkerMulti(plot, plotLatLng) {
|
||||
if (plot.poly) {
|
||||
/* Build string with coordinates for every polygon corner,
|
||||
e.g. [{"lat":"42.9992737", "lon":"23.2704823"},{"lat":"42.9974195", "lon":"23.2713401"},{"lat":"42.9993203", "lon":"23.2706528"}] */
|
||||
var polygonCoordinates = '[';
|
||||
var separator = '';
|
||||
for (x in plot.poly) {
|
||||
polygonCoordinates = polygonCoordinates
|
||||
+ separator
|
||||
+ '{"lat":"' + plot.poly[x]['lat'] + '",'
|
||||
+ ' "lon":"' + plot.poly[x]['lon'] + '"}';
|
||||
separator = ',';
|
||||
}
|
||||
polygonCoordinates = polygonCoordinates + ']';
|
||||
countTxt = '<span onclick="drawFootprint(\'' + polygonCoordinates + '\')">' + plot.count + '</span>';
|
||||
} else {
|
||||
countTxt = plot.count;
|
||||
}
|
||||
|
||||
plotIcon = eval('compositeCamerasIcon');
|
||||
|
||||
return(
|
||||
new L.Marker(plotLatLng, { icon: plotIcon }).bindTooltip(countTxt, {
|
||||
permanent: true,
|
||||
interactive: true,
|
||||
direction: 'right',
|
||||
className: 'composite-cameras-label'
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/* Draw a footprint that represents the area composite cameras are located in.
|
||||
polygonCoordinates is a string like this:
|
||||
[{"lat":"42.9992737", "lon":"23.2704823"},{"lat":"42.9974195", "lon":"23.2713401"},{"lat":"42.9993203", "lon":"23.2706528"}] */
|
||||
function drawFootprint(polygonCoordinates) {
|
||||
polygonCoordinates = JSON.parse(polygonCoordinates);
|
||||
var polygonPoints = [];
|
||||
for (x in eval(polygonCoordinates)) {
|
||||
polygonPoints.push(new L.LatLng(polygonCoordinates[x]['lat'], polygonCoordinates[x]['lon']));
|
||||
}
|
||||
if (footprintPolygon != null) {
|
||||
map.removeLayer(footprintPolygon);
|
||||
}
|
||||
footprintPolygon = L.polygon(polygonPoints, { color:'#0192d9', weight : 1, fillOpacity:0.1 });
|
||||
footprintPolygon.addTo(map);
|
||||
}
|
||||
|
||||
// Get plot type (public, outdoor, indoor)
|
||||
function getPlotType(plot) {
|
||||
return(plot['surveillance']);
|
||||
}
|
||||
|
||||
// Add camera icon.
|
||||
function getPlotMarkerCamera(plot, plotLatLng, plotType) {
|
||||
// Get icon name for current camera or guard: fixed, dome, guard
|
||||
var iconName = 'cam';
|
||||
if (plot['camera:type'] == 'fixed') {
|
||||
iconName = 'fixed';
|
||||
} else if (plot['camera:type'] == 'panning') {
|
||||
iconName = 'panning';
|
||||
} else if (plot['camera:type'] == 'dome') {
|
||||
iconName = 'dome';
|
||||
} else if (plot['surveillance:type'] == 'guard') {
|
||||
iconName = 'guard';
|
||||
}
|
||||
|
||||
/* Add postfix for cameras and guards according to their location:
|
||||
Red (public outdoor areas), Blue (private outdoor areas), Green (indoor) */
|
||||
if (plotType == 'public') {
|
||||
iconName = iconName + 'Red';
|
||||
} else if (plotType == 'indoor' ) {
|
||||
iconName = iconName + 'Green';
|
||||
} else if (plotType == 'outdoor' ) {
|
||||
iconName = iconName + 'Blue';
|
||||
}
|
||||
|
||||
// Get icon name for current traffic camera
|
||||
if (plot['surveillance:type'] == 'ALPR' || plotType == 'red_light' || plotType == 'level_crossing' || plotType == 'speed_camera') {
|
||||
iconName = 'traffic';
|
||||
}
|
||||
|
||||
// Add prefix for cameras and guards marked with a 'fixme' key: todo_
|
||||
if (plot['fixme'] != null) {
|
||||
iconName = 'todo_' + iconName;
|
||||
}
|
||||
|
||||
iconName = iconName + 'Icon';
|
||||
plotIcon = eval(iconName); // see leafletembed_icons.js
|
||||
return(new L.Marker(plotLatLng, {icon : plotIcon}));
|
||||
}
|
||||
|
||||
// Get camera height.
|
||||
function getCameraHeight(plot) {
|
||||
var cameraHeight = plot['height'];
|
||||
if (! isNumeric(cameraHeight)) {
|
||||
cameraHeight = 5;
|
||||
} else if (cameraHeight < 3) {
|
||||
cameraHeight = 3;
|
||||
} else if (cameraHeight > 12) {
|
||||
cameraHeight = 12;
|
||||
}
|
||||
return(cameraHeight);
|
||||
}
|
||||
|
||||
// Get focus radius for height.
|
||||
function getRadiusForHeight(cameraHeight) {
|
||||
return(cameraHeight * 7);
|
||||
}
|
||||
|
||||
// Get camera direction.
|
||||
function getCameraDirection(plot) {
|
||||
var cameraDirection = plot['camera:direction'];
|
||||
if (cameraDirection == null) {
|
||||
cameraDirection = plot['direction'];
|
||||
if (cameraDirection == null) {
|
||||
cameraDirection = plot['surveillance:direction'];
|
||||
}
|
||||
}
|
||||
if (cameraDirection == 'N') {
|
||||
cameraDirection = 0;
|
||||
} else if (cameraDirection == 'NE') {
|
||||
cameraDirection = 45;
|
||||
} else if (cameraDirection == 'E') {
|
||||
cameraDirection = 90;
|
||||
} else if (cameraDirection == 'SE') {
|
||||
cameraDirection = 135;
|
||||
} else if (cameraDirection == 'S') {
|
||||
cameraDirection = 180;
|
||||
} else if (cameraDirection == 'SW') {
|
||||
cameraDirection = 225;
|
||||
} else if (cameraDirection == 'W') {
|
||||
cameraDirection = 270;
|
||||
} else if (cameraDirection == 'NW') {
|
||||
cameraDirection = 315;
|
||||
}
|
||||
if (isNumeric(cameraDirection)) {
|
||||
return(cameraDirection * 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Get focus color.
|
||||
function getFocusColor(plotType) {
|
||||
var focusColor = '#6c5d53';
|
||||
if (plotType == 'public') {
|
||||
focusColor = '#d40055';
|
||||
} else if (plotType == 'indoor' ) {
|
||||
focusColor = '#00d455';
|
||||
} else if (plotType == 'outdoor' ) {
|
||||
focusColor = '#0055d4';
|
||||
}
|
||||
return(focusColor);
|
||||
}
|
||||
|
||||
// Get camera angle.
|
||||
function getCameraAngle(plot) {
|
||||
// 0° = horizontal view
|
||||
// 90° = vertical view to bottom
|
||||
// 180° = horizontal view to opposite direction
|
||||
// 270° = vertical view to sky
|
||||
// If camera angle is between 90° and 270° the camera looks to the oposite direction.
|
||||
var cameraAngle = plot['camera:angle'];
|
||||
if (cameraAngle < 0) {
|
||||
cameraAngle = -cameraAngle;
|
||||
}
|
||||
if (cameraAngle == null || !isNumeric(cameraAngle)) {
|
||||
cameraAngle = 15;
|
||||
}
|
||||
return(cameraAngle);
|
||||
}
|
||||
|
||||
// Get camera angle type.
|
||||
function getCameraAngleType(cameraAngle) {
|
||||
var cameraAngleType = 'regular';
|
||||
var tmpAngle = (cameraAngle * 1 + 90) / 180
|
||||
var quotient = Math.floor(tmpAngle);
|
||||
var remainder = tmpAngle % 1;
|
||||
if (quotient % 2 != 0) {
|
||||
cameraAngleType = 'opposite';
|
||||
}
|
||||
if ((cameraAngleType == 'regular' && remainder >= 175.5 / 180) || (cameraAngleType == 'opposite' && remainder <= 4.5 / 180)) {
|
||||
cameraAngleType = 'ground';
|
||||
} else if ((cameraAngleType == 'opposite' && remainder >= 175.5 / 180) || (cameraAngleType == 'regular' && remainder <= 4.5 / 180)) {
|
||||
cameraAngleType = 'sky';
|
||||
}
|
||||
return(cameraAngleType);
|
||||
}
|
||||
|
||||
// Get camera angle factor.
|
||||
function getCameraAngleFactor(angle) {
|
||||
cameraAngle = Math.cos(((angle) * 207986.0) / 11916720);
|
||||
return(cameraAngle);
|
||||
}
|
||||
|
||||
// Draw fixed camera focus.
|
||||
function drawCameraFocusFixed(plotLatLng, focusDirection, focusRadius, focusSize, focusColor) {
|
||||
return(new L.semiCircle(plotLatLng, { radius: focusRadius, weight:1, color:focusColor, fillOpacity:0.1 }).setDirection(focusDirection, focusSize));
|
||||
}
|
||||
|
||||
|
||||
// Draw dome focus.
|
||||
function drawCameraFocusDome(plotLatLng, focusRadius, focusColor) {
|
||||
return(new L.Circle(plotLatLng, focusRadius, { weight:1, color:focusColor, fillOpacity:0.1 }));
|
||||
}
|
||||
|
||||
// Add camera popup to camera marker.
|
||||
function addCameraDetailsData(plotMarker, plot) {
|
||||
popupDataTable = '<table class="popup-content">'
|
||||
+ '<tr><td>id</td><td><a href="https://www.openstreetmap.org/node/' + (plot.id) + '">' + (plot.id) + '</a></td></tr>'
|
||||
// + '<tr><td>user osm</td><td>' + (plot.userid) + '</td></tr>'
|
||||
+ '<tr><td>latitude</td><td>' + (plot.lat) + '</td></tr>'
|
||||
+ '<tr><td>longitude</td><td>' + (plot.lon) + '</td></tr>';
|
||||
for (x in plot) {
|
||||
if (plot[x] !== '' && x != 'multi' && x != 'id' && x != 'userid' && x != 'lat' && x != 'lon') {
|
||||
popupDataTable = popupDataTable + '<tr><td>' + x + '</td><td>';
|
||||
var descr = plot[x];
|
||||
if (descr.substr(0, 4) == 'http') {
|
||||
var suffix = descr.slice(-3).toLowerCase();
|
||||
if (suffix == 'jpg' || suffix == 'gif' || suffix == 'png') {
|
||||
popupDataTable = popupDataTable + '<a href="' + descr + '"><img alt="Link" src="' + descr + '" width="200"/></a>';
|
||||
} else {
|
||||
popupDataTable = popupDataTable + '<a href="' + descr + '">Link</a>';
|
||||
}
|
||||
} else {
|
||||
popupDataTable = popupDataTable + plot[x];
|
||||
}
|
||||
popupDataTable = popupDataTable + '</td></tr>';
|
||||
}
|
||||
}
|
||||
popupDataTable = popupDataTable +'</table>';
|
||||
|
||||
plotMarker.bindPopup(popupDataTable, {autoPan:false, maxWidth:400});
|
||||
|
||||
plotMarker.on('click', onClick);
|
||||
}
|
||||
|
||||
function isNumeric(s) {
|
||||
var intRegex = /^\d+$/;
|
||||
var floatRegex = /^((\d+(\.\d *)?)|((\d*\.)?\d+))$/;
|
||||
return ((intRegex.test(s) || floatRegex.test(s)));
|
||||
}
|
||||
|
||||
initMap()
|
||||
313
web/www/sunders/js/leafletembed_icons.js
Normal file
313
web/www/sunders/js/leafletembed_icons.js
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
/* Label with number of composite cameras. */
|
||||
var compositeCamerasIcon = L.icon({
|
||||
iconUrl: 'images/icon.png',
|
||||
iconSize: [0, 0],
|
||||
iconAnchor: [0, 0],
|
||||
labelAnchor: [-6, 0]
|
||||
});
|
||||
|
||||
/* Gray icons for non-specific cameras and guards. */
|
||||
var camIcon = L.icon({
|
||||
iconUrl: 'images/cam.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var fixedIcon = L.icon({
|
||||
iconUrl: 'images/fixed.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var panningIcon = L.icon({
|
||||
iconUrl: 'images/panning.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var domeIcon = L.icon({
|
||||
iconUrl: 'images/dome.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var guardIcon = L.icon({
|
||||
iconUrl: 'images/guard.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var trafficIcon = L.icon({
|
||||
iconUrl: 'images/traffic.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
/* Blue icons for outdoor cameras and guards.
|
||||
Those cameras and guards surveil only private, i.e. non-public areas. */
|
||||
var camBlueIcon = L.icon({
|
||||
iconUrl: 'images/camBlue.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var fixedBlueIcon = L.icon({
|
||||
iconUrl: 'images/fixedBlue.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var panningBlueIcon = L.icon({
|
||||
iconUrl: 'images/panningBlue.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var domeBlueIcon = L.icon({
|
||||
iconUrl: 'images/domeBlue.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var guardBlueIcon = L.icon({
|
||||
iconUrl: 'images/guardBlue.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
/* Green icons for indoor cameras and guards. */
|
||||
var camGreenIcon = L.icon({
|
||||
iconUrl: 'images/camGreen.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var fixedGreenIcon = L.icon({
|
||||
iconUrl: 'images/fixedGreen.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var panningGreenIcon = L.icon({
|
||||
iconUrl: 'images/panningGreen.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var domeGreenIcon = L.icon({
|
||||
iconUrl: 'images/domeGreen.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var guardGreenIcon = L.icon({
|
||||
iconUrl: 'images/guardGreen.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
/* Red icons for outdoor cameras and guards.
|
||||
Those cameras and guards surveil public, i.e. non-private areas. */
|
||||
var camRedIcon = L.icon({
|
||||
iconUrl: 'images/camRed.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var fixedRedIcon = L.icon({
|
||||
iconUrl: 'images/fixedRed.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var panningRedIcon = L.icon({
|
||||
iconUrl: 'images/panningRed.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var domeRedIcon = L.icon({
|
||||
iconUrl: 'images/domeRed.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var guardRedIcon = L.icon({
|
||||
iconUrl: 'images/guardRed.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
/* Gray-yellow icons for non-specific cameras and guards marked with a 'fixme' key. */
|
||||
var todo_camIcon = L.icon({
|
||||
iconUrl: 'images/todo_cam.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var todo_fixedIcon = L.icon({
|
||||
iconUrl: 'images/todo_fixed.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var todo_panningIcon = L.icon({
|
||||
iconUrl: 'images/todo_panning.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var todo_domeIcon = L.icon({
|
||||
iconUrl: 'images/todo_dome.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var todo_guardIcon = L.icon({
|
||||
iconUrl: 'images/todo_guard.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var todo_trafficIcon = L.icon({
|
||||
iconUrl: 'images/todo_traffic.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
/* Blue-yellow icons for outdoor cameras and guards marked with a 'fixme' key.
|
||||
Those cameras and guards surveil only private, i.e. non-public areas. */
|
||||
var todo_camBlueIcon = L.icon({
|
||||
iconUrl: 'images/todo_camBlue.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var todo_fixedBlueIcon = L.icon({
|
||||
iconUrl: 'images/todo_fixedBlue.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var todo_panningBlueIcon = L.icon({
|
||||
iconUrl: 'images/todo_panningBlue.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var todo_domeBlueIcon = L.icon({
|
||||
iconUrl: 'images/todo_domeBlue.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var todo_guardBlueIcon = L.icon({
|
||||
iconUrl: 'images/todo_guardBlue.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
/* Green-yellow icons for indoor cameras and guards marked with a 'fixme' key. */
|
||||
var todo_camGreenIcon = L.icon({
|
||||
iconUrl: 'images/todo_camGreen.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var todo_fixedGreenIcon = L.icon({
|
||||
iconUrl: 'images/todo_fixedGreen.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var todo_panningGreenIcon = L.icon({
|
||||
iconUrl: 'images/todo_panningGreen.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var todo_domeGreenIcon = L.icon({
|
||||
iconUrl: 'images/todo_domeGreen.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var todo_guardGreenIcon = L.icon({
|
||||
iconUrl: 'images/todo_guardGreen.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
/* Red-yellow icons for outdoor cameras and guards marked with a 'fixme' key.
|
||||
Those cameras and guards surveil public, i.e. non-private areas. */
|
||||
var todo_camRedIcon = L.icon({
|
||||
iconUrl: 'images/todo_camRed.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var todo_fixedRedIcon = L.icon({
|
||||
iconUrl: 'images/todo_fixedRed.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var todo_panningRedIcon = L.icon({
|
||||
iconUrl: 'images/todo_panningRed.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var todo_domeRedIcon = L.icon({
|
||||
iconUrl: 'images/todo_domeRed.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
|
||||
var todo_guardRedIcon = L.icon({
|
||||
iconUrl: 'images/todo_guardRed.png',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
popupAnchor : [0, -10]
|
||||
});
|
||||
113
web/www/sunders/js/search.js
Normal file
113
web/www/sunders/js/search.js
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
var searchLimit;
|
||||
|
||||
function displaySearchOverlay() {
|
||||
document.getElementById('search-overlay').style.display = 'block';
|
||||
}
|
||||
|
||||
// Close the search overlay.
|
||||
function closeSearchOverlay() {
|
||||
document.getElementById('search-overlay').style.display = 'none';
|
||||
document.getElementById('search-results-overlay').style.display = 'none';
|
||||
document.getElementById('buttonbar').style.bottom = '';
|
||||
}
|
||||
|
||||
// Search for possible locations
|
||||
function searchLocation(maxResults) {
|
||||
var searchString = document.getElementById('search-input').value;
|
||||
|
||||
if (searchString) {
|
||||
|
||||
document.getElementById('buttonbar').style.bottom = 0;
|
||||
document.getElementById('search-results-overlay').style.display = 'block';
|
||||
|
||||
var spinnerDiv = '<div class="spinner-bar">';
|
||||
for (var i=1; i<=10; i++) {
|
||||
spinnerDiv += '<div class="spinner spinner' + i + '">▬▬</div>';
|
||||
}
|
||||
spinnerDiv += '</div>';
|
||||
|
||||
document.getElementById('search-results-list-block').style.display = 'none';
|
||||
document.getElementById('search-spinner').innerHTML = spinnerDiv;
|
||||
document.getElementById('search-spinner-block').style.display = 'block';
|
||||
|
||||
if (maxResults) {
|
||||
searchLimit = maxResults;
|
||||
} else {
|
||||
// Search one more than required to check if there are more results and a 'next' button is required.
|
||||
searchLimit = 11;
|
||||
}
|
||||
|
||||
var searchScript = document.createElement('script');
|
||||
searchScript.src = 'https://nominatim.openstreetmap.org/search.php?q=' + searchString + '&format=json&json_callback=parseResult&limit=' + searchLimit;
|
||||
document.body.appendChild(searchScript);
|
||||
}
|
||||
}
|
||||
|
||||
function parseResult(response) {
|
||||
var searchResultDivs = '';
|
||||
|
||||
if (response.length == searchLimit) {
|
||||
var lastResultIndex = searchLimit - 1;
|
||||
var nextSearchLimit = searchLimit + 10;
|
||||
} else {
|
||||
var lastResultIndex = response.length;
|
||||
}
|
||||
|
||||
if (lastResultIndex > 10) {
|
||||
var previousSearchLimit = searchLimit - 10;
|
||||
}
|
||||
|
||||
// Button to search for the previous 10 results.
|
||||
if (previousSearchLimit) {
|
||||
searchResultDivs += '<div class="search-more search-previous" onClick="searchLocation(' + previousSearchLimit + ');return false;"></div>';
|
||||
}
|
||||
|
||||
searchResultDivs += '<div class="search-results">';
|
||||
|
||||
// Show the current 10 search results.
|
||||
for (var i=searchLimit-11; i<lastResultIndex; i++) {
|
||||
searchResult = response[i];
|
||||
searchResultDivs +=
|
||||
'<div class="search-result" onClick="gotoLocation(' + searchResult.lat + ', ' + searchResult.lon + ');return false;">' +
|
||||
'<div class="text-medium">' + searchResult.class + ' / ' + searchResult.type + '</div>' +
|
||||
'<div>' + searchResult.display_name + '</div>' +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
searchResultDivs += '</div>';
|
||||
|
||||
// Button to search for the next 10 results.
|
||||
if (nextSearchLimit) {
|
||||
searchResultDivs += '<div class="search-more search-next" onClick="searchLocation(' + nextSearchLimit + ');return false;"></div>'
|
||||
}
|
||||
|
||||
document.getElementById('search-spinner-block').style.display = 'none';
|
||||
document.getElementById('search-results-list').innerHTML = searchResultDivs;
|
||||
document.getElementById('search-results-list-block').style.display = 'block';
|
||||
}
|
||||
|
||||
// Returns the value of URL parameter #name.
|
||||
function getUrlParameter(name) {
|
||||
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
|
||||
var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
|
||||
var results = regex.exec(window.location.search);
|
||||
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
|
||||
}
|
||||
|
||||
// Open map for coordinates
|
||||
function gotoLocation(lat, lon) {
|
||||
var serverUrl = location.protocol + '//' + location.host + location.pathname;
|
||||
var embQuery = '';
|
||||
|
||||
// --- URLSearchParams is not supported by all browsers ---
|
||||
// var urlParams = new URLSearchParams(window.location.search);
|
||||
// var embedMode = urlParams.get('emb');
|
||||
var embedMode = getUrlParameter('emb');
|
||||
if (embedMode != '') {
|
||||
embQuery = '&emb=' + embedMode;
|
||||
}
|
||||
|
||||
var gotoUrl = serverUrl + '?lat=' + lat + '&lon=' + lon + '&zoom=' + map.getZoom() + embQuery;
|
||||
|
||||
window.location = gotoUrl;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue