Add Azure Maps road and satellite layers
This commit is contained in:
1 parent
3ea51a6842
commit
9733137fdd
6 files changed
+266
-4
No files matched your search
+132
-1
@@ -2,6 +2,7 @@ const lmeState = {
|
||||
map: null,
|
||||
baseLayers: {},
|
||||
currentBase: null,
|
||||
currentBaseName: "satellite",
|
||||
cadastre: null,
|
||||
cadastreLayers: ["CP.CadastralParcel", "codice_plla", "CP.CadastralZoning", "fabbricati"],
|
||||
cadastreOpacity: 0.75,
|
||||
@@ -19,7 +20,9 @@ const lmeState = {
|
||||
lastPosition: null,
|
||||
fileImportBound: false,
|
||||
resizeBound: false,
|
||||
googleMapsLoading: null
|
||||
googleMapsLoading: null,
|
||||
azureMapsKey: null,
|
||||
azureAttribution: null
|
||||
};
|
||||
|
||||
window.lmeMap = {
|
||||
@@ -36,6 +39,8 @@ window.lmeMap = {
|
||||
loadWorkspace,
|
||||
setBaseLayer,
|
||||
configureGoogleMaps,
|
||||
configureAzureMaps,
|
||||
clearAzureMaps,
|
||||
setCadastreOpacity,
|
||||
toggleCadastreLayer,
|
||||
startGps,
|
||||
@@ -117,6 +122,7 @@ function init() {
|
||||
L.popup().setLatLng(event.latlng).setContent(info).openOn(lmeState.map);
|
||||
}
|
||||
});
|
||||
lmeState.map.on("moveend", () => void updateAzureAttribution());
|
||||
|
||||
setInfo("Mappa pronta: satellite + catasto AdE");
|
||||
}
|
||||
@@ -384,6 +390,7 @@ function setBaseLayer(name) {
|
||||
lmeState.map.removeLayer(lmeState.currentBase);
|
||||
}
|
||||
lmeState.currentBase = selected.addTo(lmeState.map);
|
||||
lmeState.currentBaseName = selected === lmeState.baseLayers[name] ? name : "satellite";
|
||||
lmeState.currentBase.bringToBack();
|
||||
const labels = {
|
||||
satellite: "Satellite Esri",
|
||||
@@ -392,10 +399,17 @@ function setBaseLayer(name) {
|
||||
topographic: "Topografica Esri",
|
||||
terrain: "OpenTopoMap",
|
||||
carto: "CARTO Voyager",
|
||||
"azure-road": "Strade Azure Maps",
|
||||
"azure-satellite": "Satellite Azure Maps",
|
||||
"google-satellite": "Satellite Google Maps",
|
||||
"google-roadmap": "Strade Google Maps"
|
||||
};
|
||||
setInfo(`Sfondo attivo: ${labels[name] || labels.satellite}. Il catasto AdE resta sovrapposto.`);
|
||||
if (lmeState.currentBaseName.startsWith("azure-")) {
|
||||
void updateAzureAttribution();
|
||||
} else {
|
||||
clearAzureAttribution();
|
||||
}
|
||||
}
|
||||
|
||||
function configureGoogleMaps(apiKey) {
|
||||
@@ -443,6 +457,123 @@ function createGoogleLayers() {
|
||||
lmeState.baseLayers["google-roadmap"] ||= L.gridLayer.googleMutant({ type: "roadmap", maxZoom: 22 });
|
||||
}
|
||||
|
||||
function configureAzureMaps(subscriptionKey) {
|
||||
const key = (subscriptionKey || "").trim();
|
||||
if (!key) {
|
||||
throw new Error("Chiave Azure Maps mancante.");
|
||||
}
|
||||
if (lmeState.azureMapsKey === key
|
||||
&& lmeState.baseLayers["azure-road"]
|
||||
&& lmeState.baseLayers["azure-satellite"]) {
|
||||
return;
|
||||
}
|
||||
|
||||
const activeAzureLayer = lmeState.currentBaseName.startsWith("azure-")
|
||||
? lmeState.currentBaseName
|
||||
: null;
|
||||
if (activeAzureLayer && lmeState.currentBase) {
|
||||
lmeState.map.removeLayer(lmeState.currentBase);
|
||||
}
|
||||
|
||||
lmeState.azureMapsKey = key;
|
||||
lmeState.baseLayers["azure-road"] = createAzureLayer(key, "microsoft.base.road", 22);
|
||||
lmeState.baseLayers["azure-satellite"] = createAzureLayer(key, "microsoft.imagery", 19);
|
||||
|
||||
if (activeAzureLayer) {
|
||||
lmeState.currentBase = lmeState.baseLayers[activeAzureLayer].addTo(lmeState.map);
|
||||
lmeState.currentBase.bringToBack();
|
||||
void updateAzureAttribution();
|
||||
}
|
||||
}
|
||||
|
||||
function clearAzureMaps() {
|
||||
if (lmeState.currentBaseName.startsWith("azure-") && lmeState.currentBase) {
|
||||
lmeState.map.removeLayer(lmeState.currentBase);
|
||||
lmeState.currentBase = lmeState.baseLayers.satellite.addTo(lmeState.map);
|
||||
lmeState.currentBase.bringToBack();
|
||||
lmeState.currentBaseName = "satellite";
|
||||
}
|
||||
|
||||
delete lmeState.baseLayers["azure-road"];
|
||||
delete lmeState.baseLayers["azure-satellite"];
|
||||
lmeState.azureMapsKey = null;
|
||||
clearAzureAttribution();
|
||||
}
|
||||
|
||||
function createAzureLayer(key, tilesetId, maxNativeZoom) {
|
||||
const url = `https://atlas.microsoft.com/map/tile?api-version=2024-04-01&tilesetId=${tilesetId}&zoom={z}&x={x}&y={y}&tileSize=256&language=it-IT&view=Auto&subscription-key=${encodeURIComponent(key)}`;
|
||||
const layer = L.tileLayer(url, {
|
||||
minZoom: tilesetId === "microsoft.imagery" ? 1 : 0,
|
||||
maxNativeZoom,
|
||||
maxZoom: 22,
|
||||
attribution: "Microsoft Azure Maps"
|
||||
});
|
||||
let errorShown = false;
|
||||
layer.on("tileerror", () => {
|
||||
if (!errorShown) {
|
||||
errorShown = true;
|
||||
setInfo("Azure Maps non ha restituito le tessere. Controlla quota e permessi Render della chiave.");
|
||||
}
|
||||
});
|
||||
return layer;
|
||||
}
|
||||
|
||||
async function updateAzureAttribution() {
|
||||
if (!lmeState.azureMapsKey || !lmeState.currentBaseName.startsWith("azure-")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const requestedLayer = lmeState.currentBaseName;
|
||||
const tilesetId = requestedLayer === "azure-satellite" ? "microsoft.imagery" : "microsoft.base.road";
|
||||
const bounds = lmeState.map.getBounds();
|
||||
const zoom = Math.min(lmeState.map.getZoom(), tilesetId === "microsoft.imagery" ? 19 : 22);
|
||||
const bbox = [bounds.getWest(), bounds.getSouth(), bounds.getEast(), bounds.getNorth()].join(",");
|
||||
const url = `https://atlas.microsoft.com/map/attribution?api-version=2024-04-01&tilesetId=${tilesetId}&zoom=${zoom}&bounds=${bbox}`;
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
"subscription-key": lmeState.azureMapsKey
|
||||
}
|
||||
});
|
||||
if (!response.ok) {
|
||||
return;
|
||||
}
|
||||
const payload = await response.json();
|
||||
if (lmeState.currentBaseName !== requestedLayer) {
|
||||
return;
|
||||
}
|
||||
|
||||
const attribution = [...new Set((payload.copyrights || []).map(htmlToText).filter(Boolean))].join(" | ");
|
||||
setAzureAttribution(attribution);
|
||||
} catch {
|
||||
clearAzureAttribution();
|
||||
}
|
||||
}
|
||||
|
||||
function setAzureAttribution(text) {
|
||||
clearAzureAttribution();
|
||||
if (!text) {
|
||||
return;
|
||||
}
|
||||
lmeState.azureAttribution = escapeHtml(text);
|
||||
lmeState.map.attributionControl.addAttribution(lmeState.azureAttribution);
|
||||
}
|
||||
|
||||
function clearAzureAttribution() {
|
||||
if (lmeState.azureAttribution) {
|
||||
lmeState.map.attributionControl.removeAttribution(lmeState.azureAttribution);
|
||||
lmeState.azureAttribution = null;
|
||||
}
|
||||
}
|
||||
|
||||
function htmlToText(value) {
|
||||
const element = document.createElement("div");
|
||||
element.innerHTML = String(value || "");
|
||||
return element.textContent?.trim() || "";
|
||||
}
|
||||
|
||||
function setCadastreOpacity(value) {
|
||||
lmeState.cadastreOpacity = Number(value || 0.75);
|
||||
if (lmeState.cadastre) {
|
||||
|
||||
Reference in new issue
Block a user