|
@@ -1,373 +1,382 @@
|
|
-<!DOCTYPE html>
|
|
|
|
-<html lang="it">
|
|
|
|
-<head>
|
|
|
|
- <meta charset="UTF-8">
|
|
|
|
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
- <title>Mappa Interattiva con Layer Colorati</title>
|
|
|
|
-
|
|
|
|
- <!-- Fogli di stile -->
|
|
|
|
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-italia@2.13.4/dist/css/bootstrap-italia.min.css">
|
|
|
|
- <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css">
|
|
|
|
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css"/>
|
|
|
|
- <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
|
|
|
|
-
|
|
|
|
- <style>
|
|
|
|
- .top-bar { background-color: #004080; color: white; padding: 0.5rem 0; }
|
|
|
|
- .header { background-color: #0066CC; color: white; padding: 1rem 0; }
|
|
|
|
- /* Stile per il logo "PW" dentro un cerchio */
|
|
|
|
- .logo {
|
|
|
|
- font-family: 'Georgia', serif;
|
|
|
|
- font-size: 1.5rem;
|
|
|
|
- width: 50px; height: 50px;
|
|
|
|
- background-color: white;
|
|
|
|
- color: #0066CC;
|
|
|
|
- border-radius: 50%;
|
|
|
|
- margin-right: 10px;
|
|
|
|
- display: inline-flex;
|
|
|
|
- align-items: center;
|
|
|
|
- justify-content: center;
|
|
|
|
- }
|
|
|
|
- .header-title { color: white; font-size: 1.5rem; font-weight: bold; }
|
|
|
|
- .main-content { background-color: #f8f9fa; padding: 2rem 0; }
|
|
|
|
- #map { height: 500px; width: 100%; border-radius: 8px; }
|
|
|
|
- .search-container { margin: 20px 0; }
|
|
|
|
- .search-box { display: flex; gap: 10px; max-width: 600px; margin: 0 auto; }
|
|
|
|
- .coordinate-box { background: white; padding: 15px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); margin-top: 20px; }
|
|
|
|
- </style>
|
|
|
|
-</head>
|
|
|
|
-<body>
|
|
|
|
- <!-- Header -->
|
|
|
|
- <div class="top-bar">
|
|
|
|
- <div class="container">Project Work</div>
|
|
|
|
- </div>
|
|
|
|
-
|
|
|
|
- <!-- Header -->
|
|
|
|
- <header class="header">
|
|
|
|
- <div class="container">
|
|
|
|
- <div class="row align-items-center">
|
|
|
|
- <div class="col d-flex">
|
|
|
|
- <!-- Logo "PW" dentro un cerchio, ora cliccabile -->
|
|
|
|
- <a href="/callback" class="logo-link">
|
|
|
|
- <div class="logo">PW</div>
|
|
|
|
- </a>
|
|
|
|
- <h1 class="header-title">Mappa</h1>
|
|
|
|
- </div>
|
|
|
|
- <div class="col-auto d-flex align-items-center">
|
|
|
|
- <a href="/admin" class="text-white me-3 link-underline-hover">Gestione Dati Immobiliari</a>
|
|
|
|
- <a href="/tfo" class="text-white me-3 link-underline-hover">TFO</a>
|
|
|
|
- <a href="/buildings" class="text-white me-3 link-underline-hover">Registrazione degli Edifici</a>
|
|
|
|
- <a href="/mappa_login" class="btn btn-light">Logout</a>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </header>
|
|
|
|
-
|
|
|
|
- <main class="main-content">
|
|
|
|
- <div class="container">
|
|
|
|
- <!-- Barra di ricerca -->
|
|
|
|
- <div class="search-container">
|
|
|
|
- <div class="search-box">
|
|
|
|
- <input type="text"
|
|
|
|
- id="address"
|
|
|
|
- class="form-control"
|
|
|
|
- placeholder="Inserisci l'indirizzo"
|
|
|
|
- style="flex-grow: 1;">
|
|
|
|
- <button id="searchBtn" class="btn btn-primary">
|
|
|
|
- <i class="fas fa-search"></i> Cerca
|
|
|
|
- </button>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
-
|
|
|
|
- <!-- Mappa -->
|
|
|
|
- <div id="map"></div>
|
|
|
|
-
|
|
|
|
- <!-- Dati geografici -->
|
|
|
|
- <div class="coordinate-box">
|
|
|
|
- <div class="row">
|
|
|
|
- <div class="col-md-4 mb-3">
|
|
|
|
- <label class="form-label">Latitudine:</label>
|
|
|
|
- <input type="number" id="latInput" class="form-control" readonly>
|
|
|
|
- </div>
|
|
|
|
- <div class="col-md-4 mb-3">
|
|
|
|
- <label class="form-label">Longitudine:</label>
|
|
|
|
- <input type="number" id="lngInput" class="form-control" readonly>
|
|
|
|
- </div>
|
|
|
|
- <div class="col-md-4 mb-3">
|
|
|
|
- <label class="form-label">Indirizzo:</label>
|
|
|
|
- <input type="text" id="addressInput" class="form-control" readonly>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </main>
|
|
|
|
-
|
|
|
|
- <!-- Footer -->
|
|
|
|
- <footer id="footer" class="it-footer bg-black" role="contentinfo">
|
|
|
|
- <!-- Contenuto footer mantenuto uguale -->
|
|
|
|
- </footer>
|
|
|
|
-
|
|
|
|
- <!-- Script -->
|
|
|
|
- <!-- Includi lo script di ElevenLabs -->
|
|
|
|
-
|
|
|
|
- <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
|
|
|
|
- <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"></script>
|
|
|
|
- <script>
|
|
|
|
- // Inizializzazione Mappa
|
|
|
|
- const map = L.map('map').setView([41.9028, 12.4964], 13);
|
|
|
|
- L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
|
|
|
|
-
|
|
|
|
- // Layer edifici colorati
|
|
|
|
- const edificiLayer = L.layerGroup().addTo(map);
|
|
|
|
- let currentMarker = null;
|
|
|
|
-
|
|
|
|
- // Funzione principale per caricare gli edifici
|
|
|
|
- async function caricaEdifici() {
|
|
|
|
- if (map.getZoom() >= 16) {
|
|
|
|
- const bounds = map.getBounds();
|
|
|
|
- const bbox = `${bounds.getSouthWest().lat},${bounds.getSouthWest().lng},${bounds.getNorthEast().lat},${bounds.getNorthEast().lng}`;
|
|
|
|
-
|
|
|
|
- const query = `[out:json];
|
|
|
|
- (
|
|
|
|
- way["building"](${bbox});
|
|
|
|
- relation["building"](${bbox});
|
|
|
|
- );
|
|
|
|
- out geom;
|
|
|
|
- out tags;`;
|
|
|
|
-
|
|
|
|
- try {
|
|
|
|
- const response = await fetch(`https://overpass-api.de/api/interpreter?data=${encodeURIComponent(query)}`);
|
|
|
|
- const data = await response.json();
|
|
|
|
-
|
|
|
|
- edificiLayer.clearLayers();
|
|
|
|
-
|
|
|
|
- data.elements.forEach(element => {
|
|
|
|
- if (element.type === 'way' && element.geometry) {
|
|
|
|
- const latlngs = element.geometry.map(coord => [coord.lat, coord.lon]);
|
|
|
|
- var statoEdificio = false;
|
|
|
|
- let colorePoligono ;
|
|
|
|
- if (statoEdificio) colorePoligono = 'yellow';
|
|
|
|
- else colorePoligono = 'green';
|
|
|
|
-
|
|
|
|
- // const colori = ['#FF0000', '#00FF00'];
|
|
|
|
- const polygon = L.polygon(latlngs, {
|
|
|
|
- fillColor: colorePoligono,
|
|
|
|
- color: colorePoligono,
|
|
|
|
- fillOpacity: 0.5
|
|
|
|
- }).addTo(edificiLayer);
|
|
|
|
-
|
|
|
|
- polygon.on('click', async function() {
|
|
|
|
- var buildingType = element.tags && element.tags.building ? element.tags.building : 'Sconosciuto';
|
|
|
|
- try {
|
|
|
|
- await getAddress(latlngs[0][0], latlngs[0][1]);
|
|
|
|
- var popupContent = `
|
|
|
|
- <b>Coordinate:</b> ${latlngs[0][0]}, ${latlngs[0][1]}<br>
|
|
|
|
- <b>Tipo edificio:</b> ${buildingType}<br>
|
|
|
|
- <b>Indirizzo:</b> ${document.getElementById('addressInput').value}<br>
|
|
|
|
- <b>Stato:</b> ${statoEdificio}<br>
|
|
|
|
- <b>Codice Catastale:</b> nessuno
|
|
|
|
- `;
|
|
|
|
- polygon.bindPopup(popupContent).openPopup();
|
|
|
|
- } catch (error) {
|
|
|
|
- console.error("Errore nel recupero dell'indirizzo:", error);
|
|
|
|
- var popupContent = `
|
|
|
|
- <b>Coordinate:</b> ${latlngs[0][0]}, ${latlngs[0][1]}<br>
|
|
|
|
- <b>Tipo edificio:</b> ${buildingType}<br>
|
|
|
|
- <b>Indirizzo:</b> Indirizzo non disponibile<br>
|
|
|
|
- <b>Stato:</b> ${statoEdificio}<br>
|
|
|
|
- <b>Codice Catastale:</b> nessuno
|
|
|
|
- `;
|
|
|
|
- polygon.bindPopup(popupContent).openPopup();
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- } catch (error) {
|
|
|
|
- console.error("Errore nel caricamento edifici:", error);
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- edificiLayer.clearLayers();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- async function getAddress(lat, lng) {
|
|
|
|
- console.log(typeof(lat));
|
|
|
|
- console.log(typeof(lng));
|
|
|
|
-
|
|
|
|
- try {
|
|
|
|
- const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${lat}&lon=${lng}`);
|
|
|
|
- const data = await response.json();
|
|
|
|
-
|
|
|
|
- if (data.address) {
|
|
|
|
- document.getElementById('addressInput').value = data.display_name;
|
|
|
|
- } else {
|
|
|
|
- document.getElementById('addressInput').value = "Indirizzo non trovato";
|
|
|
|
- }
|
|
|
|
- } catch (error) {
|
|
|
|
- console.error("Errore nel geocoding inverso:", error);
|
|
|
|
- document.getElementById('addressInput').value = "Errore nel geocoding inverso";
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Funzioni di gestione posizione
|
|
|
|
- async function updatePosition(lat, lng) {
|
|
|
|
- try {
|
|
|
|
- const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}`);
|
|
|
|
- const data = await response.json();
|
|
|
|
-
|
|
|
|
- document.getElementById('latInput').value = lat;
|
|
|
|
- document.getElementById('lngInput').value = lng;
|
|
|
|
- document.getElementById('addressInput').value = data.display_name || "Indirizzo non disponibile";
|
|
|
|
-
|
|
|
|
- if (currentMarker) map.removeLayer(currentMarker);
|
|
|
|
- currentMarker = L.marker([lat, lng]).addTo(map);
|
|
|
|
-
|
|
|
|
- } catch (error) {
|
|
|
|
- console.error("Errore di geocoding inverso:", error);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Ricerca indirizzo
|
|
|
|
- async function searchAddress() {
|
|
|
|
- const address = document.getElementById('address').value;
|
|
|
|
- if (!address) return;
|
|
|
|
-
|
|
|
|
- try {
|
|
|
|
- const response = await fetch(`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(address)}`);
|
|
|
|
- const data = await response.json();
|
|
|
|
-
|
|
|
|
- if (data.length === 0) {
|
|
|
|
- alert("Indirizzo non trovato");
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- const { lat, lon: lng } = data[0];
|
|
|
|
- map.setView([lat, lng], 18);
|
|
|
|
- updatePosition(lat, lng);
|
|
|
|
-
|
|
|
|
- } catch (error) {
|
|
|
|
- console.error("Errore di ricerca:", error);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Event listeners
|
|
|
|
- document.getElementById('searchBtn').addEventListener('click', searchAddress);
|
|
|
|
- document.getElementById('address').addEventListener('keypress', (e) => {
|
|
|
|
- if (e.key === 'Enter') searchAddress();
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- map.on('click', (e) => {
|
|
|
|
- const { lat, lng } = e.latlng;
|
|
|
|
- updatePosition(lat, lng);
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- map.on('moveend', caricaEdifici);
|
|
|
|
- map.on('zoomend', caricaEdifici);
|
|
|
|
- caricaEdifici();
|
|
|
|
- </script>
|
|
|
|
-
|
|
|
|
- <script src="https://cdn.jsdelivr.net/npm/bootstrap-italia@2.8.1/dist/js/bootstrap-italia.bundle.min.js"></script>
|
|
|
|
- <script>
|
|
|
|
- document.addEventListener('DOMContentLoaded', function() {
|
|
|
|
- // Ottieni l'URL corrente
|
|
|
|
- const urlParams = new URLSearchParams(window.location.search);
|
|
|
|
- // Estrai il token dal parametro di query "token"
|
|
|
|
- const ruolo = urlParams.get('ruolo');
|
|
|
|
- const codice_fiscale = urlParams.get('codice_fiscale');
|
|
|
|
- // Salva il token in localStorage
|
|
|
|
- if (ruolo && codice_fiscale) {
|
|
|
|
- localStorage.setItem('ruolo', ruolo);
|
|
|
|
- localStorage.setItem('codice_fiscale', codice_fiscale);
|
|
|
|
- // Rimuovi il token dall'URL per sicurezza (opzionale)
|
|
|
|
- window.history.replaceState({}, document.title, window.location.pathname);
|
|
|
|
- //window.location.href = window.location.pathname;
|
|
|
|
- //Puoi anche reindirizzare ad una pagina pulita.
|
|
|
|
- //window.location.href = '/altra-pagina';
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- });
|
|
|
|
- </script>
|
|
|
|
- <!-- Widget ElevenLabs ConvAI -->
|
|
|
|
- <elevenlabs-convai agent-id="GlBWa9xJ6GdD7bAve6Yq"></elevenlabs-convai>
|
|
|
|
- <script src="https://elevenlabs.io/convai-widget/index.js" async type="text/javascript"></script>
|
|
|
|
-
|
|
|
|
- <footer id="footer" class="it-footer bg-black" role="contentinfo">
|
|
|
|
- <div class="it-footer-main py-3">
|
|
|
|
- <div class="container">
|
|
|
|
- <section class="py-4">
|
|
|
|
- <div class="row">
|
|
|
|
- <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
|
|
|
|
- <div class="link-list-wrapper">
|
|
|
|
- <h2 class="h5">Esplora SINFI</h2>
|
|
|
|
- <ul id="footer-menu-col-1" class="link-list">
|
|
|
|
- <li id="menu-item-sinfi-1" class="menu-item">
|
|
|
|
- <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/che-cose/">Cos'è SINFI</a>
|
|
|
|
- </li>
|
|
|
|
- <li id="menu-item-sinfi-2" class="menu-item">
|
|
|
|
- <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Infrastrutture Registrate</a>
|
|
|
|
- </li>
|
|
|
|
- <li id="menu-item-sinfi-3" class="menu-item">
|
|
|
|
- <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/riferimenti-normativi/">Normative di Riferimento</a>
|
|
|
|
- </li>
|
|
|
|
- <li id="menu-item-sinfi-4" class="menu-item">
|
|
|
|
- <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Open Data SINFI</a>
|
|
|
|
- </li>
|
|
|
|
- </ul>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
|
|
|
|
- <div class="link-list-wrapper">
|
|
|
|
- <h2 class="h5">Aiuto e Supporto</h2>
|
|
|
|
- <ul id="footer-menu-col-2" class="link-list">
|
|
|
|
- <li id="menu-item-aiuto-1" class="menu-item">
|
|
|
|
- <a class="list-item" href="/instructions">Istruzioni</a>
|
|
|
|
- </li>
|
|
|
|
- <li id="menu-item-aiuto-2" class="menu-item">
|
|
|
|
- <a class="list-item" href="/faq">FAQ - Domande Frequenti</a>
|
|
|
|
- </li>
|
|
|
|
- <li id="menu-item-aiuto-3" class="menu-item">
|
|
|
|
- <a class="list-item" href="/techsup">Segnalazioni e Supporto Tecnico</a>
|
|
|
|
- </li>
|
|
|
|
- </ul>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- <!-- Colonna "Community" con i loghi dei social -->
|
|
|
|
- <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
|
|
|
|
- <div class="link-list-wrapper">
|
|
|
|
- <h2 class="h5">Community</h2>
|
|
|
|
- <div class="social-icons">
|
|
|
|
- <a href="https://www.linkedin.com" target="_blank" class="me-3"><i class="fab fa-linkedin"></i></a>
|
|
|
|
- <a href="https://www.youtube.com" target="_blank" class="me-3"><i class="fab fa-youtube"></i></a>
|
|
|
|
- <a href="https://www.facebook.com" target="_blank" class="me-3"><i class="fab fa-facebook"></i></a>
|
|
|
|
- <a href="https://www.instagram.com" target="_blank" class="me-3"><i class="fab fa-instagram"></i></a>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
|
|
|
|
- <div class="link-list-wrapper">
|
|
|
|
- <h2 class="h5">SINFI</h2>
|
|
|
|
- <ul id="footer-menu-col-4" class="link-list">
|
|
|
|
- <li id="menu-item-377" class="menu-item">
|
|
|
|
- <a target="_blank" href="https://sinfi.it/portal/">Vai al sito ufficiale SINFI</a>
|
|
|
|
- </li>
|
|
|
|
- </ul>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </section>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- <div class="it-footer-small-prints clearfix">
|
|
|
|
- <div class="container">
|
|
|
|
- <nav class="menu-footer-menu-ita-container" aria-label="link utili">
|
|
|
|
- <ul id="menu-footer-menu-ita" class="it-footer-small-prints-list list-inline mb-0 d-flex flex-column flex-md-row">
|
|
|
|
- <li id="menu-item-413" class="menu-item list-inline-item"><a href="/media-policy/">Media Policy</a></li>
|
|
|
|
- <li id="menu-item-453" class="menu-item list-inline-item"><a href="/note-legali/">Privacy Policy & Note Legali</a></li>
|
|
|
|
- <li id="menu-item-1310" class="menu-item list-inline-item"><a target="_blank" href="https://form.agid.gov.it/view/9df3de50-7a42-11ef-8989-9dcab5eaa914">Dichiarazione di accessibilità</a></li>
|
|
|
|
- <li id="menu-item-411" class="menu-item list-inline-item"><a href="/mappa-del-sito/">Mappa del sito</a></li>
|
|
|
|
- <li id="menu-item-1277" class="menu-item list-inline-item"><a href="/open-data-spid/">Open Data SPID</a></li>
|
|
|
|
- </ul>
|
|
|
|
- </nav>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </footer>
|
|
|
|
-</body>
|
|
|
|
|
|
+<!DOCTYPE html>
|
|
|
|
+<html lang="it">
|
|
|
|
+<head>
|
|
|
|
+ <meta charset="UTF-8">
|
|
|
|
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
+ <title>Mappa Interattiva con Layer Colorati</title>
|
|
|
|
+
|
|
|
|
+ <!-- Fogli di stile -->
|
|
|
|
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-italia@2.13.4/dist/css/bootstrap-italia.min.css">
|
|
|
|
+ <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css">
|
|
|
|
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css"/>
|
|
|
|
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
|
|
|
|
+
|
|
|
|
+ <style>
|
|
|
|
+ /* Stile per i link con sottolineatura solo al passaggio del mouse */
|
|
|
|
+ .link-underline-hover {
|
|
|
|
+ text-decoration: none;
|
|
|
|
+ /* Rimuove la sottolineatura di base */
|
|
|
|
+ }
|
|
|
|
+ .link-underline-hover:hover {
|
|
|
|
+ text-decoration: underline;
|
|
|
|
+ /* Aggiunge la sottolineatura solo al passaggio del mouse */
|
|
|
|
+ }
|
|
|
|
+ .top-bar { background-color: #004080; color: white; padding: 0.5rem 0; }
|
|
|
|
+ .header { background-color: #0066CC; color: white; padding: 1rem 0; }
|
|
|
|
+ /* Stile per il logo "PW" dentro un cerchio */
|
|
|
|
+ .logo {
|
|
|
|
+ font-family: 'Georgia', serif;
|
|
|
|
+ font-size: 1.5rem;
|
|
|
|
+ width: 50px; height: 50px;
|
|
|
|
+ background-color: white;
|
|
|
|
+ color: #0066CC;
|
|
|
|
+ border-radius: 50%;
|
|
|
|
+ margin-right: 10px;
|
|
|
|
+ display: inline-flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ }
|
|
|
|
+ .header-title { color: white; font-size: 1.5rem; font-weight: bold; }
|
|
|
|
+ .main-content { background-color: #f8f9fa; padding: 2rem 0; }
|
|
|
|
+ #map { height: 500px; width: 100%; border-radius: 8px; }
|
|
|
|
+ .search-container { margin: 20px 0; }
|
|
|
|
+ .search-box { display: flex; gap: 10px; max-width: 600px; margin: 0 auto; }
|
|
|
|
+ .coordinate-box { background: white; padding: 15px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); margin-top: 20px; }
|
|
|
|
+ </style>
|
|
|
|
+</head>
|
|
|
|
+<body>
|
|
|
|
+ <!-- Header -->
|
|
|
|
+ <div class="top-bar">
|
|
|
|
+ <div class="container">Project Work</div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <!-- Header -->
|
|
|
|
+ <header class="header">
|
|
|
|
+ <div class="container">
|
|
|
|
+ <div class="row align-items-center">
|
|
|
|
+ <div class="col d-flex">
|
|
|
|
+ <!-- Logo "PW" dentro un cerchio, ora cliccabile -->
|
|
|
|
+ <a href="/callback" class="logo-link">
|
|
|
|
+ <div class="logo">PW</div>
|
|
|
|
+ </a>
|
|
|
|
+ <h1 class="header-title">Mappa</h1>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="col-auto d-flex align-items-center">
|
|
|
|
+ <a href="/admin" class="text-white me-3 link-underline-hover">Gestione Dati Immobiliari</a>
|
|
|
|
+ <a href="/tfo" class="text-white me-3 link-underline-hover">TFO</a>
|
|
|
|
+ <a href="/buildings" class="text-white me-3 link-underline-hover">Registrazione degli Edifici</a>
|
|
|
|
+ <a href="/mappa_login" class="btn btn-light">Logout</a>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </header>
|
|
|
|
+
|
|
|
|
+ <main class="main-content">
|
|
|
|
+ <div class="container">
|
|
|
|
+ <!-- Barra di ricerca -->
|
|
|
|
+ <div class="search-container">
|
|
|
|
+ <div class="search-box">
|
|
|
|
+ <input type="text"
|
|
|
|
+ id="address"
|
|
|
|
+ class="form-control"
|
|
|
|
+ placeholder="Inserisci l'indirizzo"
|
|
|
|
+ style="flex-grow: 1;">
|
|
|
|
+ <button id="searchBtn" class="btn btn-primary">
|
|
|
|
+ <i class="fas fa-search"></i> Cerca
|
|
|
|
+ </button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <!-- Mappa -->
|
|
|
|
+ <div id="map"></div>
|
|
|
|
+
|
|
|
|
+ <!-- Dati geografici -->
|
|
|
|
+ <div class="coordinate-box">
|
|
|
|
+ <div class="row">
|
|
|
|
+ <div class="col-md-4 mb-3">
|
|
|
|
+ <label class="form-label">Latitudine:</label>
|
|
|
|
+ <input type="number" id="latInput" class="form-control" readonly>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="col-md-4 mb-3">
|
|
|
|
+ <label class="form-label">Longitudine:</label>
|
|
|
|
+ <input type="number" id="lngInput" class="form-control" readonly>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="col-md-4 mb-3">
|
|
|
|
+ <label class="form-label">Indirizzo:</label>
|
|
|
|
+ <input type="text" id="addressInput" class="form-control" readonly>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </main>
|
|
|
|
+
|
|
|
|
+ <!-- Footer -->
|
|
|
|
+ <footer id="footer" class="it-footer bg-black" role="contentinfo">
|
|
|
|
+ <!-- Contenuto footer mantenuto uguale -->
|
|
|
|
+ </footer>
|
|
|
|
+
|
|
|
|
+ <!-- Script -->
|
|
|
|
+ <!-- Includi lo script di ElevenLabs -->
|
|
|
|
+
|
|
|
|
+ <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
|
|
|
|
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"></script>
|
|
|
|
+ <script>
|
|
|
|
+ // Inizializzazione Mappa
|
|
|
|
+ const map = L.map('map').setView([41.9028, 12.4964], 13);
|
|
|
|
+ L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
|
|
|
|
+
|
|
|
|
+ // Layer edifici colorati
|
|
|
|
+ const edificiLayer = L.layerGroup().addTo(map);
|
|
|
|
+ let currentMarker = null;
|
|
|
|
+
|
|
|
|
+ // Funzione principale per caricare gli edifici
|
|
|
|
+ async function caricaEdifici() {
|
|
|
|
+ if (map.getZoom() >= 16) {
|
|
|
|
+ const bounds = map.getBounds();
|
|
|
|
+ const bbox = `${bounds.getSouthWest().lat},${bounds.getSouthWest().lng},${bounds.getNorthEast().lat},${bounds.getNorthEast().lng}`;
|
|
|
|
+
|
|
|
|
+ const query = `[out:json];
|
|
|
|
+ (
|
|
|
|
+ way["building"](${bbox});
|
|
|
|
+ relation["building"](${bbox});
|
|
|
|
+ );
|
|
|
|
+ out geom;
|
|
|
|
+ out tags;`;
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ const response = await fetch(`https://overpass-api.de/api/interpreter?data=${encodeURIComponent(query)}`);
|
|
|
|
+ const data = await response.json();
|
|
|
|
+
|
|
|
|
+ edificiLayer.clearLayers();
|
|
|
|
+
|
|
|
|
+ data.elements.forEach(element => {
|
|
|
|
+ if (element.type === 'way' && element.geometry) {
|
|
|
|
+ const latlngs = element.geometry.map(coord => [coord.lat, coord.lon]);
|
|
|
|
+ var statoEdificio = false;
|
|
|
|
+ let colorePoligono ;
|
|
|
|
+ if (statoEdificio) colorePoligono = 'yellow';
|
|
|
|
+ else colorePoligono = 'green';
|
|
|
|
+
|
|
|
|
+ // const colori = ['#FF0000', '#00FF00'];
|
|
|
|
+ const polygon = L.polygon(latlngs, {
|
|
|
|
+ fillColor: colorePoligono,
|
|
|
|
+ color: colorePoligono,
|
|
|
|
+ fillOpacity: 0.5
|
|
|
|
+ }).addTo(edificiLayer);
|
|
|
|
+
|
|
|
|
+ polygon.on('click', async function() {
|
|
|
|
+ var buildingType = element.tags && element.tags.building ? element.tags.building : 'Sconosciuto';
|
|
|
|
+ try {
|
|
|
|
+ await getAddress(latlngs[0][0], latlngs[0][1]);
|
|
|
|
+ var popupContent = `
|
|
|
|
+ <b>Coordinate:</b> ${latlngs[0][0]}, ${latlngs[0][1]}<br>
|
|
|
|
+ <b>Tipo edificio:</b> ${buildingType}<br>
|
|
|
|
+ <b>Indirizzo:</b> ${document.getElementById('addressInput').value}<br>
|
|
|
|
+ <b>Stato:</b> ${statoEdificio}<br>
|
|
|
|
+ <b>Codice Catastale:</b> nessuno
|
|
|
|
+ `;
|
|
|
|
+ polygon.bindPopup(popupContent).openPopup();
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error("Errore nel recupero dell'indirizzo:", error);
|
|
|
|
+ var popupContent = `
|
|
|
|
+ <b>Coordinate:</b> ${latlngs[0][0]}, ${latlngs[0][1]}<br>
|
|
|
|
+ <b>Tipo edificio:</b> ${buildingType}<br>
|
|
|
|
+ <b>Indirizzo:</b> Indirizzo non disponibile<br>
|
|
|
|
+ <b>Stato:</b> ${statoEdificio}<br>
|
|
|
|
+ <b>Codice Catastale:</b> nessuno
|
|
|
|
+ `;
|
|
|
|
+ polygon.bindPopup(popupContent).openPopup();
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error("Errore nel caricamento edifici:", error);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ edificiLayer.clearLayers();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ async function getAddress(lat, lng) {
|
|
|
|
+ console.log(typeof(lat));
|
|
|
|
+ console.log(typeof(lng));
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${lat}&lon=${lng}`);
|
|
|
|
+ const data = await response.json();
|
|
|
|
+
|
|
|
|
+ if (data.address) {
|
|
|
|
+ document.getElementById('addressInput').value = data.display_name;
|
|
|
|
+ } else {
|
|
|
|
+ document.getElementById('addressInput').value = "Indirizzo non trovato";
|
|
|
|
+ }
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error("Errore nel geocoding inverso:", error);
|
|
|
|
+ document.getElementById('addressInput').value = "Errore nel geocoding inverso";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Funzioni di gestione posizione
|
|
|
|
+ async function updatePosition(lat, lng) {
|
|
|
|
+ try {
|
|
|
|
+ const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}`);
|
|
|
|
+ const data = await response.json();
|
|
|
|
+
|
|
|
|
+ document.getElementById('latInput').value = lat;
|
|
|
|
+ document.getElementById('lngInput').value = lng;
|
|
|
|
+ document.getElementById('addressInput').value = data.display_name || "Indirizzo non disponibile";
|
|
|
|
+
|
|
|
|
+ if (currentMarker) map.removeLayer(currentMarker);
|
|
|
|
+ currentMarker = L.marker([lat, lng]).addTo(map);
|
|
|
|
+
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error("Errore di geocoding inverso:", error);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Ricerca indirizzo
|
|
|
|
+ async function searchAddress() {
|
|
|
|
+ const address = document.getElementById('address').value;
|
|
|
|
+ if (!address) return;
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ const response = await fetch(`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(address)}`);
|
|
|
|
+ const data = await response.json();
|
|
|
|
+
|
|
|
|
+ if (data.length === 0) {
|
|
|
|
+ alert("Indirizzo non trovato");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const { lat, lon: lng } = data[0];
|
|
|
|
+ map.setView([lat, lng], 18);
|
|
|
|
+ updatePosition(lat, lng);
|
|
|
|
+
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error("Errore di ricerca:", error);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Event listeners
|
|
|
|
+ document.getElementById('searchBtn').addEventListener('click', searchAddress);
|
|
|
|
+ document.getElementById('address').addEventListener('keypress', (e) => {
|
|
|
|
+ if (e.key === 'Enter') searchAddress();
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ map.on('click', (e) => {
|
|
|
|
+ const { lat, lng } = e.latlng;
|
|
|
|
+ updatePosition(lat, lng);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ map.on('moveend', caricaEdifici);
|
|
|
|
+ map.on('zoomend', caricaEdifici);
|
|
|
|
+ caricaEdifici();
|
|
|
|
+ </script>
|
|
|
|
+
|
|
|
|
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap-italia@2.8.1/dist/js/bootstrap-italia.bundle.min.js"></script>
|
|
|
|
+ <script>
|
|
|
|
+ document.addEventListener('DOMContentLoaded', function() {
|
|
|
|
+ // Ottieni l'URL corrente
|
|
|
|
+ const urlParams = new URLSearchParams(window.location.search);
|
|
|
|
+ // Estrai il token dal parametro di query "token"
|
|
|
|
+ const ruolo = urlParams.get('ruolo');
|
|
|
|
+ const codice_fiscale = urlParams.get('codice_fiscale');
|
|
|
|
+ // Salva il token in localStorage
|
|
|
|
+ if (ruolo && codice_fiscale) {
|
|
|
|
+ localStorage.setItem('ruolo', ruolo);
|
|
|
|
+ localStorage.setItem('codice_fiscale', codice_fiscale);
|
|
|
|
+ // Rimuovi il token dall'URL per sicurezza (opzionale)
|
|
|
|
+ window.history.replaceState({}, document.title, window.location.pathname);
|
|
|
|
+ //window.location.href = window.location.pathname;
|
|
|
|
+ //Puoi anche reindirizzare ad una pagina pulita.
|
|
|
|
+ //window.location.href = '/altra-pagina';
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ });
|
|
|
|
+ </script>
|
|
|
|
+ <!-- Widget ElevenLabs ConvAI -->
|
|
|
|
+ <elevenlabs-convai agent-id="GlBWa9xJ6GdD7bAve6Yq"></elevenlabs-convai>
|
|
|
|
+ <script src="https://elevenlabs.io/convai-widget/index.js" async type="text/javascript"></script>
|
|
|
|
+
|
|
|
|
+ <footer id="footer" class="it-footer bg-black" role="contentinfo">
|
|
|
|
+ <div class="it-footer-main py-3">
|
|
|
|
+ <div class="container">
|
|
|
|
+ <section class="py-4">
|
|
|
|
+ <div class="row">
|
|
|
|
+ <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
|
|
|
|
+ <div class="link-list-wrapper">
|
|
|
|
+ <h2 class="h5">Esplora SINFI</h2>
|
|
|
|
+ <ul id="footer-menu-col-1" class="link-list">
|
|
|
|
+ <li id="menu-item-sinfi-1" class="menu-item">
|
|
|
|
+ <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/che-cose/">Cos'è SINFI</a>
|
|
|
|
+ </li>
|
|
|
|
+ <li id="menu-item-sinfi-2" class="menu-item">
|
|
|
|
+ <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Infrastrutture Registrate</a>
|
|
|
|
+ </li>
|
|
|
|
+ <li id="menu-item-sinfi-3" class="menu-item">
|
|
|
|
+ <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/riferimenti-normativi/">Normative di Riferimento</a>
|
|
|
|
+ </li>
|
|
|
|
+ <li id="menu-item-sinfi-4" class="menu-item">
|
|
|
|
+ <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Open Data SINFI</a>
|
|
|
|
+ </li>
|
|
|
|
+ </ul>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
|
|
|
|
+ <div class="link-list-wrapper">
|
|
|
|
+ <h2 class="h5">Aiuto e Supporto</h2>
|
|
|
|
+ <ul id="footer-menu-col-2" class="link-list">
|
|
|
|
+ <li id="menu-item-aiuto-1" class="menu-item">
|
|
|
|
+ <a class="list-item" href="/instructions">Istruzioni</a>
|
|
|
|
+ </li>
|
|
|
|
+ <li id="menu-item-aiuto-2" class="menu-item">
|
|
|
|
+ <a class="list-item" href="/faq">FAQ - Domande Frequenti</a>
|
|
|
|
+ </li>
|
|
|
|
+ <li id="menu-item-aiuto-3" class="menu-item">
|
|
|
|
+ <a class="list-item" href="/techsup">Segnalazioni e Supporto Tecnico</a>
|
|
|
|
+ </li>
|
|
|
|
+ </ul>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <!-- Colonna "Community" con i loghi dei social -->
|
|
|
|
+ <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
|
|
|
|
+ <div class="link-list-wrapper">
|
|
|
|
+ <h2 class="h5">Community</h2>
|
|
|
|
+ <div class="social-icons">
|
|
|
|
+ <a href="https://www.linkedin.com" target="_blank" class="me-3"><i class="fab fa-linkedin"></i></a>
|
|
|
|
+ <a href="https://www.youtube.com" target="_blank" class="me-3"><i class="fab fa-youtube"></i></a>
|
|
|
|
+ <a href="https://www.facebook.com" target="_blank" class="me-3"><i class="fab fa-facebook"></i></a>
|
|
|
|
+ <a href="https://www.instagram.com" target="_blank" class="me-3"><i class="fab fa-instagram"></i></a>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
|
|
|
|
+ <div class="link-list-wrapper">
|
|
|
|
+ <h2 class="h5">SINFI</h2>
|
|
|
|
+ <ul id="footer-menu-col-4" class="link-list">
|
|
|
|
+ <li id="menu-item-377" class="menu-item">
|
|
|
|
+ <a target="_blank" href="https://sinfi.it/portal/">Vai al sito ufficiale SINFI</a>
|
|
|
|
+ </li>
|
|
|
|
+ </ul>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </section>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="it-footer-small-prints clearfix">
|
|
|
|
+ <div class="container">
|
|
|
|
+ <nav class="menu-footer-menu-ita-container" aria-label="link utili">
|
|
|
|
+ <ul id="menu-footer-menu-ita" class="it-footer-small-prints-list list-inline mb-0 d-flex flex-column flex-md-row">
|
|
|
|
+ <li id="menu-item-413" class="menu-item list-inline-item"><a href="/media-policy/">Media Policy</a></li>
|
|
|
|
+ <li id="menu-item-453" class="menu-item list-inline-item"><a href="/note-legali/">Privacy Policy & Note Legali</a></li>
|
|
|
|
+ <li id="menu-item-1310" class="menu-item list-inline-item"><a target="_blank" href="https://form.agid.gov.it/view/9df3de50-7a42-11ef-8989-9dcab5eaa914">Dichiarazione di accessibilità</a></li>
|
|
|
|
+ <li id="menu-item-411" class="menu-item list-inline-item"><a href="/mappa-del-sito/">Mappa del sito</a></li>
|
|
|
|
+ <li id="menu-item-1277" class="menu-item list-inline-item"><a href="/open-data-spid/">Open Data SPID</a></li>
|
|
|
|
+ </ul>
|
|
|
|
+ </nav>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </footer>
|
|
|
|
+</body>
|
|
</html>
|
|
</html>
|