Module: NSWTopo

Extended by:
NSWTopo, Log
Included in:
NSWTopo
Defined in:
lib/nswtopo.rb,
lib/nswtopo/os.rb,
lib/nswtopo/log.rb,
lib/nswtopo/map.rb,
lib/nswtopo/zip.rb,
lib/nswtopo/font.rb,
lib/nswtopo/layer.rb,
lib/nswtopo/config.rb,
lib/nswtopo/dither.rb,
lib/nswtopo/safely.rb,
lib/nswtopo/archive.rb,
lib/nswtopo/formats.rb,
lib/nswtopo/gis/dem.rb,
lib/nswtopo/gis/gps.rb,
lib/nswtopo/version.rb,
lib/nswtopo/layer/grid.rb,
lib/nswtopo/layer/spot.rb,
lib/nswtopo/font/chrome.rb,
lib/nswtopo/formats/kmz.rb,
lib/nswtopo/formats/pdf.rb,
lib/nswtopo/formats/svg.rb,
lib/nswtopo/formats/zip.rb,
lib/nswtopo/gis/geojson.rb,
lib/nswtopo/gis/gps/gpx.rb,
lib/nswtopo/gis/gps/kml.rb,
lib/nswtopo/font/generic.rb,
lib/nswtopo/formats/svgz.rb,
lib/nswtopo/gis/esri_hdr.rb,
lib/nswtopo/layer/import.rb,
lib/nswtopo/layer/labels.rb,
lib/nswtopo/layer/raster.rb,
lib/nswtopo/layer/relief.rb,
lib/nswtopo/layer/vector.rb,
lib/nswtopo/gis/gdal_glob.rb,
lib/nswtopo/gis/shapefile.rb,
lib/nswtopo/layer/contour.rb,
lib/nswtopo/layer/control.rb,
lib/nswtopo/layer/feature.rb,
lib/nswtopo/layer/overlay.rb,
lib/nswtopo/gis/projection.rb,
lib/nswtopo/gis/world_file.rb,
lib/nswtopo/formats/mbtiles.rb,
lib/nswtopo/layer/vegetation.rb,
lib/nswtopo/gis/arcgis_server.rb,
lib/nswtopo/gis/geojson/point.rb,
lib/nswtopo/layer/declination.rb,
lib/nswtopo/layer/labels/fence.rb,
lib/nswtopo/gis/geojson/polygon.rb,
lib/nswtopo/layer/arcgis_raster.rb,
lib/nswtopo/gis/geojson/collection.rb,
lib/nswtopo/gis/geojson/line_string.rb,
lib/nswtopo/gis/geojson/multi_point.rb,
lib/nswtopo/gis/geojson/multi_polygon.rb,
lib/nswtopo/gis/arcgis_server/connection.rb,
lib/nswtopo/gis/geojson/multi_line_string.rb

Defined Under Namespace

Modules: ArcGISRaster, ArcGISServer, Config, Contour, Control, DEM, Declination, Dither, Feature, Font, Formats, GDALGlob, GeoJSON, Grid, Import, Labels, Log, OS, Overlay, Raster, Relief, Safely, Shapefile, Spot, Vector, Vegetation, WorldFile, Zip Classes: Archive, ESRIHdr, GPS, Layer, Map, Projection

Constant Summary collapse

PartialFailureError =
Class.new RuntimeError
VERSION =
"2.0.0"
MIN_VERSION =
"2.0.0"

Constants included from Log

Log::FAILURE, Log::NEUTRAL, Log::SUCCESS, Log::UPDATE

Instance Method Summary collapse

Methods included from Log

log_abort, log_neutral, log_success, log_update, log_warn

Instance Method Details

#add(archive, *layers, options) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/nswtopo.rb', line 59

