Merge pull request #2799 from tchak/refactor-carto

Refactor carto to rely on ujs and some UX fixes
This commit is contained in:
Paul Chavard 2018-10-14 21:02:26 +02:00 committed by GitHub
commit 48de67b6c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 318 additions and 516 deletions

View file

@ -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 {

View file

@ -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

View file

@ -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

View file

@ -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:
'&copy; <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);
}

View file

@ -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);

View file

@ -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:
'&copy; <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;
}

View file

@ -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);
}

View 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);
});
}

View 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])]
}
};
}

View file

@ -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]);
}

View file

@ -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:
'&copy; <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);
}
}

View file

@ -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

View 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)}
}
});

View file

@ -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 }

View file

@ -1,6 +0,0 @@
:javascript
DATA.push({
carto: {
dossierId: #{dossier.id}
}
});

View file

@ -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 }

View 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.

View file

@ -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 }

View file

@ -0,0 +1,2 @@
DS.cartoDrawZones(<%= raw(@data.to_json) %>);
<%= render_to_element('.zones', partial: 'zones', locals: { dossier: @dossier, error: @error }) %>

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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