Merge pull request #6322 from tchak/add-point-by-coordinates
Ajouter un point sur la carte en saisissant les coordonnées
This commit is contained in:
commit
00fd2783c7
8 changed files with 127 additions and 5 deletions
|
@ -135,6 +135,11 @@
|
||||||
height: 18px;
|
height: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-size-big {
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
.state-button {
|
.state-button {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,10 @@
|
||||||
color: $black;
|
color: $black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mt-1 {
|
||||||
|
margin-top: $default-spacer;
|
||||||
|
}
|
||||||
|
|
||||||
.mt-2 {
|
.mt-2 {
|
||||||
margin-top: 2 * $default-spacer;
|
margin-top: 2 * $default-spacer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,15 @@ import React, { useState } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ReactMapboxGl, { ZoomControl } from 'react-mapbox-gl';
|
import ReactMapboxGl, { ZoomControl } from 'react-mapbox-gl';
|
||||||
import DrawControl from 'react-mapbox-gl-draw';
|
import DrawControl from 'react-mapbox-gl-draw';
|
||||||
import { CursorClickIcon } from '@heroicons/react/outline';
|
import {
|
||||||
|
CursorClickIcon,
|
||||||
|
PlusIcon,
|
||||||
|
LocationMarkerIcon
|
||||||
|
} from '@heroicons/react/outline';
|
||||||
|
import CoordinateInput from 'react-coordinate-input';
|
||||||
|
import { fire } from '@utils';
|
||||||
|
import VisuallyHidden from '@reach/visually-hidden';
|
||||||
|
import { useId } from '@reach/auto-id';
|
||||||
import 'mapbox-gl/dist/mapbox-gl.css';
|
import 'mapbox-gl/dist/mapbox-gl.css';
|
||||||
import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';
|
import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';
|
||||||
|
|
||||||
|
@ -162,6 +170,87 @@ function MapEditor({ featureCollection, url, options, preview }) {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Mapbox>
|
</Mapbox>
|
||||||
|
<PointInput />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function PointInput() {
|
||||||
|
const inputId = useId();
|
||||||
|
const [value, setValue] = useState('');
|
||||||
|
const [feature, setFeature] = useState(null);
|
||||||
|
const getCurrentPosition = () => {
|
||||||
|
navigator.geolocation &&
|
||||||
|
navigator.geolocation.getCurrentPosition(({ coords }) => {
|
||||||
|
setValue(
|
||||||
|
`${coords.latitude.toPrecision(6)}, ${coords.longitude.toPrecision(
|
||||||
|
6
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const addPoint = () => {
|
||||||
|
if (feature) {
|
||||||
|
fire(document, 'map:feature:create', feature);
|
||||||
|
setValue('');
|
||||||
|
setFeature(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<label
|
||||||
|
className="areas-title mt-1"
|
||||||
|
htmlFor={inputId}
|
||||||
|
style={{ fontSize: '16px' }}
|
||||||
|
>
|
||||||
|
Ajouter un point sur la carte
|
||||||
|
</label>
|
||||||
|
<div className="flex align-center mt-1 mb-2">
|
||||||
|
{navigator.geolocation ? (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="button mr-1"
|
||||||
|
onClick={getCurrentPosition}
|
||||||
|
title="Localiser votre position"
|
||||||
|
>
|
||||||
|
<VisuallyHidden>Localiser votre position</VisuallyHidden>
|
||||||
|
<LocationMarkerIcon className="icon-size-big" />
|
||||||
|
</button>
|
||||||
|
) : null}
|
||||||
|
<CoordinateInput
|
||||||
|
id={inputId}
|
||||||
|
className="m-0 mr-1"
|
||||||
|
value={value}
|
||||||
|
onChange={(value, { dd }) => {
|
||||||
|
setValue(value);
|
||||||
|
setFeature(
|
||||||
|
dd.length
|
||||||
|
? {
|
||||||
|
type: 'Feature',
|
||||||
|
geometry: {
|
||||||
|
type: 'Point',
|
||||||
|
coordinates: dd.reverse()
|
||||||
|
},
|
||||||
|
properties: {}
|
||||||
|
}
|
||||||
|
: null
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="button"
|
||||||
|
onClick={addPoint}
|
||||||
|
disabled={!feature}
|
||||||
|
title="Ajouter le point avec les coordonnées saisies sur la carte"
|
||||||
|
>
|
||||||
|
<VisuallyHidden>
|
||||||
|
Ajouter le point avec les coordonnées saisies sur la carte
|
||||||
|
</VisuallyHidden>
|
||||||
|
<PlusIcon className="icon-size-big" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
%li{ class: editing ? '' : 'flex column mb-2' }
|
%li{ class: editing ? 'mb-1' : 'flex column mb-2' }
|
||||||
- if editing
|
- if editing
|
||||||
= link_to '#', data: { geo_area: geo_area.id } do
|
= link_to '#', data: { geo_area: geo_area.id } do
|
||||||
= geo_area_label(geo_area)
|
= geo_area_label(geo_area)
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
- champ.selections_utilisateur.each do |geo_area|
|
- champ.selections_utilisateur.each do |geo_area|
|
||||||
= render partial: 'shared/champs/carte/geo_area', locals: { geo_area: geo_area, editing: editing }
|
= render partial: 'shared/champs/carte/geo_area', locals: { geo_area: geo_area, editing: editing }
|
||||||
|
|
||||||
- if champ.cadastres?
|
- if champ.cadastres.present?
|
||||||
.areas-title Parcelles cadastrales
|
.areas-title Parcelles cadastrales
|
||||||
.areas
|
.areas
|
||||||
%ul
|
%ul
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
"@rails/webpacker": "5.1.1",
|
"@rails/webpacker": "5.1.1",
|
||||||
"@reach/combobox": "^0.13.0",
|
"@reach/combobox": "^0.13.0",
|
||||||
"@reach/slider": "^0.15.0",
|
"@reach/slider": "^0.15.0",
|
||||||
|
"@reach/visually-hidden": "^0.15.2",
|
||||||
"@sentry/browser": "^5.15.5",
|
"@sentry/browser": "^5.15.5",
|
||||||
"@tmcw/togeojson": "^4.3.0",
|
"@tmcw/togeojson": "^4.3.0",
|
||||||
"babel-plugin-macros": "^2.8.0",
|
"babel-plugin-macros": "^2.8.0",
|
||||||
|
@ -27,6 +28,7 @@
|
||||||
"match-sorter": "^6.2.0",
|
"match-sorter": "^6.2.0",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^17.0.1",
|
"react": "^17.0.1",
|
||||||
|
"react-coordinate-input": "^1.0.0-rc.2",
|
||||||
"react-dom": "^17.0.1",
|
"react-dom": "^17.0.1",
|
||||||
"react-intersection-observer": "^8.31.0",
|
"react-intersection-observer": "^8.31.0",
|
||||||
"react-mapbox-gl": "^5.1.1",
|
"react-mapbox-gl": "^5.1.1",
|
||||||
|
|
|
@ -122,7 +122,9 @@ feature 'As an administrateur I can edit types de champ', js: true do
|
||||||
preview_window = window_opened_by { click_on 'Prévisualiser le formulaire' }
|
preview_window = window_opened_by { click_on 'Prévisualiser le formulaire' }
|
||||||
within_window(preview_window) do
|
within_window(preview_window) do
|
||||||
expect(page).to have_content('Libellé de champ carte')
|
expect(page).to have_content('Libellé de champ carte')
|
||||||
expect(page).to have_content('Parcelles cadastrales')
|
expect(page).to have_content('Ajouter un point sur la carte')
|
||||||
|
fill_in 'Ajouter un point sur la carte', with: "48°52'27\"N 002°54'32\"E"
|
||||||
|
click_on 'Ajouter le point avec les coordonnées saisies sur la carte'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
22
yarn.lock
22
yarn.lock
|
@ -1740,6 +1740,14 @@
|
||||||
tiny-warning "^1.0.3"
|
tiny-warning "^1.0.3"
|
||||||
tslib "^2.1.0"
|
tslib "^2.1.0"
|
||||||
|
|
||||||
|
"@reach/visually-hidden@^0.15.2":
|
||||||
|
version "0.15.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@reach/visually-hidden/-/visually-hidden-0.15.2.tgz#07794cb53f4bd23a9452d53a0ad7778711ee323f"
|
||||||
|
integrity sha512-suDSCuKKuqiEB4UDgwWHbrPRxNwrusZ3ImXr85kfsQXGmKptMogaq22xoaHn32NC++lzZXxdWtAJriieszzFXw==
|
||||||
|
dependencies:
|
||||||
|
prop-types "^15.7.2"
|
||||||
|
tslib "^2.3.0"
|
||||||
|
|
||||||
"@sentry/browser@^5.15.5":
|
"@sentry/browser@^5.15.5":
|
||||||
version "5.15.5"
|
version "5.15.5"
|
||||||
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.15.5.tgz#d9a51f1388581067b50d30ed9b1aed2cbb333a36"
|
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.15.5.tgz#d9a51f1388581067b50d30ed9b1aed2cbb333a36"
|
||||||
|
@ -6597,6 +6605,11 @@ ignore@^5.1.1, ignore@^5.1.4:
|
||||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
|
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
|
||||||
integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
|
integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
|
||||||
|
|
||||||
|
imask@^6.0.5:
|
||||||
|
version "6.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/imask/-/imask-6.1.0.tgz#8dcf4c44c51c4297f691349b925b7d5b21edff1c"
|
||||||
|
integrity sha512-IuElVZpc7iuGw+CXfwoUZYpGdoD5H7cGo3S93gZPgjTTWfY5XAXCFL3g3b/ZJBZ18RG2dFF2kxAuuFlXMjq7oQ==
|
||||||
|
|
||||||
import-cwd@^2.0.0:
|
import-cwd@^2.0.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9"
|
resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9"
|
||||||
|
@ -10464,6 +10477,13 @@ rc@^1.2.8:
|
||||||
minimist "^1.2.0"
|
minimist "^1.2.0"
|
||||||
strip-json-comments "~2.0.1"
|
strip-json-comments "~2.0.1"
|
||||||
|
|
||||||
|
react-coordinate-input@^1.0.0-rc.2:
|
||||||
|
version "1.0.0-rc.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-coordinate-input/-/react-coordinate-input-1.0.0-rc.2.tgz#274aa920ba28318f515f22089ff2f6870a0e66bd"
|
||||||
|
integrity sha512-Umfnh0jEt/bKmIM+B/fT3QscL06CrRo0WRYIMEhgcieoeU5A54hR5WGjS7dKm33sMF5fywGXs7rZ/iyCk/N5yA==
|
||||||
|
dependencies:
|
||||||
|
imask "^6.0.5"
|
||||||
|
|
||||||
react-dom@^17.0.1:
|
react-dom@^17.0.1:
|
||||||
version "17.0.1"
|
version "17.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.1.tgz#1de2560474ec9f0e334285662ede52dbc5426fc6"
|
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.1.tgz#1de2560474ec9f0e334285662ede52dbc5426fc6"
|
||||||
|
@ -12263,7 +12283,7 @@ tslib@^2.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.1.tgz#410eb0d113e5b6356490eec749603725b021b43e"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.1.tgz#410eb0d113e5b6356490eec749603725b021b43e"
|
||||||
integrity sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==
|
integrity sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==
|
||||||
|
|
||||||
tslib@^2.1.0:
|
tslib@^2.1.0, tslib@^2.3.0:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
|
||||||
integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
|
integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
|
||||||
|
|
Loading…
Reference in a new issue