turf-ruby 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 934aa7ef548c273fb906a74bd0d16b5344002274a8148ea4ec05ea7cf1b82cb6
4
- data.tar.gz: 429c123473d5db24ec4aaf3562a1104c9c815d9b2579b843267f1cd451f6d639
3
+ metadata.gz: aace9437eb9fd63a23fb1cae270444dffa0dbf58f371ce88abf1ff7dc483fb5b
4
+ data.tar.gz: 15ef3f0c1cc5dd1d9ebfaf298512f0a509bb524a432b002cccfe48a4b5d2d011
5
5
  SHA512:
6
- metadata.gz: 2fcdbcbb0a61f0a6ccf80c9f848fb0a60025bcb70803617ca211594228f9ab0a1d44f4d0563a63d3ac3399da812bbbe61140552d029d1987b4af00abbedd37f3
7
- data.tar.gz: 0debca6e4ee62bfad49f9d7c3124fe295dbf361f67c2c340aa03a8ff2e3fc5aa564cd435e5ee929d4965a49b9dacea8d6730ba7932f3b9e4e0e2dae73d2a1f8f
6
+ metadata.gz: e56d69dd9c440438b5de0734b7c8068e745a111a27c17fa7c6fc5883eed7c42fcdc1765234605f533fb9becfc22d7009c95199111665a147738e38abe0c5c30c
7
+ data.tar.gz: c5cf79e1af361fb5010c4f997445ddc7d6378422e07252b01f105464863d2253a0d8de89ed889ec872f958a81b0cfccd6c983076d80b92aaf236f75b05c6e6c4
data/README.md CHANGED
@@ -1,4 +1,7 @@
1
- # turf-ruby [![Build Status](https://travis-ci.com/formigarafa/turf-ruby.svg?branch=master)](https://travis-ci.com/formigarafa/turf-ruby)
1
+ # turf-ruby
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/turf-ruby.svg)](https://badge.fury.io/rb/turf-ruby)
4
+ [![Build Status](https://github.com/formigarafa/turf-ruby/actions/workflows/tests.yml/badge.svg)](https://github.com/formigarafa/turf-ruby)
2
5
 
3
6
  Ruby port of [Turf.js](https://turfjs.org/), an advance geospatial analysis library.
4
7
 
@@ -1,8 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # :nodoc:
3
+ # Takes a ring and returns true or false whether or not the ring is clockwise or counter-clockwise.
4
+ #
5
+ # @param [Array<Array<Number>>] line to be evaluated
6
+ # @return [Boolean] true/false
7
+ # @example
8
+ # clockwise_ring = [[0, 0], [1, 1], [1, 0], [0, 0]]
9
+ # counter_clockwise_ring = [[0, 0], [1, 0], [1, 1], [0, 0]]
10
+ #
11
+ # boolean_clockwise(clockwise_ring)
12
+ # # => true
13
+ # boolean_clockwise(counter_clockwise_ring)
14
+ # # => false
4
15
  module Turf
5
- def boolean_clockwise(*args)
6
- raise NotImplementedError
16
+ def boolean_clockwise(line)
17
+ ring = get_coords(line)
18
+ sum = 0
19
+
20
+ ring.each_cons(2) do |prev, cur|
21
+ sum += (cur[0] - prev[0]) * (cur[1] + prev[1])
22
+ end
23
+
24
+ sum > 0
7
25
  end
8
26
  end
@@ -2,7 +2,39 @@
2
2
 
3
3
  # :nodoc:
4
4
  module Turf
5
- def boolean_concave(*args)
6
- raise NotImplementedError
5
+ # frozen_string_literal: true
6
+
7
+ # Takes a polygon and returns true or false as to whether it is concave or not.
8
+ #
9
+ # @function
10
+ # @param [Feature<Polygon>, Polygon] polygon to be evaluated
11
+ # @return [Boolean] true/false
12
+ # @example
13
+ # convex_polygon = polygon([[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]])
14
+ #
15
+ # boolean_concave(convex_polygon)
16
+ # # => false
17
+ def boolean_concave(polygon)
18
+ coords = get_geom(polygon)[:coordinates]
19
+ return false if coords[0].length <= 4
20
+
21
+ sign = nil
22
+ n = coords[0].length - 1
23
+
24
+ (0...n).each do |i|
25
+ dx1 = coords[0][(i + 2) % n][0] - coords[0][(i + 1) % n][0]
26
+ dy1 = coords[0][(i + 2) % n][1] - coords[0][(i + 1) % n][1]
27
+ dx2 = coords[0][i][0] - coords[0][(i + 1) % n][0]
28
+ dy2 = coords[0][i][1] - coords[0][(i + 1) % n][1]
29
+ zcrossproduct = (dx1 * dy2) - (dy1 * dx2)
30
+
31
+ if i.zero?
32
+ sign = zcrossproduct.positive?
33
+ elsif sign != zcrossproduct.positive?
34
+ return true
35
+ end
36
+ end
37
+
38
+ false
7
39
  end
8
40
  end
@@ -2,7 +2,127 @@
2
2
 
3
3
  # :nodoc:
4
4
  module Turf
5
- def boolean_point_on_line(*args)
6
- raise NotImplementedError
5
+ # Returns true if a point is on a line. Accepts an optional parameter to ignore the
6
+ # start and end vertices of the linestring.
7
+ #
8
+ # @param [Hash] pt GeoJSON Point
9
+ # @param [Hash] line GeoJSON LineString
10
+ # @param [Hash] options Optional parameters
11
+ # @option options [Boolean] :ignore_end_vertices whether to ignore the start and end vertices.
12
+ # @option options [Float] :epsilon Fractional number to compare with the cross product result.
13
+ # Useful for dealing with floating points such as lng/lat points
14
+ # @return [Boolean] true/false
15
+ # @example
16
+ # pt = turf_point([0, 0])
17
+ # line = turf_line_string([[-1, -1], [1, 1], [1.5, 2.2]])
18
+ # is_point_on_line = boolean_point_on_line(pt, line)
19
+ # # => true
20
+ def boolean_point_on_line(point, line, options = nil)
21
+ options ||= {}
22
+ # Normalize inputs
23
+ pt_coords = get_coord(point)
24
+ line_coords = get_coords(line)
25
+
26
+ # Main
27
+ line_coords.each_cons(2) do |line_segment_start, line_segment_end|
28
+ ignore_boundary = false
29
+ if options[:ignore_end_vertices]
30
+ first_segment = (line_coords.first == line_segment_start)
31
+ last_segment = (line_coords.last == line_segment_end)
32
+
33
+ if first_segment && last_segment
34
+ ignore_boundary = :both
35
+ elsif first_segment
36
+ ignore_boundary = :start
37
+ elsif last_segment
38
+ ignore_boundary = :end
39
+ end
40
+ end
41
+
42
+ return true if is_point_on_line_segment(
43
+ line_segment_start,
44
+ line_segment_end,
45
+ pt_coords,
46
+ ignore_boundary,
47
+ options[:epsilon],
48
+ )
49
+ end
50
+
51
+ false
52
+ end
53
+
54
+ # Determines if a point is on a line segment.
55
+ #
56
+ # @param [Array<Float>] line_segment_start Coordinate pair of the start of the line segment [x1, y1].
57
+ # @param [Array<Float>] line_segment_end Coordinate pair of the end of the line segment [x2, y2].
58
+ # @param [Array<Float>] pt Coordinate pair of the point to check [px, py].
59
+ # @param [Boolean, String] exclude_boundary Whether the point is allowed to fall on the line ends.
60
+ # Can be true, false, or one of "start", "end", or "both".
61
+ # @param [Float, NilClass] epsilon Fractional tolerance for cross-product
62
+ # comparison (useful for floating-point coordinates).
63
+ # @return [Boolean] true if the point is on the line segment, false otherwise.
64
+ def is_point_on_line_segment(line_segment_start, line_segment_end, point, exclude_boundary, epsilon = nil)
65
+ x, y = point
66
+ x1, y1 = line_segment_start
67
+ x2, y2 = line_segment_end
68
+
69
+ dxc = x - x1
70
+ dyc = y - y1
71
+ dxl = x2 - x1
72
+ dyl = y2 - y1
73
+ cross = (dxc * dyl) - (dyc * dxl)
74
+
75
+ if epsilon
76
+ return false if cross.abs > epsilon
77
+ elsif cross != 0
78
+ return false
79
+ end
80
+
81
+ # Special case: zero-length line segments
82
+ if dxl == 0 && dyl == 0
83
+ return false if exclude_boundary
84
+
85
+ return point == line_segment_start
86
+ end
87
+
88
+ case exclude_boundary
89
+ when false
90
+ if dxl.abs >= dyl.abs
91
+ if dxl > 0
92
+ x.between?(x1,
93
+ x2)
94
+ else
95
+ x.between?(x2,
96
+ x1)
97
+ end
98
+ else
99
+ (if dyl > 0
100
+ y.between?(y1,
101
+ y2)
102
+ else
103
+ y.between?(y2, y1)
104
+ end)
105
+ end
106
+ when :start
107
+ if dxl.abs >= dyl.abs
108
+ dxl > 0 ? x1 < x && x <= x2 : x2 <= x && x < x1
109
+ else
110
+ (dyl > 0 ? y1 < y && y <= y2 : y2 < y && y < y1)
111
+ end
112
+ when :end
113
+ if dxl.abs >= dyl.abs
114
+ dxl > 0 ? x1 <= x && x < x2 : x2 < x && x <= x1
115
+ else
116
+ (dyl > 0 ? y1 <= y && y < y2 : y2 < y && y <= y1)
117
+ end
118
+ when :both
119
+ if dxl.abs >= dyl.abs
120
+ dxl > 0 ? x1 < x && x < x2 : x2 < x && x < x1
121
+ else
122
+ (dyl > 0 ? y1 < y && y < y2 : y2 < y && y < y1)
123
+ end
124
+ else
125
+ false
126
+ end
7
127
  end
8
128
  end
data/lib/turf/length.rb CHANGED
@@ -18,7 +18,7 @@ module Turf
18
18
  segment_reduce(geojson, 0) do |previous_value, segment|
19
19
  previous_value ||= 0
20
20
  coords = segment.dig(:geometry, :coordinates)
21
- previous_value + Turf.distance(coords[0], coords[1], options)
21
+ previous_value + distance(coords[0], coords[1], options)
22
22
  end
23
23
  end
24
24
  end
data/lib/turf/meta.rb CHANGED
@@ -419,7 +419,7 @@ module Turf
419
419
  next
420
420
  end
421
421
 
422
- segment = Turf.line_string([previous_coords, current_coord], feature[:properties])
422
+ segment = line_string([previous_coords, current_coord], feature[:properties])
423
423
  next unless yield(segment, feature_index, multi_feature_index, geometry_index, segment_index)
424
424
 
425
425
  segment_index += 1
data/lib/turf/version.rb CHANGED
@@ -3,5 +3,5 @@
3
3
  # :nodoc:
4
4
  module Turf
5
5
  # Version of turf-ruby
6
- VERSION = "1.0.0"
6
+ VERSION = "1.1.0"
7
7
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: turf-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rafael Santos
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-04-21 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: Turf Ruby is a Ruby library for spatial analysis. It includes traditional
13
13
  spatial operations, helper functions for creating GeoJSON data, and data classification
@@ -161,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
161
161
  - !ruby/object:Gem::Version
162
162
  version: '0'
163
163
  requirements: []
164
- rubygems_version: 3.6.2
164
+ rubygems_version: 3.6.7
165
165
  specification_version: 4
166
166
  summary: A modular geospatial engine. Ruby port of TurfJS.
167
167
  test_files: []