demarches-normaliennes/app/javascript/components/MapEditor/index.jsx

180 lines
5 KiB
React
Raw Normal View History

2021-05-06 18:51:53 +02:00
import React, { useState } from 'react';
import PropTypes from 'prop-types';
2021-05-06 18:51:53 +02:00
import ReactMapboxGl, { ZoomControl } from 'react-mapbox-gl';
import DrawControl from 'react-mapbox-gl-draw';
import { CursorClickIcon } from '@heroicons/react/outline';
2021-04-28 15:34:53 +02:00
import 'mapbox-gl/dist/mapbox-gl.css';
import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';
2021-05-06 18:51:53 +02:00
import MapStyleControl, { useMapStyle } from '../shared/mapbox/MapStyleControl';
2021-03-11 12:09:27 +01:00
import { FlashMessage } from '../shared/FlashMessage';
2020-10-07 17:44:04 +02:00
import ComboAdresseSearch from '../ComboAdresseSearch';
2021-05-06 18:51:53 +02:00
import { useMapboxEditor } from './useMapboxEditor';
2020-05-14 13:36:25 +02:00
2021-05-06 18:51:53 +02:00
const Mapbox = ReactMapboxGl({});
2021-05-06 18:51:53 +02:00
function MapEditor({ featureCollection, url, options, preview }) {
const [cadastreEnabled, setCadastreEnabled] = useState(false);
const [coords, setCoords] = useState([1.7, 46.9]);
const [zoom, setZoom] = useState([5]);
2021-05-06 18:51:53 +02:00
const {
isSupported,
error,
inputs,
onLoad,
onStyleChange,
onFileChange,
drawRef,
createFeatures,
updateFeatures,
deleteFeatures,
addInputFile,
removeInputFile
} = useMapboxEditor(featureCollection, {
url,
enabled: !preview,
cadastreEnabled
});
const {
style,
layers,
setStyle,
setLayerEnabled,
setLayerOpacity
} = useMapStyle(options.layers, {
2021-05-06 18:51:53 +02:00
onStyleChange,
cadastreEnabled
});
if (!isSupported) {
return (
<p>
Nous ne pouvons pas afficher notre éditeur de carte car il est
imcompatible avec votre navigateur. Nous vous conseillons de le mettre à
jour ou utiliser les dernières versions de Chrome, Firefox ou Safari
</p>
);
}
return (
<>
2021-05-06 18:51:53 +02:00
{error && <FlashMessage message={error} level="alert" fixed={true} />}
<div>
<p style={{ marginBottom: '20px' }}>
Besoin d&apos;aide ?&nbsp;
<a
href="https://doc.demarches-simplifiees.fr/pour-aller-plus-loin/cartographie"
target="_blank"
rel="noreferrer"
>
consulter les tutoriels video
</a>
</p>
</div>
2021-05-06 18:51:53 +02:00
<div className="file-import" style={{ marginBottom: '10px' }}>
<button className="button send primary" onClick={addInputFile}>
Ajouter un fichier GPX ou KML
</button>
2020-05-07 18:30:19 +02:00
<div>
2021-05-06 18:51:53 +02:00
{inputs.map((input) => (
<div key={input.id}>
<input
title="Choisir un fichier gpx ou kml"
style={{ marginTop: '15px' }}
id={input.id}
type="file"
accept=".gpx, .kml"
disabled={input.disabled}
2021-05-06 18:51:53 +02:00
onChange={(e) => onFileChange(e, input.id)}
/>
{input.hasValue && (
<span
title="Supprimer le fichier"
className="icon refuse"
style={{
cursor: 'pointer'
}}
onClick={(e) => removeInputFile(e, input.id)}
></span>
)}
</div>
))}
2020-05-07 18:30:19 +02:00
</div>
</div>
<div
style={{
2021-05-06 18:51:53 +02:00
marginBottom: '10px'
}}
>
2020-10-07 17:44:04 +02:00
<ComboAdresseSearch
2021-05-06 18:51:53 +02:00
className="no-margin"
2020-10-07 17:44:04 +02:00
placeholder="Rechercher une adresse : saisissez au moins 2 caractères"
allowInputValues={false}
onChange={(_, { geometry: { coordinates } }) => {
setCoords(coordinates);
setZoom([17]);
}}
/>
</div>
2020-10-15 17:22:08 +02:00
<Mapbox
2021-05-06 18:51:53 +02:00
onStyleLoad={(map) => onLoad(map)}
center={coords}
zoom={zoom}
2021-05-06 18:51:53 +02:00
style={style}
containerStyle={{ height: '500px' }}
>
2021-05-06 18:51:53 +02:00
{!cadastreEnabled && (
<DrawControl
ref={drawRef}
onDrawCreate={createFeatures}
onDrawUpdate={updateFeatures}
onDrawDelete={deleteFeatures}
displayControlsDefault={false}
controls={{
point: true,
line_string: true,
polygon: true,
trash: true
}}
2020-07-29 15:27:08 +02:00
/>
2021-05-06 18:51:53 +02:00
)}
<MapStyleControl
style={style.id}
layers={layers}
setStyle={setStyle}
setLayerEnabled={setLayerEnabled}
setLayerOpacity={setLayerOpacity}
/>
<ZoomControl />
2021-05-06 18:51:53 +02:00
{options.layers.includes('cadastres') && (
<div className="cadastres-selection-control mapboxgl-ctrl-group">
<button
type="button"
onClick={() =>
setCadastreEnabled((cadastreEnabled) => !cadastreEnabled)
}
title="Sélectionner les parcelles cadastrales"
className={cadastreEnabled ? 'on' : ''}
>
<CursorClickIcon className="icon-size" />
2021-05-06 18:51:53 +02:00
</button>
</div>
)}
2020-10-15 17:22:08 +02:00
</Mapbox>
</>
);
2020-05-14 13:36:25 +02:00
}
MapEditor.propTypes = {
featureCollection: PropTypes.shape({
bbox: PropTypes.array,
2021-05-06 18:51:53 +02:00
features: PropTypes.array
}),
2020-05-14 13:36:25 +02:00
url: PropTypes.string,
preview: PropTypes.bool,
2021-05-06 18:51:53 +02:00
options: PropTypes.shape({ layers: PropTypes.array })
};
export default MapEditor;