Class: AIPP::Border
Overview
Border GeoJSON file reader
The border GeoJSON files must be a geometry collection of one or more line strings:
{
"type": "GeometryCollection",
"geometries": [
{
"type": "LineString",
"coordinates": [
[6.009531650000042, 45.12013319700009],
[6.015747738000073, 45.12006702600007]
]
}
]
}
Defined Under Namespace
Classes: Position
Instance Attribute Summary collapse
-
#file ⇒ Object
readonly
Returns the value of attribute file.
-
#geometries ⇒ Object
readonly
Returns the value of attribute geometries.
Instance Method Summary collapse
-
#closed?(geometry_index:) ⇒ Boolean
Whether the given geometry is closed or not.
-
#initialize(file) ⇒ Border
constructor
A new instance of Border.
- #inspect ⇒ String
-
#name ⇒ String
Name of the border.
-
#nearest(geometry_index: nil, xy:) ⇒ AIPP::Border::Position
Find a position on a geometry nearest to the given coordinates.
-
#segment(from_position:, to_position:) ⇒ Array<AIXM::XY>
Get a segment of a geometry between the given starting and ending positions.
Constructor Details
#initialize(file) ⇒ Border
Returns a new instance of Border.
29 30 31 32 33 |
# File 'lib/aipp/border.rb', line 29 def initialize(file) @file = file.is_a?(Pathname) ? file : Pathname(file) fail(ArgumentError, "file must have extension .geojson") unless @file.extname == '.geojson' @geometries = load_geometries end |
Instance Attribute Details
#file ⇒ Object (readonly)
Returns the value of attribute file.
26 27 28 |
# File 'lib/aipp/border.rb', line 26 def file @file end |
#geometries ⇒ Object (readonly)
Returns the value of attribute geometries.
27 28 29 |
# File 'lib/aipp/border.rb', line 27 def geometries @geometries end |
Instance Method Details
#closed?(geometry_index:) ⇒ Boolean
Whether the given geometry is closed or not
A geometry is considered closed when it’s first coordinate equals the last coordinate.
58 59 60 61 |
# File 'lib/aipp/border.rb', line 58 def closed?(geometry_index:) geometry = @geometries[geometry_index] geometry.first == geometry.last end |
#inspect ⇒ String
36 37 38 |
# File 'lib/aipp/border.rb', line 36 def inspect %Q(#<#{self.class} file=#{@file}>) end |
#name ⇒ String
Name of the border
By convention, the name of the border is taken from the filename with both the extension .geojson and all non alphanumeric characters dropped and the resulting string upcased.
47 48 49 |
# File 'lib/aipp/border.rb', line 47 def name @file.basename('.geojson').to_s.gsub(/\W/, '').upcase end |
#nearest(geometry_index: nil, xy:) ⇒ AIPP::Border::Position
Find a position on a geometry nearest to the given coordinates
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/aipp/border.rb', line 69 def nearest(geometry_index: nil, xy:) position = nil min_distance = 21_000_000 # max distance on earth in meters @geometries.each.with_index do |geometry, g_index| next unless geometry_index.nil? || geometry_index == g_index geometry.each.with_index do |coordinates, c_index| distance = xy.distance(coordinates).dist if distance < min_distance position = Position.new(geometries: geometries, geometry_index: g_index, coordinates_index: c_index) min_distance = distance end end end position end |
#segment(from_position:, to_position:) ⇒ Array<AIXM::XY>
Get a segment of a geometry between the given starting and ending positions
The segment ends either at the given ending position or at the last coordinates of the geometry. However, if the geometry is closed, the segment always continues up to the given ending position.
95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/aipp/border.rb', line 95 def segment(from_position:, to_position:) fail(ArgumentError, "both positions must be on the same geometry") unless from_position.geometry_index == to_position.geometry_index geometry_index = from_position.geometry_index geometry = @geometries[geometry_index] if closed?(geometry_index: geometry_index) up = from_position.coordinates_index.upto(to_position.coordinates_index) down = from_position.coordinates_index.downto(0) + (geometry.count - 2).downto(to_position.coordinates_index) geometry.values_at(*(up.count < down.count ? up : down).to_a) else geometry.values_at(*from_position.coordinates_index.up_or_downto(to_position.coordinates_index).to_a) end end |