def add(archive, *layers, options)
  create_options = {
    after: Layer.sanitise(options.delete :after),
    before: Layer.sanitise(options.delete :before),
    replace: Layer.sanitise(options.delete :replace),
    overwrite: options.delete(:overwrite)
  }
  map = Map.load archive

  Enumerator.new do |yielder|
    while layers.any?
      layer, basedir = layers.shift
      path = Pathname(layer).expand_path(*basedir)
      case layer
      when /^controls\.(gpx|kml)$/i
        yielder << [path.basename(path.extname).to_s, "type" => "Control", "path" => path]
      when /\.(gpx|kml)$/i
        yielder << [path.basename(path.extname).to_s, "type" => "Overlay", "path" => path]
      when /\.(tiff?|png|jpg)$/i
        yielder << [path.basename(path.extname).to_s, "type" => "Import", "path" => path]
      when "contours"
        yielder << [layer, "type" => "Contour"]
      when "spot-heights"
        yielder << [layer, "type" => "Spot"]
      when "relief"
        yielder << [layer, "type" => "Relief"]
      when "grid"
        yielder << [layer, "type" => "Grid"]
      when "declination"
        yielder << [layer, "type" => "Declination"]
      when "controls"
        yielder << [layer, "type" => "Control"]
      when /\.yml$/i
        basedir ||= path.parent
        raise "couldn't find '#{layer}'" unless path.file?
        case contents = YAML.load(path.read)
        when Array
          contents.reverse.map do |item|
            Pathname(item.to_s)
          end.each do |relative_path|
            raise "#{relative_path} is not a relative path" unless relative_path.relative?
            layers.prepend [Pathname(relative_path).expand_path(path.parent).relative_path_from(basedir).to_s, basedir]
          end
        when Hash
          name = path.sub_ext("").relative_path_from(basedir).descend.map(&:basename).join(?.)
          yielder << [name, contents.merge("source" => path)]
        else
          raise "couldn't parse #{path}"
        end
      else
        path = Pathname("#{layer}.yml")
        raise "#{layer} is not a relative path" unless path.relative?
        basedir ||= layer_dirs.find do |root|
          path.expand_path(root).file?
        end
        layers.prepend [path.to_s, basedir]
      end
    end
  rescue YAML::Exception
    raise "couldn't parse #{path}"
  end.map do |name, params|
    params.merge! options.transform_keys(&:to_s)
    params.merge! Config[name] if Config[name]
    Layer.new(name, map, params)
  end.tap do |layers|
    raise OptionParser::MissingArgument, "no layers specified" unless layers.any?
    unless layers.one?
      raise OptionParser::InvalidArgument, "can't specify resolution when adding multiple layers" if options[:resolution]
      raise OptionParser::InvalidArgument, "can't specify data path when adding multiple layers" if options[:path]
    end
    map.add *layers, create_options
  end
end

#config(layer = nil, **options) ⇒ Object



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/nswtopo.rb', line 207

def config(layer = nil, **options)
  chrome, firefox, path, resolution, layer_dir, labelling, delete = options.values_at :chrome, :firefox, :path, :resolution, :"layer-dir", :labelling, :delete
  raise "not a directory: %s" % layer_dir if layer_dir && !layer_dir.directory?
  raise "chrome path is not an executable" if chrome && !chrome.executable?
  raise "firefox path is not an executable" if firefox && !firefox.executable?
  Config.store("chrome", chrome.to_s) if chrome
  Config.store("firefox", firefox.to_s) if firefox
  Config.store("labelling", labelling) unless labelling.nil?
  Config.store("layer-dir", layer_dir.to_s) if layer_dir

  layer = Layer.sanitise layer
  case
  when !layer
    raise OptionParser::InvalidArgument, "no layer name specified for path" if path
    raise OptionParser::InvalidArgument, "no layer name specified for resolution" if resolution
  when path || resolution
    Config.store(layer, "path", path.to_s) if path
    Config.store(layer, "resolution", resolution) if resolution
  end
  Config.delete(*layer, delete) if delete

  if options.empty?
    puts Config.to_str.each_line.drop(1)
    log_neutral "no configuration yet" if Config.empty?
  else
    Config.save
    log_success "configuration updated"
  end
end

#contours(archive, dem_path, options) ⇒ Object



133
134
135
# File 'lib/nswtopo.rb', line 133

def contours(archive, dem_path, options)
  add archive, "contours", options.merge(path: Pathname(dem_path))
end

#controls(archive, gps_path, options) ⇒ Object



153
154
155
# File 'lib/nswtopo.rb', line 153

