module Hexagonly::Polygon::Methods

Adds Polygon methods to an object. The Polygon corners are read via the poly_points method. You can override this method or use the poly_points_method class method to set a method name for reading polygon corners.

@example

class MyPolygon

  include Hexagonly::Polygon::Methods
  poly_points_method :corners

  attr_reader :corners
  def initialize(corners); @corners = corners; end

end

Attributes

collected_points[RW]
geo_properties[RW]
geo_style[RW]
rejected_points[RW]

Public Class Methods

included(base) click to toggle source
# File lib/hexagonly/polygon.rb, line 21
def self.included(base)
  base.extend(ClassMethods)
end

Public Instance Methods

contains?(point) click to toggle source

Crossing count algorithm for determining whether a point lies within a polygon. Ported from www.visibone.com/inpoly/inpoly.c.txt (original C code by Bob Stein & Craig Yap).

# File lib/hexagonly/polygon.rb, line 44
def contains?(point)
  raise "Not a valid polygon!" if poly_points.nil? || poly_points.size < 3

  is_inside = false
  old_p = poly_points.last
  poly_points.each do |new_p|
    if new_p.x_coord > old_p.x_coord
      first_p = old_p
      second_p = new_p
    else
      first_p = new_p
      second_p = old_p
    end
    if ((new_p.x_coord < point.x_coord) == (point.x_coord <= old_p.x_coord)) && ((point.y_coord - first_p.y_coord) * (second_p.x_coord - first_p.x_coord) < (second_p.y_coord - first_p.y_coord) * (point.x_coord - first_p.x_coord))
      is_inside = ! is_inside
    end
    old_p = new_p
  end

  is_inside
end
grab(points) click to toggle source

Grabs all points within the polygon boundries from an array of Points and appends them to @collected_points. All rejected Points are stored under @rejected_points (if you want to pass the to other objects).

@param points [Array<Hexagonly::Point>]

@return [Array<Hexagonly::Point] the grabed points

# File lib/hexagonly/polygon.rb, line 73
def grab(points)
  parts = points.partition{ |p| contains?(p) }
  @collected_points ||= []
  @collected_points += parts[0]
  @rejected_points = parts[1]

  parts[0]
end
poly_points() click to toggle source
# File lib/hexagonly/polygon.rb, line 35
def poly_points
  raise NoMethodError if self.class.poly_points_method_name.nil?

  send(self.class.poly_points_method_name)
end
to_geojson() click to toggle source
# File lib/hexagonly/polygon.rb, line 84
def to_geojson
  points = poly_points.map{ |p| [p.x_coord, p.y_coord] }
  points << points.last
  {
    :type => "Feature",
    :geometry => {
      :type => "Polygon",
      :coordinates => [points]
    },
    :style => geo_style,
    :properties => geo_properties
  }
end