Merge pull request #5209 from betagouv/dev

2020-06-02-01
This commit is contained in:
Kara Diaby 2020-06-02 14:54:37 +02:00 committed by GitHub
commit 46b8baf42f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 4598 additions and 42 deletions

View file

@ -43,7 +43,7 @@ gem 'haml-rails'
gem 'hashie' gem 'hashie'
gem 'jquery-rails' # Use jquery as the JavaScript library gem 'jquery-rails' # Use jquery as the JavaScript library
gem 'jwt' gem 'jwt'
gem 'kaminari', '= 1.1.1' # Pagination gem 'kaminari', '1.2.1' # Pagination
gem 'lograge' gem 'lograge'
gem 'logstash-event' gem 'logstash-event'
gem 'mailjet' gem 'mailjet'

View file

@ -331,18 +331,18 @@ GEM
bindata bindata
jsonapi-renderer (0.2.2) jsonapi-renderer (0.2.2)
jwt (2.1.0) jwt (2.1.0)
kaminari (1.1.1) kaminari (1.2.1)
activesupport (>= 4.1.0) activesupport (>= 4.1.0)
kaminari-actionview (= 1.1.1) kaminari-actionview (= 1.2.1)
kaminari-activerecord (= 1.1.1) kaminari-activerecord (= 1.2.1)
kaminari-core (= 1.1.1) kaminari-core (= 1.2.1)
kaminari-actionview (1.1.1) kaminari-actionview (1.2.1)
actionview actionview
kaminari-core (= 1.1.1) kaminari-core (= 1.2.1)
kaminari-activerecord (1.1.1) kaminari-activerecord (1.2.1)
activerecord activerecord
kaminari-core (= 1.1.1) kaminari-core (= 1.2.1)
kaminari-core (1.1.1) kaminari-core (1.2.1)
launchy (2.4.3) launchy (2.4.3)
addressable (~> 2.3) addressable (~> 2.3)
letter_opener (1.7.0) letter_opener (1.7.0)
@ -380,7 +380,7 @@ GEM
mimemagic (0.3.4) mimemagic (0.3.4)
mini_mime (1.0.2) mini_mime (1.0.2)
mini_portile2 (2.4.0) mini_portile2 (2.4.0)
minitest (5.14.0) minitest (5.14.1)
momentjs-rails (2.20.1) momentjs-rails (2.20.1)
railties (>= 3.1) railties (>= 3.1)
multi_json (1.14.1) multi_json (1.14.1)
@ -458,7 +458,7 @@ GEM
byebug (~> 10.0) byebug (~> 10.0)
pry (~> 0.10) pry (~> 0.10)
public_suffix (4.0.3) public_suffix (4.0.3)
puma (3.12.4) puma (3.12.6)
pundit (2.0.1) pundit (2.0.1)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
raabro (1.1.6) raabro (1.1.6)
@ -775,7 +775,7 @@ DEPENDENCIES
hashie hashie
jquery-rails jquery-rails
jwt jwt
kaminari (= 1.1.1) kaminari (= 1.2.1)
launchy launchy
letter_opener_web letter_opener_web
lograge lograge

