Merge commit '48de67b6c9c0faa337994f86ed81f6bbf73cdd04'
This commit is contained in:
commit
98a3bc32e5
24 changed files with 320 additions and 518 deletions
|
@ -6,10 +6,10 @@
|
|||
#carte-page {
|
||||
#map {
|
||||
height: 600px;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
#map.qp,
|
||||
#map.cadastre {
|
||||
#map.edit {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
|
@ -30,13 +30,6 @@
|
|||
cursor: url("/assets/edit.png"), default !important;
|
||||
}
|
||||
|
||||
#infos-dossiers {
|
||||
#map.mini {
|
||||
height: 300px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
#map.mode-create {
|
||||
cursor: url("/assets/pencil.png"), crosshair !important;
|
||||
}
|
||||
|
@ -47,17 +40,17 @@
|
|||
stroke-opacity: 1;
|
||||
stroke: #D7217E;
|
||||
position: absolute;
|
||||
z-index: 1001;
|
||||
z-index: 100;
|
||||
fill: #D7217E;
|
||||
fill-opacity: 0.75;
|
||||
}
|
||||
|
||||
#map.mode-delete path {
|
||||
#map.mode-delete path.leaflet-polygon {
|
||||
cursor: no-drop !important;
|
||||
}
|
||||
|
||||
#map.mode-delete path:hover {
|
||||
fill: #4D4D4D !important;
|
||||
&:hover {
|
||||
fill: #4D4D4D !important;
|
||||
}
|
||||
}
|
||||
|
||||
#map div.leaflet-edge {
|
||||
|
|
|
@ -103,13 +103,13 @@ class Admin::ProceduresController < AdminController
|
|||
if ProcedurePath.valid?(@procedure, path)
|
||||
@procedure.publish_with_path!(path)
|
||||
reset_procedure
|
||||
flash.notice = 'Démarche modifiée. Tous les brouillons de cette démarche ont été supprimés.'
|
||||
flash.notice = 'Démarche modifiée. Tous les dossiers de cette démarche ont été supprimés.'
|
||||
else
|
||||
flash.alert = 'Lien de la démarche invalide.'
|
||||
end
|
||||
else
|
||||
reset_procedure
|
||||
flash.notice = 'Démarche modifiée. Tous les brouillons de cette démarche ont été supprimés.'
|
||||
flash.notice = 'Démarche modifiée.'
|
||||
end
|
||||
|
||||
redirect_to edit_admin_procedure_path(id: @procedure.id)
|
||||
|
|
|
@ -129,25 +129,6 @@ module NewGestionnaire
|
|||
end
|
||||
end
|
||||
|
||||
def position
|
||||
etablissement = dossier.etablissement
|
||||
|
||||
if etablissement.present?
|
||||
point = Carto::Geocodeur.convert_adresse_to_point(etablissement.geo_adresse)
|
||||
end
|
||||
|
||||
lon = "2.428462"
|
||||
lat = "46.538192"
|
||||
zoom = "13"
|
||||
|
||||
if point.present?
|
||||
lon = point.x.to_s
|
||||
lat = point.y.to_s
|
||||
end
|
||||
|
||||
render json: { lon: lon, lat: lat, zoom: zoom, dossier_id: params[:dossier_id] }
|
||||
end
|
||||
|
||||
def create_avis
|
||||
@avis = Avis.new(avis_params.merge(claimant: current_gestionnaire, dossier: dossier))
|
||||
if @avis.save
|
||||
|
|
|
@ -12,51 +12,43 @@ class Users::CarteController < UsersController
|
|||
end
|
||||
|
||||
def save
|
||||
safe_json_latlngs = clean_json_latlngs(params[:json_latlngs])
|
||||
geo_json = clean_json_latlngs(params[:selection])
|
||||
dossier = current_user_dossier
|
||||
|
||||
dossier.quartier_prioritaires.each(&:destroy)
|
||||
dossier.cadastres.each(&:destroy)
|
||||
|
||||
if safe_json_latlngs.present?
|
||||
ModuleApiCartoService.save_qp! dossier, safe_json_latlngs
|
||||
ModuleApiCartoService.save_cadastre! dossier, safe_json_latlngs
|
||||
if geo_json.present?
|
||||
ModuleApiCartoService.save_qp! dossier, geo_json
|
||||
ModuleApiCartoService.save_cadastre! dossier, geo_json
|
||||
end
|
||||
|
||||
dossier.update(json_latlngs: safe_json_latlngs)
|
||||
dossier.update!(json_latlngs: geo_json)
|
||||
|
||||
redirect_to brouillon_dossier_path(dossier)
|
||||
end
|
||||
|
||||
def get_position
|
||||
begin
|
||||
etablissement = current_user_dossier.etablissement
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
etablissement = nil
|
||||
def zones
|
||||
@dossier = current_user_dossier
|
||||
@data = {}
|
||||
|
||||
geo_json = JSON.parse(params.required(:selection))
|
||||
|
||||
if geo_json.first == ["error", "TooManyPolygons"]
|
||||
@error = true
|
||||
else
|
||||
if @dossier.procedure.module_api_carto.quartiers_prioritaires?
|
||||
quartiers_prioritaires = ModuleApiCartoService.generate_qp(geo_json).values
|
||||
@dossier.quartier_prioritaires.build(quartiers_prioritaires)
|
||||
@data[:quartiersPrioritaires] = quartiers_prioritaires
|
||||
end
|
||||
|
||||
if @dossier.procedure.module_api_carto.cadastre?
|
||||
cadastres = ModuleApiCartoService.generate_cadastre(geo_json)
|
||||
@dossier.cadastres.build(cadastres)
|
||||
@data[:cadastres] = cadastres
|
||||
end
|
||||
end
|
||||
|
||||
if etablissement.present?
|
||||
point = Carto::Geocodeur.convert_adresse_to_point(etablissement.geo_adresse)
|
||||
end
|
||||
|
||||
lon = '2.428462'
|
||||
lat = '46.538192'
|
||||
zoom = '13'
|
||||
|
||||
if point.present?
|
||||
lon = point.x.to_s
|
||||
lat = point.y.to_s
|
||||
end
|
||||
|
||||
render json: { lon: lon, lat: lat, zoom: zoom, dossier_id: params[:dossier_id] }
|
||||
end
|
||||
|
||||
def get_qp
|
||||
render json: { quartier_prioritaires: ModuleApiCartoService.generate_qp(JSON.parse(params[:coordinates])) }
|
||||
end
|
||||
|
||||
def get_cadastre
|
||||
render json: { cadastres: ModuleApiCartoService.generate_cadastre(JSON.parse(params[:coordinates])) }
|
||||
end
|
||||
|
||||
def self.route_authorization
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
import L from 'leaflet';
|
||||
import { getJSON } from '@utils';
|
||||
|
||||
import { getData } from '../shared/data';
|
||||
import { DEFAULT_POSITION } from '../shared/carto';
|
||||
|
||||
import { initMap } from '../shared/carto';
|
||||
import {
|
||||
drawCadastre,
|
||||
drawQuartiersPrioritaires,
|
||||
|
@ -12,31 +8,17 @@ import {
|
|||
|
||||
function initialize() {
|
||||
if (document.getElementById('map')) {
|
||||
getJSON(getData('carto').getPositionUrl).then(
|
||||
position => initializeWithPosition(position),
|
||||
() => initializeWithPosition(DEFAULT_POSITION)
|
||||
);
|
||||
const position = getData('carto').position;
|
||||
const map = initMap(position);
|
||||
const data = getData('carto');
|
||||
|
||||
// draw external polygons
|
||||
drawCadastre(map, data);
|
||||
drawQuartiersPrioritaires(map, data);
|
||||
|
||||
// draw user polygon
|
||||
drawUserSelection(map, data);
|
||||
}
|
||||
}
|
||||
|
||||
addEventListener('turbolinks:load', initialize);
|
||||
|
||||
function initializeWithPosition(position) {
|
||||
const map = L.map('map', {
|
||||
scrollWheelZoom: false
|
||||
}).setView([position.lat, position.lon], position.zoom);
|
||||
|
||||
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution:
|
||||
'© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
|
||||
}).addTo(map);
|
||||
|
||||
const data = getData('carto');
|
||||
|
||||
// draw external polygons
|
||||
drawCadastre(map, data);
|
||||
drawQuartiersPrioritaires(map, data);
|
||||
|
||||
// draw user polygon
|
||||
drawUserSelection(map, data);
|
||||
}
|
||||
|
|
|
@ -1,45 +1,32 @@
|
|||
import L from 'leaflet';
|
||||
import {
|
||||
drawLayer,
|
||||
noEditStyle,
|
||||
CADASTRE_POLYGON_STYLE,
|
||||
QP_POLYGON_STYLE
|
||||
} from '../../shared/carto';
|
||||
|
||||
function drawLayerWithItems(map, items, style) {
|
||||
if (Array.isArray(items) && items.length > 0) {
|
||||
const layer = new L.GeoJSON();
|
||||
|
||||
items.forEach(function(item) {
|
||||
layer.addData(item.geometry);
|
||||
});
|
||||
|
||||
layer.setStyle(style).addTo(map);
|
||||
}
|
||||
export function drawCadastre(map, data) {
|
||||
drawLayer(
|
||||
map,
|
||||
data.cadastres,
|
||||
noEditStyle(CADASTRE_POLYGON_STYLE),
|
||||
'cadastres'
|
||||
);
|
||||
}
|
||||
|
||||
export function drawCadastre(map, { dossierCadastres }) {
|
||||
drawLayerWithItems(map, dossierCadastres, {
|
||||
fillColor: '#8A6D3B',
|
||||
weight: 2,
|
||||
opacity: 0.7,
|
||||
color: '#8A6D3B',
|
||||
dashArray: '3',
|
||||
fillOpacity: 0.5
|
||||
});
|
||||
export function drawQuartiersPrioritaires(map, data) {
|
||||
drawLayer(
|
||||
map,
|
||||
data.quartiersPrioritaires,
|
||||
noEditStyle(QP_POLYGON_STYLE),
|
||||
'quartiersPrioritaires'
|
||||
);
|
||||
}
|
||||
|
||||
export function drawQuartiersPrioritaires(
|
||||
map,
|
||||
{ dossierQuartiersPrioritaires }
|
||||
) {
|
||||
drawLayerWithItems(map, dossierQuartiersPrioritaires, {
|
||||
fillColor: '#31708F',
|
||||
weight: 2,
|
||||
opacity: 0.7,
|
||||
color: '#31708F',
|
||||
dashArray: '3',
|
||||
fillOpacity: 0.5
|
||||
});
|
||||
}
|
||||
|
||||
export function drawUserSelection(map, { dossierJsonLatLngs }) {
|
||||
if (dossierJsonLatLngs.length > 0) {
|
||||
const polygon = L.polygon(dossierJsonLatLngs, {
|
||||
export function drawUserSelection(map, data) {
|
||||
if (data.selection.length > 0) {
|
||||
const polygon = L.polygon(data.selection, {
|
||||
color: 'red',
|
||||
zIndex: 3
|
||||
}).addTo(map);
|
||||
|
|
|
@ -1,142 +1,69 @@
|
|||
import L from 'leaflet';
|
||||
import area from '@turf/area';
|
||||
import FreeDraw, { NONE, EDIT, CREATE, DELETE } from 'leaflet-freedraw';
|
||||
import $ from 'jquery';
|
||||
|
||||
import FreeDraw, { NONE, CREATE } from 'leaflet-freedraw';
|
||||
import { fire, on, getJSON } from '@utils';
|
||||
|
||||
import { getData } from '../shared/data';
|
||||
import { DEFAULT_POSITION, LAT, LON } from '../shared/carto';
|
||||
import { qpActive, displayQP, getQP } from './carto/qp';
|
||||
import { cadastreActive, displayCadastre, getCadastre } from './carto/cadastre';
|
||||
import { initMap } from '../shared/carto';
|
||||
|
||||
import polygonArea from './carto/polygon_area';
|
||||
import drawFactory from './carto/draw';
|
||||
|
||||
function initialize() {
|
||||
if ($('#map').length > 0) {
|
||||
getPosition(getData('carto').dossierId).then(
|
||||
position => initializeWithPosition(position),
|
||||
() => initializeWithPosition(DEFAULT_POSITION)
|
||||
);
|
||||
if (document.getElementById('map')) {
|
||||
const data = getData('carto');
|
||||
const position = data.position;
|
||||
|
||||
const map = initMap(position);
|
||||
const freeDraw = new FreeDraw({
|
||||
mode: NONE,
|
||||
smoothFactor: 4,
|
||||
mergePolygons: false
|
||||
});
|
||||
|
||||
map.addLayer(freeDraw);
|
||||
|
||||
addEventFreeDraw(freeDraw);
|
||||
addEventSearchAddress(map);
|
||||
|
||||
const cartoDrawZones = drawFactory(map, freeDraw);
|
||||
window.DS = { cartoDrawZones };
|
||||
|
||||
cartoDrawZones(data);
|
||||
|
||||
if (freeDraw.polygons[0]) {
|
||||
map.setZoom(18);
|
||||
map.fitBounds(freeDraw.polygons[0].getBounds());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addEventListener('turbolinks:load', initialize);
|
||||
|
||||
function initializeWithPosition(position) {
|
||||
const OSM = L.tileLayer(
|
||||
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
{
|
||||
attribution:
|
||||
'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
||||
}
|
||||
);
|
||||
|
||||
const map = L.map('map', {
|
||||
center: new L.LatLng(position.lat, position.lon),
|
||||
zoom: position.zoom,
|
||||
layers: [OSM],
|
||||
scrollWheelZoom: false
|
||||
});
|
||||
|
||||
if (qpActive()) {
|
||||
displayQP(map, getJsonValue('#quartier_prioritaires'));
|
||||
}
|
||||
|
||||
if (cadastreActive()) {
|
||||
displayCadastre(map, getJsonValue('#cadastres'));
|
||||
}
|
||||
|
||||
const freeDraw = new FreeDraw({
|
||||
mode: NONE,
|
||||
smoothFactor: 4,
|
||||
mergePolygons: false
|
||||
});
|
||||
|
||||
map.addLayer(freeDraw);
|
||||
|
||||
const latLngs = getJsonValue('#json_latlngs');
|
||||
|
||||
if (latLngs.length) {
|
||||
map.setZoom(18);
|
||||
|
||||
for (let polygon of latLngs) {
|
||||
freeDraw.createPolygon(polygon);
|
||||
}
|
||||
|
||||
map.fitBounds(freeDraw.polygons[0].getBounds());
|
||||
} else if (position.lat == LAT && position.lon == LON) {
|
||||
map.setView(new L.LatLng(position.lat, position.lon), position.zoom);
|
||||
}
|
||||
|
||||
addEventFreeDraw(map, freeDraw);
|
||||
addEventSearchAddress(map);
|
||||
}
|
||||
|
||||
function getExternalData(map, latLngs) {
|
||||
const { dossierId } = getData('carto');
|
||||
|
||||
if (qpActive()) {
|
||||
getQP(dossierId, latLngs).then(qps => displayQP(map, qps));
|
||||
}
|
||||
|
||||
if (cadastreActive()) {
|
||||
const polygons = { type: 'FeatureCollection', features: [] };
|
||||
|
||||
for (let i = 0; i < latLngs.length; i++) {
|
||||
polygons.features.push(featurePolygonLatLngs(latLngs[i]));
|
||||
}
|
||||
|
||||
if (area(polygons) < 300000) {
|
||||
getCadastre(dossierId, latLngs).then(cadastres =>
|
||||
displayCadastre(map, cadastres)
|
||||
);
|
||||
} else {
|
||||
displayCadastre(map, [{ zoom_error: true }]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function featurePolygonLatLngs(coordinates) {
|
||||
return {
|
||||
type: 'Feature',
|
||||
properties: {},
|
||||
geometry: {
|
||||
type: 'Polygon',
|
||||
coordinates: [JSON.parse(getJsonPolygons([coordinates]))['latLngs']]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function addEventFreeDraw(map, freeDraw) {
|
||||
function addEventFreeDraw(freeDraw) {
|
||||
freeDraw.on('markers', ({ latLngs }) => {
|
||||
$('#json_latlngs').val(JSON.stringify(latLngs));
|
||||
const input = document.querySelector('input[name=selection]');
|
||||
|
||||
addEventEdit(freeDraw);
|
||||
if (polygonArea(latLngs) < 300000) {
|
||||
input.value = JSON.stringify(latLngs);
|
||||
} else {
|
||||
input.value = '{ "error": "TooManyPolygons" }';
|
||||
}
|
||||
|
||||
getExternalData(map, latLngs);
|
||||
fire(input, 'change');
|
||||
});
|
||||
|
||||
$('#map').on('click', () => {
|
||||
on('#map', 'click', () => {
|
||||
freeDraw.mode(NONE);
|
||||
});
|
||||
|
||||
$('#new').on('click', () => {
|
||||
on('#new', 'click', () => {
|
||||
freeDraw.mode(CREATE);
|
||||
});
|
||||
}
|
||||
|
||||
function addEventEdit(freeDraw) {
|
||||
$('.leaflet-container svg').removeAttr('pointer-events');
|
||||
$('.leaflet-container g path').on('click', () => {
|
||||
setTimeout(function() {
|
||||
freeDraw.mode(EDIT | DELETE);
|
||||
}, 50);
|
||||
});
|
||||
}
|
||||
|
||||
function getPosition(dossierId) {
|
||||
return $.getJSON(`/users/dossiers/${dossierId}/carte/position`);
|
||||
}
|
||||
|
||||
function getAddressPoint(map, request) {
|
||||
$.get('/ban/address_point', { request }).then(data => {
|
||||
getJSON('/ban/address_point', { request }).then(data => {
|
||||
if (data.lat !== null) {
|
||||
map.setView(new L.LatLng(data.lat, data.lon), data.zoom);
|
||||
}
|
||||
|
@ -144,34 +71,11 @@ function getAddressPoint(map, request) {
|
|||
}
|
||||
|
||||
function addEventSearchAddress(map) {
|
||||
$("#search-by-address input[type='address']").on(
|
||||
on(
|
||||
'#search-by-address input[type=address]',
|
||||
'autocomplete:select',
|
||||
(_, seggestion) => {
|
||||
getAddressPoint(map, seggestion['label']);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function getJsonValue(selector) {
|
||||
let data = document.querySelector(selector).value;
|
||||
if (data && data !== '[]') {
|
||||
return JSON.parse(data);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
function getJsonPolygons(latLngGroups) {
|
||||
var groups = [];
|
||||
|
||||
latLngGroups.forEach(function forEach(latLngs) {
|
||||
var group = [];
|
||||
|
||||
latLngs.forEach(function forEach(latLng) {
|
||||
group.push('[' + latLng.lng + ', ' + latLng.lat + ']');
|
||||
});
|
||||
|
||||
groups.push('{ "latLngs": [' + group.join(', ') + '] }');
|
||||
});
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
import L from 'leaflet';
|
||||
import $ from 'jquery';
|
||||
|
||||
export function cadastreActive() {
|
||||
return $('#map.cadastre').length > 0;
|
||||
}
|
||||
|
||||
export function getCadastre(dossierId, coordinates) {
|
||||
return $.ajax({
|
||||
method: 'post',
|
||||
url: `/users/dossiers/${dossierId}/carte/cadastre`,
|
||||
data: { coordinates: JSON.stringify(coordinates) },
|
||||
dataType: 'json'
|
||||
}).then(({ cadastres }) => cadastres);
|
||||
}
|
||||
|
||||
let cadastreItems;
|
||||
|
||||
export function displayCadastre(map, cadastres) {
|
||||
if (!cadastreActive()) return;
|
||||
|
||||
$('#cadastre.list ul').html('');
|
||||
newCadastreLayer(map);
|
||||
|
||||
if (cadastres.length == 1 && cadastres[0]['zoom_error']) {
|
||||
$('#cadastre.list ul').html(
|
||||
'<li><b>Merci de dessiner une surface plus petite afin de récupérer les parcelles cadastrales.</b></li>'
|
||||
);
|
||||
} else if (cadastres.length > 0) {
|
||||
cadastres.forEach(function(cadastre) {
|
||||
$('#cadastre.list ul').append(
|
||||
'<li> Parcelle nº ' +
|
||||
cadastre.numero +
|
||||
' - Feuille ' +
|
||||
cadastre.code_arr +
|
||||
' ' +
|
||||
cadastre.section +
|
||||
' ' +
|
||||
cadastre.feuille +
|
||||
'</li>'
|
||||
);
|
||||
|
||||
cadastreItems.addData(cadastre.geometry);
|
||||
});
|
||||
|
||||
cadastreItems.setStyle({
|
||||
fillColor: '#8a6d3b',
|
||||
weight: 2,
|
||||
opacity: 0.3,
|
||||
color: 'white',
|
||||
dashArray: '3',
|
||||
fillOpacity: 0.7
|
||||
});
|
||||
} else {
|
||||
$('#cadastre.list ul').html('<li>AUCUN</li>');
|
||||
}
|
||||
}
|
||||
|
||||
function newCadastreLayer(map) {
|
||||
if (cadastreItems) {
|
||||
map.removeLayer(cadastreItems);
|
||||
}
|
||||
|
||||
cadastreItems = new L.GeoJSON();
|
||||
cadastreItems.addTo(map);
|
||||
}
|
45
app/javascript/old_design/carto/draw.js
Normal file
45
app/javascript/old_design/carto/draw.js
Normal file
|
@ -0,0 +1,45 @@
|
|||
import { EDIT, DELETE } from 'leaflet-freedraw';
|
||||
import { on } from '@utils';
|
||||
|
||||
import {
|
||||
drawLayer,
|
||||
CADASTRE_POLYGON_STYLE,
|
||||
QP_POLYGON_STYLE
|
||||
} from '../../shared/carto';
|
||||
|
||||
const SOURCES = {
|
||||
cadastres: CADASTRE_POLYGON_STYLE,
|
||||
quartiersPrioritaires: QP_POLYGON_STYLE
|
||||
};
|
||||
|
||||
export default function draw(map, freeDraw) {
|
||||
return data => {
|
||||
if (data.selection) {
|
||||
drawSelection(freeDraw, data.selection);
|
||||
}
|
||||
for (let source of Object.keys(SOURCES)) {
|
||||
if (data[source]) {
|
||||
drawLayer(map, data[source], SOURCES[source], source);
|
||||
}
|
||||
}
|
||||
addEventEdit(freeDraw);
|
||||
};
|
||||
}
|
||||
|
||||
function drawSelection(selection, freeDraw) {
|
||||
for (let polygon of selection) {
|
||||
freeDraw.createPolygon(polygon);
|
||||
}
|
||||
}
|
||||
|
||||
function addEventEdit(freeDraw) {
|
||||
document
|
||||
.querySelector('.leaflet-container svg')
|
||||
.removeAttribute('pointer-events');
|
||||
|
||||
on('.leaflet-container g path', 'click', () => {
|
||||
setTimeout(() => {
|
||||
freeDraw.mode(EDIT | DELETE);
|
||||
}, 50);
|
||||
});
|
||||
}
|
19
app/javascript/old_design/carto/polygon_area.js
Normal file
19
app/javascript/old_design/carto/polygon_area.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
import area from '@turf/area';
|
||||
|
||||
export default function polygonArea(latLngs) {
|
||||
return area({
|
||||
type: 'FeatureCollection',
|
||||
features: latLngs.map(featurePolygonLatLngs)
|
||||
});
|
||||
}
|
||||
|
||||
function featurePolygonLatLngs(latLngs) {
|
||||
return {
|
||||
type: 'Feature',
|
||||
properties: {},
|
||||
geometry: {
|
||||
type: 'Polygon',
|
||||
coordinates: [latLngs.map(({ lng, lat }) => [lng, lat])]
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
import L from 'leaflet';
|
||||
import $ from 'jquery';
|
||||
|
||||
export function qpActive() {
|
||||
return $('#map.qp').length > 0;
|
||||
}
|
||||
|
||||
export function getQP(dossierId, coordinates) {
|
||||
return $.ajax({
|
||||
method: 'post',
|
||||
url: `/users/dossiers/${dossierId}/carte/qp`,
|
||||
data: { coordinates: JSON.stringify(coordinates) },
|
||||
dataType: 'json'
|
||||
}).done(({ quartier_prioritaires }) => values(quartier_prioritaires));
|
||||
}
|
||||
|
||||
let qpItems;
|
||||
|
||||
export function displayQP(map, qps) {
|
||||
if (!qpActive()) return;
|
||||
|
||||
$('#qp.list ul').html('');
|
||||
newQPLayer(map);
|
||||
|
||||
if (qps.length > 0) {
|
||||
qps.forEach(function(qp) {
|
||||
$('#qp.list ul').append('<li>' + qp.commune + ' : ' + qp.nom + '</li>');
|
||||
|
||||
qpItems.addData(qp.geometry);
|
||||
});
|
||||
|
||||
qpItems.setStyle({
|
||||
fillColor: '#31708f',
|
||||
weight: 2,
|
||||
opacity: 0.3,
|
||||
color: 'white',
|
||||
dashArray: '3',
|
||||
fillOpacity: 0.7
|
||||
});
|
||||
} else {
|
||||
$('#qp.list ul').html('<li>AUCUN</li>');
|
||||
}
|
||||
}
|
||||
|
||||
function newQPLayer(map) {
|
||||
if (qpItems) {
|
||||
map.removeLayer(qpItems);
|
||||
}
|
||||
|
||||
qpItems = new L.GeoJSON();
|
||||
qpItems.addTo(map);
|
||||
}
|
||||
|
||||
function values(obj) {
|
||||
return Object.keys(obj).map(v => obj[v]);
|
||||
}
|
|
@ -1,5 +1,71 @@
|
|||
const LON = '2.428462';
|
||||
const LAT = '46.538192';
|
||||
const DEFAULT_POSITION = { lon: LON, lat: LAT, zoom: 5 };
|
||||
import L from 'leaflet';
|
||||
|
||||
export { DEFAULT_POSITION, LAT, LON };
|
||||
const LAYERS = {};
|
||||
|
||||
export function initMap(position) {
|
||||
const map = L.map('map', {
|
||||
scrollWheelZoom: false
|
||||
}).setView([position.lat, position.lon], position.zoom);
|
||||
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution:
|
||||
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
}).addTo(map);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
export function drawLayer(map, data, style, layerName = 'default') {
|
||||
removeLayer(map, layerName);
|
||||
|
||||
if (Array.isArray(data) && data.length > 0) {
|
||||
const layer = createLayer(map, layerName);
|
||||
|
||||
data.forEach(function(item) {
|
||||
layer.addData(item.geometry);
|
||||
});
|
||||
|
||||
layer.setStyle(style).addTo(map);
|
||||
}
|
||||
}
|
||||
|
||||
export function noEditStyle(style) {
|
||||
return Object.assign({}, style, {
|
||||
opacity: 0.7,
|
||||
fillOpacity: 0.5,
|
||||
color: style.fillColor
|
||||
});
|
||||
}
|
||||
|
||||
const POLYGON_STYLE = {
|
||||
weight: 2,
|
||||
opacity: 0.3,
|
||||
color: 'white',
|
||||
dashArray: '3',
|
||||
fillOpacity: 0.7
|
||||
};
|
||||
|
||||
export const CADASTRE_POLYGON_STYLE = Object.assign({}, POLYGON_STYLE, {
|
||||
fillColor: '#8a6d3b'
|
||||
});
|
||||
|
||||
export const QP_POLYGON_STYLE = Object.assign({}, POLYGON_STYLE, {
|
||||
fillColor: '#31708f'
|
||||
});
|
||||
|
||||
function createLayer(map, layerName) {
|
||||
const layer = (LAYERS[layerName] = new L.GeoJSON(undefined, {
|
||||
interactive: false
|
||||
}));
|
||||
layer.addTo(map);
|
||||
return layer;
|
||||
}
|
||||
|
||||
function removeLayer(map, layerName) {
|
||||
const layer = LAYERS[layerName];
|
||||
|
||||
if (layer) {
|
||||
delete LAYERS[layerName];
|
||||
map.removeLayer(layer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -241,6 +241,23 @@ class Dossier < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def geo_position
|
||||
if etablissement.present?
|
||||
point = Carto::Geocodeur.convert_adresse_to_point(etablissement.geo_adresse)
|
||||
end
|
||||
|
||||
lon = "2.428462"
|
||||
lat = "46.538192"
|
||||
zoom = "13"
|
||||
|
||||
if point.present?
|
||||
lon = point.x.to_s
|
||||
lat = point.y.to_s
|
||||
end
|
||||
|
||||
{ lon: lon, lat: lat, zoom: zoom }
|
||||
end
|
||||
|
||||
def unspecified_attestation_champs
|
||||
attestation_template = procedure.attestation_template
|
||||
|
||||
|
|
9
app/views/shared/champs/carto/_init.html.haml
Normal file
9
app/views/shared/champs/carto/_init.html.haml
Normal file
|
@ -0,0 +1,9 @@
|
|||
:javascript
|
||||
DATA.push({
|
||||
carto: {
|
||||
position: #{raw(dossier.geo_position.to_json)},
|
||||
selection: #{raw(ensure_safe_json(dossier.json_latlngs))},
|
||||
cadastres: #{raw(dossier.cadastres.to_json)},
|
||||
quartiersPrioritaires: #{raw(dossier.quartier_prioritaires.to_json)}
|
||||
}
|
||||
});
|
|
@ -16,12 +16,4 @@
|
|||
%li
|
||||
= "Parcelle n° #{p.numero} - Feuille #{p.code_arr} #{p.section} #{p.feuille}"
|
||||
|
||||
:javascript
|
||||
DATA.push({
|
||||
carto: {
|
||||
getPositionUrl: "#{position_gestionnaire_dossier_path(dossier.procedure, dossier)}",
|
||||
dossierJsonLatLngs: #{raw(ensure_safe_json(dossier.json_latlngs))},
|
||||
dossierCadastres: #{raw(ensure_safe_json(dossier.cadastres.to_json))},
|
||||
dossierQuartiersPrioritaires: #{raw(ensure_safe_json(dossier.quartier_prioritaires.to_json))}
|
||||
}
|
||||
});
|
||||
= render partial: 'shared/champs/carto/init', locals: { dossier: dossier }
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
:javascript
|
||||
DATA.push({
|
||||
carto: {
|
||||
dossierId: #{dossier.id}
|
||||
}
|
||||
});
|
|
@ -1,13 +1,8 @@
|
|||
#carte-page.row
|
||||
.col-md-12.col-lg-12
|
||||
#map{ class: dossier.procedure.module_api_carto.classes }
|
||||
#map.edit
|
||||
|
||||
- if dossier.procedure.module_api_carto.quartiers_prioritaires
|
||||
.col-md-9.col-lg-9#qp.col-md-3.col-lg-3.list
|
||||
%h3.text-info Quartiers prioritaires
|
||||
%ul
|
||||
%span.zones
|
||||
= render partial: 'zones', locals: { dossier: dossier, error: @error }
|
||||
|
||||
- if dossier.procedure.module_api_carto.cadastre
|
||||
.col-md-9.col-lg-9#cadastre.col-md-3.col-lg-3.list
|
||||
%h3.text-warning Cadastres
|
||||
%ul
|
||||
= render partial: 'shared/champs/carto/init', locals: { dossier: dossier }
|
||||
|
|
19
app/views/users/carte/_zones.html.haml
Normal file
19
app/views/users/carte/_zones.html.haml
Normal file
|
@ -0,0 +1,19 @@
|
|||
- if dossier.procedure.module_api_carto.quartiers_prioritaires?
|
||||
.col-md-9.col-lg-9#qp.col-md-3.col-lg-3.list
|
||||
%h3.text-info Quartiers prioritaires
|
||||
%ul
|
||||
- dossier.quartier_prioritaires.each do |qp|
|
||||
%li #{qp.commune} : #{qp.nom}
|
||||
|
||||
- if error.present?
|
||||
%b Merci de dessiner une surface plus petite afin de récupérer les quartiers prioritaires.
|
||||
|
||||
- if dossier.procedure.module_api_carto.cadastre?
|
||||
.col-md-9.col-lg-9#cadastre.col-md-3.col-lg-3.list
|
||||
%h3.text-warning Parcelles cadastrales
|
||||
%ul
|
||||
- dossier.cadastres.each do |cadastre|
|
||||
%li Parcelle nº #{cadastre.numero} - Feuille #{cadastre.code_arr} #{cadastre.section} #{cadastre.feuille}
|
||||
|
||||
- if error.present?
|
||||
%b Merci de dessiner une surface plus petite afin de récupérer les parcelles cadastrales.
|
|
@ -20,13 +20,9 @@
|
|||
|
||||
= form_tag(url_for({ controller: :carte, action: :save, dossier_id: @dossier.id }), class: 'form-inline', method: 'POST') do
|
||||
%br
|
||||
%input#json_latlngs{ type: 'hidden', value: "#{@dossier.json_latlngs}", name: 'json_latlngs' }
|
||||
%input#quartier_prioritaires{ type: 'hidden', value: "#{@dossier.quartier_prioritaires.to_json}" }
|
||||
%input#cadastres{ type: 'hidden', value: "#{@dossier.cadastres.to_json}" }
|
||||
%input{ type: 'hidden', value: "#{@dossier.json_latlngs}", name: 'selection', data: { remote: true, url: users_dossier_carte_zones_path(@dossier), method: 'POST' } }
|
||||
|
||||
- if @dossier.brouillon?
|
||||
= render partial: '/layouts/etape_suivante'
|
||||
- else
|
||||
= render partial: '/layouts/modifications_terminees'
|
||||
|
||||
= render partial: 'users/carte/init_carto', locals: { dossier: @dossier }
|
||||
|
|
2
app/views/users/carte/zones.js.erb
Normal file
2
app/views/users/carte/zones.js.erb
Normal file
|
@ -0,0 +1,2 @@
|
|||
DS.cartoDrawZones(<%= raw(@data.to_json) %>);
|
||||
<%= render_to_element('.zones', partial: 'zones', locals: { dossier: @dossier, error: @error }) %>
|
|
@ -152,10 +152,7 @@ Rails.application.routes.draw do
|
|||
resources :dossiers do
|
||||
get '/add_siret' => 'dossiers/add_siret#show'
|
||||
|
||||
get '/carte/position' => 'carte#get_position'
|
||||
post '/carte/qp' => 'carte#get_qp'
|
||||
post '/carte/cadastre' => 'carte#get_cadastre'
|
||||
|
||||
post '/carte/zones' => 'carte#zones'
|
||||
get '/carte' => 'carte#show'
|
||||
post '/carte' => 'carte#save'
|
||||
|
||||
|
@ -333,9 +330,6 @@ Rails.application.routes.draw do
|
|||
post 'repasser-en-construction' => 'dossiers#repasser_en_construction'
|
||||
post 'terminer'
|
||||
post 'send-to-instructeurs' => 'dossiers#send_to_instructeurs'
|
||||
scope :carte do
|
||||
get 'position'
|
||||
end
|
||||
post 'avis' => 'dossiers#create_avis'
|
||||
get 'print' => 'dossiers#print'
|
||||
end
|
||||
|
|
|
@ -64,7 +64,7 @@ shared_examples 'carte_controller_spec' do
|
|||
let(:json_latlngs) { multipolygon.to_json }
|
||||
|
||||
before do
|
||||
post :save, params: { dossier_id: dossier.id, json_latlngs: json_latlngs }
|
||||
post :save, params: { dossier_id: dossier.id, selection: json_latlngs }
|
||||
dossier.reload
|
||||
end
|
||||
|
||||
|
@ -101,7 +101,7 @@ shared_examples 'carte_controller_spec' do
|
|||
context 'En train de modifier la localisation' do
|
||||
let(:dossier) { create(:dossier, state: Dossier.states.fetch(:en_construction)) }
|
||||
before do
|
||||
post :save, params: { dossier_id: dossier.id, json_latlngs: '' }
|
||||
post :save, params: { dossier_id: dossier.id, selection: '' }
|
||||
end
|
||||
|
||||
it 'Redirection vers le formulaire de la procedure' do
|
||||
|
@ -117,7 +117,7 @@ shared_examples 'carte_controller_spec' do
|
|||
.to receive(:to_params)
|
||||
.and_return({ "QPCODE1234" => { :code => "QPCODE1234", :nom => "QP de test", :commune => "Paris", :geometry => { :type => "MultiPolygon", :coordinates => [[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]] } } })
|
||||
|
||||
post :save, params: { dossier_id: dossier.id, json_latlngs: json_latlngs }
|
||||
post :save, params: { dossier_id: dossier.id, selection: json_latlngs }
|
||||
end
|
||||
|
||||
context 'when json_latlngs params is empty' do
|
||||
|
@ -164,7 +164,7 @@ shared_examples 'carte_controller_spec' do
|
|||
.to receive(:to_params)
|
||||
.and_return([{ :surface_intersection => "0.0006", :surface_parcelle => 11252.692583090324, :numero => "0013", :feuille => 1, :section => "CD", :code_dep => "30", :nom_com => "Le Grau-du-Roi", :code_com => "133", :code_arr => "000", :geometry => { :type => "MultiPolygon", :coordinates => [[[[4.134084, 43.5209193], [4.1346615, 43.5212035], [4.1346984, 43.521189], [4.135096, 43.5213848], [4.1350839, 43.5214122], [4.1352697, 43.521505], [4.1356278, 43.5211065], [4.1357402, 43.5207188], [4.1350935, 43.5203936], [4.135002, 43.5204366], [4.1346051, 43.5202412], [4.134584, 43.5202472], [4.1345572, 43.5202551], [4.134356, 43.5203137], [4.1342488, 43.5203448], [4.134084, 43.5209193]]]] } }])
|
||||
|
||||
post :save, params: { dossier_id: dossier.id, json_latlngs: json_latlngs }
|
||||
post :save, params: { dossier_id: dossier.id, selection: json_latlngs }
|
||||
end
|
||||
|
||||
context 'when json_latlngs params is empty' do
|
||||
|
@ -210,96 +210,33 @@ shared_examples 'carte_controller_spec' do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#get_position' do
|
||||
context 'when etablissement is nil' do
|
||||
before do
|
||||
dossier.update etablissement: nil
|
||||
describe 'POST #zones' do
|
||||
let(:module_api_carto) { create(:module_api_carto, :with_quartiers_prioritaires) }
|
||||
render_views
|
||||
|
||||
stub_request(:get, /http:\/\/api-adresse[.]data[.]gouv[.]fr\/search[?]limit=1&q=/)
|
||||
.to_return(status: 200, body: '{"query": "babouba", "version": "draft", "licence": "ODbL 1.0", "features": [], "type": "FeatureCollection", "attribution": "BAN"}', headers: {})
|
||||
get :get_position, params: { dossier_id: dossier.id }
|
||||
end
|
||||
|
||||
subject { JSON.parse(response.body) }
|
||||
|
||||
it 'on enregistre des coordonnées lat et lon avec les valeurs par defaut' do
|
||||
expect(subject['lat']).to eq('46.538192')
|
||||
expect(subject['lon']).to eq('2.428462')
|
||||
end
|
||||
end
|
||||
|
||||
context 'Geocodeur renvoie les positions par defaut' do
|
||||
let(:etablissement) { create(:etablissement, adresse: bad_adresse, numero_voie: 'dzj', type_voie: 'fzjfk', nom_voie: 'hdidjkz', complement_adresse: 'fjef', code_postal: 'fjeiefk', localite: 'zjfkfz') }
|
||||
let(:dossier) { create(:dossier, etablissement: etablissement) }
|
||||
|
||||
before do
|
||||
stub_request(:get, /http:\/\/api-adresse[.]data[.]gouv[.]fr\/search[?]limit=1&q=/)
|
||||
.to_return(status: 200, body: '{"query": "babouba", "version": "draft", "licence": "ODbL 1.0", "features": [], "type": "FeatureCollection", "attribution": "BAN"}', headers: {})
|
||||
get :get_position, params: { dossier_id: dossier.id }
|
||||
end
|
||||
|
||||
subject { JSON.parse(response.body) }
|
||||
|
||||
it 'on enregistre des coordonnées lat et lon avec les valeurs par defaut' do
|
||||
expect(subject['lat']).to eq('46.538192')
|
||||
expect(subject['lon']).to eq('2.428462')
|
||||
end
|
||||
end
|
||||
|
||||
context 'retour d\'un fichier JSON avec 3 attributs' do
|
||||
before do
|
||||
stub_request(:get, "http://api-adresse.data.gouv.fr/search?limit=1&q=#{adresse}")
|
||||
.to_return(status: 200, body: '{"query": "50 avenue des champs u00e9lysu00e9es Paris 75008", "version": "draft", "licence": "ODbL 1.0", "features": [{"geometry": {"coordinates": [2.306888, 48.870374], "type": "Point"}, "type": "Feature", "properties": {"city": "Paris", "label": "50 Avenue des Champs u00c9lysu00e9es 75008 Paris", "housenumber": "50", "id": "ADRNIVX_0000000270748251", "postcode": "75008", "name": "50 Avenue des Champs u00c9lysu00e9es", "citycode": "75108", "context": "75, u00cele-de-France", "score": 0.9054545454545454, "type": "housenumber"}}], "type": "FeatureCollection", "attribution": "BAN"}', headers: {})
|
||||
|
||||
get :get_position, params: { dossier_id: dossier.id }
|
||||
end
|
||||
subject { JSON.parse(response.body) }
|
||||
|
||||
it 'format JSON valide' do
|
||||
expect(response.content_type).to eq('application/json')
|
||||
end
|
||||
|
||||
it 'latitude' do
|
||||
expect(subject['lat']).to eq('48.870374')
|
||||
end
|
||||
|
||||
it 'longitude' do
|
||||
expect(subject['lon']).to eq('2.306888')
|
||||
end
|
||||
|
||||
it 'dossier_id' do
|
||||
expect(subject['dossier_id']).to eq(dossier.id.to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #get_qp' do
|
||||
before do
|
||||
allow_any_instance_of(CARTO::SGMAP::QuartiersPrioritaires::Adapter)
|
||||
.to receive(:to_params)
|
||||
.and_return({ "QPCODE1234" => { :code => "QPCODE1234", :geometry => { :type => "MultiPolygon", :coordinates => [[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]] } } })
|
||||
|
||||
post :get_qp, params: { dossier_id: dossier.id, coordinates: coordinates }
|
||||
post :zones, params: { dossier_id: dossier.id, selection: json_latlngs.to_json }, format: 'js'
|
||||
end
|
||||
|
||||
context 'when coordinates are empty' do
|
||||
let(:coordinates) { '[]' }
|
||||
|
||||
subject { JSON.parse(response.body) }
|
||||
let(:json_latlngs) { [] }
|
||||
|
||||
it 'Quartier Prioritaire Adapter does not call' do
|
||||
expect(subject['quartier_prioritaires']).to eq({})
|
||||
expect(response.body).to include("DS.cartoDrawZones({\"quartiersPrioritaires\":[]});")
|
||||
end
|
||||
end
|
||||
|
||||
context 'when coordinates are informed' do
|
||||
let(:coordinates) { '[[{"lat":48.87442541960633,"lng":2.3859214782714844},{"lat":48.87273183590832,"lng":2.3850631713867183},{"lat":48.87081237174292,"lng":2.3809432983398438},{"lat":48.8712640169951,"lng":2.377510070800781},{"lat":48.87510283703279,"lng":2.3778533935546875},{"lat":48.87544154230615,"lng":2.382831573486328},{"lat":48.87442541960633,"lng":2.3859214782714844}]]' }
|
||||
let(:json_latlngs) { [[{ "lat": 48.87442541960633, "lng": 2.3859214782714844 }, { "lat": 48.87273183590832, "lng": 2.3850631713867183 }, { "lat": 48.87081237174292, "lng": 2.3809432983398438 }, { "lat": 48.8712640169951, "lng": 2.377510070800781 }, { "lat": 48.87510283703279, "lng": 2.3778533935546875 }, { "lat": 48.87544154230615, "lng": 2.382831573486328 }, { "lat": 48.87442541960633, "lng": 2.3859214782714844 }]] }
|
||||
|
||||
subject { JSON.parse(response.body)['quartier_prioritaires'] }
|
||||
it { expect(subject).not_to be_nil }
|
||||
it { expect(subject['QPCODE1234']['code']).to eq('QPCODE1234') }
|
||||
it { expect(subject['QPCODE1234']['geometry']['type']).to eq('MultiPolygon') }
|
||||
it { expect(subject['QPCODE1234']['geometry']['coordinates']).to eq([[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]]) }
|
||||
it { expect(response.body).not_to be_nil }
|
||||
it { expect(response.body).to include('QPCODE1234') }
|
||||
it { expect(response.body).to include('MultiPolygon') }
|
||||
it { expect(response.body).to include('[2.38715792094576,48.8723062632126]') }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,14 +6,14 @@ describe 'shared/dossiers/map.html.haml', type: :view do
|
|||
end
|
||||
|
||||
describe "javascript variables printing" do
|
||||
let(:dossier) { create(:dossier, :with_entreprise, json_latlngs: json_latlngs) }
|
||||
let(:dossier) { create(:dossier, json_latlngs: json_latlngs) }
|
||||
|
||||
context 'with a correct json' do
|
||||
let(:json_latlngs) { "[[{\"lat\":50.659255436656736,\"lng\":3.080635070800781},{\"lat\":50.659255436656736,\"lng\":3.079690933227539},{\"lat\":50.659962770886516,\"lng\":3.0800342559814453},{\"lat\":50.659962770886516,\"lng\":3.0811500549316406},{\"lat\":50.659255436656736,\"lng\":3.080635070800781}]]" }
|
||||
|
||||
before { subject }
|
||||
|
||||
it { expect(rendered).to have_content('dossierJsonLatLngs: [[{"lat":50.659255436656736,"lng":3.080635070800781},{"lat":50.659255436656736,"lng":3.079690933227539},{"lat":50.659962770886516,"lng":3.0800342559814453},{"lat":50.659962770886516,"lng":3.0811500549316406},{"lat":50.659255436656736,"lng":3.080635070800781}]],') }
|
||||
it { expect(rendered).to have_content('selection: [[{"lat":50.659255436656736,"lng":3.080635070800781},{"lat":50.659255436656736,"lng":3.079690933227539},{"lat":50.659962770886516,"lng":3.0800342559814453},{"lat":50.659962770886516,"lng":3.0811500549316406},{"lat":50.659255436656736,"lng":3.080635070800781}]],') }
|
||||
end
|
||||
|
||||
context 'without a correct json' do
|
||||
|
@ -21,7 +21,7 @@ describe 'shared/dossiers/map.html.haml', type: :view do
|
|||
|
||||
before { subject }
|
||||
|
||||
it { expect(rendered).to have_content('dossierJsonLatLngs: {},') }
|
||||
it { expect(rendered).to have_content('selection: {},') }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,7 +23,7 @@ describe 'users/carte/show.html.haml', type: :view do
|
|||
|
||||
context 'présence des inputs hidden' do
|
||||
it 'stockage du json des polygons dessinés' do
|
||||
expect(rendered).to have_selector('input[type=hidden][id=json_latlngs][name=json_latlngs]', visible: false)
|
||||
expect(rendered).to have_selector('input[type=hidden][name=selection]', visible: false)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue