nswtopo 3.1 → 3.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|