View file

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import ortho from './images/preview-ortho.png'; import ortho from '../MapStyles/images/preview-ortho.png';
import vector from './images/preview-vector.png'; import vector from '../MapStyles/images/preview-vector.png';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
const SwitchMapStyle = ({ isVector }) => { const SwitchMapStyle = ({ isVector }) => {

View file

@ -7,8 +7,10 @@ import SwitchMapStyle from './SwitchMapStyle';
import SearchInput from './SearchInput'; import SearchInput from './SearchInput';
import { getJSON, ajax } from '@utils'; import { getJSON, ajax } from '@utils';
import { gpx, kml } from '@tmcw/togeojson/dist/togeojson.es.js'; import { gpx, kml } from '@tmcw/togeojson/dist/togeojson.es.js';
import ortho from './styles/ortho.json'; import ortho from '../MapStyles/ortho.json';
import vector from './styles/vector.json'; import orthoCadastre from '../MapStyles/orthoCadastre.json';
import vector from '../MapStyles/vector.json';
import vectorCadastre from '../MapStyles/vectorCadastre.json';
import { polygonCadastresFill, polygonCadastresLine } from './utils'; import { polygonCadastresFill, polygonCadastresLine } from './utils';
import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css'; import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';
@ -25,7 +27,7 @@ function filterFeatureCollection(featureCollection, source) {
function noop() {} function noop() {}
function MapEditor({ featureCollection, url, preview }) { function MapEditor({ featureCollection, url, preview, hasCadastres }) {
const drawControl = useRef(null); const drawControl = useRef(null);
const [style, setStyle] = useState('ortho'); const [style, setStyle] = useState('ortho');
const [coords, setCoords] = useState([1.7, 46.9]); const [coords, setCoords] = useState([1.7, 46.9]);
@ -33,7 +35,12 @@ function MapEditor({ featureCollection, url, preview }) {
const [currentMap, setCurrentMap] = useState({}); const [currentMap, setCurrentMap] = useState({});
const [bbox, setBbox] = useState(featureCollection.bbox); const [bbox, setBbox] = useState(featureCollection.bbox);
const [importInputs, setImportInputs] = useState([]); const [importInputs, setImportInputs] = useState([]);
const mapStyle = style === 'ortho' ? ortho : vector; let mapStyle = style === 'ortho' ? ortho : vector;
if (hasCadastres) {
mapStyle = style === 'ortho' ? orthoCadastre : vectorCadastre;
}
const cadastresFeatureCollection = filterFeatureCollection( const cadastresFeatureCollection = filterFeatureCollection(
featureCollection, featureCollection,
'cadastre' 'cadastre'
@ -170,26 +177,14 @@ function MapEditor({ featureCollection, url, preview }) {
const draw = drawControl.current.draw; const draw = drawControl.current.draw;
const featureCollection = draw.getAll(); const featureCollection = draw.getAll();
let inputs = [...importInputs]; let inputs = [...importInputs];
let drawFeatureIdToRemove;
const inputToRemove = inputs.find((input) => input.id === inputId); const inputToRemove = inputs.find((input) => input.id === inputId);
for (const feature of featureCollection.features) { for (const feature of featureCollection.features) {
if (inputToRemove.featureId === feature.properties.id) { if (inputToRemove.featureId === feature.properties.id) {
drawFeatureIdToRemove = feature.id; const featureToRemove = draw.get(feature.id);
}
}
if (inputToRemove.featureId) {
try {
await getJSON(`${url}/${inputToRemove.featureId}`, null, 'delete'); await getJSON(`${url}/${inputToRemove.featureId}`, null, 'delete');
draw.delete(drawFeatureIdToRemove).getAll(); draw.delete(feature.id).getAll();
} catch (e) { updateFeaturesList([featureToRemove]);
throw new Error(
`La feature ${inputToRemove.featureId} a déjà été supprimée manuellement`,
e
);
} finally {
updateImportInputs(inputs, inputId);
} }
} }
updateImportInputs(inputs, inputId); updateImportInputs(inputs, inputId);
@ -212,6 +207,18 @@ function MapEditor({ featureCollection, url, preview }) {
return ( return (
<> <>
<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>
<div className="file-import" style={{ marginBottom: '20px' }}> <div className="file-import" style={{ marginBottom: '20px' }}>
<button className="button send primary" onClick={addInputFile}> <button className="button send primary" onClick={addInputFile}>
Ajouter un fichier GPX ou KML Ajouter un fichier GPX ou KML
@ -244,7 +251,7 @@ function MapEditor({ featureCollection, url, preview }) {
</div> </div>
<div <div
style={{ style={{
marginBottom: '62px' marginBottom: '50px'
}} }}
> >
<SearchInput <SearchInput
@ -310,7 +317,8 @@ MapEditor.propTypes = {
id: PropTypes.number id: PropTypes.number
}), }),
url: PropTypes.string, url: PropTypes.string,
preview: PropTypes.bool preview: PropTypes.bool,
hasCadastres: PropTypes.bool
}; };
export default MapEditor; export default MapEditor;

View file

@ -0,0 +1,36 @@
import React from 'react';
import ortho from '../MapStyles/images/preview-ortho.png';
import vector from '../MapStyles/images/preview-vector.png';
import PropTypes from 'prop-types';
const SwitchMapStyle = ({ isVector }) => {
const style = isVector ? 'Satellite' : 'Vectoriel';
const source = `${isVector ? ortho : vector}`;
const imgStyle = {
width: '100%',
height: '100%',
cursor: 'pointer'
};
const textStyle = {
position: 'relative',
bottom: '26px',
left: '4px',
color: `${isVector ? '#fff' : '#000'}`
};
return (
<div className="switch-style mapboxgl-ctrl-swith-map-style">
<img alt={style} style={imgStyle} src={source} />
<div className="text" style={textStyle}>
{style}
</div>
</div>
);
};
SwitchMapStyle.propTypes = {
isVector: PropTypes.bool
};
export default SwitchMapStyle;

View file

@ -1,11 +1,26 @@
import React from 'react'; import React, { useState } from 'react';
import ReactMapboxGl, { ZoomControl, GeoJSONLayer } from 'react-mapbox-gl'; import ReactMapboxGl, { ZoomControl, GeoJSONLayer } from 'react-mapbox-gl';
import mapboxgl from 'mapbox-gl'; import mapboxgl from 'mapbox-gl';
import SwitchMapStyle from './SwitchMapStyle';
import ortho from '../MapStyles/ortho.json';
import orthoCadastre from '../MapStyles/orthoCadastre.json';
import vector from '../MapStyles/vector.json';
import vectorCadastre from '../MapStyles/vectorCadastre.json';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
const Map = ReactMapboxGl({}); const Map = ReactMapboxGl({});
const MapReader = ({ featureCollection }) => { const MapReader = ({ featureCollection }) => {
const [style, setStyle] = useState('ortho');
const hasCadastres = featureCollection.features.find(
(feature) => feature.properties.source === 'cadastre'
);
let mapStyle = style === 'ortho' ? ortho : vector;
if (hasCadastres) {
mapStyle = style === 'ortho' ? orthoCadastre : vectorCadastre;
}
const [a1, a2, b1, b2] = featureCollection.bbox; const [a1, a2, b1, b2] = featureCollection.bbox;
const boundData = [ const boundData = [
[a1, a2], [a1, a2],
@ -52,7 +67,7 @@ const MapReader = ({ featureCollection }) => {
}; };
const polygonCadastresFill = { const polygonCadastresFill = {
'fill-color': '#9CA090', 'fill-color': '#FAD859',
'fill-opacity': 0.5 'fill-opacity': 0.5
}; };
@ -97,7 +112,7 @@ const MapReader = ({ featureCollection }) => {
<Map <Map
fitBounds={boundData} fitBounds={boundData}
fitBoundsOptions={{ padding: 100 }} fitBoundsOptions={{ padding: 100 }}
style="https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json" style={mapStyle}
containerStyle={{ containerStyle={{
height: '400px', height: '400px',
width: '100%' width: '100%'
@ -121,6 +136,20 @@ const MapReader = ({ featureCollection }) => {
fillPaint={polygonCadastresFill} fillPaint={polygonCadastresFill}
linePaint={polygonCadastresLine} linePaint={polygonCadastresLine}
/> />
<div
className="style-switch"
style={{
position: 'absolute',
bottom: 0,
left: 0
}}
onClick={() =>
style === 'ortho' ? setStyle('vector') : setStyle('ortho')
}
>
<SwitchMapStyle isVector={style === 'vector' ? true : false} />
</div>
<ZoomControl /> <ZoomControl />
</Map> </Map>
); );

View file

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View file

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -80,6 +80,10 @@ class Champs::CarteChamp < Champ
} }
end end
def has_cadastres?
cadastres? ? true : false
end
def geometry? def geometry?
geo_areas.present? geo_areas.present?
end end

View file

@ -6,12 +6,12 @@
%ul.footer-logos %ul.footer-logos
%li.footer-text %li.footer-text
Un service fourni par la Un service fourni par la
= link_to "DINUM", "http://www.modernisation.gouv.fr/", title: "Direction Interministérielle au Numérique" = link_to "DINUM", "https://numerique.gouv.fr/", title: "Direction Interministérielle au Numérique"
%br %br
et incubé par et incubé par
= link_to "beta.gouv.fr", "https://beta.gouv.fr", title: "le site de Beta.gouv.fr" = link_to "beta.gouv.fr", "https://beta.gouv.fr", title: "le site de Beta.gouv.fr"
%li %li
= link_to "http://www.modernisation.gouv.fr/", title: "DINUM" do = link_to "https://numerique.gouv.fr/", title: "DINUM" do
%span.footer-logo.footer-logo-dinum{ role: 'img', 'aria-label': 'DINUM' } %span.footer-logo.footer-logo-dinum{ role: 'img', 'aria-label': 'DINUM' }
= link_to "https://beta.gouv.fr", title: "le site de Beta.gouv.fr" do = link_to "https://beta.gouv.fr", title: "le site de Beta.gouv.fr" do
%span.footer-logo.footer-logo-beta-gouv-fr{ role: 'img', 'aria-label': 'beta.gouv.fr' } %span.footer-logo.footer-logo-beta-gouv-fr{ role: 'img', 'aria-label': 'beta.gouv.fr' }

View file

@ -1,6 +1,6 @@
- if feature_enabled?(:new_map_editor) - if feature_enabled?(:new_map_editor)
- preview = !champ.persisted? - preview = !champ.persisted?
= react_component("MapEditor", { featureCollection: champ.to_feature_collection, url: champs_carte_features_path(preview ? 'preview' : champ), preview: preview }, class: "carte-#{champ.id}") = react_component("MapEditor", { featureCollection: champ.to_feature_collection, hasCadastres: champ.has_cadastres?, url: champs_carte_features_path(preview ? 'preview' : champ), preview: preview }, class: "carte-#{champ.id}")
- else - else
.toolbar .toolbar
%button.button.primary.new-area Ajouter une zone %button.button.primary.new-area Ajouter une zone