# == 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 # class GeoArea < ApplicationRecord belongs_to :champ, optional: false store :properties, accessors: [ :description, :surface_intersection, :surface_parcelle, :numero, :feuille, :section, :code_dep, :nom_com, :code_com, :code_arr, :code, :nom, :commune, :culture, :code_culture, :surface, :bio ] enum source: { cadastre: 'cadastre', selection_utilisateur: 'selection_utilisateur' } scope :selections_utilisateur, -> { where(source: sources.fetch(:selection_utilisateur)) } scope :cadastres, -> { where(source: sources.fetch(:cadastre)) } validates :geometry, geo_json: true, allow_blank: false def to_feature { type: 'Feature', geometry: safe_geometry, properties: properties.symbolize_keys.merge( source: source, area: area, length: length, id: id, champ_id: champ.stable_id, dossier_id: champ.dossier_id ).compact } end def safe_geometry RGeo::GeoJSON.encode(rgeo_geometry) end def rgeo_geometry RGeo::GeoJSON.decode(geometry.to_json, geo_factory: RGeo::Geographic.simple_mercator_factory) rescue RGeo::Error::InvalidGeometry nil end def self.from_feature_collection(feature_collection) feature_collection[:features].map do |feature| GeoArea.new( source: feature[:properties].delete(:source), properties: feature[:properties], geometry: feature[:geometry] ) end end def area if polygon? GeojsonService.area(geometry.deep_symbolize_keys).round(1) end end def length if line? GeojsonService.length(geometry.deep_symbolize_keys).round(1) end end def location if point? Geo::Coord.new(*rgeo_geometry.coordinates.reverse).to_s end end def line? geometry['type'] == 'LineString' end def polygon? geometry['type'] == 'Polygon' end def point? geometry['type'] == 'Point' end end