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 +4 -4
- data/README.md +4 -1
- data/lib/turf/boolean_clockwise.rb +21 -3
- data/lib/turf/boolean_concave.rb +34 -2
- data/lib/turf/boolean_point_on_line.rb +122 -2
- data/lib/turf/length.rb +1 -1
- data/lib/turf/meta.rb +1 -1
- data/lib/turf/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aace9437eb9fd63a23fb1cae270444dffa0dbf58f371ce88abf1ff7dc483fb5b
|
4
|
+
data.tar.gz: 15ef3f0c1cc5dd1d9ebfaf298512f0a509bb524a432b002cccfe48a4b5d2d011
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e56d69dd9c440438b5de0734b7c8068e745a111a27c17fa7c6fc5883eed7c42fcdc1765234605f533fb9becfc22d7009c95199111665a147738e38abe0c5c30c
|
7
|
+
data.tar.gz: c5cf79e1af361fb5010c4f997445ddc7d6378422e07252b01f105464863d2253a0d8de89ed889ec872f958a81b0cfccd6c983076d80b92aaf236f75b05c6e6c4
|
data/README.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
# turf-ruby
|
1
|
+
# turf-ruby
|
2
|
+
|
3
|
+
[](https://badge.fury.io/rb/turf-ruby)
|
4
|
+
[](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
|
-
#
|
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(
|
6
|
-
|
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
|
data/lib/turf/boolean_concave.rb
CHANGED
@@ -2,7 +2,39 @@
|
|
2
2
|
|
3
3
|
# :nodoc:
|
4
4
|
module Turf
|
5
|
-
|
6
|
-
|
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
|
-
|
6
|
-
|
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 +
|
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 =
|
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
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.
|
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:
|
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.
|
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: []
|