nswtopo 3.1 → 3.1.2
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/bin/nswtopo +3 -2
- data/lib/nswtopo/commands/scrape.rb +1 -1
- data/lib/nswtopo/formats/svg.rb +1 -9
- data/lib/nswtopo/formats.rb +2 -2
- data/lib/nswtopo/gis/dem.rb +2 -2
- data/lib/nswtopo/gis/geojson/collection.rb +4 -4
- data/lib/nswtopo/layer/arcgis_raster.rb +3 -5
- data/lib/nswtopo/layer/contour.rb +2 -2
- data/lib/nswtopo/layer/raster.rb +3 -3
- data/lib/nswtopo/layer/relief.rb +2 -2
- data/lib/nswtopo/layer/vegetation.rb +1 -1
- data/lib/nswtopo/map.rb +18 -4
- data/lib/nswtopo/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8f6740cf4e3532418e42aff410453d38a26cbdd2cb087a7ee7d753ca6d252d13
|
|
4
|
+
data.tar.gz: 6968cbfab11ce7d74f4d75ad53a562d89730a8551ae6baea6c8ea6360a010dc2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f250d4a093f83d06c9b606c012a05e35739e6fca2805a0abe95c2129a7bffd0edb530c60d3262ca5716e32bb7d2d7a69e6e4e27756e2f81ce49ba0f9ca34baff
|
|
7
|
+
data.tar.gz: 20b7ac67eee937b5c273c17029ce441e8912dddd2ad75f3ea58ead8ed54b132f2466a15ac0e2f68d3e38a26de139cd5cd1106478db2d0735b9d852b5c3404fc5
|
data/bin/nswtopo
CHANGED
|
@@ -41,8 +41,8 @@ begin
|
|
|
41
41
|
log_abort "ruby 3.1.4 or greater required"
|
|
42
42
|
when !Zlib.const_defined?(:GzipFile)
|
|
43
43
|
log_abort "ruby with GZIP_SUPPORT required"
|
|
44
|
-
when (GDAL_VERSION.split(/\D+/).take(3).map(&:to_i) <=> [3,
|
|
45
|
-
log_abort "GDAL 3.
|
|
44
|
+
when (GDAL_VERSION.split(/\D+/).take(3).map(&:to_i) <=> [3,8]) < 0
|
|
45
|
+
log_abort "GDAL 3.8 or greater required"
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
digits = '\d+(?:_\d+)*'
|
|
@@ -220,6 +220,7 @@ begin
|
|
|
220
220
|
parser.on "-b", "--bounds <bounds.kml>", Pathname, "bounds for map as KML or GPX file"
|
|
221
221
|
parser.on "-c", "--coords <x1,y1,...>", CoordList, "bounds for map as one or more WGS84",
|
|
222
222
|
"longitude/latitude pairs"
|
|
223
|
+
parser.on "-n", "--neatline <neatline.kml>", Pathname, "neatline for map as KML file"
|
|
223
224
|
parser.on "-d", "--dimensions <width,height>", Dimensions, "map dimensions in mm"
|
|
224
225
|
parser.on "-r", "--rotation <rotation>", Rotation, "map rotation angle in clockwise",
|
|
225
226
|
"degrees, 'auto' or 'magnetic'"
|
|
@@ -29,7 +29,7 @@ module NSWTopo
|
|
|
29
29
|
queue = Queue.new
|
|
30
30
|
thread = Thread.new do
|
|
31
31
|
while page = queue.pop
|
|
32
|
-
*, status = Open3.capture3 *%W[ogr2ogr #{path} /vsistdin
|
|
32
|
+
*, status = Open3.capture3 *%W[ogr2ogr #{path} /vsistdin?buffer_limit=-1], *flags, *format_flags, stdin_data: page.to_json
|
|
33
33
|
format_flags = %w[-update -append]
|
|
34
34
|
queue.close unless status.success?
|
|
35
35
|
end
|
data/lib/nswtopo/formats/svg.rb
CHANGED
|
@@ -17,14 +17,6 @@ module NSWTopo
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
module Formats
|
|
20
|
-
def neatline_path_data
|
|
21
|
-
@neatline.coordinates.map do |ring|
|
|
22
|
-
ring.map do |point|
|
|
23
|
-
point.join(" ")
|
|
24
|
-
end.join(" L ").prepend("M ").concat(" Z")
|
|
25
|
-
end.join(" ")
|
|
26
|
-
end
|
|
27
|
-
|
|
28
20
|
def render_svg(svg_path, background:, **options)
|
|
29
21
|
if uptodate?("map.svg", "map.yml")
|
|
30
22
|
log_update "nswtopo: reading existing map SVG"
|
|
@@ -63,7 +55,7 @@ module NSWTopo
|
|
|
63
55
|
# add defs for map filters and masks
|
|
64
56
|
defs = svg.add_element("defs", "id" => "map.defs")
|
|
65
57
|
defs.add_element("rect", "id" => "map.rect", "width" => width, "height" => height)
|
|
66
|
-
defs.add_element("path", "id" => "map.neatline", "d" =>
|
|
58
|
+
defs.add_element("path", "id" => "map.neatline", "d" => @neatline.svg_path_data)
|
|
67
59
|
defs.add_element("clipPath", "id" => "map.clip").add_element("use", "href" => "#map.neatline")
|
|
68
60
|
|
|
69
61
|
# add a filter converting alpha channel to cutout mask
|
data/lib/nswtopo/formats.rb
CHANGED
|
@@ -78,8 +78,8 @@ module NSWTopo
|
|
|
78
78
|
raster_info = "%i×%i (%.1fMpx) map raster at %s" % [*raster_size, megapixels, ppi_info]
|
|
79
79
|
log_update "chrome: creating #{raster_info}"
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
(0...
|
|
81
|
+
raster_size.map do |px|
|
|
82
|
+
(0...px).step(TILE).map do |px|
|
|
83
83
|
[px, px * mm_per_px]
|
|
84
84
|
end
|
|
85
85
|
end.inject(&:product).map(&:transpose).map do |raster_offset, viewport_offset|
|
data/lib/nswtopo/gis/dem.rb
CHANGED
|
@@ -30,7 +30,7 @@ module NSWTopo
|
|
|
30
30
|
|
|
31
31
|
indexed_dem_path = temp_dir / "dem.#{index}.tif"
|
|
32
32
|
OS.gdalbuildvrt "-overwrite", "-allow_projection_difference", "-a_srs", projection, "-input_file_list", txt_path, vrt_path
|
|
33
|
-
OS.gdalwarp "-t_srs", @map.projection, "-tr", @mm_per_px, @mm_per_px, "-r", "bilinear", "-cutline", "GeoJSON:/vsistdin
|
|
33
|
+
OS.gdalwarp "-t_srs", @map.projection, "-tr", @mm_per_px, @mm_per_px, "-r", "bilinear", "-cutline", "GeoJSON:/vsistdin?buffer_limit=-1", "-crop_to_cutline", vrt_path, indexed_dem_path do |stdin|
|
|
34
34
|
stdin.puts cutline.to_json
|
|
35
35
|
end
|
|
36
36
|
indexed_dem_path
|
|
@@ -64,7 +64,7 @@ module NSWTopo
|
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
log_update "%s: smoothing DEM raster" % @name
|
|
67
|
-
OS.gdal_translate "/vsistdin
|
|
67
|
+
OS.gdal_translate "/vsistdin?buffer_limit=-1", blur_path do |stdin|
|
|
68
68
|
stdin.write xml
|
|
69
69
|
end
|
|
70
70
|
end
|
|
@@ -47,7 +47,7 @@ module NSWTopo
|
|
|
47
47
|
|
|
48
48
|
def reproject_to(projection)
|
|
49
49
|
return self if self.projection == projection
|
|
50
|
-
json = OS.ogr2ogr "-t_srs", projection, "-f", "GeoJSON", "-lco", "RFC7946=NO", "/vsistdout/", "GeoJSON:/vsistdin
|
|
50
|
+
json = OS.ogr2ogr "-t_srs", projection, "-f", "GeoJSON", "-lco", "RFC7946=NO", "/vsistdout/", "GeoJSON:/vsistdin?buffer_limit=-1" do |stdin|
|
|
51
51
|
stdin.puts to_json
|
|
52
52
|
end
|
|
53
53
|
Collection.load json, projection: projection
|
|
@@ -67,7 +67,7 @@ module NSWTopo
|
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
extend Forwardable
|
|
70
|
-
delegate %i[coordinates properties wkt area] => :first
|
|
70
|
+
delegate %i[coordinates properties wkt area svg_path_data] => :first
|
|
71
71
|
delegate %i[length] => :@features
|
|
72
72
|
|
|
73
73
|
def to_json(**extras)
|
|
@@ -83,7 +83,7 @@ module NSWTopo
|
|
|
83
83
|
end
|
|
84
84
|
|
|
85
85
|
def with_sql(sql, name: @name)
|
|
86
|
-
json = OS.ogr2ogr *%w[-f GeoJSON -lco RFC7946=NO /vsistdout/ GeoJSON:/vsistdin
|
|
86
|
+
json = OS.ogr2ogr *%w[-f GeoJSON -lco RFC7946=NO /vsistdout/ GeoJSON:/vsistdin?buffer_limit=-1 -dialect SQLite -sql], sql do |stdin|
|
|
87
87
|
stdin.puts to_json
|
|
88
88
|
end
|
|
89
89
|
Collection.load(json, projection: @projection).with_name(name)
|
|
@@ -123,7 +123,7 @@ module NSWTopo
|
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
def clip(polygon)
|
|
126
|
-
OS.ogr2ogr "-f", "GeoJSON", "-lco", "RFC7946=NO", "-clipsrc", polygon.wkt, "/vsistdout/", "GeoJSON:/vsistdin
|
|
126
|
+
OS.ogr2ogr "-f", "GeoJSON", "-lco", "RFC7946=NO", "-clipsrc", polygon.wkt, "/vsistdout/", "GeoJSON:/vsistdin?buffer_limit=-1" do |stdin|
|
|
127
127
|
stdin.puts to_json
|
|
128
128
|
end.then do |json|
|
|
129
129
|
Collection.load json, projection: @projection
|
|
@@ -26,17 +26,15 @@ module NSWTopo
|
|
|
26
26
|
end || lods.last
|
|
27
27
|
tile_level, tile_resolution = lod.values_at "level", "resolution"
|
|
28
28
|
|
|
29
|
-
target_bbox.
|
|
30
|
-
|
|
31
|
-
end.transpose.map(&:minmax).zip(tile_sizes).map do |bound, tile_size|
|
|
32
|
-
bound / tile_resolution / tile_size
|
|
29
|
+
target_bbox.bounds.zip(origin, tile_sizes).map do |(min, max), origin, tile_size|
|
|
30
|
+
[(min - origin) / tile_resolution / tile_size, (max - origin) / tile_resolution / tile_size]
|
|
33
31
|
end.map do |min, max|
|
|
34
32
|
(min.floor..max.ceil).each_cons(2).to_a
|
|
35
33
|
end.inject(&:product).inject(GeoJSON::Collection.new(projection: service.projection)) do |tiles, (cols, rows)|
|
|
36
34
|
[cols, rows].zip(tile_sizes).map do |indices, tile_size|
|
|
37
35
|
indices.map { |index| index * tile_size * tile_resolution }
|
|
38
36
|
end.transpose.map do |corner|
|
|
39
|
-
corner
|
|
37
|
+
corner.zip(origin).map(&:sum)
|
|
40
38
|
end.transpose.then do |bounds|
|
|
41
39
|
ring = bounds.inject(&:product).values_at(0,2,3,1,0)
|
|
42
40
|
ullr = bounds.inject(&:product).values_at(1,2).flatten
|
|
@@ -42,7 +42,7 @@ module NSWTopo
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def check_geos!
|
|
45
|
-
json = OS.ogr2ogr "-dialect", "SQLite", "-sql", "SELECT geos_version() AS version", "-f", "GeoJSON", "-lco", "RFC7946=NO", "/vsistdout/", "
|
|
45
|
+
json = OS.ogr2ogr "-dialect", "SQLite", "-sql", "SELECT geos_version() AS version", "-f", "GeoJSON", "-lco", "RFC7946=NO", "/vsistdout/", "GeoJSON:/vsistdin?buffer_limit=-1" do |stdin|
|
|
46
46
|
stdin.write GeoJSON::Collection.new.to_json
|
|
47
47
|
end
|
|
48
48
|
raise unless version = JSON.parse(json).dig("features", 0, "properties", "version")
|
|
@@ -107,7 +107,7 @@ module NSWTopo
|
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
contours.each_slice(100).inject(nil) do |update, features|
|
|
110
|
-
OS.ogr2ogr "-a_srs", @map.projection, "-nln", "contour", *update, "-simplify", @simplify, *db_flags, db_path, "GeoJSON:/vsistdin
|
|
110
|
+
OS.ogr2ogr "-a_srs", @map.projection, "-nln", "contour", *update, "-simplify", @simplify, *db_flags, db_path, "GeoJSON:/vsistdin?buffer_limit=-1" do |stdin|
|
|
111
111
|
stdin.write contours.with_features(features).to_json
|
|
112
112
|
end
|
|
113
113
|
%w[-update -append]
|
data/lib/nswtopo/layer/raster.rb
CHANGED
|
@@ -3,7 +3,7 @@ module NSWTopo
|
|
|
3
3
|
using Helpers
|
|
4
4
|
def create
|
|
5
5
|
Dir.mktmppath do |temp_dir|
|
|
6
|
-
args = ["-t_srs", @map.projection, "-r", "bilinear", "-cutline", "GeoJSON:/vsistdin
|
|
6
|
+
args = ["-t_srs", @map.projection, "-r", "bilinear", "-cutline", "GeoJSON:/vsistdin?buffer_limit=-1", "-te", *@map.te, "-of", "GTiff", "-co", "TILED=YES"]
|
|
7
7
|
args += ["-tr", @mm_per_px, @mm_per_px] if Numeric === @mm_per_px
|
|
8
8
|
OS.gdalwarp *args, get_raster(temp_dir), "/vsistdout/" do |stdin|
|
|
9
9
|
stdin.puts @map.cutline.to_json
|
|
@@ -31,7 +31,7 @@ module NSWTopo
|
|
|
31
31
|
end.then do |(width, height), (_, mm_per_px, *)|
|
|
32
32
|
image.add_attributes "width" => width, "height" => height, "transform" => "scale(#{mm_per_px})"
|
|
33
33
|
end
|
|
34
|
-
OS.gdal_translate "-of", "PNG", "-co", "ZLEVEL=9", "/vsistdin
|
|
34
|
+
OS.gdal_translate "-of", "PNG", "-co", "ZLEVEL=9", "/vsistdin?buffer_limit=-1", "/vsistdout/" do |stdin|
|
|
35
35
|
stdin.binmode.write tif
|
|
36
36
|
end.then do |png|
|
|
37
37
|
image.add_attributes "href" => "data:image/png;base64,#{Base64.encode64 png}", "image-rendering" => "optimizeQuality"
|
|
@@ -40,7 +40,7 @@ module NSWTopo
|
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def to_s
|
|
43
|
-
OS.gdalinfo "-json", "/vsistdin
|
|
43
|
+
OS.gdalinfo "-json", "/vsistdin?buffer_limit=-1" do |stdin|
|
|
44
44
|
stdin.binmode.write @map.read(filename)
|
|
45
45
|
end.then do |json|
|
|
46
46
|
JSON.parse(json).values_at "size", "geoTransform"
|
data/lib/nswtopo/layer/relief.rb
CHANGED
|
@@ -50,7 +50,7 @@ module NSWTopo
|
|
|
50
50
|
end.inject(&:merge)
|
|
51
51
|
|
|
52
52
|
log_update "%s: calculating DEM" % @name
|
|
53
|
-
OS.gdal_grid "-a", "linear:radius=0:nodata=-9999", "-zfield", "elevation", "-ot", "Float32", "-txe", *bounds[0], "-tye", *bounds[1], "-outsize", *outsize, "
|
|
53
|
+
OS.gdal_grid "-a", "linear:radius=0:nodata=-9999", "-zfield", "elevation", "-ot", "Float32", "-txe", *bounds[0], "-tye", *bounds[1], "-outsize", *outsize, "GeoJSON:/vsistdin?buffer_limit=-1", dem_path do |stdin|
|
|
54
54
|
stdin.puts collection.to_json
|
|
55
55
|
end
|
|
56
56
|
|
|
@@ -64,7 +64,7 @@ module NSWTopo
|
|
|
64
64
|
begin
|
|
65
65
|
log_update "%s: generating shaded relief" % @name
|
|
66
66
|
OS.gdaldem *%W[hillshade -q -compute_edges -s #{@map.scale / 1000.0} -z #{@factor} -az #{@azimuth} -#{@method}], dem_path, raw_path
|
|
67
|
-
OS.gdalwarp "-t_srs", @map.projection, "-cutline", "GeoJSON:/vsistdin
|
|
67
|
+
OS.gdalwarp "-t_srs", @map.projection, "-cutline", "GeoJSON:/vsistdin?buffer_limit=-1", "-crop_to_cutline", raw_path, tif_path do |stdin|
|
|
68
68
|
stdin.puts cutline.to_json
|
|
69
69
|
end
|
|
70
70
|
rescue OS::Error
|
|
@@ -64,7 +64,7 @@ module NSWTopo
|
|
|
64
64
|
tif_path = temp_dir / "source.tif"
|
|
65
65
|
vrt_path = temp_dir / "source.vrt"
|
|
66
66
|
|
|
67
|
-
args = ["-t_srs", @map.projection, "-r", "nearest", "-cutline", "GeoJSON:/vsistdin
|
|
67
|
+
args = ["-t_srs", @map.projection, "-r", "nearest", "-cutline", "GeoJSON:/vsistdin?buffer_limit=-1", "-crop_to_cutline"]
|
|
68
68
|
args += ["-tr", @mm_per_px, @mm_per_px] if @mm_per_px
|
|
69
69
|
OS.gdalwarp *args, *vrt_paths, tif_path do |stdin|
|
|
70
70
|
stdin.puts @map.cutline.to_json
|
data/lib/nswtopo/map.rb
CHANGED
|
@@ -16,12 +16,18 @@ module NSWTopo
|
|
|
16
16
|
extend Forwardable
|
|
17
17
|
delegate %i[write mtime read uptodate?] => :@archive
|
|
18
18
|
|
|
19
|
-
def self.init(archive, scale: 25000, rotation: 0.0, bounds: nil, coords: nil, dimensions: nil, margins: nil, **neatline_options)
|
|
19
|
+
def self.init(archive, scale: 25000, rotation: 0.0, bounds: nil, coords: nil, neatline: nil, dimensions: nil, margins: nil, **neatline_options)
|
|
20
20
|
points = case
|
|
21
21
|
when dimensions && margins
|
|
22
22
|
raise "can't specify both margins and map dimensions"
|
|
23
|
+
when dimensions && neatline
|
|
24
|
+
raise "can't specify both neatline and map dimensions"
|
|
25
|
+
when bounds && neatline
|
|
26
|
+
raise "can't specify both bounds and neatline"
|
|
27
|
+
when coords && neatline
|
|
28
|
+
raise "can't specify both neatline and map coordinates"
|
|
23
29
|
when coords && bounds
|
|
24
|
-
raise "can't specify both bounds
|
|
30
|
+
raise "can't specify both bounds and map coordinates"
|
|
25
31
|
when coords
|
|
26
32
|
GeoJSON.multipoint(coords)
|
|
27
33
|
when bounds
|
|
@@ -29,6 +35,10 @@ module NSWTopo
|
|
|
29
35
|
margins ||= [15, 15] unless dimensions || gps.polygons.any?
|
|
30
36
|
raise "no features found in %s" % bounds if gps.none?
|
|
31
37
|
end
|
|
38
|
+
when neatline
|
|
39
|
+
neatline = GPS.load(neatline)
|
|
40
|
+
raise "neatline must be a single polygon" unless neatline.polygon?
|
|
41
|
+
neatline
|
|
32
42
|
else
|
|
33
43
|
raise "no bounds file or map coordinates specified"
|
|
34
44
|
end.dissolve_points
|
|
@@ -73,8 +83,12 @@ module NSWTopo
|
|
|
73
83
|
raise "not enough information to calculate map size – check bounds file, or specify map dimensions or margins"
|
|
74
84
|
end
|
|
75
85
|
|
|
76
|
-
|
|
77
|
-
|
|
86
|
+
if neatline
|
|
87
|
+
neatline = neatline.reproject_to projection
|
|
88
|
+
else
|
|
89
|
+
ring = [0, 0].zip(dimensions).inject(&:product).values_at(0,2,3,1,0)
|
|
90
|
+
neatline = GeoJSON.polygon [ring], projection: projection, name: "neatline"
|
|
91
|
+
end
|
|
78
92
|
|
|
79
93
|
neatline_options.each do |key, value|
|
|
80
94
|
case key
|
data/lib/nswtopo/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nswtopo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Matthew Hollingworth
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-
|
|
11
|
+
date: 2023-11-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description:
|
|
14
14
|
email:
|
|
@@ -150,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
150
150
|
- !ruby/object:Gem::Version
|
|
151
151
|
version: '0'
|
|
152
152
|
requirements:
|
|
153
|
-
- GDAL >= v3.
|
|
153
|
+
- GDAL >= v3.8
|
|
154
154
|
- Google Chrome >= v112
|
|
155
155
|
rubygems_version: 3.3.26
|
|
156
156
|
signing_key:
|