landxml/examples/web-converter/main.js

193 lines
6.0 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: '&copy; <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.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 = `<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;
}
}());