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