(function() { const xmlTextarea = document.getElementById("xml-editor"); const geojsonTextarea = document.getElementById("geojson-editor"); const transformButton = document.getElementById("transform-button"); const projectionSelect = document.getElementById("projection-select"); const downloadLink = document.getElementById("download-link"); const fileSelector = document.getElementById("file-selector"); const loadFileButton = document.getElementById("load-file-button"); const xmlEditor = CodeMirror.fromTextArea(xmlTextarea, { lineNumbers: true, mode: 'application/xml', }); const geojsonEditor = CodeMirror.fromTextArea(geojsonTextarea, { lineNumbers: true, mode: 'application/json', }); const map = L.map('map', {zoomSnap: 0}).setView([0, 0], 1); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 50, maxNativeZoom: 18, attribution: '© OpenStreetMap contributors' }).addTo(map); let geojsonLayer; let projection = "auto_detect"; const lastXML = localStorage.getItem("lastXML"); const lastProjection = localStorage.getItem("lastProjection"); if (lastXML) xmlEditor.setValue(lastXML); if (lastProjection) { projection = lastProjection; projectionSelect.value = projection; } projectionSelect.addEventListener("change", () => { projection = projectionSelect.value; localStorage.setItem("lastProjection", projection); }); transformButton.addEventListener("click", () => { const xml = xmlEditor.getValue(); const converter = new landxml.Converter(); try { localStorage.setItem("lastXML", xml); } catch(err) { console.error(err); } converter.toGeoJSON(xml, { projection }) .then(geojson => { if(!geojson) return; console.log("Generated GeoJSON:", geojson); geojsonEditor.setValue(JSON.stringify(geojson, null, 2)); updatePreview(); }) .catch(err => { console.error(err); alert(err.message); }) ; }); let downloadLinkTimeout; let refreshTimeout; geojsonEditor.on("change", () => { clearTimeout(downloadLinkTimeout); downloadLinkTimeout = setTimeout(() => { const geojson = geojsonEditor.getValue(); downloadLink.setAttribute('href', 'data:application/json;charset=utf-8,' + encodeURIComponent(geojson)); downloadLink.setAttribute('download', "geojson_"+Date.now()+".json"); }, 1000); clearTimeout(refreshTimeout); refreshTimeout = setTimeout(updatePreview, 1000); }); fileSelector.addEventListener('change', (event) => { const fileList = event.target.files; console.log(fileList); const reader = new FileReader(); const onLoad = (evt) => { reader.removeEventListener('load', onLoad); xmlEditor.setValue(evt.target.result); fileSelector.value = null; }; reader.addEventListener('load', onLoad); reader.readAsText(fileList[0]); }); loadFileButton.addEventListener('click', () => { fileSelector.click(); }); let selectedFeature; function updatePreview() { let geojson; try { geojson = JSON.parse(geojsonEditor.getValue()); } catch(err) { console.error(err); return; } if (geojsonLayer) { geojsonLayer.remove(); } geojsonLayer = L.geoJSON(geojson, { style: feature => { return { color: feature.properties.landxmlColor, fillColor: feature.properties.landxmlColor, fillOpacity: 0.5, weight: 1, } }, onEachFeature: (f, l) => { if(f.geometry.type !== 'Point') l.bringToBack(); } }).on('click', (e) => { // Check for selected if (selectedFeature) { // Reset selected to default style e.target.resetStyle(selectedFeature) } // Assign new selected selectedFeature = e.layer const feature = selectedFeature.feature; console.log('Selected feature:', feature); if(feature.geometry.type !== 'Point') { // Style selected selectedFeature.setStyle({ 'fillOpacity': 0.9 }) } selectedFeature.bindPopup(featurePropertiesToHTML(feature)).openPopup(); }).addTo(map); const bounds = geojsonLayer.getBounds(); map.fitBounds(bounds); } function featurePropertiesToHTML(feature) { let html = `${feature.properties.name}

`; if (feature.geometry.type === "Point") { html += `
`; } html += ` Propriétés

`; Object.keys(feature.properties).sort().forEach(key => { html += ` `; }); html += `
Clé Valeur
${key} ${feature.properties[key]}
`; return html; } }());