Sha256: fedf5f08e7abffeab1063320b9bb2342be280db6eba06a6bea205762b50f5db4

Contents?: true

Size: 1.83 KB

Versions: 7

Compression:

Stored size: 1.83 KB

Contents

# frozen_string_literal: true

class Map::PolygonService
  CACHE_EXPIRES = 1.hours

  def initialize(glebas = nil)
    @glebas = glebas
  end

  def inside_any_gleba?(point)
    glebas.each do |gleba|
      coords = polygon(gleba)
      coords.each do |coord|
        return gleba if point_inside?(point, coord)
      end
    end

    nil
  end

  def glebas
    @glebas ||= Gleba.select(:cd_gleba, :cd_propriedade, :arquivo_kml, :descricao).active.with_kml
  end

  def inside_polygons?(point, polygons)
    polygons.any? do |polygon|
      point_inside?(point, polygon)
    end
  end

  private

  # Algoritmo portado de código javascript
  # ray-casting algorithm based on
  # http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
  # https://github.com/substack/point-in-polygon
  def point_inside?(point, polygon)
    x = (point[:latitude] || point['latitude']).to_f
    y = (point[:longitude] || point['longitude']).to_f

    inside = false
    i = 0
    j = polygon.length - 1

    polygon.length.times do
      xi = (polygon[i][1] || polygon[i]['latitude']).to_f
      yi = (polygon[i][0] || polygon[i]['longitude']).to_f

      xj = (polygon[j][1] || polygon[j]['latitude']).to_f
      yj = (polygon[j][0] || polygon[j]['longitude']).to_f

      intersect = ((yi > y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi)

      inside = !inside if intersect
      i += 1
      j = i - 1
    end

    inside
  end

  def coordinates(gleba)
    if gleba.respond_to?(:coordinates)
      gleba.coordinates
    elsif gleba.respond_to?(:at)
      gleba.at(:coordinates).text.strip
    else
      Map::KmlService.new(gleba.arquivo_kml).coordinates
    end
  end

  def polygon(gleba)
    SafeCacheService.new("#{gleba.id}/coordinates", expires_in: CACHE_EXPIRES, execute_if: Rails.env.production?)
      .fetch { coordinates(gleba) }
  end
end

Version data entries

7 entries across 7 versions & 1 rubygems

Version Path
aqila-mapas-0.4.12 lib/map/polygon_service.rb
aqila-mapas-0.4.11 lib/map/polygon_service.rb
aqila-mapas-0.4.9 lib/map/polygon_service.rb
aqila-mapas-0.4.8 lib/map/polygon_service.rb
aqila-mapas-0.4.7 lib/map/polygon_service.rb
aqila-mapas-0.4.6 lib/map/polygon_service.rb
aqila-mapas-0.4.5 lib/map/polygon_service.rb