From d8ae089e9387a37d453a51bef2b40984c7155d71 Mon Sep 17 00:00:00 2001 From: kara Diaby Date: Fri, 15 May 2020 15:26:49 +0200 Subject: [PATCH] [Carto] Improve files import UX + import KML files --- app/javascript/components/MapEditor/index.js | 119 +++++++++++++++++-- 1 file changed, 108 insertions(+), 11 deletions(-) diff --git a/app/javascript/components/MapEditor/index.js b/app/javascript/components/MapEditor/index.js index aa329b524..04c55a708 100644 --- a/app/javascript/components/MapEditor/index.js +++ b/app/javascript/components/MapEditor/index.js @@ -6,7 +6,7 @@ import DrawControl from 'react-mapbox-gl-draw'; import SwitchMapStyle from './SwitchMapStyle'; import SearchInput from './SearchInput'; import { getJSON, ajax } from '@utils'; -import { gpx } from '@tmcw/togeojson/dist/togeojson.es.js'; +import { gpx, kml } from '@tmcw/togeojson/dist/togeojson.es.js'; import ortho from './styles/ortho.json'; import vector from './styles/vector.json'; import { polygonCadastresFill, polygonCadastresLine } from './utils'; @@ -32,6 +32,7 @@ function MapEditor({ featureCollection, url, preview }) { const [zoom, setZoom] = useState([5]); const [currentMap, setCurrentMap] = useState({}); const [bbox, setBbox] = useState(featureCollection.bbox); + const [importInputs, setImportInputs] = useState([]); const mapStyle = style === 'ortho' ? ortho : vector; const cadastresFeatureCollection = filterFeatureCollection( featureCollection, @@ -50,6 +51,13 @@ function MapEditor({ featureCollection, url, preview }) { draw.setFeatureProperty(lid, 'id', feature.properties.id); } + const generateId = () => Math.random().toString(20).substr(2, 6); + + const updateImportInputs = (inputs, inputId) => { + const updatedInputs = inputs.filter((input) => input.id !== inputId); + setImportInputs(updatedInputs); + }; + async function onDrawCreate({ features }) { for (const feature of features) { const data = await getJSON(url, { feature }, 'post'); @@ -95,29 +103,98 @@ function MapEditor({ featureCollection, url, preview }) { } }; - const onGpxImport = (e) => { + const onFileImport = (e, inputId) => { + const isGpxFile = e.target.files[0].name.includes('.gpx'); let reader = new FileReader(); reader.readAsText(e.target.files[0], 'UTF-8'); reader.onload = async (event) => { - const featureCollection = gpx( - new DOMParser().parseFromString(event.target.result, 'text/xml') - ); + let featureCollection; + isGpxFile + ? (featureCollection = gpx( + new DOMParser().parseFromString(event.target.result, 'text/xml') + )) + : (featureCollection = kml( + new DOMParser().parseFromString(event.target.result, 'text/xml') + )); + const resultFeatureCollection = await getJSON( `${url}/import`, featureCollection, 'post' ); + + let inputs = [...importInputs]; + const setInputs = inputs.map((input) => { + if (input.id === inputId) { + input.disabled = true; + input.hasValue = true; + resultFeatureCollection.features.forEach((feature) => { + if ( + JSON.stringify(feature.geometry) === + JSON.stringify(featureCollection.features[0].geometry) + ) { + input.featureId = feature.properties.id; + } + }); + } + return input; + }); + drawControl.current.draw.set( filterFeatureCollection( resultFeatureCollection, 'selection_utilisateur' ) ); + updateFeaturesList(resultFeatureCollection.features); + setImportInputs(setInputs); setBbox(resultFeatureCollection.bbox); }; }; + const addInputFile = (e) => { + e.preventDefault(); + let inputs = [...importInputs]; + inputs.push({ + id: generateId(), + disabled: false, + featureId: null, + hasValue: false + }); + setImportInputs(inputs); + }; + + const removeInputFile = async (e, inputId) => { + e.preventDefault(); + const draw = drawControl.current.draw; + const featureCollection = draw.getAll(); + let inputs = [...importInputs]; + let drawFeatureIdToRemove; + const inputToRemove = inputs.find((input) => input.id === inputId); + + for (const feature of featureCollection.features) { + if (inputToRemove.featureId === feature.properties.id) { + drawFeatureIdToRemove = feature.id; + } + } + + if (inputToRemove.featureId) { + try { + await getJSON(`${url}/${inputToRemove.featureId}`, null, 'delete'); + draw.delete(drawFeatureIdToRemove).getAll(); + } catch (e) { + throw new Error( + `La feature ${inputToRemove.featureId} a déjà été supprimée manuellement`, + e + ); + } finally { + updateImportInputs(inputs, inputId); + } + } + updateImportInputs(inputs, inputId); + }; + useEffect(() => { addEventListener('cadastres:update', onCadastresUpdate); return () => removeEventListener('cadastres:update', onCadastresUpdate); @@ -136,13 +213,33 @@ function MapEditor({ featureCollection, url, preview }) { return ( <>
+
-

- Importer un fichier GPX -

-
-
- + {importInputs.map((input) => ( +
+ onFileImport(e, input.id)} + /> + {input.hasValue && ( + removeInputFile(e, input.id)} + > + )} +
+ ))}