193 lines
6.1 KiB
JavaScript
193 lines
6.1 KiB
JavaScript
(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: '© <a href="https://openstreetmap.org/copyright">OpenStreetMap contributors</a>'
|
|
}).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.color,
|
|
fillColor: feature.properties.fill,
|
|
fillOpacity: feature.properties['fill-opacity'],
|
|
weight: feature.properties['stroke-width'],
|
|
}
|
|
},
|
|
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({
|
|
'fillColor': 'blue'
|
|
})
|
|
}
|
|
|
|
selectedFeature.bindPopup(featurePropertiesToHTML(feature)).openPopup();
|
|
|
|
}).addTo(map);
|
|
const bounds = geojsonLayer.getBounds();
|
|
map.fitBounds(bounds);
|
|
}
|
|
|
|
function featurePropertiesToHTML(feature) {
|
|
let html = `<b>${feature.properties.name}</b><br /><br />`;
|
|
if (feature.geometry.type === "Point") {
|
|
html += `
|
|
<ul>
|
|
<li><b>Latitude</b> ${feature.geometry.coordinates[1]}°</li>
|
|
<li><b>Longitude</b> ${feature.geometry.coordinates[0]}°</li>
|
|
<li><b>Altitude</b> ${feature.geometry.coordinates[2]}m</li>
|
|
</ul>
|
|
<br />
|
|
`;
|
|
}
|
|
html += `
|
|
<b>Propriétés</b><br/><br/>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Clé</th>
|
|
<th>Valeur</th>
|
|
</tr>
|
|
<thead>
|
|
<tbody>
|
|
`;
|
|
Object.keys(feature.properties).sort().forEach(key => {
|
|
html += `
|
|
<tr>
|
|
<td>${key}</td>
|
|
<td>${feature.properties[key]}</td>
|
|
</tr>
|
|
`;
|
|
});
|
|
html += `
|
|
</tbody>
|
|
<table/>
|
|
`;
|
|
return html;
|
|
}
|
|
|
|
}()); |