Class: NSWTopo::GeoJSON::Polygon
- Inherits:
-
Object
- Object
- NSWTopo::GeoJSON::Polygon
- Includes:
- SVG
- Defined in:
- lib/nswtopo/gis/geojson/polygon.rb
Class Method Summary collapse
Instance Method Summary collapse
- #add_ring(ring) ⇒ Object
- #area ⇒ Object
- #bounds ⇒ Object
- #centroid ⇒ Object
- #contains?(geometry) ⇒ Boolean
- #freeze! ⇒ Object
- #remove_holes(&block) ⇒ Object
- #rings ⇒ Object
- #svg_path_data ⇒ Object
- #wkt ⇒ Object
Class Method Details
.[](coordinates, properties = nil, &block) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 |
# File 'lib/nswtopo/gis/geojson/polygon.rb', line 6 def self.[](coordinates, properties = nil, &block) new(coordinates, properties) do @coordinates.each.with_index do |coordinates, index| LineString[coordinates] do |ring| ring.coordinates << ring.first unless ring.closed? ring.coordinates.reverse! if index.zero? ^ ring.exterior? end end block.call self if block_given? end end |
Instance Method Details
#add_ring(ring) ⇒ Object
52 53 54 |
# File 'lib/nswtopo/gis/geojson/polygon.rb', line 52 def add_ring(ring) Polygon.new [*@coordinates, ring.coordinates], @properties end |
#area ⇒ Object
56 57 58 |
# File 'lib/nswtopo/gis/geojson/polygon.rb', line 56 def area rings.sum(&:signed_area) end |
#bounds ⇒ Object
25 26 27 |
# File 'lib/nswtopo/gis/geojson/polygon.rb', line 25 def bounds first.transpose.map(&:minmax) end |
#centroid ⇒ Object
37 38 39 40 41 42 43 44 45 46 |
# File 'lib/nswtopo/gis/geojson/polygon.rb', line 37 def centroid flat_map do |ring| ring.each_cons(2).map do |p0, p1| next (p0 + p1) * p0.cross(p1), 3 * p0.cross(p1) end end.transpose.then do |centroids_x6, signed_areas_x6| point = centroids_x6.inject(&:+) / signed_areas_x6.inject(&:+) Point.new point, @properties end end |
#contains?(geometry) ⇒ Boolean
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/nswtopo/gis/geojson/polygon.rb', line 66 def contains?(geometry) geometry = Point.new(geometry) if Vector === geometry geometry.dissolve_points.coordinates.all? do |point| sum do |ring| ring.each_cons(2).inject(0) do |winding, (p0, p1)| case when p1.y > point.y && p0.y <= point.y && (p0 - p1).cross(p0 - point) >= 0 then winding + 1 when p0.y > point.y && p1.y <= point.y && (p1 - p0).cross(p0 - point) >= 0 then winding - 1 when p0.y == point.y && p1.y == point.y && p0.x >= point.x && p1.x < point.x then winding + 1 when p0.y == point.y && p1.y == point.y && p1.x >= point.x && p0.x < point.x then winding - 1 else winding end end end.nonzero? end end |
#freeze! ⇒ Object
18 19 20 21 |
# File 'lib/nswtopo/gis/geojson/polygon.rb', line 18 def freeze! @coordinates.each(&:freeze) freeze end |
#remove_holes(&block) ⇒ Object
60 61 62 63 64 |
# File 'lib/nswtopo/gis/geojson/polygon.rb', line 60 def remove_holes(&block) rings.reject_linestrings do |ring| ring.interior? && (block_given? ? block.call(ring) : true) end.to_polygon end |
#rings ⇒ Object
48 49 50 |
# File 'lib/nswtopo/gis/geojson/polygon.rb', line 48 def rings MultiLineString.new @coordinates, @properties end |
#svg_path_data ⇒ Object
83 84 85 |
# File 'lib/nswtopo/gis/geojson/polygon.rb', line 83 def svg_path_data rings.map(&:svg_path_data).join(?\s) end |
#wkt ⇒ Object
29 30 31 32 33 34 35 |
# File 'lib/nswtopo/gis/geojson/polygon.rb', line 29 def wkt map do |ring| ring.map do |point| point.join(" ") end.join(", ").prepend("(").concat(")") end.join(", ").prepend("POLYGON (").concat(")") end |