From 28a047a64b80fb3d0fba0b06b2c4a87fd8f4dd4d Mon Sep 17 00:00:00 2001 From: Simon Lehericey Date: Mon, 30 Oct 2017 16:54:33 +0100 Subject: [PATCH] [Fix #508]Api GeoJson: export dossier.json_latlngs to geojson --- app/models/dossier.rb | 6 +++ app/models/user_geometry.rb | 40 +++++++++++++++++ app/serializers/dossier_serializer.rb | 21 ++++++++- app/serializers/user_geometry_serializer.rb | 3 ++ .../api/v1/dossiers_controller_spec.rb | 14 ++++++ spec/models/dossier_spec.rb | 45 +++++++++++++++++++ 6 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 app/models/user_geometry.rb create mode 100644 app/serializers/user_geometry_serializer.rb diff --git a/app/models/dossier.rb b/app/models/dossier.rb index e6ac87ad7..55f3148a8 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -373,6 +373,12 @@ class Dossier < ActiveRecord::Base end end + def user_geometry + if json_latlngs.present? + UserGeometry.new(json_latlngs) + end + end + private def build_attestation diff --git a/app/models/user_geometry.rb b/app/models/user_geometry.rb new file mode 100644 index 000000000..8f5e398aa --- /dev/null +++ b/app/models/user_geometry.rb @@ -0,0 +1,40 @@ +class UserGeometry + alias :read_attribute_for_serialization :send + + def initialize(json_latlngs) + @json_latlngs = json_latlngs + end + + def value + to_geo_json(@json_latlngs) + end + + def type_de_champ + { + id: -1, + libelle: 'user_geometry', + type_champ: 'user_geometry', + order_place: -1, + descripton: '' + } + end + + private + + def to_geo_json(json_latlngs) + json = JSON.parse(json_latlngs) + + coordinates = json.map do |lat_longs| + outbounds = lat_longs.map do |lat_long| + [lat_long['lng'], lat_long['lat']] + end + + [outbounds] + end + + { + type: 'MultiPolygon', + coordinates: coordinates + } + end +end diff --git a/app/serializers/dossier_serializer.rb b/app/serializers/dossier_serializer.rb index 3ed432e69..3cb69bbde 100644 --- a/app/serializers/dossier_serializer.rb +++ b/app/serializers/dossier_serializer.rb @@ -23,7 +23,11 @@ class DossierSerializer < ActiveModel::Serializer has_many :types_de_piece_justificative has_many :champs do - object.champs + object.quartier_prioritaires + object.cadastres + champs = object.champs + object.quartier_prioritaires + object.cadastres + if object.user_geometry.present? + champs << object.user_geometry + end + champs end def email @@ -41,4 +45,19 @@ class DossierSerializer < ActiveModel::Serializer def invites object.invites_gestionnaires.pluck(:email) end + + private + + def user_geometry(dossier) + { + value: dossier.geometry, + type_de_champ: { + id: -1, + libelle: 'user_geometry', + type_champ: 'user_geometry', + order_place: -1, + descripton: '' + } + } + end end diff --git a/app/serializers/user_geometry_serializer.rb b/app/serializers/user_geometry_serializer.rb new file mode 100644 index 000000000..964bda894 --- /dev/null +++ b/app/serializers/user_geometry_serializer.rb @@ -0,0 +1,3 @@ +class UserGeometrySerializer < ActiveModel::Serializer + attributes :value, :type_de_champ +end diff --git a/spec/controllers/api/v1/dossiers_controller_spec.rb b/spec/controllers/api/v1/dossiers_controller_spec.rb index 5e2465469..58c49bb29 100644 --- a/spec/controllers/api/v1/dossiers_controller_spec.rb +++ b/spec/controllers/api/v1/dossiers_controller_spec.rb @@ -260,6 +260,20 @@ describe API::V1::DossiersController do it { expect(subject[:type_de_champ]).to match({ id: -1, libelle: 'cadastre', type_champ: 'cadastre', order_place: -1, descripton: ''}) } it { expect(subject[:value]).to match(dossier.cadastres.first.geometry.symbolize_keys) } end + + context 'when the dossier includes some user geometry' do + before do + dossier.json_latlngs = '[[{"lat": 2.0, "lng": 102.0}, {"lat": 3.0, "lng": 103.0}, {"lat": 2.0, "lng": 102.0}]]' + dossier.save + end + + subject do + super().find { |champ| champ[:type_de_champ][:type_champ] == 'user_geometry' } + end + + it { expect(subject[:type_de_champ]).to match({ id: -1, libelle: 'user_geometry', type_champ: 'user_geometry', order_place: -1, descripton: ''}) } + it { expect(subject[:value]).to match(UserGeometry.new(dossier.json_latlngs).value) } + end end describe 'champs_private' do diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index 87386c3d5..66c8e8a16 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -967,4 +967,49 @@ describe Dossier do it { is_expected.to eq("#{dossier.individual.nom} #{dossier.individual.prenom}") } end end + + describe 'geometry' do + let(:dossier) { create(:dossier, json_latlngs: json_latlngs) } + let(:json_latlngs) { nil } + + subject{ dossier.user_geometry } + + context 'when there are no map' do + it { is_expected.to eq(nil) } + end + + context 'when there are 2 polygones' do + let(:json_latlngs) do + '[[{"lat": 2.0, "lng": 102.0}, {"lat": 3.0, "lng": 103.0}, {"lat": 2.0, "lng": 102.0}], + [{"lat": 2.0, "lng": 102.0}, {"lat": 3.0, "lng": 103.0}, {"lat": 2.0, "lng": 102.0}]]' + end + + let(:expected) do + { + "type": "MultiPolygon", + "coordinates": + [ + [ + [ + [102.0, 2.0], + [103.0, 3.0], + [102.0, 2.0] + ] + ], + [ + [ + [102.0, 2.0], + [103.0, 3.0], + [102.0, 2.0] + ] + ] + ] + } + end + + subject{ dossier.user_geometry.value } + + it { is_expected.to eq(expected) } + end + end end