Initial commit
This commit is contained in:
92
examples/web-converter/index.html
Normal file
92
examples/web-converter/index.html
Normal file
@ -0,0 +1,92 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>LandXML Converter Example</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.1/css/bulma.min.css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/codemirror@5.58.1/lib/codemirror.min.css">
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
|
||||
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
|
||||
crossorigin=""/>
|
||||
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
|
||||
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
|
||||
crossorigin=""></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/codemirror@5.58.1/lib/codemirror.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/codemirror@5.58.3/mode/javascript/javascript.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/codemirror@5.58.3/mode/xml/xml.js"></script>
|
||||
<script type="text/javascript" src="/bundles/landxml.browser.dev.js" defer></script>
|
||||
<script type="text/javascript" src="main.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<section class="section">
|
||||
<div class="container is-fluid">
|
||||
<h1 class="title">LandXML Converter Example</h1>
|
||||
</div>
|
||||
</section>
|
||||
<section class="section pt-0">
|
||||
<div class="container is-fluid">
|
||||
<div class="columns">
|
||||
<div class="column is-6">
|
||||
<div class="level is-paddingless">
|
||||
<div class="level-left">
|
||||
<h3 class="is-size-3 level-item">LandXML</h3>
|
||||
</div>
|
||||
<div class="level-right">
|
||||
<input type="file" id="file-selector" style="display:none" accept=".xml">
|
||||
<button id="load-file-button" class="button level-item is-medium">Charger un fichier</button>
|
||||
</div>
|
||||
</div>
|
||||
<textarea id="xml-editor" class="textarea" rows="25"></textarea>
|
||||
|
||||
<div class="level mt-3">
|
||||
<div class="level-left"></div>
|
||||
<div class="level-right">
|
||||
<div class="level-item">
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label is-normal">
|
||||
<label class="label">Projection</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field is-narrow">
|
||||
<div class="control">
|
||||
<div class="select is-fullwidth">
|
||||
<select id="projection-select">
|
||||
<option value="auto_detect">Détection automatique (si possible)</option>
|
||||
<option value="EPSG:3944">RGF93 (CC44)</option>
|
||||
<option value="EPSG:3945">RGF93 (CC45)</option>
|
||||
<option value="EPSG:3947">RGF93 (CC47)</option>
|
||||
<option value="EPSG:3948">RGF93 (CC48)</option>
|
||||
<option value="EPSG:3949">RGF93 (CC49)</option>
|
||||
<option value="EPSG:3950">RGF93 (CC50)</option>
|
||||
<option value="EPSG:2154">RGF93 (Lambert-93)</option>
|
||||
<option value="EPSG:27572">NTF (Lambert II)</option>
|
||||
<option value="EPSG:27573">NTF (Lambert III)</option>
|
||||
<option value="EPSG:4275">NTF</option>
|
||||
<option value="EPSG:4326">WGS84</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button id="transform-button" class="button is-primary is-medium level-item">Transformer</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-6">
|
||||
<h3 class="is-size-3">GeoJSON</h3>
|
||||
<textarea id="geojson-editor" class="textarea" rows="25"></textarea>
|
||||
<div class="buttons is-right mt-3">
|
||||
<a id="download-link" href="#" class="button is-link is-medium">Télécharger</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="is-size-3">Prévisualisation</h3>
|
||||
<div class="is-fullwidth" id="map" style="height:800px;"></div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
156
examples/web-converter/main.js
Normal file
156
examples/web-converter/main.js
Normal file
@ -0,0 +1,156 @@
|
||||
(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) => {
|
||||
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);
|
||||
|
||||
// Bring selected to front
|
||||
//selectedFeature.bringToFront()
|
||||
// Style selected
|
||||
selectedFeature.setStyle({
|
||||
'fillColor': 'blue'
|
||||
})
|
||||
|
||||
selectedFeature.bindPopup(`<b>${feature.properties.name}</b><br>${feature.properties.description}`).openPopup();
|
||||
}).addTo(map);
|
||||
const bounds = geojsonLayer.getBounds();
|
||||
map.fitBounds(bounds);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}());
|
Reference in New Issue
Block a user