2020-08-06 16:35:45 +02:00
|
|
|
# == Schema Information
|
|
|
|
#
|
|
|
|
# Table name: geo_areas
|
|
|
|
#
|
|
|
|
# id :bigint not null, primary key
|
|
|
|
# geometry :jsonb
|
|
|
|
# properties :jsonb
|
|
|
|
# source :string
|
|
|
|
# created_at :datetime
|
|
|
|
# updated_at :datetime
|
|
|
|
# champ_id :bigint
|
|
|
|
# geo_reference_id :string
|
|
|
|
#
|
2018-10-16 13:01:12 +02:00
|
|
|
class GeoArea < ApplicationRecord
|
2022-08-31 13:09:00 +02:00
|
|
|
include ActionView::Helpers::NumberHelper
|
2020-07-20 16:50:12 +02:00
|
|
|
belongs_to :champ, optional: false
|
2018-10-16 13:01:12 +02:00
|
|
|
|
2021-05-06 18:50:06 +02:00
|
|
|
# FIXME: once geo_areas are migrated to not use YAML serialization we can enable store_accessor
|
|
|
|
# store_accessor :properties, :description, :numero, :section
|
|
|
|
|
|
|
|
def properties
|
|
|
|
value = read_attribute(:properties)
|
|
|
|
if value.is_a? String
|
|
|
|
ActiveRecord::Coders::YAMLColumn.new(:properties).load(value)
|
|
|
|
else
|
2021-05-26 12:22:35 +02:00
|
|
|
value || {}
|
2021-05-06 18:50:06 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def description
|
|
|
|
properties['description']
|
|
|
|
end
|
|
|
|
|
|
|
|
def numero
|
|
|
|
properties['numero']
|
|
|
|
end
|
|
|
|
|
|
|
|
def section
|
|
|
|
properties['section']
|
|
|
|
end
|
|
|
|
|
|
|
|
def filename
|
|
|
|
properties['filename']
|
|
|
|
end
|
2018-10-16 13:01:12 +02:00
|
|
|
|
|
|
|
enum source: {
|
2018-10-23 15:38:20 +02:00
|
|
|
cadastre: 'cadastre',
|
2018-10-31 13:29:25 +01:00
|
|
|
selection_utilisateur: 'selection_utilisateur'
|
2018-10-16 13:01:12 +02:00
|
|
|
}
|
|
|
|
|
2020-04-09 17:32:20 +02:00
|
|
|
scope :selections_utilisateur, -> { where(source: sources.fetch(:selection_utilisateur)) }
|
2018-10-16 13:01:12 +02:00
|
|
|
scope :cadastres, -> { where(source: sources.fetch(:cadastre)) }
|
2018-12-19 11:09:13 +01:00
|
|
|
|
2021-03-11 10:22:49 +01:00
|
|
|
validates :geometry, geo_json: true, allow_blank: false
|
2023-02-14 18:38:01 +01:00
|
|
|
before_validation :normalize_geometry
|
2021-03-11 10:22:49 +01:00
|
|
|
|
2020-04-09 17:32:20 +02:00
|
|
|
def to_feature
|
|
|
|
{
|
|
|
|
type: 'Feature',
|
2023-02-14 18:38:01 +01:00
|
|
|
geometry: geometry.deep_symbolize_keys,
|
2021-05-06 18:50:06 +02:00
|
|
|
properties: cadastre_properties.merge(
|
2020-04-30 15:49:43 +02:00
|
|
|
source: source,
|
|
|
|
area: area,
|
|
|
|
length: length,
|
2021-05-06 18:50:06 +02:00
|
|
|
description: description,
|
|
|
|
filename: filename,
|
2020-04-30 15:49:43 +02:00
|
|
|
id: id,
|
2022-11-16 11:50:19 +01:00
|
|
|
champ_label: champ.libelle,
|
2020-04-30 15:49:43 +02:00
|
|
|
champ_id: champ.stable_id,
|
2022-12-16 15:07:26 +01:00
|
|
|
champ_row: champ.row_id,
|
2022-11-16 11:50:19 +01:00
|
|
|
champ_private: champ.private?,
|
2020-04-30 15:49:43 +02:00
|
|
|
dossier_id: champ.dossier_id
|
|
|
|
).compact
|
2020-04-09 17:32:20 +02:00
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2022-08-31 13:09:00 +02:00
|
|
|
def label
|
|
|
|
case source
|
|
|
|
when GeoArea.sources.fetch(:cadastre)
|
2022-09-16 15:50:50 +02:00
|
|
|
I18n.t("cadastre", scope: 'geo_area.label', numero: numero, prefixe: prefixe, section: section, surface: surface.round, commune: commune)
|
2022-08-31 13:09:00 +02:00
|
|
|
when GeoArea.sources.fetch(:selection_utilisateur)
|
|
|
|
if polygon?
|
|
|
|
if area > 0
|
|
|
|
I18n.t("area", scope: 'geo_area.label', area: number_with_delimiter(area))
|
|
|
|
else
|
|
|
|
I18n.t("area_unknown", scope: 'geo_area.label')
|
|
|
|
end
|
|
|
|
elsif line?
|
|
|
|
if length > 0
|
|
|
|
I18n.t("line", scope: 'geo_area.label', length: number_with_delimiter(length))
|
|
|
|
else
|
|
|
|
I18n.t("line_unknown", scope: 'geo_area.label')
|
|
|
|
end
|
|
|
|
elsif point?
|
|
|
|
I18n.t("point", scope: 'geo_area.label', location: location)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-04-15 15:43:38 +02:00
|
|
|
def area
|
2020-10-01 11:32:56 +02:00
|
|
|
if polygon?
|
|
|
|
GeojsonService.area(geometry.deep_symbolize_keys).round(1)
|
2020-04-15 15:43:38 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def length
|
2020-10-01 11:33:15 +02:00
|
|
|
if line?
|
|
|
|
GeojsonService.length(geometry.deep_symbolize_keys).round(1)
|
2020-04-15 15:43:38 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def location
|
|
|
|
if point?
|
2023-02-14 18:38:01 +01:00
|
|
|
Geo::Coord.new(*geometry['coordinates'].reverse).to_s
|
2020-04-15 15:43:38 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def line?
|
|
|
|
geometry['type'] == 'LineString'
|
|
|
|
end
|
|
|
|
|
|
|
|
def polygon?
|
|
|
|
geometry['type'] == 'Polygon'
|
|
|
|
end
|
|
|
|
|
|
|
|
def point?
|
|
|
|
geometry['type'] == 'Point'
|
|
|
|
end
|
2021-05-06 18:50:06 +02:00
|
|
|
|
|
|
|
def legacy_cadastre?
|
|
|
|
cadastre? && properties['surface_intersection'].present?
|
|
|
|
end
|
|
|
|
|
|
|
|
def cadastre?
|
|
|
|
source == GeoArea.sources.fetch(:cadastre)
|
|
|
|
end
|
|
|
|
|
|
|
|
def cadastre_properties
|
|
|
|
if cadastre?
|
|
|
|
{
|
|
|
|
cid: cid,
|
|
|
|
numero: numero,
|
|
|
|
section: section,
|
|
|
|
prefixe: prefixe,
|
|
|
|
commune: commune,
|
|
|
|
surface: surface
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def code_dep
|
|
|
|
if legacy_cadastre?
|
|
|
|
properties['code_dep']
|
|
|
|
else
|
|
|
|
properties['commune'][0..1]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def code_com
|
|
|
|
if legacy_cadastre?
|
|
|
|
properties['code_com']
|
|
|
|
else
|
|
|
|
properties['commune'][2...commune.size]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def nom_com
|
|
|
|
if legacy_cadastre?
|
|
|
|
properties['nom_com']
|
|
|
|
else
|
|
|
|
''
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def surface_intersection
|
|
|
|
if legacy_cadastre?
|
|
|
|
properties['surface_intersection']
|
|
|
|
else
|
|
|
|
''
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def feuille
|
|
|
|
if legacy_cadastre?
|
|
|
|
properties['feuille']
|
|
|
|
else
|
|
|
|
1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def code_arr
|
|
|
|
prefixe
|
|
|
|
end
|
|
|
|
|
|
|
|
def surface_parcelle
|
|
|
|
surface
|
|
|
|
end
|
|
|
|
|
|
|
|
def surface
|
|
|
|
if legacy_cadastre?
|
|
|
|
properties['surface_parcelle']
|
|
|
|
else
|
|
|
|
properties['contenance']
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def prefixe
|
|
|
|
if legacy_cadastre?
|
|
|
|
properties['code_arr']
|
|
|
|
else
|
|
|
|
properties['prefixe']
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def commune
|
|
|
|
if legacy_cadastre?
|
|
|
|
"#{properties['code_dep']}#{properties['code_com']}"
|
|
|
|
else
|
|
|
|
properties['commune']
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def cid
|
|
|
|
if legacy_cadastre?
|
|
|
|
"#{code_dep}#{code_com}#{code_arr}#{section}#{numero}"
|
|
|
|
else
|
|
|
|
properties['id']
|
|
|
|
end
|
|
|
|
end
|
2023-02-14 18:38:01 +01:00
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def normalize_geometry
|
|
|
|
if geometry.present?
|
|
|
|
normalized_geometry = rgeo_geometry
|
|
|
|
if normalized_geometry.present?
|
|
|
|
self.geometry = RGeo::GeoJSON.encode(normalized_geometry)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def rgeo_geometry
|
|
|
|
RGeo::GeoJSON.decode(geometry.to_json, geo_factory: RGeo::Geographic.simple_mercator_factory)
|
|
|
|
rescue RGeo::Error::InvalidGeometry
|
|
|
|
nil
|
|
|
|
end
|
2018-10-16 13:01:12 +02:00
|
|
|
end
|