Skip to content

Commit a9991c6

Browse files
authored
Let gmtread be able to accept R in projected coordinates. (#1836)
... and optionally project the grid (works only for remote datasets).
1 parent 8c284a8 commit a9991c6

2 files changed

Lines changed: 46 additions & 3 deletions

File tree

src/gmtreadwrite.jl

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,19 @@ Specify data type (with *type*=true, e.g. `img=true`). Choose among:
5959
6060
Use ``layers=:all`` to read all levels of a 3D cube netCDF file.
6161
62+
- `R` | `region` | `limits`: A numeric vector (or a Tuple) or a string defining the region of interest.
63+
If numeric, it must have four elements: `[xmin, xmax, ymin, ymax]`.
64+
If string, it must be in the form `xmin/xmax/ymin/ymax`. Default is to read entire file extent.
65+
66+
When reading remote files via the '@' mechanism, the region can be given in projected coordinates,
67+
provided that the `proj` option is also given and describing system used in `R`.
68+
69+
- `J` | `proj` | `projection`: When `region` is given in projected coordinates, this option must be
70+
provided, otherwise it is ignored. The syntax is the same as in all modules that use the `proj` option.
71+
72+
- `convert`: In case that both the `region` and `proj` options are used, this option (any value will do)
73+
can be used to request that the grid be converted to the new projection defined by `proj`.
74+
6275
- $(_opt_R)
6376
- $(opt_V)
6477
- $(_opt_bi)
@@ -85,6 +98,7 @@ function gmtread(_fname::String; kwargs...)
8598
cmd, opt_bi = parse_bi(d, cmd)
8699
proggy = "read " # When reading an entire grid cube, this will change to 'grdinterpolate'
87100
doTimeCheck = true # By default check for time columns in text files
101+
opt_J = "" # Will hold a grdproject proj string if `proj` and `convert`options are used.
88102

89103
# Process these first so they may take precedence over defaults set below
90104
opt_T = add_opt(d, "", "Tg", [:grd :grid])
@@ -163,8 +177,7 @@ function gmtread(_fname::String; kwargs...)
163177
elseif ((fname[1] == '@' && any(contains.(fname, ["_relief", "_age", "_dist", "_faa", "_gebco", "_geoid", "_mag", "_mask", "_mdt", "_mss", "_synbath", "_wdmam"]))) || startswith(fname, "@srtm_"))
164178
opt_T = " -Tg"
165179
end
166-
# To shut up a f annoying GMT warning.
167-
#(opt_T == " -Tg") && startswith(fname, "@earth_") && !endswith(fname, "_g") && !endswith(fname, "_p") && (fname *= "_g")
180+
if (opt_T != "") cmd, opt_J = parse_R_projected(d, cmd, opt_R) end # See if we have a non-geographic region request
168181
end
169182

170183
(opt_T == "" && opt_bi != "") && (opt_T = " -Td") # If asked to read binary, must be a 'data' file.
@@ -210,7 +223,21 @@ function gmtread(_fname::String; kwargs...)
210223
if (isISF)
211224
o = gmtisf(fname; d...)
212225
else
213-
o = (proggy == "gdalread") ? gdalread(fname, gdopts) : gmt(proggy * fname * cmd)
226+
lay = "" # May need to temporarily change the layout
227+
if (opt_J !== "") # Means that we will ne to project after reading, so do it with TRB (or should it be BRB?)
228+
((ind = findfirst(" -&", cmd)) !== nothing) && (lay = cmd[ind[1]:ind[1]+5])
229+
(lay !== "") && (cmd = replace(cmd, lay => "")) # Remove layout from cmd
230+
end
231+
layout = (opt_J !== "") ? " -&TRB" : "" # If we are going to project, read in row major order
232+
o = (proggy == "gdalread") ? gdalread(fname, gdopts) : gmt(proggy * fname * cmd * layout)
233+
if (opt_J !== "") # Project the grid
234+
o = gmt("grdproject" * lay * opt_J, o)
235+
if contains(opt_J, "+proj") # Only projections given (or consructed to) in GMT syntax are not saved in grid's metadata
236+
o.proj4 = replace(opt_J[4:end], "+" => " +") # Set the proj4 string and reset the spaces
237+
elseif (isdigit(opt_J[4]) && isdigit(opt_J[8]))
238+
o.epsg = parse(Int, opt_J[4:8])
239+
end
240+
end
214241
end
215242
(isempty(o)) && (@warn("\tfile \"$fname\" is empty or has no data after the header.\n"); return GMTdataset())
216243
((prj = planets_prj4(fname)) != "") && (o.proj4 = prj) # Get cached (@moon_..., etc) planets proj4
@@ -296,6 +323,18 @@ function gmtread(_fname::String; kwargs...)
296323
return O
297324
end
298325

326+
# ---------------------------------------------------------------------------------
327+
function parse_R_projected(d, cmd, opt_R)
328+
# If opt_R is non geographic, convert to geographic via mapproject and return new cmd
329+
((opt_J = parse_J(d, "")[1]) === "") && return cmd, "" # Nothing to do
330+
opt_J = contains(opt_J, "+width") ? opt_J[1:end-10] : (isdigit(opt_J[4]) && isdigit(opt_J[end])) ? opt_J * " -F -C" : opt_J[1:3] * lowercase(opt_J[4]) * opt_J[5:end-3] * "1:1 -F -C" # Remove +width or size
331+
xmin, xmax, ymin, ymax = opt_R2num(opt_R)
332+
Rgeog = gmt("mapproject -I" * opt_J, [xmin ymin; xmax ymax])
333+
new_R = @sprintf(" -R%f/%f/%f/%f", Rgeog[1,1], Rgeog[2,1], Rgeog[1,2], Rgeog[2,2])
334+
out_J = (find_in_dict(d, [:convert])[1] !== nothing) ? opt_J : ""
335+
return (opt_R === "") ? new_R : replace(cmd, opt_R => new_R), out_J
336+
end
337+
299338
# ---------------------------------------------------------------------------------
300339
function planets_prj4(fname)
301340
# If fname refers to a (cached) planet other than Earth, return the proj4 string for it.

test/test_misc.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,4 +398,8 @@
398398
remotegrid("earth_relief", "5m") == "@earth_relief_05m"
399399
remotegrid("mag", "1d", reg="p") == "@earth_mag_01d_p"
400400

401+
println(" GMTREAD_CONVERT")
402+
gmtread("@earth_relief_05m", R=[400000, 500000, 4500000, 4540000], J="+proj=utm +zone=29");
403+
gmtread("@earth_relief_05m", R=[400000, 500000, 4500000, 4540000], J="+proj=utm +zone=29", convert=true, layout="TRB");
404+
gmtread("@earth_relief_05m", R=[400000, 500000, 4500000, 4540000], J=32629, convert=true);
401405
end

0 commit comments

Comments
 (0)