diff --git a/src/common_options.jl b/src/common_options.jl index 7973ab5e5..a092a41be 100644 --- a/src/common_options.jl +++ b/src/common_options.jl @@ -3323,13 +3323,12 @@ end # --------------------------------------------------------------------------------------------------- vector_attrib(d::Dict, lixo) = vector_attrib(d) # When comming from add_opt() -vector_attrib(t::NamedTuple) = vector_attrib(Dict(pairs(t))) +vector_attrib(t::NamedTuple) = vector_attrib(Dict{Symbol,Any}(pairs(t))) function vector_attrib(; kwargs...)::String d = KW(kwargs) vector_attrib(d::Dict) end -function vector_attrib(d::Dict)::String - #d = KW(kwargs) +function vector_attrib(d::Dict{Symbol,Any})::String cmd::String = add_opt(d, "", "", [:len :length]) (haskey(d, :angle)) && (cmd = string(cmd, "+a", d[:angle])) if (haskey(d, :middle)) @@ -3434,7 +3433,7 @@ function vector4_attrib(; kwargs...)::String end # ----------------------------------- -function helper_vec_loc(d::Dict, symb, cmd::String)::String +function helper_vec_loc(d::Dict{Symbol,Any}, symb::Symbol, cmd::String)::String # Helper function for the 'begin', 'middle', 'end' vector attrib function (isa(d[symb], Bool) && d[symb]) && return cmd # We don't want a 'true' becoming a "i" t::String = string(d[symb]) diff --git a/src/finish_PS_nested.jl b/src/finish_PS_nested.jl index 247a201bd..069146257 100644 --- a/src/finish_PS_nested.jl +++ b/src/finish_PS_nested.jl @@ -106,9 +106,9 @@ function add_opt_module(d::Dict)::Vector{String} end # --------------------------------------------------------------------------------------------------- -function colorbar_triangles(val::StrSymb)::String +colorbar_triangles(val::StrSymb)::String = colorbar_triangles(lowercase(string(val))) +function colorbar_triangles(val_str::String)::String # Accepts Top/TopTri[High|Low], Bottom/BottomTri, Left/LeftTri, Right/RightTri or triangles (caseless) - val_str::String = lowercase(string(val)) anc = "RM"; tris = "" # Default anchor Right Middle and no triangles if (contains(val_str, "tri") && !isempty(CURRENT_CPT[])) # Sets CPT.bfn to match colormap end colors if (CURRENT_CPT[].bfn[1,:] == [0.0, 0.0, 0.0] && CURRENT_CPT[].bfn[1,:] == [1.0, 1.0, 1.0]) diff --git a/src/gdal/gdal.jl b/src/gdal/gdal.jl index fb9353de2..e7dac2add 100644 --- a/src/gdal/gdal.jl +++ b/src/gdal/gdal.jl @@ -1485,7 +1485,7 @@ abstract type AbstractGeomFieldDefn end # needs to have a `ptr::GDALGeomFieldDe (proj4) && return epsg2proj(epsg) return "" end - function _getproj(G_I, proj4::Bool, wkt::Bool, epsg::Bool) + function _getproj(@nospecialize(G_I), proj4::Bool, wkt::Bool, epsg::Bool) (!proj4 && !wkt && !epsg) && (proj4 = true) prj::String, _prj::Int = "", 0 if (proj4) @@ -1503,9 +1503,6 @@ abstract type AbstractGeomFieldDefn end # needs to have a `ptr::GDALGeomFieldDe @warn("Sorry, conversion to EPSG is not yet implemented.") end return (_prj != 0) ? _prj : prj - #prj = G_I.proj4 - #(prj == "") && (prj = G_I.wkt) - #return (!proj4) ? prj : startswith(prj, "PROJCS") ? toPROJ4(importWKT(prj)) : prj end getproj(G::GMTgrid; proj4::Bool=false, wkt::Bool=false, epsg::Bool=false) = _getproj(G, proj4, wkt, epsg) getproj(I::GMTimage; proj4::Bool=false, wkt::Bool=false, epsg::Bool=false) = _getproj(I, proj4, wkt, epsg) diff --git a/src/gdal/gdal_tools.jl b/src/gdal/gdal_tools.jl index 0b553bc16..cfca6d039 100644 --- a/src/gdal/gdal_tools.jl +++ b/src/gdal/gdal_tools.jl @@ -327,12 +327,13 @@ end function helper_run_GDAL_fun(f::Function, indata, dest::String, opts, method::String="", kwargs...)::Union{GItype, GDtype, Gdal.AbstractDataset, Nothing} ressurectGDAL() # Another black-hole plug attempt. opts = gdal_opts2vec(opts) # Guarantied to return a Vector{String} - d, opts_vs, got_GMT_opts = GMT_opts_to_GDAL(f, opts, kwargs...) + d = KW(kwargs) + opts_vs, got_GMT_opts = GMT_opts_to_GDAL(f, opts, d) _helper_run_GDAL_fun(f, indata, dest, opts_vs, method, got_GMT_opts, d) end # --------------------------------------------------------------------------------------------------- -function _helper_run_GDAL_fun(f, indata, dest, opts, method, got_GMT_opts, d)::Union{GItype, GDtype, Gdal.AbstractDataset, Nothing} +function _helper_run_GDAL_fun(f::Function, indata, dest::String, opts::Vector{String}, method, got_GMT_opts::Bool, d::Dict{Symbol, Any})::Union{GItype, GDtype, Gdal.AbstractDataset, Nothing} # This second level helper function reduces the number of multiple compiles. Here, only 'indata' may have different types. Vd::Int = ((val = find_in_dict(d, [:Vd])[1]) !== nothing) ? val : 0 # More gymns to avoid Anys @@ -429,9 +430,8 @@ function save_cpt4gdal(cpt::GMTcpt, outname::String) end # --------------------------------------------------------------------------------------------------- -function GMT_opts_to_GDAL(f::Function, opts::Vector{String}, kwargs...) +function GMT_opts_to_GDAL(f::Function, opts::Vector{String}, d::Dict{Symbol, Any}) # Helper function to process some GMT options and turn them into GDAL syntax - d = KW(kwargs) # See if 'opts' is a kwarg if isempty(opts) && ((val = GMT.hlp_desnany_vstr(d, [:opts])) !== String[]) @@ -462,7 +462,7 @@ function GMT_opts_to_GDAL(f::Function, opts::Vector{String}, kwargs...) t = split(opt_I[4:end], '/') (length(t) == 1) ? append!(opts, ["-tr", t[1], t[1]]) : append!(opts, ["-tr", t[1], t[2]]) end - return d, opts, (opt_R != "" || length(opt_J) > 1 || opt_I != "") + return opts, (opt_R != "" || length(opt_J) > 1 || opt_I != "") end # --------------------------------------------------------------------------------------------------- diff --git a/src/grdimage.jl b/src/grdimage.jl index a2c20205d..eae29d36c 100644 --- a/src/grdimage.jl +++ b/src/grdimage.jl @@ -160,7 +160,7 @@ function _grdimage(cmd0::String, arg1, arg2, arg3, O::Bool, K::Bool, d::Dict) end # --------------------------------------------------------------------------------------------------- -function common_insert_R!(d::Dict, O::Bool, cmd0, I_G; is3D=false) +function common_insert_R!(d::Dict, O::Bool, cmd0, @nospecialize(I_G); is3D=false) # Set -R in 'd' under several conditions. We may need this to make -J=:guess to work O && return CTRL.limits .= 0.0 # Have to play safe on this because some eventual show calls may have left this non-empty @@ -204,7 +204,7 @@ function common_insert_R!(d::Dict, O::Bool, cmd0, I_G; is3D=false) end # --------------------------------------------------------------------------------------------------- -function common_shade(d::Dict, cmd::String, arg1, arg2, arg3, arg4, prog) +function common_shade(d::Dict, cmd::String, @nospecialize(arg1), @nospecialize(arg2), @nospecialize(arg3), @nospecialize(arg4), prog::String) # Used both by grdimage and grdview symbs = [:I :shade :shading :intensity] (SHOW_KWARGS[]) && return print_kwarg_opts(symbs, "GMTgrid | String"), arg1, arg2, arg3, arg4 diff --git a/src/histo_funs.jl b/src/histo_funs.jl index e0ccd1290..3c2ae4df6 100644 --- a/src/histo_funs.jl +++ b/src/histo_funs.jl @@ -1,4 +1,7 @@ -function find_histo_limits(In, thresholds=nothing, width=20, hst_::Matrix{Float64}=Matrix{Float64}(undef,0,2)) +function find_histo_limits(In, thresholds=nothing, width=20, hst::Matrix{Float64}=Matrix{Float64}(undef,0,2)) + _find_histo_limits(In, thresholds === nothing ? () : thresholds, Float64(width), hst) +end +function _find_histo_limits(@nospecialize(In), thresholds::Tuple, width::Float64, hst_::Matrix{Float64}) # Find the histogram limits of a UInt16 GMTimage that allow to better stretch the histogram # THRESHOLDS is an optional Tuple input containing the left and right histo thresholds, in percentage, # between which the histogram values will be retained. Defaults are (0.1, 0.4) percent. Note, this diff --git a/src/plot.jl b/src/plot.jl index fbed9afa1..e24c4b82e 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -1029,8 +1029,8 @@ arrows(arg1; kw...) = arrows("", arg1; first=true, kw...) arrows!(arg1; kw...) = arrows("", arg1; first=false, kw...) # ------------------------------------------------------------------------------------------------------ -function helper_vecZscale!(d::Dict, arg1, first::Bool, typevec::Int; opt_R::String="", fancy_arrow::Bool=false, paper_u::Bool=false) - # We have a GMT bug (up till 6.4.0) that screws when vector components are dx,dy or r,theta and +function helper_vecZscale!(d::Dict{Symbol, Any}, arg1, first::Bool, typevec::Int; opt_R::String="", fancy_arrow::Bool=false, paper_u::Bool=false) + # We have a GMT bug (up till 6.6.0) that screws when vector components are dx,dy or r,theta and # x,y is not isometric or when -Sv+z (and possibly in other cases). So, between thinking and # dumb trial-and-error I came out with this patch that computes two scale factors, one to be applied # to the y component and the other that sets a +z under the hood. @@ -1106,7 +1106,7 @@ function helper_vecZscale!(d::Dict, arg1, first::Bool, typevec::Int; opt_R::Stri end # ------------------------------------------------------------------------------------------------------ -function helper_vecBug(d, arg1, first::Bool, haveR::Bool, haveVarFill::Bool, typevec::Int; isfeather::Bool=false) +function helper_vecBug(d::Dict{Symbol, Any}, arg1, first::Bool, haveR::Bool, haveVarFill::Bool, typevec::Int; isfeather::Bool=false) # Helper function that deals with setting several defaults and mostly patch a GMT vectors bug. # TYPEVEC = 0, ==> u,v = theta,rho. TYPEVEC = 1, ==> u,v = u,v. TYPEVEC = 2, ==> u,v = x2,y2 diff --git a/src/pshistogram.jl b/src/pshistogram.jl index 49aaf698b..24122713d 100644 --- a/src/pshistogram.jl +++ b/src/pshistogram.jl @@ -164,6 +164,7 @@ function histogram_helper(cmd0::String, arg1, O::Bool, K::Bool, d::Dict{Symbol,A limit_L = nothing do_auto = ((val_auto = find_in_dict(d, [:auto :thresholds])[1]) !== nothing) ? true : false # Automatic bounds detetion + (val_auto == 1) && (val_auto = nothing) # If auto=true, we want to pass a nothing to the find_histo_limits() fun do_getauto = ((val_getauto = find_in_dict(d, [:getauto :getthresholds])[1]) !== nothing) ? true : false do_zoom = ((find_in_dict(d, [:zoom])[1]) !== nothing) ? true : false # Automatic zoom to interesting region diff --git a/src/psxy.jl b/src/psxy.jl index be24f1ea0..f2d706a4c 100644 --- a/src/psxy.jl +++ b/src/psxy.jl @@ -11,13 +11,15 @@ const psxyz! = plot3d! function common_plot_xyz(cmd0::String, arg1, caller::String, first::Bool, is3D::Bool; kwargs...) d, K, O = init_module(first, kwargs...) # Also checks if the user wants ONLY the HELP mode (cmd0 != "" && arg1 === nothing && is_in_dict(d, [:groupvar :hue]) !== nothing) && (arg1 = gmtread(cmd0); cmd0 = "") - _common_plot_xyz(cmd0, arg1, caller, O, K, is3D, d) + _common_plot_xyz(wrapDatasets(cmd0, arg1), caller, O, K, is3D, d) end function common_plot_xyz(cmd0::String, arg1, caller::String, first::Bool, is3D::Bool, d::Dict{Symbol, Any}) (cmd0 != "" && arg1 === nothing && is_in_dict(d, [:groupvar :hue]) !== nothing) && (arg1 = gmtread(cmd0); cmd0 = "") - _common_plot_xyz(cmd0, arg1, caller, !first, true, is3D, d) + _common_plot_xyz(wrapDatasets(cmd0, arg1), caller, !first, true, is3D, d) end -function _common_plot_xyz(cmd0::String, arg1, caller::String, O::Bool, K::Bool, is3D::Bool, d::Dict{Symbol, Any}) +function _common_plot_xyz(w::wrapDatasets, caller::String, O::Bool, K::Bool, is3D::Bool, d::Dict{Symbol, Any}) + cmd0, arg1 = unwrapDatasets(w) + first = !O (caller != "bar") && (arg1 = if_multicols(d, arg1, is3D)) # Check if it was asked to split a GMTdataset in its columns @@ -692,7 +694,7 @@ OR - `pagebg`: an image file name or a GMTimage/GMTgrid object In this case the above defaults for the _width_ and _offset_ parameters are used """ -function fish_pagebg(d::Dict, cmd::Vector{String}; autoJZ::Bool=true)::Vector{String} +function fish_pagebg(d::Dict{Symbol, Any}, cmd::Vector{String}; autoJZ::Bool=true)::Vector{String} ((val = find_in_dict(d, [:pagebg])[1]) === nothing) && return cmd width::Float64 = 0.8; off_X::Float64 = 0.0; off_Y::Float64 = 0.0 # The off's are offsets from the center opt_U = "" diff --git a/src/utils_types.jl b/src/utils_types.jl index eebb1db76..3f50d3a45 100644 --- a/src/utils_types.jl +++ b/src/utils_types.jl @@ -2442,16 +2442,19 @@ function grid2img(G::GMTgrid{<:Unsigned}) end # --------------------------------------------------------------------------------------------------- -function grdimg_hdr_xy(@nospecialize(mat), reg, hdr, x=Float64[], y=Float64[], is_transposed=false) - # Thin wrapper: convert to concrete types, then call the single-compilation implementation - _grdimg_hdr_xy(mat, Int(reg)::Int, Float64.(vec(hdr)), Float64.(vec(x)), Float64.(vec(y)), is_transposed == 1) -end - -function _grdimg_hdr_xy(@nospecialize(mat), reg::Int, hdr::Vector{Float64}, x::Vector{Float64}, y::Vector{Float64}, is_transposed::Bool) +function grdimg_hdr_xy(mat, reg::Int, hdr, x=Float64[], y=Float64[], is_transposed=false) + # Thin wrapper: extract all mat-dependent info here, so _grdimg_hdr_xy needs no mat argument + row_dim, col_dim = is_transposed ? (2,1) : (1,2) + nx = size(mat, col_dim)::Int; ny = size(mat, row_dim)::Int + _hdr = vec(Float64.(hdr)); _x = vec(Float64.(x)); _y = vec(Float64.(y)) + need_extrema = (!isempty(_x) && !isempty(_y)) || isempty(_hdr) || length(_hdr) == 4 + zmin, zmax = need_extrema ? extrema_nan(mat) : (NaN, NaN) + mat1_is_nothing = (ny == 1 && nx == 2 && mat[1] === nothing) + _grdimg_hdr_xy(reg, nx, ny, Float64(zmin), Float64(zmax), mat1_is_nothing, _hdr, _x, _y) +end + +function _grdimg_hdr_xy(reg::Int, nx::Int, ny::Int, zmin::Float64, zmax::Float64, mat1_is_nothing::Bool, hdr::Vector{Float64}, x::Vector{Float64}, y::Vector{Float64}) # Generate x,y coords array and compute/update header plus increments for grids/images -# Arrays coming from GDAL are often scanline so they are transposed. In that case is_transposed should be true - row_dim, col_dim = (is_transposed) ? (2,1) : (1,2) - nx = size(mat, col_dim); ny = size(mat, row_dim); one_or_zero = reg == 0 ? 1 : 0 if (!isempty(x) && !isempty(y)) # But not tested if they are equi-spaced as they MUST be @@ -2469,26 +2472,22 @@ function _grdimg_hdr_xy(@nospecialize(mat), reg::Int, hdr::Vector{Float64}, x::V end x_inc = (x[end] - x[1]) / (nx - one_or_zero); isnan(x_inc) && (x_inc = 0.0) # When vertical slices y_inc = (y[end] - y[1]) / (ny - one_or_zero); isnan(y_inc) && (y_inc = 0.0) - zmin::Float64, zmax::Float64 = extrema_nan(mat) - hdr = Float64.([x[1], x[end], y[1], y[end], zmin, zmax]) + hdr = [x[1], x[end], y[1], y[end], zmin, zmax] elseif (isempty(hdr)) - zmin, zmax = extrema_nan(mat) if (reg == 0) x = collect(1.0:nx); y = collect(1.0:ny) else x = collect(0.5:nx+0.5); y = collect(0.5:ny+0.5) end - hdr = Float64.([x[1], x[end], y[1], y[end], zmin, zmax]) + hdr = [x[1], x[end], y[1], y[end], zmin, zmax] x_inc = 1.0; y_inc = 1.0 else (length(hdr) != 9 && length(hdr) != 4) && error("The HDR array must have 4 or 9 elements") - (eltype(hdr) != Float64) && (hdr = Float64.(hdr)) if (length(hdr) == 4) # No increments nor min/max, must compute them x_inc = (hdr[2] - hdr[1]) / (nx - one_or_zero) y_inc = (hdr[4] - hdr[3]) / (ny - one_or_zero) - zmin, zmax = extrema_nan(mat) hdr = append!(hdr, [zmin, zmax, reg, x_inc, y_inc]) end one_or_zero = (hdr[7] == 0) ? 1 : 0 - if (ny == 1 && nx == 2 && mat[1] === nothing) + if (mat1_is_nothing) # In this case the 'mat' is a tricked matrix with [nothing val]. Compute nx,ny from header # The final matrix will be computed in the main mat2grid method nx = Int(round((hdr[2] - hdr[1]) / hdr[8] + one_or_zero)) @@ -2500,10 +2499,6 @@ function _grdimg_hdr_xy(@nospecialize(mat), reg::Int, hdr::Vector{Float64}, x::V x_inc = (hdr[2] - hdr[1]) / (nx - one_or_zero) y_inc = (hdr[4] - hdr[3]) / (ny - one_or_zero) end - if (isa(x, UnitRange)) x = collect(x) end # The AbstractArrays are much less forgivable - if (isa(y, UnitRange)) y = collect(y) end - if (!isa(x, Vector{Float64})) x = Float64.(x) end - if (!isa(y, Vector{Float64})) y = Float64.(y) end return x, y, hdr, x_inc, y_inc end