590 lines
17 KiB
JavaScript
590 lines
17 KiB
JavaScript
|
/* eslint-disable no-undef */
|
||
|
|
||
|
let retryConnection = false;
|
||
|
|
||
|
var markers = L.markerClusterGroup({
|
||
|
chunkedLoading: true,
|
||
|
removeOutsideVisibleBounds: true,
|
||
|
});
|
||
|
|
||
|
// Prepare everything we need for the map
|
||
|
let theMarker = L.Marker.extend({
|
||
|
options: {
|
||
|
id: "-1",
|
||
|
},
|
||
|
});
|
||
|
// Icons
|
||
|
const defaultIcon = L.icon({
|
||
|
iconUrl: "/img/marker-icon.png",
|
||
|
shadowUrl: "",
|
||
|
iconSize: [25, 41], // size of the icon
|
||
|
shadowSize: [41, 41], // size of the shadow
|
||
|
iconAnchor: [12, 41], // point of the icon which will correspond to marker's location
|
||
|
popupAnchor: [1, -34], // point from which the popup should open relative to the iconAnchor
|
||
|
});
|
||
|
|
||
|
const signalIcon = L.icon({
|
||
|
iconUrl: "/img/signal.png",
|
||
|
shadowUrl: "",
|
||
|
|
||
|
iconSize: [30, 30], // size of the icon
|
||
|
shadowSize: [0, 0], // size of the shadow
|
||
|
iconAnchor: [15, 15], // point of the icon which will correspond to marker's location
|
||
|
shadowAnchor: [0, 0], // the same for the shadow
|
||
|
popupAnchor: [0, 0], // point from which the popup should open relative to the iconAnchor
|
||
|
});
|
||
|
|
||
|
const temperatureIcon = L.icon({
|
||
|
iconUrl: "/img/temperature.png",
|
||
|
shadowUrl: "",
|
||
|
|
||
|
iconSize: [30, 30], // size of the icon
|
||
|
shadowSize: [0, 0], // size of the shadow
|
||
|
iconAnchor: [15, 15], // point of the icon which will correspond to marker's location
|
||
|
shadowAnchor: [0, 0], // the same for the shadow
|
||
|
popupAnchor: [0, 0], // point from which the popup should open relative to the iconAnchor
|
||
|
});
|
||
|
|
||
|
const cctvIcon = L.icon({
|
||
|
iconUrl: "/img/cctv.png",
|
||
|
shadowUrl: "",
|
||
|
|
||
|
iconSize: [30, 30], // size of the icon
|
||
|
shadowSize: [0, 0], // size of the shadow
|
||
|
iconAnchor: [15, 15], // point of the icon which will correspond to marker's location
|
||
|
shadowAnchor: [0, 0], // the same for the shadow
|
||
|
popupAnchor: [0, 0], // point from which the popup should open relative to the iconAnchor
|
||
|
});
|
||
|
|
||
|
const wifiIcon = L.icon({
|
||
|
iconUrl: "/img/wifi.png",
|
||
|
shadowUrl: "",
|
||
|
|
||
|
iconSize: [30, 30], // size of the icon
|
||
|
shadowSize: [0, 0], // size of the shadow
|
||
|
iconAnchor: [15, 15], // point of the icon which will correspond to marker's location
|
||
|
shadowAnchor: [0, 0], // the same for the shadow
|
||
|
popupAnchor: [0, 0], // point from which the popup should open relative to the iconAnchor
|
||
|
});
|
||
|
|
||
|
function showPosition(position) {
|
||
|
mymap.setView(
|
||
|
new L.LatLng(position.coords.latitude, position.coords.longitude),
|
||
|
10
|
||
|
);
|
||
|
}
|
||
|
// Share a point
|
||
|
function sharePOI(id) {
|
||
|
const url = "https://pointsight.project-name-here.de/#" + id;
|
||
|
sidebar.prevContent = sidebar._contentContainer.innerHTML;
|
||
|
navigator.clipboard.writeText(url);
|
||
|
makeToastNotification(
|
||
|
"Copy successful",
|
||
|
"The link to this point has been copied to your clipboard"
|
||
|
);
|
||
|
}
|
||
|
|
||
|
function prepareSidebar(point_id, panTo = false) {
|
||
|
const rawData = httpGet(
|
||
|
"/api/retrieve?uid=" +
|
||
|
point_id +
|
||
|
"&key=b03f8aaf-1f32-4d9e-914a-9a50f904833d"
|
||
|
);
|
||
|
if (rawData.length > 0 && !rawData.includes("502 Bad Gateway")) {
|
||
|
retryConnection = false;
|
||
|
try {
|
||
|
toggleModal("popup-modal-no-conn", false);
|
||
|
retryConnection = false;
|
||
|
} catch (error) {
|
||
|
error;
|
||
|
}
|
||
|
const moreData = JSON.parse(rawData)[0][0];
|
||
|
// Inject toolbar
|
||
|
let inspector =
|
||
|
'<i class="fas fa-flag reportBtn" style="padding: 4px;" onclick="reportPOI(\'' +
|
||
|
point_id +
|
||
|
"')\"></i>";
|
||
|
inspector +=
|
||
|
'<i class="fas fa-share-alt reportBtn" style="padding: 4px;" onclick="sharePOI(\'' +
|
||
|
point_id +
|
||
|
"')\"></i>";
|
||
|
console.warn(moreData);
|
||
|
if (moreData.type == "webcam-iframe") {
|
||
|
// Prepare the template
|
||
|
inspector += httpGet("/templates/inspectorContentIframe.html");
|
||
|
inspector = inspector.replaceAll("#TITLE", moreData.titel);
|
||
|
inspector = inspector.replaceAll("#URL", moreData.url);
|
||
|
inspector = inspector.replaceAll("#URL", moreData.url);
|
||
|
} else if (moreData.type == "webcam-image") {
|
||
|
// Prepare the template
|
||
|
inspector += httpGet("/templates/inspectorContentImage.html");
|
||
|
inspector = inspector.replaceAll("#TITLE", moreData.titel);
|
||
|
inspector = inspector.replaceAll("#URL", moreData.url);
|
||
|
} else if (moreData.type == "iframe") {
|
||
|
// Prepare the template
|
||
|
inspector += httpGet("/templates/inspectorContentIframe.html");
|
||
|
inspector = inspector.replaceAll("#TITLE", moreData.titel);
|
||
|
inspector = inspector.replaceAll("#URL", moreData.url);
|
||
|
inspector = inspector.replaceAll("#URL", moreData.url);
|
||
|
} else if (moreData.type == "request-info") {
|
||
|
// Prepare the template
|
||
|
inspector += httpGet("/templates/inspectorGeneral.html");
|
||
|
inspector = inspector.replaceAll("#TITLE", moreData.object.titel);
|
||
|
inspector = inspector.replaceAll("#description", httpGet(moreData.url));
|
||
|
} else {
|
||
|
inspector += httpGet("/templates/inspectorGeneral.html");
|
||
|
inspector = inspector.replaceAll("#TITLE", moreData.titel);
|
||
|
inspector = inspector.replaceAll("#description", moreData.description);
|
||
|
}
|
||
|
// document.getElementById("inspector").innerHTML = inspector;
|
||
|
|
||
|
sidebar.setContent(inspector);
|
||
|
sidebar.show();
|
||
|
if (panTo) {
|
||
|
mymap.panTo([moreData.location.x, moreData.location.y]);
|
||
|
}
|
||
|
} else {
|
||
|
try {
|
||
|
if (!retryConnection) {
|
||
|
toggleModal("popup-modal-no-conn", true);
|
||
|
}
|
||
|
|
||
|
retryConnection = true;
|
||
|
} catch (error) {
|
||
|
error;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Handles click actions for markers
|
||
|
function onClick(e) {
|
||
|
prepareSidebar(this.options.object.uid);
|
||
|
}
|
||
|
|
||
|
const form = document.getElementById("reportForm");
|
||
|
form.addEventListener("submit", (event) => {
|
||
|
// submit event detected
|
||
|
event.preventDefault();
|
||
|
console.log("Report done by users");
|
||
|
// Change the UI
|
||
|
document.getElementById("reportBtnText").style.display = "none";
|
||
|
document.getElementById("loadingSpinner").style.display = "block";
|
||
|
document.getElementById("submitBtn").disabled = true;
|
||
|
// Get all values
|
||
|
const formy = new FormData(form);
|
||
|
const reason = formy.get("reason");
|
||
|
const email = formy.get("email");
|
||
|
const pointId = document.getElementById("pointId").innerHTML;
|
||
|
const baseUrl =
|
||
|
"/api/internal/report?key=b03f8aaf-1f32-4d9e-914a-9a50f904833d&";
|
||
|
let reqUrl =
|
||
|
baseUrl + "reason=" + reason + "&mail=" + email + "&point_id=" + pointId;
|
||
|
const response = httpGet(reqUrl);
|
||
|
const reponseParsed = JSON.parse(response);
|
||
|
if (reponseParsed.status == "success") {
|
||
|
setTimeout(() => {
|
||
|
document.getElementById("loadingDone").style.display = "block";
|
||
|
document.getElementById("loadingSpinner").style.display = "none";
|
||
|
}, 1000);
|
||
|
setTimeout(() => {
|
||
|
document.getElementById("reportBtnText").style.display = "block";
|
||
|
document.getElementById("loadingSpinner").style.display = "none";
|
||
|
document.getElementById("submitBtn").disabled = false;
|
||
|
document.getElementById("loadingDone").style.display = "none";
|
||
|
toggleModal("report-modal", false);
|
||
|
form.reset();
|
||
|
makeToastNotification("Report successful", "Thank you for your report.");
|
||
|
}, 2000);
|
||
|
} else {
|
||
|
if (reponseParsed.message == "Invalid mail") {
|
||
|
setTimeout(() => {
|
||
|
document.getElementById("reportBtnText").style.display = "block";
|
||
|
document.getElementById("loadingSpinner").style.display = "none";
|
||
|
document.getElementById("loadingDone").style.display = "none";
|
||
|
document.getElementById("submitBtn").disabled = false;
|
||
|
toggleModal("report-modal", false);
|
||
|
form.reset();
|
||
|
|
||
|
document.getElementById("Geomodal-content").innerHTML =
|
||
|
"It seemed like you provided an invalid mail address. Please try again.";
|
||
|
toggleModal("popup-modal", true);
|
||
|
}, 1000);
|
||
|
} else {
|
||
|
setTimeout(() => {
|
||
|
document.getElementById("reportBtnText").style.display = "block";
|
||
|
document.getElementById("loadingSpinner").style.display = "none";
|
||
|
document.getElementById("loadingDone").style.display = "none";
|
||
|
document.getElementById("submitBtn").disabled = false;
|
||
|
toggleModal("report-modal", false);
|
||
|
form.reset();
|
||
|
|
||
|
document.getElementById("Geomodal-content").innerHTML =
|
||
|
"Something went wrong, please try again later";
|
||
|
toggleModal("popup-modal", true);
|
||
|
}, 1000);
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
function reportPOI(poi_id) {
|
||
|
document.getElementById("pointId").innerHTML = poi_id;
|
||
|
toggleModal("report-modal", true);
|
||
|
/*const url = "/api/internal/report&key=b03f8aaf-1f32-4d9e-914a-9a50f904833d&"
|
||
|
console.log(poi_id)*/
|
||
|
}
|
||
|
function httpGet(theUrl) {
|
||
|
var xmlHttp = new XMLHttpRequest();
|
||
|
xmlHttp.open("GET", theUrl, false); // false for synchronous request
|
||
|
xmlHttp.send(null);
|
||
|
return xmlHttp.responseText;
|
||
|
}
|
||
|
|
||
|
function httpGetTriggerForMapData(theUrl) {
|
||
|
var xmlHttp = new XMLHttpRequest();
|
||
|
xmlHttp.open("GET", theUrl, true); // Doing it asynchronous
|
||
|
xmlHttp.send(null);
|
||
|
xmlHttp.onerror = function (e) {
|
||
|
console.log(e);
|
||
|
};
|
||
|
xmlHttp.onloadend = function (e) {
|
||
|
setTimeout(function () {
|
||
|
if (
|
||
|
xmlHttp.responseText.length > 0 &&
|
||
|
!xmlHttp.responseText.includes("502 Bad Gateway")
|
||
|
) {
|
||
|
retryConnection = false;
|
||
|
try {
|
||
|
toggleModal("popup-modal-no-conn", false);
|
||
|
retryConnection = false;
|
||
|
} catch (error) {
|
||
|
error;
|
||
|
}
|
||
|
response = xmlHttp.responseText;
|
||
|
allMarks = 0;
|
||
|
response = JSON.parse(response);
|
||
|
allMarks = response;
|
||
|
|
||
|
markerList = [];
|
||
|
for (h in response) {
|
||
|
item = response[h];
|
||
|
let mIcon = defaultIcon;
|
||
|
if (item.icon == "signalIcon") {
|
||
|
mIcon = signalIcon;
|
||
|
} else if (item.icon == "cctvIcon") {
|
||
|
mIcon = cctvIcon;
|
||
|
} else if (item.icon == "wifiIcon") {
|
||
|
mIcon = wifiIcon;
|
||
|
} else if (item.icon == "temperatureIcon") {
|
||
|
mIcon = temperatureIcon;
|
||
|
}
|
||
|
|
||
|
var marker = new theMarker([item.location.x, item.location.y], {
|
||
|
icon: mIcon,
|
||
|
object: item,
|
||
|
}).on("click", onClick);
|
||
|
markerList.push(marker);
|
||
|
}
|
||
|
// response.forEach(addPin);
|
||
|
markers.clearLayers();
|
||
|
markers.addLayers(markerList);
|
||
|
mymap.addLayer(markers);
|
||
|
syncBtn.state("default"); // Make sure the button is back to default
|
||
|
} else {
|
||
|
try {
|
||
|
if (!retryConnection) {
|
||
|
toggleModal("popup-modal-no-conn", true);
|
||
|
}
|
||
|
|
||
|
retryConnection = true;
|
||
|
} catch (error) {
|
||
|
error;
|
||
|
}
|
||
|
}
|
||
|
}, 50);
|
||
|
};
|
||
|
}
|
||
|
|
||
|
// Try to find where to user is
|
||
|
function home() {
|
||
|
if (navigator.geolocation) {
|
||
|
setTimeout(function () {
|
||
|
navigator.geolocation.getCurrentPosition(showPosition);
|
||
|
}, 200);
|
||
|
} else {
|
||
|
console.warn("Geolocation of user could not be fetched");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
home();
|
||
|
|
||
|
let allMarks = [];
|
||
|
var layerGroup = L.layerGroup().addTo(mymap);
|
||
|
var scale = L.control.scale().addTo(mymap);
|
||
|
var locator = L.control
|
||
|
.locate({
|
||
|
onLocationError: function (err) {
|
||
|
console.log(err);
|
||
|
let tip = err.message;
|
||
|
if (err.message.indexOf("User denied Geolocation") > -1) {
|
||
|
tip =
|
||
|
"You have denied the location request. Please allow it in your browser settings.";
|
||
|
}
|
||
|
document.getElementById("Geomodal-content").innerHTML = tip;
|
||
|
toggleModal("popup-modal", true);
|
||
|
},
|
||
|
})
|
||
|
.addTo(mymap);
|
||
|
|
||
|
/*mymap.addControl(
|
||
|
new L.Control.Fullscreen({
|
||
|
title: {
|
||
|
false: "View Fullscreen",
|
||
|
true: "Exit Fullscreen",
|
||
|
},
|
||
|
})
|
||
|
);*/
|
||
|
|
||
|
var sidebar = L.control.sidebar("sidebar", {
|
||
|
closeButton: true,
|
||
|
position: "right",
|
||
|
});
|
||
|
mymap.addControl(sidebar);
|
||
|
|
||
|
var sidebar2 = L.control.sidebar("sidebar-left", {
|
||
|
// Filter one
|
||
|
closeButton: true,
|
||
|
position: "left",
|
||
|
});
|
||
|
mymap.addControl(sidebar2);
|
||
|
// sidebar2.setContent(httpGet("/templates/filterPage.html"));
|
||
|
|
||
|
L.easyButton("fa-filter", function (btn, map) {
|
||
|
if (sidebar2.isVisible()) {
|
||
|
sidebar2.hide();
|
||
|
} else {
|
||
|
sidebar2.show();
|
||
|
}
|
||
|
}).addTo(mymap);
|
||
|
|
||
|
syncBtn = L.easyButton({
|
||
|
states: [
|
||
|
{
|
||
|
stateName: "default", // name the state
|
||
|
icon: "fa-sync", // and define its properties
|
||
|
title: "Reload POIs", // like its title
|
||
|
onClick: function (btn, map) {
|
||
|
// and its callback
|
||
|
updatePois(); // Update all da fancy POIs
|
||
|
btn.state("loading"); // change state on click!
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
stateName: "loading",
|
||
|
icon: "fa-sync fa-spin",
|
||
|
title: "Reloading...",
|
||
|
},
|
||
|
],
|
||
|
});
|
||
|
syncBtn.addTo(mymap);
|
||
|
|
||
|
searchBtn = L.easyButton({
|
||
|
states: [
|
||
|
{
|
||
|
stateName: "default", // name the state
|
||
|
icon: "fa-search", // and define its properties
|
||
|
title: "Search", // like its title
|
||
|
onClick: function (btn, map) {
|
||
|
// and its callback
|
||
|
sear.toggle();
|
||
|
btn.state("search"); // change state on click!
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
stateName: "search",
|
||
|
icon: "fa-search fa-spin",
|
||
|
title: "Hide search",
|
||
|
onClick: function (btn, map) {
|
||
|
// and its callback
|
||
|
sear.toggle();
|
||
|
btn.state("default"); // change state on click!
|
||
|
},
|
||
|
},
|
||
|
],
|
||
|
});
|
||
|
searchBtn.addTo(mymap);
|
||
|
|
||
|
// Start getting the pois
|
||
|
setTimeout(updatePois, 500);
|
||
|
var additionalFilters = "";
|
||
|
function updatePois() {
|
||
|
// Create a filter string
|
||
|
const enabledFilters = [];
|
||
|
try {
|
||
|
for (fi in tagsAvail) {
|
||
|
const tag = tagsAvail[fi];
|
||
|
if (document.getElementById("tag_" + tag).checked ) {
|
||
|
enabledFilters.push(tag);
|
||
|
}
|
||
|
}
|
||
|
additionalFilters =
|
||
|
'{"conjunction": "OR", "filters": [["tag","' + enabledFilters.join('"],["tag","') + '"]]}';
|
||
|
} catch (error) {
|
||
|
console.log("Filter sidebar seems not ready yet");
|
||
|
}
|
||
|
|
||
|
console.log(additionalFilters);
|
||
|
const bounds = mymap.getBounds();
|
||
|
httpGetTriggerForMapData(
|
||
|
"/api/getPOI?boundingEast=" +
|
||
|
bounds.getNorthEast().lat +
|
||
|
";" +
|
||
|
bounds.getNorthEast().lng +
|
||
|
"&boundingWest=" +
|
||
|
bounds.getSouthWest().lat +
|
||
|
";" +
|
||
|
bounds.getSouthWest().lng +
|
||
|
"&key=b03f8aaf-1f32-4d9e-914a-9a50f904833d&filter=" +
|
||
|
additionalFilters
|
||
|
);
|
||
|
}
|
||
|
|
||
|
let prevZoom = mymap.getZoom();
|
||
|
let prevCenter = mymap.getCenter();
|
||
|
let hasCenterChanged = false;
|
||
|
let maxZoomReached = mymap.getZoom();
|
||
|
|
||
|
setTimeout(function () {
|
||
|
prevCenter = mymap.getCenter();
|
||
|
prevZoom = mymap.getZoom();
|
||
|
}, 200);
|
||
|
|
||
|
function getDistanceBetweenCoordinates(lat1, lon1, lat2, lon2) {
|
||
|
var R = 6371; // Radius of the earth in km
|
||
|
var dLat = deg2rad(lat2 - lat1); // deg2rad below
|
||
|
var dLon = deg2rad(lon2 - lon1);
|
||
|
var a =
|
||
|
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
|
||
|
Math.cos(deg2rad(lat1)) *
|
||
|
Math.cos(deg2rad(lat2)) *
|
||
|
Math.sin(dLon / 2) *
|
||
|
Math.sin(dLon / 2);
|
||
|
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
||
|
var d = R * c; // Distance in km
|
||
|
return d;
|
||
|
}
|
||
|
|
||
|
function deg2rad(deg) {
|
||
|
return deg * (Math.PI / 180);
|
||
|
}
|
||
|
|
||
|
mymap.on("dragend", function () {
|
||
|
console.info(
|
||
|
getDistanceBetweenCoordinates(
|
||
|
prevCenter.lat,
|
||
|
prevCenter.lng,
|
||
|
mymap.getCenter().lat,
|
||
|
mymap.getCenter().lng
|
||
|
)
|
||
|
);
|
||
|
if (
|
||
|
getDistanceBetweenCoordinates(
|
||
|
prevCenter.lat,
|
||
|
prevCenter.lng,
|
||
|
mymap.getCenter().lat,
|
||
|
mymap.getCenter().lng
|
||
|
) >= 20
|
||
|
) {
|
||
|
setTimeout(updatePois, 2);
|
||
|
console.info("Updating POIs");
|
||
|
}
|
||
|
prevCenter = mymap.getCenter();
|
||
|
maxZoomReached = mymap.getZoom();
|
||
|
hasCenterChanged = true;
|
||
|
});
|
||
|
|
||
|
mymap.on("zoomend", function () {
|
||
|
console.info(mymap.getZoom() - prevZoom);
|
||
|
prevZoom = mymap.getZoom();
|
||
|
|
||
|
if (mymap.getZoom() <= maxZoomReached) {
|
||
|
maxZoomReached = mymap.getZoom();
|
||
|
console.info("Updating POIs");
|
||
|
setTimeout(updatePois, 2);
|
||
|
} else {
|
||
|
if (hasCenterChanged == false) {
|
||
|
veryLongIntegerVariableWhichNoOneWillEverUseHopefully = 42;
|
||
|
} else {
|
||
|
console.info("Updating POIs");
|
||
|
setTimeout(updatePois, 2);
|
||
|
}
|
||
|
}
|
||
|
hasCenterChanged = false;
|
||
|
});
|
||
|
|
||
|
function applyFilter() {
|
||
|
const val = document.getElementById("filter").value;
|
||
|
console.log(val);
|
||
|
additionalFilters =
|
||
|
'{"filters": [["tag", "' + val + '"]], "conjunction": "OR"}'; // {"filters": [["tag", "webcam"]], "conjunction": "OR"}
|
||
|
updatePois();
|
||
|
}
|
||
|
|
||
|
setTimeout(function () {
|
||
|
let lat = -1;
|
||
|
let lng = -1;
|
||
|
let zoom = 5;
|
||
|
let shouldThings = 0;
|
||
|
let point_id = "";
|
||
|
if (window.location.href.indexOf("#") > -1) {
|
||
|
point_id = window.location.href.split("#")[1];
|
||
|
prepareSidebar(point_id, true);
|
||
|
setTimeout(updatePois, 500);
|
||
|
} else {
|
||
|
window.location.search
|
||
|
.substr(1)
|
||
|
.split("&")
|
||
|
.forEach(function (item) {
|
||
|
const param = item.split("=");
|
||
|
if (param[0] === "lat" && _.isFinite(param[1])) {
|
||
|
lat = param[1];
|
||
|
shouldThings++;
|
||
|
} else if (param[0] === "lng" && _.isFinite(param[1])) {
|
||
|
lng = param[1];
|
||
|
shouldThings++;
|
||
|
} else if (param[0] === "zoom" && _.isFinite(param[1])) {
|
||
|
zoom = param[1];
|
||
|
shouldThings++;
|
||
|
}
|
||
|
if (shouldThings >= 2) {
|
||
|
mymap.flyTo([lat, lng], zoom);
|
||
|
console.log(lat, lng, zoom);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
}, 500);
|
||
|
|
||
|
setInterval(function () {
|
||
|
if (retryConnection) {
|
||
|
updatePois();
|
||
|
}
|
||
|
}, 5000);
|
||
|
|
||
|
mymap.on("contextmenu.show", (e) => {
|
||
|
mymap.contextmenu.removeItem(0);
|
||
|
mymap.contextmenu.insertItem(
|
||
|
{
|
||
|
text:
|
||
|
"<b class='background-color=\"red\"'>" +
|
||
|
e.latlng.lat.toFixed(4) +
|
||
|
", " +
|
||
|
e.latlng.lng.toFixed(4) +
|
||
|
"</b>",
|
||
|
callback: copyLocation,
|
||
|
},
|
||
|
0
|
||
|
);
|
||
|
});
|
||
|
sear = L.control.search({ position: "topleft" });
|
||
|
|
||
|
mymap.addControl(sear);
|