nswtopo 2.0.0.pre.beta1 → 3.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/COPYING +70 -83
- data/bin/nswtopo +227 -116
- data/docs/README.md +1 -12
- data/docs/add.md +1 -1
- data/docs/config.md +1 -1
- data/docs/contours.md +3 -1
- data/docs/init.md +8 -0
- data/docs/inspect.md +103 -0
- data/docs/move.md +9 -0
- data/docs/render.md +16 -7
- data/docs/scrape.md +67 -0
- data/docs/spot-heights.md +6 -2
- data/lib/nswtopo/archive.rb +50 -41
- data/lib/nswtopo/chrome.rb +227 -0
- data/lib/nswtopo/commands/add.rb +106 -0
- data/lib/nswtopo/commands/config.rb +38 -0
- data/lib/nswtopo/commands/inspect.rb +74 -0
- data/lib/nswtopo/commands/layers.rb +22 -0
- data/lib/nswtopo/commands/scrape.rb +79 -0
- data/lib/nswtopo/commands.rb +57 -0
- data/lib/nswtopo/dither.rb +5 -3
- data/lib/nswtopo/font.rb +46 -21
- data/lib/nswtopo/formats/gemf.rb +42 -0
- data/lib/nswtopo/formats/kmz.rb +26 -24
- data/lib/nswtopo/formats/mbtiles.rb +5 -41
- data/lib/nswtopo/formats/pdf.rb +82 -17
- data/lib/nswtopo/formats/svg.rb +114 -45
- data/lib/nswtopo/formats/svgz.rb +2 -2
- data/lib/nswtopo/formats/zip.rb +33 -23
- data/lib/nswtopo/formats.rb +77 -32
- data/lib/nswtopo/geometry/overlap.rb +1 -32
- data/lib/nswtopo/geometry/r_tree.rb +16 -10
- data/lib/nswtopo/geometry/segment.rb +3 -3
- data/lib/nswtopo/geometry/straight_skeleton/nodes.rb +5 -6
- data/lib/nswtopo/geometry/vector_sequence.rb +7 -6
- data/lib/nswtopo/gis/arcgis/connection.rb +56 -0
- data/lib/nswtopo/gis/arcgis/layer/map.rb +163 -0
- data/lib/nswtopo/gis/arcgis/layer/query.rb +87 -0
- data/lib/nswtopo/gis/arcgis/layer/renderer.rb +66 -0
- data/lib/nswtopo/gis/arcgis/layer/statistics.rb +15 -0
- data/lib/nswtopo/gis/arcgis/layer.rb +201 -0
- data/lib/nswtopo/gis/arcgis/service.rb +57 -0
- data/lib/nswtopo/gis/arcgis.rb +3 -0
- data/lib/nswtopo/gis/dem.rb +13 -12
- data/lib/nswtopo/gis/esri_hdr.rb +8 -2
- data/lib/nswtopo/gis/geojson/collection.rb +45 -21
- data/lib/nswtopo/gis/geojson/multi_line_string.rb +2 -24
- data/lib/nswtopo/gis/geojson/multi_polygon.rb +2 -53
- data/lib/nswtopo/gis/geojson/polygon.rb +15 -0
- data/lib/nswtopo/gis/geojson.rb +12 -3
- data/lib/nswtopo/gis/gps/kml.rb +25 -19
- data/lib/nswtopo/gis/gps.rb +2 -0
- data/lib/nswtopo/gis/projection.rb +35 -24
- data/lib/nswtopo/gis/shapefile.rb +89 -16
- data/lib/nswtopo/gis.rb +1 -2
- data/lib/nswtopo/helpers/array.rb +0 -11
- data/lib/nswtopo/helpers/colour.rb +34 -14
- data/lib/nswtopo/layer/arcgis_raster.rb +44 -48
- data/lib/nswtopo/layer/colour_mask.rb +5 -0
- data/lib/nswtopo/layer/contour.rb +35 -28
- data/lib/nswtopo/layer/control.rb +2 -7
- data/lib/nswtopo/layer/declination.rb +9 -9
- data/lib/nswtopo/layer/feature.rb +36 -22
- data/lib/nswtopo/layer/grid.rb +30 -27
- data/lib/nswtopo/layer/import.rb +1 -21
- data/lib/nswtopo/layer/labels/barrier.rb +39 -0
- data/lib/nswtopo/layer/labels.rb +551 -383
- data/lib/nswtopo/layer/mask_render.rb +37 -0
- data/lib/nswtopo/layer/overlay.rb +2 -2
- data/lib/nswtopo/layer/raster.rb +31 -41
- data/lib/nswtopo/layer/raster_import.rb +17 -0
- data/lib/nswtopo/layer/raster_render.rb +15 -0
- data/lib/nswtopo/layer/relief.rb +27 -95
- data/lib/nswtopo/layer/spot.rb +63 -62
- data/lib/nswtopo/layer/vector/cutout.rb +15 -0
- data/lib/nswtopo/layer/vector/knockout.rb +16 -0
- data/lib/nswtopo/layer/vector.rb +121 -89
- data/lib/nswtopo/layer/vegetation.rb +39 -34
- data/lib/nswtopo/layer.rb +30 -16
- data/lib/nswtopo/map.rb +202 -109
- data/lib/nswtopo/os.rb +5 -27
- data/lib/nswtopo/tiled_web_map.rb +54 -0
- data/lib/nswtopo/tree_indenter.rb +27 -0
- data/lib/nswtopo/version.rb +27 -2
- data/lib/nswtopo.rb +6 -199
- metadata +41 -22
- data/lib/nswtopo/font/chrome.rb +0 -59
- data/lib/nswtopo/font/generic.rb +0 -25
- data/lib/nswtopo/gis/arcgis_server/connection.rb +0 -52
- data/lib/nswtopo/gis/arcgis_server.rb +0 -155
- data/lib/nswtopo/gis/geojson/multi_point.rb +0 -12
- data/lib/nswtopo/gis/world_file.rb +0 -19
- data/lib/nswtopo/layer/labels/fence.rb +0 -20
|
@@ -6,22 +6,17 @@ module NSWTopo
|
|
|
6
6
|
diameter: 7.0
|
|
7
7
|
colour: darkmagenta
|
|
8
8
|
stroke-width: 0.25
|
|
9
|
+
knockout: 0.1
|
|
9
10
|
waterdrop:
|
|
10
11
|
stroke: blue
|
|
11
12
|
labels:
|
|
12
|
-
dupe: outline
|
|
13
|
-
outline:
|
|
14
|
-
stroke: white
|
|
15
|
-
fill: none
|
|
16
|
-
stroke-width: 0.25
|
|
17
|
-
stroke-opacity: 0.75
|
|
18
13
|
position: [ aboveright, belowright, aboveleft, belowleft, right, left, above, below ]
|
|
19
14
|
font-family: sans-serif
|
|
20
15
|
font-style: normal
|
|
21
16
|
stroke: none
|
|
22
17
|
YAML
|
|
23
18
|
SCALING_PARAMS = <<~YAML
|
|
24
|
-
|
|
19
|
+
barrier: 2.0
|
|
25
20
|
control:
|
|
26
21
|
symbol:
|
|
27
22
|
- circle:
|
|
@@ -17,23 +17,23 @@ module NSWTopo
|
|
|
17
17
|
def get_features
|
|
18
18
|
@params["fill"] ||= @params["stroke"]
|
|
19
19
|
declination = @angle || @map.declination
|
|
20
|
-
col_spacing =
|
|
21
|
-
row_spacing =
|
|
22
|
-
col_offset =
|
|
20
|
+
col_spacing = @spacing
|
|
21
|
+
row_spacing = @arrows * 0.5
|
|
22
|
+
col_offset = @offset % @spacing
|
|
23
23
|
|
|
24
|
-
radius = 0.5 * @map.bounds.transpose.distance
|
|
24
|
+
radius = 0.5 * @map.neatline.bounds.transpose.distance
|
|
25
25
|
j_max = (radius / col_spacing).ceil
|
|
26
26
|
i_max = (radius / row_spacing).ceil
|
|
27
27
|
|
|
28
|
-
collection = GeoJSON::Collection.new(@map.projection)
|
|
28
|
+
collection = GeoJSON::Collection.new(projection: @map.neatline.projection)
|
|
29
29
|
(-j_max..j_max).each do |j|
|
|
30
30
|
x = j * col_spacing + col_offset
|
|
31
|
-
coordinates = [[x,
|
|
32
|
-
point.rotate_by_degrees(-
|
|
31
|
+
coordinates = [[x, radius], [x, -radius]].map do |point|
|
|
32
|
+
point.rotate_by_degrees(declination - @map.rotation).plus @map.dimensions.times(0.5)
|
|
33
33
|
end
|
|
34
34
|
collection.add_linestring coordinates
|
|
35
35
|
(-i_max..i_max).reject(&j.even? ? :even? : :odd?).map do |i|
|
|
36
|
-
[x, i * row_spacing].rotate_by_degrees(-
|
|
36
|
+
[x, i * row_spacing].rotate_by_degrees(declination - @map.rotation).plus @map.dimensions.times(0.5)
|
|
37
37
|
end.each do |coordinates|
|
|
38
38
|
collection.add_point coordinates, "rotation" => declination
|
|
39
39
|
end
|
|
@@ -45,7 +45,7 @@ module NSWTopo
|
|
|
45
45
|
lines = features.grep(GeoJSON::LineString)
|
|
46
46
|
return @name if lines.none?
|
|
47
47
|
line = lines.map(&:coordinates).max_by(&:distance)
|
|
48
|
-
angle = 90
|
|
48
|
+
angle = 90 + 180 * Math::atan2(*line.diff.reverse) / Math::PI + @map.rotation
|
|
49
49
|
"%s: %i line%s at %.1f°%s" % [@name, lines.length, (?s unless lines.one?), angle.abs, angle > 0 ? ?E : angle < 0 ? ?W : nil]
|
|
50
50
|
end
|
|
51
51
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module NSWTopo
|
|
2
2
|
module Feature
|
|
3
|
-
include Vector,
|
|
3
|
+
include Vector, Log
|
|
4
4
|
CREATE = %w[features]
|
|
5
5
|
|
|
6
6
|
def get_features
|
|
@@ -11,25 +11,34 @@ module NSWTopo
|
|
|
11
11
|
else raise "#{@source.basename}: invalid or no features specified"
|
|
12
12
|
end
|
|
13
13
|
end.slice_before do |args|
|
|
14
|
-
!args
|
|
14
|
+
!args.delete(:fallback)
|
|
15
15
|
end.map do |fallbacks|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
16
|
+
fallbacks.each.with_object({})
|
|
17
|
+
end.map do |fallbacks|
|
|
18
|
+
args, options = *fallbacks.next
|
|
19
|
+
source, error = args.delete(:source), nil
|
|
20
|
+
source = @path if @path
|
|
21
|
+
log_update "%s: %s" % [@name, options.any? ? "failed to retrieve features, trying fallback source" : "retrieving features"]
|
|
22
|
+
raise "#{@source.basename}: no feature source defined" unless source
|
|
23
|
+
source_path = Pathname(source).expand_path(@source.parent)
|
|
24
|
+
options.merge! args
|
|
25
|
+
collection = case
|
|
26
|
+
when ArcGIS::Service === source
|
|
27
|
+
layer = ArcGIS::Service.new(source).layer(**options.slice(:layer, :where), geometry: @map.neatline(**MARGIN).bbox, decode: true)
|
|
28
|
+
layer.features(**options.slice(:per_page)) do |count, total|
|
|
29
|
+
log_update "%s: retrieved %i of %i feature%s" % [@name, count, total, (?s if total > 1)]
|
|
30
|
+
end.reproject_to(@map.neatline.projection)
|
|
31
|
+
when Shapefile::Source === source_path
|
|
32
|
+
layer = Shapefile::Source.new(source_path).layer(**options.slice(:where, :sql, :layer), geometry: @map.neatline(**MARGIN), projection: @map.neatline.projection)
|
|
33
|
+
layer.features
|
|
34
|
+
else
|
|
26
35
|
raise "#{@source.basename}: invalid feature source: #{source}"
|
|
27
|
-
rescue ArcGISServer::Error => error
|
|
28
|
-
next options, nil, error
|
|
29
36
|
end
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
next collection, options
|
|
38
|
+
rescue ArcGIS::Connection::Error => error
|
|
39
|
+
retry
|
|
40
|
+
rescue StopIteration
|
|
41
|
+
raise error
|
|
33
42
|
end.each do |collection, options|
|
|
34
43
|
rotation_attribute, arithmetic = case options[:rotation]
|
|
35
44
|
when /^90 - (\w+)$/ then [$1, true]
|
|
@@ -37,15 +46,15 @@ module NSWTopo
|
|
|
37
46
|
end
|
|
38
47
|
|
|
39
48
|
collection.each do |feature|
|
|
40
|
-
categories = [*options[:category]].
|
|
49
|
+
categories = [*options[:category]].flat_map do |category|
|
|
41
50
|
Hash === category ? [*category] : [category]
|
|
42
|
-
end.
|
|
51
|
+
end.map do |attribute, substitutions|
|
|
43
52
|
value = feature.fetch(attribute, attribute)
|
|
44
53
|
substitutions ? substitutions.fetch(value, value) : value
|
|
45
54
|
end
|
|
46
55
|
|
|
47
56
|
options[:sizes].tap do |mm, max = 9|
|
|
48
|
-
unit =
|
|
57
|
+
unit = (mm == true ? 5 : mm)
|
|
49
58
|
case feature
|
|
50
59
|
when GeoJSON::LineString, GeoJSON::MultiLineString
|
|
51
60
|
size = (Math::log2(feature.length) - Math::log2(unit)).ceil rescue 0
|
|
@@ -71,17 +80,22 @@ module NSWTopo
|
|
|
71
80
|
feature.fetch(attribute, attribute)
|
|
72
81
|
end.map(&:to_s).reject(&:empty?)
|
|
73
82
|
|
|
83
|
+
dual = options[:dual].then do |attribute|
|
|
84
|
+
feature.fetch(attribute, attribute) if attribute
|
|
85
|
+
end
|
|
86
|
+
|
|
74
87
|
categories = categories.map(&:to_s).reject(&:empty?).map(&method(:categorise))
|
|
75
88
|
properties = {}
|
|
76
89
|
properties["category"] = categories if categories.any?
|
|
77
90
|
properties["label"] = labels if labels.any?
|
|
91
|
+
properties["dual"] = dual if dual
|
|
78
92
|
properties["draw"] = false if options[:draw] == false
|
|
79
|
-
properties["draw"] = false if @name =~
|
|
93
|
+
properties["draw"] = false if @name =~ /[-_]labels$/ && !options.key?(:draw)
|
|
80
94
|
properties["rotation"] = rotation if rotation
|
|
81
95
|
|
|
82
96
|
feature.properties.replace properties
|
|
83
97
|
end
|
|
84
|
-
end.map(&:first).inject(&:merge)
|
|
98
|
+
end.map(&:first).inject(&:merge).rename(@name)
|
|
85
99
|
end
|
|
86
100
|
end
|
|
87
101
|
end
|
data/lib/nswtopo/layer/grid.rb
CHANGED
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
module NSWTopo
|
|
2
2
|
module Grid
|
|
3
3
|
include Vector
|
|
4
|
-
CREATE = %w[interval]
|
|
4
|
+
CREATE = %w[interval border]
|
|
5
5
|
INSET = 1.5
|
|
6
6
|
DEFAULTS = YAML.load <<~YAML
|
|
7
7
|
interval: 1000.0
|
|
8
8
|
stroke: black
|
|
9
9
|
stroke-width: 0.1
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
edge:
|
|
11
|
+
fill: none
|
|
12
|
+
preserve: true
|
|
12
13
|
labels:
|
|
13
|
-
dupe: outline
|
|
14
|
-
outline:
|
|
15
|
-
stroke: white
|
|
16
|
-
fill: none
|
|
17
|
-
stroke-width: 10%
|
|
18
|
-
opacity: 0.65
|
|
19
14
|
font-family: Arial Narrow, sans-serif
|
|
20
15
|
font-size: 2.3
|
|
21
16
|
stroke: none
|
|
@@ -24,11 +19,11 @@ module NSWTopo
|
|
|
24
19
|
YAML
|
|
25
20
|
|
|
26
21
|
def get_features
|
|
27
|
-
Projection.utm_zones(@map.
|
|
28
|
-
utm,
|
|
29
|
-
|
|
22
|
+
Projection.utm_zones(@map.neatline).flat_map do |zone|
|
|
23
|
+
utm, utm_geometry = Projection.utm(zone), Projection.utm_geometry(zone)
|
|
24
|
+
map_geometry = @map.neatline(**MARGIN).reproject_to_wgs84
|
|
30
25
|
|
|
31
|
-
eastings, northings = @map.
|
|
26
|
+
eastings, northings = @map.neatline.reproject_to(utm).bounds.map do |min, max|
|
|
32
27
|
(min / @interval).floor..(max / @interval).ceil
|
|
33
28
|
end.map do |counts|
|
|
34
29
|
counts.map { |count| count * @interval }
|
|
@@ -39,27 +34,34 @@ module NSWTopo
|
|
|
39
34
|
end
|
|
40
35
|
|
|
41
36
|
eastings, northings = [grid, grid.transpose].map.with_index do |lines, index|
|
|
42
|
-
lines.inject GeoJSON::Collection.new(utm) do |collection, line|
|
|
37
|
+
lines.inject GeoJSON::Collection.new(projection: utm) do |collection, line|
|
|
43
38
|
coord = line[0][index]
|
|
44
39
|
label = [coord / 100000, (coord / 1000) % 100]
|
|
45
40
|
label << coord % 1000 unless @interval % 1000 == 0
|
|
46
41
|
collection.add_linestring line, "label" => label, "ends" => [0, 1], "category" => index.zero? ? "easting" : "northing"
|
|
47
|
-
end.reproject_to_wgs84.clip
|
|
42
|
+
end.reproject_to_wgs84.clip(utm_geometry).clip(map_geometry).explode.each do |linestring|
|
|
48
43
|
linestring["ends"].delete 0 if linestring.coordinates[0][0] % 6 < 0.00001
|
|
49
44
|
linestring["ends"].delete 1 if linestring.coordinates[-1][0] % 6 < 0.00001
|
|
50
45
|
end
|
|
51
46
|
end
|
|
52
47
|
|
|
53
|
-
boundary_points = GeoJSON.multilinestring(grid.transpose, projection: utm).reproject_to_wgs84.clip
|
|
48
|
+
boundary_points = GeoJSON.multilinestring(grid.transpose, projection: utm).reproject_to_wgs84.clip(utm_geometry).coordinates.map(&:first)
|
|
54
49
|
boundary = GeoJSON.linestring boundary_points, properties: { "category" => "boundary" }
|
|
55
50
|
|
|
56
51
|
[eastings, northings, boundary]
|
|
57
|
-
end.
|
|
52
|
+
end.tap do |collections|
|
|
53
|
+
next unless @border
|
|
54
|
+
mm = -0.5 * @params["stroke-width"]
|
|
55
|
+
@map.neatline(mm: mm).reproject_to_wgs84.tap do |border|
|
|
56
|
+
border.properties.replace "category" => "edge"
|
|
57
|
+
collections << border
|
|
58
|
+
end
|
|
59
|
+
end.inject(&:merge)
|
|
58
60
|
end
|
|
59
61
|
|
|
60
62
|
def label_element(labels, label_params)
|
|
61
63
|
font_size = label_params["font-size"]
|
|
62
|
-
parts = labels.zip(
|
|
64
|
+
parts = labels.zip(["%d\u00a0", "%02d", "\u00a0%03d"]).map do |part, format|
|
|
63
65
|
format % part
|
|
64
66
|
end.zip([80, 100, 80])
|
|
65
67
|
|
|
@@ -70,19 +72,20 @@ module NSWTopo
|
|
|
70
72
|
tspan.add_text text
|
|
71
73
|
end
|
|
72
74
|
|
|
73
|
-
text_length = parts.
|
|
74
|
-
|
|
75
|
-
end
|
|
75
|
+
text_length = parts.sum do |text, percent|
|
|
76
|
+
Font.glyph_length text, label_params.merge("font-size" => font_size * percent / 100.0)
|
|
77
|
+
end
|
|
76
78
|
text_path.add_attribute "textLength", VALUE % text_length
|
|
77
79
|
[text_length, text_path]
|
|
78
80
|
end
|
|
79
81
|
|
|
80
82
|
def labeling_features
|
|
83
|
+
return [] if @params["unlabeled"]
|
|
81
84
|
label_params = @params["labels"]
|
|
82
85
|
font_size = label_params["font-size"]
|
|
83
|
-
offset = 0.85 * font_size
|
|
86
|
+
offset = -0.85 * font_size
|
|
84
87
|
inset = INSET + font_size * 0.5 * Math::sin(@map.rotation.abs * Math::PI / 180)
|
|
85
|
-
|
|
88
|
+
inset_geometry = @map.neatline(mm: -inset)
|
|
86
89
|
|
|
87
90
|
gridlines = features.select do |linestring|
|
|
88
91
|
linestring["label"]
|
|
@@ -99,14 +102,14 @@ module NSWTopo
|
|
|
99
102
|
easting["ends"].map! { |index| 1 - index }
|
|
100
103
|
end if flip_eastings
|
|
101
104
|
|
|
102
|
-
gridlines.map do |gridline|
|
|
103
|
-
gridline.offset(offset, splits: false)
|
|
104
|
-
end.
|
|
105
|
+
gridlines.inject(GeoJSON::Collection.new(projection: @map.neatline.projection)) do |collection, gridline|
|
|
106
|
+
collection << gridline.offset(offset, splits: false)
|
|
107
|
+
end.clip(inset_geometry).explode.flat_map do |gridline|
|
|
105
108
|
label, ends = gridline.values_at "label", "ends"
|
|
106
109
|
%i[itself reverse].values_at(*ends).map do |order|
|
|
107
110
|
text_length, text_path = label_element(label, label_params)
|
|
108
111
|
segment = gridline.coordinates.send(order).take(2)
|
|
109
|
-
fraction = text_length
|
|
112
|
+
fraction = text_length / segment.distance
|
|
110
113
|
coordinates = [segment[0], segment.along(fraction)].send(order)
|
|
111
114
|
GeoJSON::LineString.new coordinates, "label" => text_path
|
|
112
115
|
end
|
data/lib/nswtopo/layer/import.rb
CHANGED
|
@@ -1,25 +1,5 @@
|
|
|
1
1
|
module NSWTopo
|
|
2
2
|
module Import
|
|
3
|
-
include Raster
|
|
4
|
-
|
|
5
|
-
def get_raster(temp_dir)
|
|
6
|
-
crop_path = temp_dir / "crop.tif"
|
|
7
|
-
|
|
8
|
-
json = begin
|
|
9
|
-
OS.gdalinfo "-json", @path
|
|
10
|
-
rescue OS::Error
|
|
11
|
-
raise "invalid raster file: #{@path}"
|
|
12
|
-
end
|
|
13
|
-
palette = JSON.parse(json)["bands"].any? do |band|
|
|
14
|
-
"Palette" == band["colorInterpretation"]
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
projection = Projection.new(@path)
|
|
18
|
-
args = ["-projwin", *@map.projwin(projection), @path, crop_path]
|
|
19
|
-
args = ["-expand", "rgba", *args] if palette
|
|
20
|
-
OS.gdal_translate *args
|
|
21
|
-
|
|
22
|
-
return Numeric === @resolution ? @resolution : @map.get_raster_resolution(crop_path), crop_path
|
|
23
|
-
end
|
|
3
|
+
include RasterImport, Raster, RasterRender
|
|
24
4
|
end
|
|
25
5
|
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module NSWTopo
|
|
2
|
+
module Labels
|
|
3
|
+
class Barrier
|
|
4
|
+
class Segment
|
|
5
|
+
def initialize(segment, barrier)
|
|
6
|
+
@segment, @barrier = segment, barrier
|
|
7
|
+
@bounds = @segment.transpose.map(&:minmax).map do |min, max|
|
|
8
|
+
[min - barrier.buffer, max + barrier.buffer]
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
attr_reader :barrier, :bounds
|
|
12
|
+
|
|
13
|
+
def conflicts_with?(segment, buffer: 0)
|
|
14
|
+
[@segment, segment].overlap?(@barrier.buffer + buffer)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def initialize(feature, buffer)
|
|
19
|
+
@feature, @buffer = feature, buffer
|
|
20
|
+
end
|
|
21
|
+
attr_reader :buffer
|
|
22
|
+
|
|
23
|
+
def segments
|
|
24
|
+
case @feature
|
|
25
|
+
when GeoJSON::Point
|
|
26
|
+
[[@feature.coordinates] * 2]
|
|
27
|
+
when GeoJSON::LineString
|
|
28
|
+
@feature.coordinates.segments
|
|
29
|
+
when GeoJSON::Polygon
|
|
30
|
+
@feature.coordinates.flat_map do |coordinates|
|
|
31
|
+
coordinates.segments
|
|
32
|
+
end
|
|
33
|
+
end.map do |segment|
|
|
34
|
+
Segment.new segment, self
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|