Module: NSWTopo::ArcGISRaster
- Includes:
- Log, Raster, RasterRender
- Defined in:
- lib/nswtopo/layer/arcgis_raster.rb
Constant Summary collapse
- CREATE =
%w[url]
Constants included from Log
Log::FAILURE, Log::NEUTRAL, Log::SUCCESS, Log::UPDATE
Instance Method Summary collapse
Methods included from Raster
#create, #empty?, #filename, #image_element, #to_s
Methods included from RasterRender
Methods included from Log
#log_abort, #log_neutral, #log_success, #log_update, #log_warn
Instance Method Details
#get_raster(temp_dir) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/nswtopo/layer/arcgis_raster.rb', line 6 def get_raster(temp_dir) raise "no resolution specified for #{@name}" unless Numeric === @mm_per_px txt_path = temp_dir / "mosaic.txt" vrt_path = temp_dir / "mosaic.vrt" service = ArcGIS::Service.new @url local_bbox = @map.cutline.bbox target_bbox = local_bbox.reproject_to service.projection target_resolution = @mm_per_px * Math::sqrt(target_bbox.first.area / local_bbox.first.area) raise "not a tiled map or image server: #{@url}" unless tile_info = service["tileInfo"] lods = tile_info["lods"] origin = tile_info["origin"].values_at "x", "y" tile_sizes = tile_info.values_at "cols", "rows" lods.sort_by! do |lod| -lod["resolution"] end lod = lods.find do |lod| lod["resolution"] < target_resolution end || lods.last tile_level, tile_resolution = lod.values_at "level", "resolution" target_bbox.coordinates.first.map do |corner| corner.minus(origin) end.transpose.map(&:minmax).zip(tile_sizes).map do |bound, tile_size| bound / tile_resolution / tile_size end.map do |min, max| (min.floor..max.ceil).each_cons(2).to_a end.inject(&:product).inject(GeoJSON::Collection.new(projection: service.projection)) do |tiles, (cols, rows)| [cols, rows].zip(tile_sizes).map do |indices, tile_size| indices.times(tile_size * tile_resolution) end.transpose.map do |corner| corner.plus(origin) end.transpose.then do |bounds| ring = bounds.inject(&:product).values_at(0,2,3,1,0) ullr = bounds.inject(&:product).values_at(1,2).flatten row, col = rows[1].abs, cols[0] tiles.add_polygon [ring], ullr: ullr, row: row, col: col end end.clip(target_bbox.first).then do |tiles| tiles.map.with_index do |feature, index| row, col, ullr = feature.values_at("row", "col", "ullr") rel_path = "tile/#{tile_level}/#{row}/#{col}" jpg_path = temp_dir / "#{row}.#{col}" # could be png tif_path = temp_dir / "#{row}.#{col}.tif" gdal_args = ["-a_srs", service.projection, "-a_ullr", *ullr, "-of", "GTiff", jpg_path, tif_path] log_update "%s: retrieving tile %i of %i" % [@name, index + 1, tiles.length] service.get(rel_path, blankTile: true) do |response| jpg_path.binwrite response.body end OS.gdal_translate *gdal_args tif_path end end.tap do |tif_paths| log_update "%s: mosaicing %s tiles" % [@name, tif_paths.length] if tif_paths.length > 1 txt_path.write tif_paths.join(?\n) end OS.gdalbuildvrt "-input_file_list", txt_path, vrt_path return vrt_path end |