def controls(archive, gps_path, options)
  add archive, "controls", options.merge(path: Pathname(gps_path))
end

#declination(archive, options) ⇒ Object



149
150
151
# File 'lib/nswtopo.rb', line 149

def declination(archive, options)
  add archive, "declination", options
end

#delete(archive, *names, options) ⇒ Object



162
163
164
165
166
167
168
169
170
171
# File 'lib/nswtopo.rb', line 162

def delete(archive, *names, options)
  map = Map.load archive
  names.map do |name|
    Layer.sanitise name
  end.uniq.map do |name|
    name[?*] ? %r[^#{name.gsub(?., '\.').gsub(?*, '.*')}$] : name
  end.tap do |names|
    map.delete *names
  end
end

#grid(archive, options) ⇒ Object



145
146
147
# File 'lib/nswtopo.rb', line 145

def grid(archive, options)
  add archive, "grid", options
end

#info(archive, options) ⇒ Object



55
56
57
# File 'lib/nswtopo.rb', line 55

def info(archive, options)
  puts Map.load(archive).info(options)
end

#init(archive, options) ⇒ Object



47
48
49
# File 'lib/nswtopo.rb', line 47

def init(archive, options)
  puts Map.init(archive, options)
end

#layer_dirsObject



51
52
53
# File 'lib/nswtopo.rb', line 51

def layer_dirs
  @layer_dirs ||= Array(Config["layer-dir"]).map(&Pathname.method(:new)) << Pathname.pwd
end

#layers(state: nil, indent: "") ⇒ Object



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/nswtopo.rb', line 189

def layers(state: nil, indent: "")
  layer_dirs.grep_v(Pathname.pwd).flat_map do |directory|
    Array(state).inject(directory, &:/).glob("*")
  end.sort.each do |path|
    case
    when path.directory?
      next if path.glob("**/*.yml").none?
      puts [indent, path.basename.sub_ext("")].join
      layers state: [*state, path.basename], indent: "  " + indent
    when path.sub_ext("").directory?
    when path.extname == ".yml"
      puts [indent, path.basename.sub_ext("")].join
    end
  end.tap do |paths|
    log_warn "no layers installed" if paths.none?
  end
end

#overlay(archive, gps_path, options) ⇒ Object

Raises:

  • (OptionParser::InvalidArgument)


157
158
159
160
# File 'lib/nswtopo.rb', line 157

def overlay(archive, gps_path, options)
  raise OptionParser::InvalidArgument, gps_path unless gps_path =~ /\.(gpx|kml)$/i
  add archive, gps_path, options.merge(path: Pathname(gps_path))
end

#relief(archive, dem_path, options) ⇒ Object



141
142
143
# File 'lib/nswtopo.rb', line 141

def relief(archive, dem_path, options)
  add archive, "relief", options.merge(path: Pathname(dem_path))
end

#render(archive, *formats, options) ⇒ Object



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/nswtopo.rb', line 173

def render(archive, *formats, options)
  overwrite = options.delete :overwrite
  formats << "svg" if formats.empty?
  formats.map do |format|
    Pathname(Formats === format ? "#{archive.basename}.#{format}" : format)
  end.uniq.each do |path|
    format = path.extname.delete_prefix(?.)
    raise "unrecognised format: #{path}" if format.empty?
    raise "unrecognised format: #{format}" unless Formats === format
    raise "file already exists: #{path}" if path.exist? && !overwrite
    raise "non-existent directory: #{path.parent}" unless path.parent.directory?
  end.tap do |paths|
    Map.load(archive).render *paths, options
  end
end

#spot_heights(archive, dem_path, options) ⇒ Object



137
138
139
# File 'lib/nswtopo.rb', line 137

def spot_heights(archive, dem_path, options)
  add archive, "spot-heights", options.merge(path: Pathname(dem_path))
end

#with_browserObject



237
238
239
240
241
242
243
# File 'lib/nswtopo.rb', line 237

def with_browser
  browser_name, browser_path = Config.slice("chrome", "firefox").first
  raise "please configure a path for google chrome" unless browser_name
  yield browser_name, Pathname.new(browser_path)
rescue Errno::ENOENT
  raise "invalid %s path: %s" % [browser_name, browser_path]
end