always validate geometries returned from api
This commit is contained in:
parent
3fe1e75c36
commit
7c58f06c60
6 changed files with 104 additions and 46 deletions
|
@ -14,7 +14,7 @@ module Types
|
||||||
|
|
||||||
global_id_field :id
|
global_id_field :id
|
||||||
field :source, GeoAreaSource, null: false
|
field :source, GeoAreaSource, null: false
|
||||||
field :geometry, Types::GeoJSON, null: false
|
field :geometry, Types::GeoJSON, null: false, method: :safe_geometry
|
||||||
|
|
||||||
definition_methods do
|
definition_methods do
|
||||||
def resolve_type(object, context)
|
def resolve_type(object, context)
|
||||||
|
|
|
@ -49,7 +49,7 @@ class GeoArea < ApplicationRecord
|
||||||
def to_feature
|
def to_feature
|
||||||
{
|
{
|
||||||
type: 'Feature',
|
type: 'Feature',
|
||||||
geometry: geometry,
|
geometry: safe_geometry,
|
||||||
properties: properties.symbolize_keys.merge(
|
properties: properties.symbolize_keys.merge(
|
||||||
source: source,
|
source: source,
|
||||||
area: area,
|
area: area,
|
||||||
|
@ -61,6 +61,10 @@ class GeoArea < ApplicationRecord
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def safe_geometry
|
||||||
|
RGeo::GeoJSON.encode(rgeo_geometry)
|
||||||
|
end
|
||||||
|
|
||||||
def rgeo_geometry
|
def rgeo_geometry
|
||||||
RGeo::GeoJSON.decode(geometry.to_json, geo_factory: RGeo::Geographic.simple_mercator_factory)
|
RGeo::GeoJSON.decode(geometry.to_json, geo_factory: RGeo::Geographic.simple_mercator_factory)
|
||||||
rescue RGeo::Error::InvalidGeometry
|
rescue RGeo::Error::InvalidGeometry
|
||||||
|
|
|
@ -13,7 +13,7 @@ class ChampSerializer < ActiveModel::Serializer
|
||||||
def value
|
def value
|
||||||
case object
|
case object
|
||||||
when GeoArea
|
when GeoArea
|
||||||
object.geometry
|
object.safe_geometry
|
||||||
else
|
else
|
||||||
object.for_api
|
object.for_api
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,6 +20,10 @@ class GeoAreaSerializer < ActiveModel::Serializer
|
||||||
attribute :surface, if: :include_parcelle_agricole?
|
attribute :surface, if: :include_parcelle_agricole?
|
||||||
attribute :bio, if: :include_parcelle_agricole?
|
attribute :bio, if: :include_parcelle_agricole?
|
||||||
|
|
||||||
|
def geometry
|
||||||
|
object.safe_geometry
|
||||||
|
end
|
||||||
|
|
||||||
def include_cadastre?
|
def include_cadastre?
|
||||||
object.source == GeoArea.sources.fetch(:cadastre)
|
object.source == GeoArea.sources.fetch(:cadastre)
|
||||||
end
|
end
|
||||||
|
|
|
@ -57,6 +57,71 @@ FactoryBot.define do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
trait :polygon_with_extra_coordinate do
|
||||||
|
geometry do
|
||||||
|
{
|
||||||
|
"type": "Polygon",
|
||||||
|
"coordinates": [
|
||||||
|
[
|
||||||
|
[2.428439855575562, 46.538476837725796, 0],
|
||||||
|
[2.4284291267395024, 46.53842148758162, 0],
|
||||||
|
[2.4282521009445195, 46.53841410755813, 0],
|
||||||
|
[2.42824137210846, 46.53847314771794, 0],
|
||||||
|
[2.428284287452698, 46.53847314771794, 0],
|
||||||
|
[2.428364753723145, 46.538487907747864, 0],
|
||||||
|
[2.4284291267395024, 46.538491597754714, 0],
|
||||||
|
[2.428439855575562, 46.538476837725796, 0]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
trait :invalid_multi_polygon do
|
||||||
|
geometry do
|
||||||
|
{
|
||||||
|
"type": "MultiPolygon",
|
||||||
|
"coordinates": [
|
||||||
|
[
|
||||||
|
[
|
||||||
|
[5.894422531127931, 48.22810341752755],
|
||||||
|
[5.893049240112306, 48.22427237832278],
|
||||||
|
[5.892534255981446, 48.22593062452037],
|
||||||
|
[5.892791748046875, 48.2260449843468],
|
||||||
|
[5.894422531127931, 48.229933066408215],
|
||||||
|
[5.894422531127931, 48.22810341752755]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[
|
||||||
|
[5.8950233459472665, 48.229933066408215],
|
||||||
|
[5.893478393554688, 48.228961073585126],
|
||||||
|
[5.892791748046875, 48.228903896961775],
|
||||||
|
[5.892705917358398, 48.230390468407535],
|
||||||
|
[5.8950233459472665, 48.229933066408215]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[
|
||||||
|
[5.893220901489259, 48.229246955743626],
|
||||||
|
[5.893392562866212, 48.22884672027457],
|
||||||
|
[5.892705917358398, 48.22878954352343],
|
||||||
|
[5.892019271850587, 48.22856083588024],
|
||||||
|
[5.892019271850587, 48.2277031731152],
|
||||||
|
[5.890989303588868, 48.22787470681807],
|
||||||
|
[5.889959335327149, 48.22787470681807],
|
||||||
|
[5.890560150146485, 48.22838930447709],
|
||||||
|
[5.890645980834962, 48.22878954352343],
|
||||||
|
[5.890989303588868, 48.229018250144584],
|
||||||
|
[5.892362594604493, 48.22930413198368],
|
||||||
|
[5.893220901489259, 48.229246955743626]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
trait :line_string do
|
trait :line_string do
|
||||||
geometry do
|
geometry do
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,53 +24,38 @@ RSpec.describe GeoArea, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#rgeo_geometry' do
|
describe '#rgeo_geometry' do
|
||||||
let(:geo_area) { build(:geo_area, geometry: geometry) }
|
let(:geo_area) { build(:geo_area, :polygon) }
|
||||||
|
let(:polygon) do
|
||||||
|
{
|
||||||
|
"type" => "Polygon",
|
||||||
|
"coordinates" => [
|
||||||
|
[
|
||||||
|
[2.428439855575562, 46.538476837725796],
|
||||||
|
[2.4284291267395024, 46.53842148758162],
|
||||||
|
[2.4282521009445195, 46.53841410755813],
|
||||||
|
[2.42824137210846, 46.53847314771794],
|
||||||
|
[2.428284287452698, 46.53847314771794],
|
||||||
|
[2.428364753723145, 46.538487907747864],
|
||||||
|
[2.4284291267395024, 46.538491597754714],
|
||||||
|
[2.428439855575562, 46.538476837725796]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(geo_area.geometry).to eq(polygon) }
|
||||||
|
|
||||||
context 'invalid' do
|
context 'invalid' do
|
||||||
let(:geometry) do
|
let(:geo_area) { build(:geo_area, :invalid_multi_polygon) }
|
||||||
{
|
|
||||||
"type" => "MultiPolygon",
|
|
||||||
"coordinates" => [
|
|
||||||
[
|
|
||||||
[
|
|
||||||
[5.894422531127931, 48.22810341752755],
|
|
||||||
[5.893049240112306, 48.22427237832278],
|
|
||||||
[5.892534255981446, 48.22593062452037],
|
|
||||||
[5.892791748046875, 48.2260449843468],
|
|
||||||
[5.894422531127931, 48.229933066408215],
|
|
||||||
[5.894422531127931, 48.22810341752755]
|
|
||||||
]
|
|
||||||
],
|
|
||||||
[
|
|
||||||
[
|
|
||||||
[5.8950233459472665, 48.229933066408215],
|
|
||||||
[5.893478393554688, 48.228961073585126],
|
|
||||||
[5.892791748046875, 48.228903896961775],
|
|
||||||
[5.892705917358398, 48.230390468407535],
|
|
||||||
[5.8950233459472665, 48.229933066408215]
|
|
||||||
]
|
|
||||||
],
|
|
||||||
[
|
|
||||||
[
|
|
||||||
[5.893220901489259, 48.229246955743626],
|
|
||||||
[5.893392562866212, 48.22884672027457],
|
|
||||||
[5.892705917358398, 48.22878954352343],
|
|
||||||
[5.892019271850587, 48.22856083588024],
|
|
||||||
[5.892019271850587, 48.2277031731152],
|
|
||||||
[5.890989303588868, 48.22787470681807],
|
|
||||||
[5.889959335327149, 48.22787470681807],
|
|
||||||
[5.890560150146485, 48.22838930447709],
|
|
||||||
[5.890645980834962, 48.22878954352343],
|
|
||||||
[5.890989303588868, 48.229018250144584],
|
|
||||||
[5.892362594604493, 48.22930413198368],
|
|
||||||
[5.893220901489259, 48.229246955743626]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
it { expect(geo_area.rgeo_geometry).to be_nil }
|
it { expect(geo_area.rgeo_geometry).to be_nil }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'polygon_with_extra_coordinate' do
|
||||||
|
let(:geo_area) { build(:geo_area, :polygon_with_extra_coordinate) }
|
||||||
|
|
||||||
|
it { expect(geo_area.geometry).not_to eq(polygon) }
|
||||||
|
it { expect(geo_area.safe_geometry).to eq(polygon) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue