lib/nswtopo/layer/spot.rb in nswtopo-3.0.1 vs lib/nswtopo/layer/spot.rb in nswtopo-3.1
- old
+ new
@@ -1,9 +1,11 @@
module NSWTopo
module Spot
- include Vector, DEM, Log
- CREATE = %w[spacing smooth prefer extent]
+ using Helpers
+ include VectorRender, DEM, Log
+
+ CREATE = %w[spacing smooth prefer extent epsg]
DEFAULTS = YAML.load <<~YAML
spacing: 15
smooth: 0.2
extent: 4
symbol:
@@ -37,11 +39,11 @@
line.chomp.split(?\s).map(&:to_f)
end
end
module Candidate
- attr_accessor :elevation, :knoll
+ attr_accessor :elevation, :knoll, :conflicts
module PreferKnolls
def ordinal; [conflicts.size, -elevation] end
end
@@ -51,21 +53,13 @@
module PreferNeither
def ordinal; conflicts.size end
end
- def conflicts
- @conflicts ||= Set[]
- end
-
def <=>(other)
self.ordinal <=> other.ordinal
end
-
- def bounds(buffer: 0)
- coordinates.map { |coordinate| [coordinate - buffer, coordinate + buffer] }
- end
end
def ordering
@ordering ||= case @prefer
when "knolls" then Candidate::PreferKnolls
@@ -88,11 +82,11 @@
aspect.nrows.times do |row|
log_update "%s: finding flat areas: %.1f%%" % [@name, 100.0 * (row + 1) / aspect.nrows]
aspect.ncols.times do |col|
offsets.map!(&:next)
next if row < 1 || col < 1 || row >= aspect.nrows - 1 || col >= aspect.ncols - 1
- next if block&.call col, row
+ next if block_given? && block.call(col, row)
ccw, cw = offsets.each_cons(2).inject([true, true]) do |(ccw, cw), (o1, o2)|
break unless ccw || cw
a1, a2 = aspect.values.values_at o1, o2
break unless a1 && a2
(a2 - a1) % 360 < 180 ? [ccw, false] : [false, cw]
@@ -122,19 +116,19 @@
mask = pixels_knolls(dem_lr_path).map(&:first).to_set
pixels, knolls = pixels_knolls(dem_hr_path) do |col, row|
!mask.include? [(col * @mm_per_px / low_resolution).floor, (row * @mm_per_px / low_resolution).floor]
end.entries.transpose
+ raise "no elevation data found in map area" unless pixels
locations = raster_locations dem_hr_path, pixels
elevations = raster_values dem_hr_path, pixels
locations.zip(elevations, knolls).map do |coordinates, elevation, knoll|
- GeoJSON::Point.new(coordinates).tap do |feature|
+ GeoJSON::Point[coordinates, "label" => elevation.round] do |feature|
feature.extend Candidate, ordering
- feature.knoll, feature.elevation = knoll, elevation
- feature["label"] = elevation.round
+ feature.knoll, feature.elevation, feature.conflicts = knoll, elevation, Set[]
end
end
end
end
@@ -142,12 +136,12 @@
selected, remaining = [], AVLTree.new
spatial_index = RTree.load(candidates, &:bounds)
candidates.each.with_index do |candidate, index|
log_update "%s: examining candidates: %.1f%%" % [@name, 100.0 * index / candidates.length]
- spatial_index.search(candidate.bounds(buffer: @spacing)).each do |other|
+ spatial_index.search(candidate.bounds, @spacing).each do |other|
next if other == candidate
- next if [candidate, other].map(&:coordinates).distance > @spacing
+ next if (candidate.coordinates - other.coordinates).norm > @spacing
candidate.conflicts << other
end
end.each do |candidate|
remaining << candidate
end