class Geokit::Polygon

A complex polygon made of multiple points. End point must equal start point to close the poly.

Attributes

points[RW]

Public Class Methods

new(points) click to toggle source

Pass in an array of Geokit::LatLng

# File lib/geokit/polygon.rb, line 7
def initialize(points)
  @points = points

  # A Polygon must be 'closed', the last point equal to the first point
  # Append the first point to the array to close the polygon
  @points << points[0] if points[0] != points[-1]
end

Public Instance Methods

centroid() click to toggle source

A polygon is static and can not be updated with new points, as a result calculate the centroid once and store it when requested.

# File lib/geokit/polygon.rb, line 39
def centroid
  @centroid ||= calculate_centroid
end
contains?(point) click to toggle source
# File lib/geokit/polygon.rb, line 15
def contains?(point)
  last_point = @points[-1]
  oddNodes = false
  x = point.lng
  y = point.lat

  @points.each do |p|
    yi = p.lat
    xi = p.lng
    yj = last_point.lat
    xj = last_point.lng
    if yi < y && yj >= y ||
        yj < y && yi >= y
      oddNodes = !oddNodes if xi + (y - yi) / (yj - yi) * (xj - xi) < x
    end

    last_point = p
  end

  oddNodes
end

Private Instance Methods

calculate_centroid() click to toggle source
# File lib/geokit/polygon.rb, line 45
def calculate_centroid
  centroid_lat = 0.0
  centroid_lng = 0.0
  signed_area = 0.0

  # Iterate over each element in the list but the last item as it's
  # calculated by the i+1 logic
  @points[0...-1].each_index do |i|
    x0 = @points[i].lat
    y0 = @points[i].lng
    x1 = @points[i + 1].lat
    y1 = @points[i + 1].lng
    a = (x0 * y1) - (x1 * y0)
    signed_area += a
    centroid_lat += (x0 + x1) * a
    centroid_lng += (y0 + y1) * a
  end

  signed_area *= 0.5
  centroid_lat /= (6.0 * signed_area)
  centroid_lng /= (6.0 * signed_area)

  Geokit::LatLng.new(centroid_lat, centroid_lng)
end