require 'rgeo' require 'geo_graf/polygon' module GeoGraf class GeosNotInstalledError < StandardError; end class IntersectionCalculator def initialize(input_geodata) @geodata ||= input_geodata .map { |geodatum| {id: geodatum[:id], polygon: polygon_from_coords(geodatum[:polygon_coords])} } .sort_by { |geodatum| geodatum[:polygon].area } # always have smaller first end def intersections intersections = [] geodata.combination(2) do |smaller, bigger| intersection_area = smaller[:polygon].intersection_area(bigger[:polygon]) unless intersection_area.zero? intersections << { id: smaller[:id], contained_area_percentage: (intersection_area.to_f / smaller[:polygon].area * 100).round, container_id: bigger[:id] } end end intersections end private attr_reader :geodata def polygon_from_coords(coords) Polygon.new(coords, rgeo_factory) end def rgeo_factory raise(GeosNotInstalledError, 'The Geos library needs to be installed (see README.md).') unless RGeo::Geos.supported? @factory ||= RGeo::Geographic.simple_mercator_factory end end end