diff --git a/src/GMT.jl b/src/GMT.jl index e7b376c25..3575b9daf 100644 --- a/src/GMT.jl +++ b/src/GMT.jl @@ -96,7 +96,7 @@ const DEF_FIG_AXES = Ref{String}(DEF_FIG_AXES_BAK) # This one may be be changed const DEF_FIG_AXES3 = Ref{String}(DEF_FIG_AXES3_BAK)# "" const FIG_MARGIN = Ref{Int}(1) # Figure margin in points after convertion by 'psconvert'. Accessible 'margin' common option const global CTRL = CTRLstruct(zeros(13), zeros(6), [true], [false], - [:arrows, :bubblechart, :basemap, :band, :clip, :coast, :colorbar, :grdcontour, :hband, :hlines, :inset, :logo, :lines, :grdvector, :plot, :plot3, :quiver, :scatter, :scatter3, :stairs, :text, :vlines, :vband], ["", "", ""], ["", "", "", " "], ["", ""], ["", ""], [false, true], [C_NULL], [Dict()]) + [:arrows, :bubblechart, :basemap, :band, :clip, :coast, :colorbar, :grdcontour, :hband, :hlines, :inset, :logo, :lines, :grdvector, :plot, :plot3, :quiver, :scatter, :scatter3, :stairs, :text, :vlines, :vband], ["", "", ""], ["", "", "", " "], ["", ""], ["", ""], [false, true], [C_NULL], [Dict{Symbol,Any}()]) const pocket_call = Ref{Vector{Any}}(Any[nothing, nothing, nothing, nothing, nothing, nothing])# Extracted from CTRL to isolate type instability const CTRLshapes = CTRLstruct2(true, true, "") # Used in sub-module Drawing const prj4WGS84 = "+proj=longlat +datum=WGS84 +units=m +no_defs"# This is used in many places @@ -387,7 +387,7 @@ using .Laszip gmtwrite(t, [0.0 0; 1 1]) gmtread(t) gmtread(TESTSDIR * "assets/burro_cenora.jpg") - coast(R=:g, proj=:guess, W=(level=1, pen=(2, :green)), savefig=tempname()*".ps") + #coast(R=:g, proj=:guess, W=(level=1, pen=(2, :green)), savefig=tempname()*".ps") rm(t) D = mat2ds(rand(3, 3), colnames=["Time", "b", "c"]) D.attrib = Dict("Timecol" => "1") diff --git a/src/common_options.jl b/src/common_options.jl index a092a41be..1d218a8b9 100644 --- a/src/common_options.jl +++ b/src/common_options.jl @@ -2,7 +2,7 @@ const KW = Dict{Symbol,Any} nt2dict(nt::NamedTuple) = nt2dict(; nt...) -nt2dict(; kw...) = Dict(kw) +nt2dict(; kw...) = Dict{Symbol,Any}(kw) # Need the Symbol.() below in oder to work from PyCall # A darker an probably more efficient way is: ((; kw...) -> kw.data)(; d...) but breaks in PyCall dict2nt(d::AbstractDict)::NamedTuple = NamedTuple{Tuple(Symbol.(keys(d)))}(values(d)) @@ -1425,15 +1425,18 @@ end # --------------------------------------------------------------------------------------------------- function parse_type_anchor(d::Dict, cmd::String, symbs::VMs, mapa::NamedTuple, def_CS::Char, del::Bool=true) + _parse_type_anchor(d, cmd, symbs, Dict{Symbol,Any}(nt2dict(mapa)), def_CS, del) +end +function _parse_type_anchor(d::Dict, cmd::String, symbs::VMs, mapa::Dict{Symbol,Any}, def_CS::Char, del::Bool) # SYMBS: [:D :pos :position] | ... - # MAPA is the NamedTuple of suboptions + # MAPA is the Dict of suboptions (converted from NamedTuple in wrapper) # def_CS is the default "Coordinate system". Colorbar has 'J', logo has 'g', many have 'j' (SHOW_KWARGS[]) && return print_kwarg_opts(symbs, mapa) # Just print the kwargs of this option call got_str = false for s in symbs # Check if arg value is a string. If yes, ignore 'def_CS' (haskey(d, s) && isa(d[s], StrSymb)) && (got_str = true; break) end - opt::String = add_opt(d, "", "", symbs, mapa; del=del) + opt::String = _add_opt_2(d, "", "", vec(symbs), mapa, nothing, del, false, false, true) (!isempty(opt) && symbs[1] == :D && def_CS == 'J' && opt[1] == '+') && (opt = "RM" * opt) # Special case in colorbar whith +e (triangs) if (!got_str && opt != "" && opt[1] != 'j' && opt[1] != 'J' && opt[1] != 'g' && opt[1] != 'n' && opt[1] != 'x') opt = def_CS * opt @@ -1443,7 +1446,7 @@ function parse_type_anchor(d::Dict, cmd::String, symbs::VMs, mapa::NamedTuple, d end # --------------------------------------------------------------------------------------------------- -function parse_UXY(cmd::String, d::Dict, aliases, opt::Char)::String +function parse_UXY(cmd::String, d::Dict{Symbol,Any}, aliases, opt::Char)::String # Parse the global -U, -X, -Y options. Return CMD same as input if no option OPT in args # ALIASES: [:X :xshift :x_offset] (same for Y) or [:U :time_stamp :timestamp] val, symb = find_in_dict(d, aliases, true) @@ -1457,7 +1460,7 @@ function parse_UXY(cmd::String, d::Dict, aliases, opt::Char)::String end # --------------------------------------------------------------------------------------------------- -function parse_V(d::Dict, cmd::String)::String +function parse_V(d::Dict{Symbol,Any}, cmd::String)::String # Parse the global -V option. Return CMD same as input if no -V option in args if ((val = find_in_dict(d, [:V :verbose], true)[1]) !== nothing) if (isa(val, Bool) && val) cmd *= " -V" @@ -1468,14 +1471,14 @@ function parse_V(d::Dict, cmd::String)::String end # --------------------------------------------------------------------------------------------------- -function parse_V_params(d::Dict, cmd::String) +function parse_V_params(d::Dict{Symbol,Any}, cmd::String) # Parse the global -V option and the --PAR=val. Return CMD same as input if no options in args cmd = parse_V(d, cmd) return parse_params(d, cmd) end # --------------------------------------------------------------------------------------------------- -function parse_UVXY(d::Dict, cmd::String) +function parse_UVXY(d::Dict{Symbol,Any}, cmd::String) cmd = parse_V(d, cmd) cmd = parse_UXY(cmd, d, [:X :x_offset :xshift], 'X') cmd = parse_UXY(cmd, d, [:Y :y_offset :yshift], 'Y') @@ -1484,13 +1487,13 @@ function parse_UVXY(d::Dict, cmd::String) end # --------------------------------------------------------------------------------------------------- -function parse_a(d::Dict, cmd::String) +function parse_a(d::Dict{Symbol,Any}, cmd::String) # Parse the global -a option. Return CMD same as input if no -a option in args parse_helper(cmd, d, [:a :aspatial], " -a") end # --------------------------------------------------------------------------------------------------- -function parse_b(d::Dict, cmd::String, symbs::Array{Symbol}=[:b :binary], io::String="") +function parse_b(d::Dict{Symbol,Any}, cmd::String, symbs::Array{Symbol}=[:b :binary], io::String="") # Parse the global -b option. Return CMD same as input if no -b option in args cmd_::String = add_opt(d, "", string(symbs[1])*io, symbs, (ncols=("", arg2str, 1), type=("", data_type, 2), swapp_bytes="_w", little_endian="_+l", big_endian="+b")) @@ -1501,7 +1504,7 @@ parse_bo(d::Dict, cmd::String) = parse_b(d, cmd, [:b :bo :binary_out], "o") # --------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------- -function parse_c(d::Dict, cmd::String)::Tuple{String, String} +function parse_c(d::Dict{Symbol,Any}, cmd::String)::Tuple{String, String} # Most of the work here is because GMT counts from 0 but here we count from 1, so conversions needed opt_val::String = "" if ((val = find_in_dict(d, [:c :panel])[1]) !== nothing) @@ -1521,7 +1524,7 @@ function parse_c(d::Dict, cmd::String)::Tuple{String, String} end # --------------------------------------------------------------------------------------------------- -function parse_d(d::Dict, cmd::String, symbs::VMs=[:d :nodata]) +function parse_d(d::Dict{Symbol,Any}, cmd::String, symbs::VMs=[:d :nodata]) (SHOW_KWARGS[]) && return (print_kwarg_opts(symbs, "$(symbs[2])=val"),"") parse_helper(cmd, d, [:d :nodata], " -d") end @@ -1534,7 +1537,7 @@ parse_i(d::Dict, cmd::String) = parse_helper(cmd, d, [:i :incols :incol], " -i" parse_j(d::Dict, cmd::String) = parse_helper(cmd, d, [:j :metric :spherical :spherical_dist], " -j") # --------------------------------------------------------------------------------- -function parse_f(d::Dict, cmd::String) +function parse_f(d::Dict{Symbol,Any}, cmd::String) # For plotting time (-ft) in X one must add 'T' to -JX but that is boring and difficult to automatize # GMT6.3 now has it internal but previous versions no. So do that job here. cmd, opt_f = parse_helper(cmd, d, [:f :geog :colinfo :coltypes :coltype], " -f") @@ -1550,7 +1553,7 @@ function parse_f(d::Dict, cmd::String) end # --------------------------------------------------------------------------------- -function parse_l(d::Dict, cmd::String, del::Bool=false) +function parse_l(d::Dict{Symbol,Any}, cmd::String, del::Bool=false) cmd_::String = add_opt(d, "", "l", [:l :legend], (text=("", arg2str, 1), hline=("+D", add_opt_pen), vspace="+G", header="+H", image="+I", line_text="+L", n_cols="+N", ncols="+N", ssize="+S", start_vline=("+V", add_opt_pen), end_vline=("+v", add_opt_pen), font=("+f", font), fill="+g", justify="+j", offset="+o", frame_pen=("+p", add_opt_pen), width="+w", scale="+x"); del=del) # Now make sure blanks in legend text are wrapped in "" @@ -1564,7 +1567,7 @@ function parse_l(d::Dict, cmd::String, del::Bool=false) end # --------------------------------------------------------------------------------- -function parse_n(d::Dict, cmd::String, gmtcompat::Bool=false) +function parse_n(d::Dict{Symbol,Any}, cmd::String, gmtcompat::Bool=false) # Parse the global -n option. Return CMD same as input if no -n option in args # The GMTCOMPAT arg is used to reverse the default aliasing in GMT, which is ON by default # However, practise has shown that this makes projecting images significantly slower with not clear benefits @@ -1583,11 +1586,11 @@ function parse_n(d::Dict, cmd::String, gmtcompat::Bool=false) end # --------------------------------------------------------------------------------- -parse_o(d::Dict, cmd::String) = parse_helper(cmd, d, [:o :outcols :outcol], " -o", ',') -parse_p(d::Dict, cmd::String) = parse_helper(cmd, d, [:p :view :perspective], " -p") +parse_o(d::Dict{Symbol,Any}, cmd::String) = parse_helper(cmd, d, [:o :outcols :outcol], " -o", ',') +parse_p(d::Dict{Symbol,Any}, cmd::String) = parse_helper(cmd, d, [:p :view :perspective], " -p") # --------------------------------------------------------------------------------- -function parse_q(d::Dict, cmd::String) +function parse_q(d::Dict{Symbol,Any}, cmd::String) parse_helper(cmd, d, [:q :inrow :inrows], " -q") parse_helper(cmd, d, [:qo :outrow :outrows], " -qo") end @@ -1595,15 +1598,15 @@ end # --------------------------------------------------------------------------------------------------- # Parse the global -: option. Return CMD same as input if no -: option in args # But because we can't have a variable called ':' we use only the aliases -parse_swap_xy(d::Dict, cmd::String) = parse_helper(cmd, d, [:yx :swap_xy], " -:") +parse_swap_xy(d::Dict{Symbol,Any}, cmd::String) = parse_helper(cmd, d, [:yx :swap_xy], " -:") # --------------------------------------------------------------------------------------------------- # Parse the global -? option. Return CMD same as input if no -? option in args -parse_s(d::Dict, cmd::String) = parse_helper(cmd, d, [:s :skiprows :skip_NaN], " -s") -parse_x(d::Dict, cmd::String) = parse_helper(cmd, d, [:x :cores :n_threads], " -x") +parse_s(d::Dict{Symbol,Any}, cmd::String) = parse_helper(cmd, d, [:s :skiprows :skip_NaN], " -s") +parse_x(d::Dict{Symbol,Any}, cmd::String) = parse_helper(cmd, d, [:x :cores :n_threads], " -x") # --------------------------------------------------------------------------------------------------- -function parse_w(d::Dict, cmd::String) +function parse_w(d::Dict{Symbol,Any}, cmd::String) # -wy|a|w|d|h|m|s|cperiod[/phase][+ccol] val, symb = find_in_dict(d, [:w :wrap :cyclic], false) (val === nothing) && return cmd, "" @@ -1627,7 +1630,7 @@ function parse_w(d::Dict, cmd::String) end # --------------------------------------------------------------------------------------------------- -function parse_r(d::Dict, cmd::String, del::Bool=true) +function parse_r(d::Dict{Symbol,Any}, cmd::String, del::Bool=true) # Accept both numeric (0 or != 0) and string/symbol arguments opt_val::String = "" val = find_in_dict(d, [:r :reg :registration], del)[1] @@ -1639,7 +1642,7 @@ function parse_r(d::Dict, cmd::String, del::Bool=true) end # --------------------------------------------------------------------------------------------------- -function parse_t(d::Dict, cmd::String, del::Bool=true) +function parse_t(d::Dict{Symbol,Any}, cmd::String, del::Bool=true) opt_val::String = "" if ((val = find_in_dict(d, [:t :alpha :transparency], del)[1]) !== nothing) (val == "" || val == 0) && return cmd, "" # To allow programatically calls were -t is unknown @@ -1652,7 +1655,7 @@ function parse_t(d::Dict, cmd::String, del::Bool=true) end # --------------------------------------------------------------------------------------------------- -function parse_write(d::Dict, cmd::String)::String +function parse_write(d::Dict{Symbol,Any}, cmd::String)::String if ((val = hlp_desnany_str(d, [:write :savefile :|>])) !== "") cmd *= " > " * val end @@ -1660,7 +1663,7 @@ function parse_write(d::Dict, cmd::String)::String end # --------------------------------------------------------------------------------------------------- -function parse_append(d::Dict, cmd::String)::String +function parse_append(d::Dict{Symbol,Any}, cmd::String)::String if ((val = hlp_desnany_str(d, [:append])) !== "") cmd *= " >> " * val end @@ -1668,7 +1671,7 @@ function parse_append(d::Dict, cmd::String)::String end # --------------------------------------------------------------------------------------------------- -function parse_helper(cmd::String, d::Dict, symbs::VMs, opt::String, sep='/')::Tuple{String, String} +function parse_helper(cmd::String, d::Dict{Symbol,Any}, symbs::VMs, opt::String, sep='/')::Tuple{String, String} # Helper function to the parse_?() global options. (SHOW_KWARGS[]) && return (print_kwarg_opts(symbs, "(Common option not yet expanded)"),"") opt_val::String = "" @@ -1680,7 +1683,7 @@ function parse_helper(cmd::String, d::Dict, symbs::VMs, opt::String, sep='/')::T end # --------------------------------------------------------------------------------------------------- -function parse_common_opts(d::Dict, cmd::String, opts::VMs; first::Bool=true, is3D::Bool=false)::Tuple{String, String} +function parse_common_opts(d::Dict{Symbol,Any}, cmd::String, opts::VMs; first::Bool=true, is3D::Bool=false)::Tuple{String, String} (SHOW_KWARGS[]) && return (print_kwarg_opts(opts, "(Common options)"),"") # Just print the options ignore_J, ignore_R, ignore_p, ignore_t = false, false, false, false @@ -1754,7 +1757,7 @@ function parse_common_opts(d::Dict, cmd::String, opts::VMs; first::Bool=true, is end # --------------------------------------------------------------------------------------------------- -function parse_theme(d::Dict, del::Bool=true) +function parse_theme(d::Dict{Symbol,Any}, del::Bool=true) # This must always be processed before parse_B so it's the first call in that function if ((val = find_in_dict(d, [:theme], del)[1]) !== nothing) isa(val, NamedTuple) && theme(string(val[1])::String; nt2dict(val)...) @@ -1763,7 +1766,7 @@ function parse_theme(d::Dict, del::Bool=true) end # --------------------------------------------------------------------------------------------------- -function parse_these_opts(cmd::String, d::Dict, opts)::String +function parse_these_opts(cmd::String, d::Dict{Symbol,Any}, opts)::String # Parse a group of options that individualualy would had been parsed as (example): # cmd = add_opt(d, cmd, "A", [:A :horizontal]) for opt in opts @@ -1777,7 +1780,7 @@ end parse_G(d::Dict, cmd::String) = parse_helper(cmd, d, [:G :save :write :outgrid :outfile], " -G") # --------------------------------------------------------------------------------------------------- -function parse_I(d::Dict, cmd::String, symbs, opt::String, del::Bool=true)::String +function parse_I(d::Dict{Symbol,Any}, cmd::String, symbs, opt::String, del::Bool=true)::String # Parse the quasi-global -I option. But arguments can be strings, arrays, tuples or NamedTuples # At the end we must recreate this syntax: xinc[unit][+e|n][/yinc[unit][+e|n]] or get_that_string(arg)::String = string(arg)::String # Function barrier. Shuting up JET, etc. @@ -1816,7 +1819,7 @@ function parse_I(d::Dict, cmd::String, symbs, opt::String, del::Bool=true)::Stri end # --------------------------------------------------------------------------------------------------- -function parse_params(d::Dict, cmd::String; del::Bool=true)::String +function parse_params(d::Dict{Symbol,Any}, cmd::String; del::Bool=true)::String # Parse the gmt.conf parameters when used from within the modules. Return a --PAR=val string # The input to this kwarg can be a tuple (e.g. (PAR,val)) or a NamedTuple (P1=V1, P2=V2,...) @@ -1838,7 +1841,7 @@ function parse_params(d::Dict, cmd::String; del::Bool=true)::String end # --------------------------------------------------------------------------------------------------- -function add_opt_pen(d::Dict, @nospecialize(symbs::Union{Nothing, VMs}); opt::String="", del::Bool=true)::String +function add_opt_pen(d::Dict{Symbol,Any}, @nospecialize(symbs::Union{Nothing, VMs}); opt::String="", del::Bool=true)::String # Build a pen option. Input can be either a full hard core string or spread in lw (or lt), lc, ls, etc or a tuple (SHOW_KWARGS[]) && return print_kwarg_opts(symbs, "NamedTuple | Tuple | String | Number") # Just print the options @@ -1871,7 +1874,7 @@ function add_opt_pen(d::Dict, @nospecialize(symbs::Union{Nothing, VMs}); opt::St c::String = (:color in k) ? string(val[:color]) : "" s::String = (:style in k) ? string(val[:style]) : "" if (w != "" || c != "" || s != "") - out = opt * add_opt_pen(Dict(:pen => (w,c,s)), symbs, opt="", del=false) + out = opt * add_opt_pen(Dict{Symbol,Any}(:pen => (w,c,s)), symbs, opt="", del=false) else d2 = nt2dict(val) # Decompose the NT and feed into this-self t = add_opt_pen(d2, symbs, opt="", del=false) @@ -1920,7 +1923,7 @@ function add_opt_pen(d::Dict, @nospecialize(symbs::Union{Nothing, VMs}); opt::St end # ------------------------------------------------------------------------------------------------------ -function helper_arrows(d::Dict; del::Bool=true)::String +function helper_arrows(d::Dict{Symbol,Any}; del::Bool=true)::String # Helper function to set the vector head attributes (SHOW_KWARGS[]) && return print_kwarg_opts([:arrow :vector :arrow4 :vector4 :vecmap :geovec :geovector], "NamedTuple | String") @@ -1939,7 +1942,7 @@ function helper_arrows(d::Dict; del::Bool=true)::String end # --------------------------------------------------------------------------------------------------- -function opt_pen(d::Dict, opt::Char, symbs::VMs)::String +function opt_pen(d::Dict{Symbol,Any}, opt::Char, symbs::VMs)::String # Create an option string of the type -Wpen (SHOW_KWARGS[]) && return print_kwarg_opts(symbs, "Tuple | String | Number") # Just print the options @@ -1986,7 +1989,7 @@ function parse_pen(pen::Tuple)::String end # --------------------------------------------------------------------------------------------------- -function parse_pen_color(d::Dict, symbs=nothing, del::Bool=false)::String +function parse_pen_color(d::Dict{Symbol,Any}, symbs=nothing, del::Bool=false)::String # Need this as a separate fun because it's used from modules lc::String = "" (symbs === nothing) && (symbs = [:lc :linecolor]) @@ -1997,7 +2000,7 @@ function parse_pen_color(d::Dict, symbs=nothing, del::Bool=false)::String end # --------------------------------------------------------------------------------------------------- -function build_pen(d::Dict, del::Bool=false)::String +function build_pen(d::Dict{Symbol,Any}, del::Bool=false)::String # Search for lw, lc, ls in d and create a pen string in case they exist # If no pen specs found, return the empty string "" @@ -2060,7 +2063,7 @@ function parse_arg_and_pen(arg::Tuple, sep::String="/", pen::Bool=true, opt::Str end # --------------------------------------------------------------------------------------------------- -function parse_ls_code!(d::Dict) +function parse_ls_code!(d::Dict{Symbol,Any}) if ((val = find_in_dict(d, [:ls :linestyle])[1]) !== nothing) if (isa(val, String) && (val[1] == '-' || val[1] == '.' || isdigit(val[1]))) d[:ls] = val # Assume it's a "--." or the more complex len_gap_len_gap... form. So reset it and return @@ -2072,8 +2075,8 @@ function parse_ls_code!(d::Dict) return nothing end -mk_styled_line!(d::Dict, code::Symbol) = mk_styled_line!(d, string(code)) -function mk_styled_line!(d::Dict, code::String) +mk_styled_line!(d::Dict{Symbol,Any}, code::Symbol) = mk_styled_line!(d, string(code)) +function mk_styled_line!(d::Dict{Symbol,Any}, code::String) # Parse the CODE string and generate line style. These line styles can be a single annotated line with symbols # or two lines, one a plain line and the other the symbols to plot. This is achieved by tweaking the D dict # and inserting in it the members that the common_plot_xyz function is expecting. @@ -2119,7 +2122,7 @@ function mk_styled_line!(d::Dict, code::String) d[:compact] = line_decorated_with_symbol(d, isfront, lw=lw, lc=lc, symbol=symbol) end else # e.g. lineCirc - marca = get_marker_name(Dict(:marker => symbol), nothing, [:marker], false)[1] # This fun lieves in psxy.jl + marca = get_marker_name(Dict{Symbol,Any}(:marker => symbol), nothing, [:marker], false)[1] # This fun lieves in psxy.jl (marca == "") && error("The selected symbol [$(symbol)] is invalid") noinv_ML = isletter(code[end]) # If false, by default use a white outline and a fill color @@ -2141,7 +2144,7 @@ function mk_styled_line!(d::Dict, code::String) end # --------------------------------------------------------------------------------------------------- -function line_decorated_with_symbol(d::Dict, isfront::Bool=false; lw=0.75, lc="black", ms=0, symbol="circ", dist=0, fill="white")::String +function line_decorated_with_symbol(d::Dict{Symbol,Any}, isfront::Bool=false; lw=0.75, lc="black", ms=0, symbol="circ", dist=0, fill="white")::String # Create an Annotated line with few controls. We estimate the symbol size after the line thickness. (lc == "") && (lc = "black") _lw = (lw == "") ? 0.75 : isa(lw, String) ? parse(Float64, lw) : lw # If last case is not numeric ... @@ -2156,7 +2159,7 @@ function line_decorated_with_symbol(d::Dict, isfront::Bool=false; lw=0.75, lc="b end # --------------------------------------------------------------------------------------------------- -function line_front(d::Dict, gap, lw, lc, fill, symbol, ss)::String +function line_front(d::Dict{Symbol,Any}, gap, lw, lc, fill, symbol, ss)::String d[:G] = fill if (symbol[1] == 's') # Arrows (slips) are tricky ss *= 4; gap *= 2 @@ -2177,7 +2180,7 @@ function line_decorated_with_string(str::AbstractString; dist=0)::String end # --------------------------------------------------------------------------------------------------- -function arg2str(d::Dict, symbs)::String +function arg2str(d::Dict{Symbol,Any}, symbs)::String # Version that allow calls from add_opt() arg2str(find_in_dict(d, symbs)[1]) end @@ -2216,7 +2219,7 @@ function arg2str(arg::GMTdataset, sep='/')::String end # --------------------------------------------------------------------------------------------------- -function finish_PS(d::Dict, cmd::Vector{String}, output::String, K::Bool, O::Bool)::Vector{String} +function finish_PS(d::Dict{Symbol,Any}, cmd::Vector{String}, output::String, K::Bool, O::Bool)::Vector{String} # Finish a PS creating command. All PS creating modules should use this. IamModern[] && return cmd # In Modern mode this fun does not play for k = 1:length(cmd) @@ -2228,7 +2231,7 @@ function finish_PS(d::Dict, cmd::Vector{String}, output::String, K::Bool, O::Boo end # --------------------------------------------------------------------------------------------------- -function finish_PS(d::Dict, cmd::String, output::String, K::Bool, O::Bool)::String +function finish_PS(d::Dict{Symbol,Any}, cmd::String, output::String, K::Bool, O::Bool)::String if (!O && ((val = hlp_desnany_str(d, [:P :portrait])) === "")) cmd *= " -P" end opt = (K && !O) ? " -K" : ((K && O) ? " -K -O" : "") @@ -2246,7 +2249,7 @@ function finish_PS(d::Dict, cmd::String, output::String, K::Bool, O::Bool)::Stri end # --------------------------------------------------------------------------------------------------- -function prepare2geotif(d::Dict, cmd::Vector{String}, opt_T::String, O::Bool)::Tuple{Vector{String}, String} +function prepare2geotif(d::Dict{Symbol,Any}, cmd::Vector{String}, opt_T::String, O::Bool)::Tuple{Vector{String}, String} # Prepare automatic settings to allow creating a GeoTIF or a KML from a PS map # Makes use of psconvert -W option function helper2geotif(cmd::String)::String @@ -2276,7 +2279,7 @@ function prepare2geotif(d::Dict, cmd::Vector{String}, opt_T::String, O::Bool)::T elseif (isa(val, NamedTuple) || isa(val, AbstractDict)) # [+tdocname][+nlayername][+ofoldername][+aaltmode[alt]][+lminLOD/maxLOD][+fminfade/maxfade][+uURL] isa(val, AbstractDict) && (val = Base.invokelatest(dict2nt, val)) - opt_T = add_opt(Base.invokelatest(Dict,:kml => val), " -TG -W+k", "", [:kml], + opt_T = add_opt(Base.invokelatest(Dict{Symbol,Any},:kml => val), " -TG -W+k", "", [:kml], (title="+t", layer="+n", layername="+n", folder="+o", foldername="+o", altmode="+a", LOD=("+l", arg2str), fade=("+f", arg2str), URL="+u")) end end @@ -2284,11 +2287,11 @@ function prepare2geotif(d::Dict, cmd::Vector{String}, opt_T::String, O::Bool)::T end # --------------------------------------------------------------------------------------------------- -function add_opt_1char(cmd::String, d::Dict, symbs::Vector{Matrix{Symbol}}; del::Bool=true)::String +function add_opt_1char(cmd::String, d::Dict{Symbol,Any}, symbs::Vector{Matrix{Symbol}}; del::Bool=true)::String # Scan the D Dict for SYMBS keys and if found create the new option OPT and append it to CMD # If DEL == true we remove the found key. # The keyword value must be a string, symbol or a tuple of them. We only retain the first character of each item - # Ex: GMT.add_opt_1char("", Dict(:N => ("abc", "sw", "x"), :Q=>"datum"), [[:N :geod2aux], [:Q :list]]) == " -Nasx -Qd" + # Ex: GMT.add_opt_1char("", Dict{Symbol,Any}(:N => ("abc", "sw", "x"), :Q=>"datum"), [[:N :geod2aux], [:Q :list]]) == " -Nasx -Qd" (SHOW_KWARGS[]) && return print_kwarg_opts(symbs, "Str | Symb | Tuple") for opt in symbs ((val = find_in_dict(d, opt, del)[1]) === nothing) && continue @@ -2306,7 +2309,7 @@ function add_opt_1char(cmd::String, d::Dict, symbs::Vector{Matrix{Symbol}}; del: end # --------------------------------------------------------------------------------------------------- -function add_opt(d::Dict, cmd::String, opt::String, mapa::NamedTuple)::String +function add_opt(d::Dict{Symbol,Any}, cmd::String, opt::String, mapa::NamedTuple)::String # Thin wrapper: convert NT to Dict to compile _add_opt only once _add_opt_1(d, cmd, opt, Dict{Symbol,Any}(nt2dict(mapa))) end @@ -2327,7 +2330,7 @@ function _add_opt_1(d::Dict, cmd::String, opt::String, mapa::Dict{Symbol,Any}):: end # -function add_opt(d::Dict, cmd::String, opt::String, symbs::VMs)::String +function add_opt(d::Dict{Symbol,Any}, cmd::String, opt::String, symbs::VMs)::String ((val = find_in_dict(d, symbs, true)[1]) === nothing) && return cmd isa(val, AbstractDict) && (val = Base.invokelatest(dict2nt, val)) isa(val, NamedTuple) && return cmd # Happens when the inline 'inset' passed a NT with options for inset itself and not the module it called @@ -2336,14 +2339,14 @@ function add_opt(d::Dict, cmd::String, opt::String, symbs::VMs)::String end # -function add_opt(d::Dict, cmd::String, opt::String, symbs::VMs, mapa; grow_mat=nothing, del::Bool=true, expand::Bool=false, expand_str::Bool=false)::String +function add_opt(d::Dict{Symbol,Any}, cmd::String, opt::String, symbs::VMs, mapa; grow_mat=nothing, del::Bool=true, expand::Bool=false, expand_str::Bool=false)::String # Thin wrapper: convert NamedTuple mapa to Dict to avoid recompilation for each distinct NT type mapa_is_nt = isa(mapa, NamedTuple) _mapa = mapa_is_nt ? Dict{Symbol,Any}(nt2dict(mapa)) : (mapa === nothing ? Dict{Symbol,Any}() : mapa) _add_opt_2(d, cmd, opt, vec(symbs), _mapa, grow_mat, del, expand, expand_str, mapa_is_nt) end -function _add_opt_2(d::Dict, cmd::String, opt::String, symbs::Vector{Symbol}, @nospecialize(mapa), @nospecialize(grow_mat), del::Bool, expand::Bool, expand_str::Bool, mapa_is_nt::Bool)::String +function _add_opt_2(d::Dict{Symbol,Any}, cmd::String, opt::String, symbs::Vector{Symbol}, @nospecialize(mapa), @nospecialize(grow_mat), del::Bool, expand::Bool, expand_str::Bool, mapa_is_nt::Bool)::String # Scan the D Dict for SYMBS keys and if found create the new option OPT and append it to CMD # If DEL == false we do not remove the found key. # 'grow_mat=mat', is a special case to append to a matrix (can't realy be done in Julia) @@ -2428,7 +2431,7 @@ function genFun(this_key::Symbol, user_input::NamedTuple, mapa)::String if (haskey(val_namedTup, key[k])) val = val_namedTup[key[k]] if (isa(val, Function)) - if (val == add_opt_fill) out *= val(Dict(key[k] => user_input[key[k]]))::String end + if (val == add_opt_fill) out *= val(Dict{Symbol,Any}(key[k] => user_input[key[k]]))::String end else out *= string(val_namedTup[key[k]])::String end @@ -2462,14 +2465,14 @@ function add_opt_1(nt::NamedTuple, d, arg)::String # if (isa(this_val, Tuple)) # Complexify it. Here, d[key[k]][2] must be a function name. if (isa(nt[k], NamedTuple)) if (this_val[2] == add_opt_fill) - cmd *= string(this_val[1])::String * this_val[2]("", Dict(key[k] => nt[k]), [key[k]])::String + cmd *= string(this_val[1])::String * this_val[2]("", Dict{Symbol,Any}(key[k] => nt[k]), [key[k]])::String else local_opt = (this_val[2] == helper_decorated) ? true : nothing # 'true' means single argout cmd *= string(this_val[1])::String * this_val[2](nt2dict(nt[k]), local_opt)::String end else # if (length(this_val) == 2) # Run the function - cmd *= string(this_val[1])::String * this_val[2](Dict(key[k] => nt[k]), [key[k]])::String + cmd *= string(this_val[1])::String * this_val[2](Dict{Symbol,Any}(key[k] => nt[k]), [key[k]])::String else # This branch is to deal with options -Td, -Tm, -L and -D of basemap & psscale ind_o += 1 (ind_o > 2) && (@warn("You passed more than 1 of the exclusive options in a anchor type option, keeping first but this may break."); ind_o = 1) @@ -2567,12 +2570,12 @@ function add_opt(fun::Function, t1::Tuple, t2::NamedTuple, del::Bool, mat) end # --------------------------------------------------------------------------------------------------- -function add_opt(d::Dict, cmd::String, opt::String, symbs::VMs, need_symb::Symbol, args, nt_opts::NamedTuple) +function add_opt(d::Dict{Symbol,Any}, cmd::String, opt::String, symbs::VMs, need_symb::Symbol, args, nt_opts::NamedTuple) # Thin wrapper: nospecialize args, convert nt_opts NT to Dict _add_opt_3(d, cmd, opt, symbs, need_symb, args, nt2dict(nt_opts)) end -function _add_opt_3(d::Dict, cmd::String, opt::String, symbs::VMs, need_symb::Symbol, @nospecialize(args), nt_opts_d::Dict) +function _add_opt_3(d::Dict{Symbol,Any}, cmd::String, opt::String, symbs::VMs, need_symb::Symbol, @nospecialize(args), nt_opts_d::Dict) # This version specializes in the case where an option may transmit an array, or read a file, with optional flags. # When optional flags are used we need to use NamedTuples (the NT_OPTS arg). In that case the NEED_SYMB # is the keyword name (a symbol) whose value holds the array. An error is raised if this symbol is missing in D @@ -2588,7 +2591,7 @@ function _add_opt_3(d::Dict, cmd::String, opt::String, symbs::VMs, need_symb::Sy isa(val, AbstractDict) && (val = Base.invokelatest(dict2nt, val)) if (isa(val, Tuple) && length(val) == 2) # This is crazzy trickery to accept also (e.g) C=(pratt,"200k") instead of C=(pts=pratt,dist="200k") - d[symb] = Base.invokelatest(dict2nt, Dict(need_symb => val[1], keys(nt_opts_d)[1] => val[2])) # Need to patch also the input option + d[symb] = Base.invokelatest(dict2nt, Dict{Symbol,Any}(need_symb => val[1], keys(nt_opts_d)[1] => val[2])) # Need to patch also the input option val = d[symb] end if (isa(val, NamedTuple)) @@ -2627,11 +2630,11 @@ function _add_opt_3(d::Dict, cmd::String, opt::String, symbs::VMs, need_symb::Sy end # --------------------------------------------------------------------------------------------------- -function add_opt_cpt(d::Dict, cmd::String, symbs::VMs, opt::Char, N_args::Int=0, arg1=nothing, arg2=nothing, +function add_opt_cpt(d::Dict{Symbol,Any}, cmd::String, symbs::VMs, opt::Char, N_args::Int=0, arg1=nothing, arg2=nothing, store::Bool=false, def::Bool=false, opt_T::String="", in_bag::Bool=false) _add_opt_cpt(d, cmd, symbs, opt, N_args, arg1, arg2, store, def, opt_T, in_bag) end -function _add_opt_cpt(d::Dict, cmd::String, symbs::VMs, opt::Char, N_args::Int, @nospecialize(arg1), @nospecialize(arg2), +function _add_opt_cpt(d::Dict{Symbol,Any}, cmd::String, symbs::VMs, opt::Char, N_args::Int, @nospecialize(arg1), @nospecialize(arg2), store::Bool, def::Bool, opt_T::String, in_bag::Bool) # Deal with options of the form -Ccolor, where color can be a string or a GMTcpt type # SYMBS is normally: CPTaliases @@ -2713,11 +2716,11 @@ end # --------------------------------------------------------------------------------------------------- #add_opt_fill(d::Dict, opt::String="") = add_opt_fill("", d, [d[collect(keys(d))[1]]], opt) # Use ONLY when len(d) == 1 -function add_opt_fill(d::Dict, opt::String="") +function add_opt_fill(d::Dict{Symbol,Any}, opt::String="") add_opt_fill(d, [collect(keys(d))[1]], opt) # Use ONLY when len(d) == 1 end -add_opt_fill(d::Dict, symbs::VMs, opt="") = add_opt_fill("", d, symbs, opt) -function add_opt_fill(cmd::String, d::Dict, @nospecialize(symbs::VMs), opt::String="", del::Bool=true)::String +add_opt_fill(d::Dict{Symbol,Any}, symbs::VMs, opt="") = add_opt_fill("", d, symbs, opt) +function add_opt_fill(cmd::String, d::Dict{Symbol,Any}, @nospecialize(symbs::VMs), opt::String="", del::Bool=true)::String # Deal with the area fill attributes option. Normally, -G (SHOW_KWARGS[]) && return print_kwarg_opts(symbs, "NamedTuple | Tuple | Array | String | Number") ((val = find_in_dict(d, symbs, del)[1]) === nothing) && return cmd @@ -2758,7 +2761,7 @@ function add_opt_fill(@nospecialize(val), cmd::String="", opt::String="")::Stri end # --------------------------------------------------------------------------------------------------- -function get_cpt_set_R(d::Dict, cmd0::String, cmd::String, opt_R::String, got_fname::Int, arg1, arg2=nothing, arg3=nothing, prog::String="") +function get_cpt_set_R(d::Dict{Symbol,Any}, cmd0::String, cmd::String, opt_R::String, got_fname::Int, arg1, arg2=nothing, arg3=nothing, prog::String="") # Get CPT either from keyword input of from CURRENT_CPT. # Also puts -R in cmd when accessing grids from grdimage|view|contour, etc... (due to a GMT bug that doesn't do it) # Use CMD0 = "" to use this function from within non-grd modules @@ -2919,7 +2922,7 @@ function get_color(val::VecOrMat{<:Real})::String end # --------------------------------------------------------------------------------------------------- -function font(d::Dict, symbs)::String +function font(d::Dict{Symbol,Any}, symbs)::String ((val = find_in_dict(d, symbs)[1]) !== nothing) ? font(val) : "" end font(val::String)::String = val @@ -2971,7 +2974,8 @@ function data_type(val) end # --------------------------------------------------------------------------------------------------- -axis(nt::NamedTuple, D::Dict{Symbol,Any}=Dict{Symbol,Any}(); x::Bool=false, y::Bool=false, z::Bool=false, secondary::Bool=false) = axis(D; x=x, y=y, z=z, secondary=secondary, nt...) +axis(nt::NamedTuple, D::Dict{Symbol,Any}=Dict{Symbol,Any}(); x::Bool=false, y::Bool=false, z::Bool=false, secondary::Bool=false) = + axis(D; x=x, y=y, z=z, secondary=secondary, nt...) function axis(D::Dict{Symbol,Any}=Dict{Symbol,Any}(); x::Bool=false, y::Bool=false, z::Bool=false, secondary::Bool=false, kwargs...)::Tuple{String, Vector{Bool}} d = KW(kwargs) # These kwargs always come from the fields of a NamedTuple invokelatest(axis, D, x, y, z, secondary, d) @@ -3322,7 +3326,7 @@ function str_with_blancs(str)::String end # --------------------------------------------------------------------------------------------------- -vector_attrib(d::Dict, lixo) = vector_attrib(d) # When comming from add_opt() +vector_attrib(d::Dict{Symbol,Any}, lixo) = vector_attrib(d) # When comming from add_opt() vector_attrib(t::NamedTuple) = vector_attrib(Dict{Symbol,Any}(pairs(t))) function vector_attrib(; kwargs...)::String d = KW(kwargs) @@ -3400,11 +3404,10 @@ function vector_attrib(d::Dict{Symbol,Any})::String end # --------------------------------------------------------------------------------------------------- -#vector4_attrib(d::Dict, lixo=nothing) = vector4_attrib(; d...) # When comming from add_opt() -vector4_attrib(t::NamedTuple) = vector4_attrib(; t...) -function vector4_attrib(; kwargs...)::String +vector4_attrib(t::NamedTuple) = vector4_attrib(nt2dict(t)) +vector4_attrib(; kwargs...)::String = vector4_attrib(KW(kwargs)) +function vector4_attrib(d::Dict{Symbol,Any})::String # Old GMT4 vectors (still supported in GMT6) - d = KW(kwargs) cmd::String = "t" if ((val = hlp_desnany_str(d, [:align :center])) !== "") c::Char = val[1] @@ -3453,9 +3456,9 @@ end # --------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------- -decorated(nt::NamedTuple) = decorated(;nt...) -function decorated(;kwargs...)::String - d = KW(kwargs) +decorated(nt::NamedTuple) = decorated(nt2dict(nt)) +decorated(; kwargs...)::String = decorated(KW(kwargs)) +function decorated(d::Dict{Symbol,Any})::String cmd::String, optD::String = helper_decorated(d) if (haskey(d, :dec2)) # -S~ mode (decorated, with symbols, lines). @@ -3510,7 +3513,7 @@ end # --------------------------------------------------------- helper_decorated(nt::NamedTuple, compose=false) = helper_decorated(nt2dict(nt), compose) -function helper_decorated(d::Dict, compose=false) +function helper_decorated(d::Dict{Symbol,Any}, compose=false) # Helper function to deal with the gap and symbol size parameters. # At same time it's also what we need to call to build up the grdcontour -G option. cmd::String = ""; optD::String = "" @@ -3576,7 +3579,7 @@ function helper_decorated(d::Dict, compose=false) end # ------------------------------------------------- -function parse_quoted(d::Dict, opt)::String +function parse_quoted(d::Dict{Symbol,Any}, opt)::String # This function is isolated from () above to allow calling it seperately from grdcontour # In fact both -A and -G grdcontour options are almost equal to a decorated line in psxy. # So we need a mechanism to call it all at once (psxy) or in two parts (grdcontour). @@ -3619,7 +3622,7 @@ end # --------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------- -function fname_out(d::Dict, del::Bool=false) +function fname_out(d::Dict{Symbol,Any}, del::Bool=false) # Create a file name in the TMP dir when OUT holds only a known extension. The name is: GMT_user.ext EXT::String = FMT[]; fname::AbstractString = "" @@ -3665,7 +3668,7 @@ function fname_out(d::Dict, del::Bool=false) end # --------------------------------------------------------------------------------------------------- -function read_data(d::Dict, fname::String, cmd::String, arg, opt_R::String="", is3D::Bool=false, get_info::Bool=false) +function read_data(d::Dict{Symbol,Any}, fname::String, cmd::String, arg, opt_R::String="", is3D::Bool=false, get_info::Bool=false) # Use 'get_info=true' to force reading the file when fname != "" if (isa(arg, GMTfv) || isa(arg, Vector{GMTfv})) # A quick and dirty way to parse the GMTfv type @@ -3732,7 +3735,7 @@ function read_data_barr_1(d, arg_is_nothing::Bool) return arg end -function _read_data(d::Dict, cmd::String, arg, opt_R::String="", is3D::Bool=false, get_info::Bool=false, +function _read_data(d::Dict{Symbol,Any}, cmd::String, arg, opt_R::String="", is3D::Bool=false, get_info::Bool=false, opt_i::String="", opt_di::String="", opt_yx::String="")#::Tuple{String, Union{Nothing, GDtype}, String, Matrix{Float64}, String} # In case DATA holds a file name, read that data and put it in ARG # Also compute a tight -R if this was not provided. This forces reading a the `fname` file if provided. @@ -3863,7 +3866,7 @@ function _read_data(d::Dict, cmd::String, arg, opt_R::String="", is3D::Bool=fals end # --------------------------------------------------------------------------------------------------- -round_wesn(wesn::Array{Int}, geo::Bool=false, pad=zeros(2)) = round_wesn(float(wesn), geo, pad) +round_wesn(wesn::Array{Int}, geo::Bool=false, pad=zeros(2)) = round_wesn(Float64.(wesn), geo, pad) function round_wesn(wesn::Array{Float64, 2}, geo::Bool=false, pad=zeros(2))::Array{Float64, 2} # When input is an one row matix return an output of same size _wesn = vec(wesn) @@ -4036,7 +4039,7 @@ function is_gridtri(D)::Bool end # --------------------------------------------------------------------------------------------------- -function find_data(d::Dict, cmd0::String, cmd::String, args...) +function find_data(d::Dict{Symbol,Any}, cmd0::String, cmd::String, args...) # ... (SHOW_KWARGS[]) && return cmd, 0, nothing # In HELP mode we do nothing here @@ -4101,7 +4104,7 @@ function find_data(d::Dict, cmd0::String, cmd::String, args...) end # --------------------------------------------------------------------------------------------------- -function write_data(d::Dict, cmd::String)::String +function write_data(d::Dict{Symbol,Any}, cmd::String)::String # Check if we need to save to file (redirect stdout) if ((val = hlp_desnany_str(d, [:|>])) !== "") cmd = string(cmd, " > ", val) elseif ((val = hlp_desnany_str(d, [:write])) !== "") cmd = string(cmd, " > ", val) @@ -4111,7 +4114,7 @@ function write_data(d::Dict, cmd::String)::String end # --------------------------------------------------------------------------------------------------- -function common_grd(d::Dict, cmd0::String, cmd::String, prog::String, args...) +function common_grd(d::Dict{Symbol,Any}, cmd0::String, cmd::String, prog::String, args...) n_args = 0 for k = 1:numel(args) if (args[k] !== nothing) n_args += 1 end end # Drop the nothings if (n_args <= 1) cmd, got_fname, arg1 = find_data(d, cmd0, cmd, args[1]) @@ -4123,7 +4126,7 @@ function common_grd(d::Dict, cmd0::String, cmd::String, prog::String, args...) end # --------------------------------------------------------------------------------------------------- -function common_grd(d::Dict, cmd::String, args...) +function common_grd(d::Dict{Symbol,Any}, cmd::String, args...) # This chunk of code is shared by several grdxxx & other modules, so wrap it in a function IamModern[] && (cmd = replace(cmd, " -R " => " ")) (haskey(d, :Vd) && d[:Vd] > 2) && show_args_types(args...) @@ -4139,8 +4142,8 @@ function common_grd(d::Dict, cmd::String, args...) end # --------------------------------------------------------------------------------------------------- -dbg_print_cmd(d::Dict, cmd::String) = dbg_print_cmd(d, [cmd]) -function dbg_print_cmd(d::Dict, cmd::Vector{String}) +dbg_print_cmd(d::Dict{Symbol,Any}, cmd::String) = dbg_print_cmd(d, [cmd]) +function dbg_print_cmd(d::Dict{Symbol,Any}, cmd::Vector{String}) # Print the gmt command when the Vd>=1 kwarg was used. # In case of CONVERT_SYNTAX = true, just put the cmds in a global var 'cmds_history' used in movie @@ -4287,9 +4290,9 @@ end # --------------------------------------------------------------------------------------------------- # Use only to close PS fig and optionally convert/show -function showfig(; kwargs...) +showfig(; kwargs...) = showfig(KW(kwargs)) +function showfig(d::Dict{Symbol,Any}) helper_showfig4modern() && return nothing # If called from modern mode we are done here. - d = KW(kwargs) (!haskey(d, :show)) && (d[:show] = true) # The default is to show CTRL.limits .= 0.0; CTRL.proj_linear[1] = true; # Reset these for safety !isempty(LEGEND_TYPE[].optsDict) && (d[:legend] = dict2nt(LEGEND_TYPE[].optsDict)) # Recover opt settings @@ -4380,7 +4383,7 @@ function put_in_slot(cmd::String, opt::Char, args...) end # --------------------------------------------------------------------------------------------------- -function arg_in_slot(d::Dict, cmd::String, symbs::VMs, objtype, arg1, arg2) +function arg_in_slot(d::Dict{Symbol,Any}, cmd::String, symbs::VMs, objtype, arg1, arg2) # Either put the contents of an option in first empty arg? when it's a GMT type # or add it to cmd if it's a string (e.g., file name) or a number. if ((val = find_in_dict(d, symbs)[1]) !== nothing) @@ -4396,7 +4399,7 @@ function arg_in_slot(d::Dict, cmd::String, symbs::VMs, objtype, arg1, arg2) return cmd, arg1, arg2 end -function arg_in_slot(d::Dict, cmd::String, symbs::VMs, objtype, arg1, arg2, arg3) +function arg_in_slot(d::Dict{Symbol,Any}, cmd::String, symbs::VMs, objtype, arg1, arg2, arg3) if ((val = find_in_dict(d, symbs)[1]) !== nothing) cmd *= string(" -", symbs[1]) if (isa(val, objtype)) @@ -4410,7 +4413,7 @@ function arg_in_slot(d::Dict, cmd::String, symbs::VMs, objtype, arg1, arg2, arg3 return cmd, arg1, arg2, arg3 end -function arg_in_slot(d::Dict, cmd::String, symbs::VMs, objtype, arg1, arg2, arg3, arg4) +function arg_in_slot(d::Dict{Symbol,Any}, cmd::String, symbs::VMs, objtype, arg1, arg2, arg3, arg4) if ((val = find_in_dict(d, symbs)[1]) !== nothing) cmd *= string(" -", symbs[1])::String if (isa(val, objtype)) @@ -4474,7 +4477,7 @@ function finish_PS_module(d::Dict, cmd::Vector{String}, opt_extra::String, K::Bo end # --------------------------------------------------------------------------------------------------- -function _finish_PS_module(d::Dict, cmd::Vector{String}, opt_extra::String, K::Bool, O::Bool, finish::Bool, args::Vector{Any}) +function _finish_PS_module(d::Dict{Symbol,Any}, cmd::Vector{String}, opt_extra::String, K::Bool, O::Bool, finish::Bool, args::Vector{Any}) # FNAME_EXT hold the extension when not PS # OPT_EXTRA is used by grdcontour -D or pssolar -I to not try to create and view an img file @@ -4716,7 +4719,7 @@ end legend_bag() = legend_bag(Vector{String}(), Vector{String}(), Vector{String}(), "", Dict{Symbol,Any}(), 0) # -------------------------------------------------------------------------------------------------- -function put_in_legend_bag(d::Dict, cmd, arg, O::Bool=false, opt_l::String="") +function put_in_legend_bag(d::Dict{Symbol,Any}, cmd, arg, O::Bool=false, opt_l::String="") # So far this fun is only called from plot() and stores line/symbol info in a const global var LEGEND_TYPE _valLegend = find_in_dict(d, [:legend :l], false)[1] # false because we must keep it alive till digests_legend_bag() @@ -4980,7 +4983,7 @@ end #end # --------------------------------------------------------------------------------------------------- -function get_legend_font(d::Dict, fs=0; modern::Bool=false)::String +function get_legend_font(d::Dict{Symbol,Any}, fs=0; modern::Bool=false)::String # This fun gets the font size to be used in legends, but it serves two masters. On one side we want to keep the # legend defaults in modern mode (inside gmtbegin()) using the gmt.conf setings. For that pass FS=0 and MODERN=TRUE # On the other hand, from the GMT.jl classic-but-modern, the default (on calling this) is FS=8. @@ -5000,7 +5003,7 @@ function get_legend_font(d::Dict, fs=0; modern::Bool=false)::String end # --------------------------------------------------------------------------------------------------- -function set_defcpt!(d::Dict, cmd0::String, G) +function set_defcpt!(d::Dict{Symbol,Any}, cmd0::String, G) # When dealing with remote grids (those that start with a @), assign them a default CPT if (cmd0 != "") cptname = check_remote_cpt(cmd0) @@ -5039,7 +5042,7 @@ function check_remote_cpt(cmd0::String) end # --------------------------------------------------------------------------------------------------- -function common_get_R_cpt(d::Dict, cmd0::String, cmd::String, opt_R::String, got_fname::Int, arg1, arg2, arg3, prog::String) +function common_get_R_cpt(d::Dict{Symbol,Any}, cmd0::String, cmd::String, opt_R::String, got_fname::Int, arg1, arg2, arg3, prog::String) # Used by several proggys if (CONVERT_SYNTAX[]) # Here we cannot risk to execute any code. Just parsing. Movie stuff cmd, = add_opt_cpt(d, cmd, CPTaliases, 'C') @@ -5121,7 +5124,7 @@ function interp_vec(x::AbstractVecOrMat{<:Real}, val::Union{VecOrMat{<:Real}, Tu end # -------------------------------------------------------------------------------------------------- -function help_show_options(d::Dict) +function help_show_options(d::Dict{Symbol,Any}) if (find_in_dict(d, [:help])[1] !== nothing) SHOW_KWARGS[] = true end # Put in HELP mode end diff --git a/src/extras/mapsize2region.jl b/src/extras/mapsize2region.jl index 76e9d4735..67dba2576 100644 --- a/src/extras/mapsize2region.jl +++ b/src/extras/mapsize2region.jl @@ -45,9 +45,9 @@ function mapsize2region(; proj="", scale="", clon=NaN, clat=NaN, width=0, height @assert clon != NaN && clat != NaN "Center longitude and latitude must be specified" @assert width > 0 && height > 0 "Width and height must be positive" @assert contains(scale, ':') "Scale must be in the form of '1:xxxx'" - (!isa(proj, StrSymb)) && (proj = parse_J(Dict(:J => proj, :scale => scale), "")[1][4:end]; scale="") # scale is now in J - (bnds != "") && (bnds = parse_R(Dict(:R => bnds), "")[4:end]) # If bnds is not empty, parse it - (!isa(scale, StrSymb)) && (scale = parse_Scale(Dict(:S => scale), "")) # If scale is not a StrSymb, parse it + (!isa(proj, StrSymb)) && (proj = parse_J(Dict{Symbol,Any}(:J => proj, :scale => scale), "")[1][4:end]; scale="") # scale is now in J + (bnds != "") && (bnds = parse_R(Dict{Symbol,Any}(:R => bnds), "")[4:end]) # If bnds is not empty, parse it + (!isa(scale, StrSymb)) && (scale = parse_Scale(Dict{Symbol,Any}(:S => scale), "")) # If scale is not a StrSymb, parse it (bnds == "" && proj == "m" || startswith(proj, "merc") || startswith(proj, "Merc")) && (bnds="-180/180/-85/85") # Default bounds for Mercator opt_R, opt_J = mapsize2region(string(proj), scale, Float64(clon), Float64(clat), Float64(width), Float64(height), bnds) (plot != 0) && coast(R=opt_R, J=opt_J, shore=true, show=true, Vd=1) diff --git a/src/extras/seismicity.jl b/src/extras/seismicity.jl index 8b9be02e9..40d7d9dd3 100644 --- a/src/extras/seismicity.jl +++ b/src/extras/seismicity.jl @@ -136,7 +136,7 @@ function seismicity(; starttime::Union{DateTime, String}="", endtime::Union{Date plot!(D[:,1:4]; ml="faint", S=opt_S, C=C, show=see, Vd=Vd, d...) d = CTRL.pocket_d[1] d[:show] = show - ms = (_size !== nothing) ? parse_opt_S(Dict(:size => _size), [3., 4, 5, 6, 7, 8, 9])[1] : [3., 4, 5, 6, 7, 8, 9] .* 0.02 + ms = (_size !== nothing) ? parse_opt_S(Dict{Symbol,Any}(:size => _size), [3., 4, 5, 6, 7, 8, 9])[1] : [3., 4, 5, 6, 7, 8, 9] .* 0.02 st = (starttime != "") ? string(starttime) : string(Date(now() - Dates.Day(30))) et = (endtime != "") ? string(endtime) : string(Date(now())) legend && seislegend(; first=false, title="From "*st*" to "*et, cmap=C, mags=ms, pos="JBC+o0/1c+w12c/2.3c", d...) diff --git a/src/extras/weather.jl b/src/extras/weather.jl index 3a9bb2b00..01eeb98ae 100644 --- a/src/extras/weather.jl +++ b/src/extras/weather.jl @@ -264,7 +264,7 @@ function ecmwf(source::Symbol=:reanalysis; filename="", cb::Bool=false, dataset= last = (region == "") ? "\n" : ",\n" # Having an extra comma at the end of the line is a json syntax error params *= "\"download_format\": \"unarchived\"" * last if (region != "") # The region is provided by parse_R() as a string like " -R58/6/55/9" (N/W/S/E) - optR = split(parse_R(Dict(:R => region), "")[1], '/') + optR = split(parse_R(Dict{Symbol,Any}(:R => region), "")[1], '/') params *= "\"area\": [" * optR[1][4:end] * ", " * optR[4] * ", " * optR[2] * ", " * optR[3] * "]\n" end params = "{\"product_type\": [\"reanalysis\"],\n" * params * "}" diff --git a/src/gdal/gdal_tools.jl b/src/gdal/gdal_tools.jl index 0858193e3..8025d7b34 100644 --- a/src/gdal/gdal_tools.jl +++ b/src/gdal/gdal_tools.jl @@ -334,17 +334,19 @@ function gdalvectortranslate(indata, opts=String[]; dest="/vsimem/tmp", kwargs.. helper_run_GDAL_fun(gdalvectortranslate, indata, dest, opts, "", KW(kwargs)) end -function helper_run_GDAL_fun(f::Function, indata, dest::String, opts, method::String, d::Dict{Symbol, Any})::Union{GItype, GDtype, Gdal.AbstractDataset, Nothing} +function helper_run_GDAL_fun(f::Function, indata, dest::String, opts, method::String, d::Dict{Symbol, Any}) ressurectGDAL() # Another black-hole plug attempt. opts = gdal_opts2vec(opts) # Guarantied to return a Vector{String} - #d = KW(kwargs) + opts_vs = gdal_opts2vec(opts) # Guarantied to return a Vector{String} 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) + d_fun = Dict{Symbol, Function}(:fun => f) # To avoid fck compilation for each different fuction + _helper_run_GDAL_fun(d_fun, indata, dest, opts_vs, method, got_GMT_opts, d) end # --------------------------------------------------------------------------------------------------- -function _helper_run_GDAL_fun(f::Function, indata, dest::String, opts::Union{String, 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. +function _helper_run_GDAL_fun(d_fun::Dict{Symbol, Function}, @nospecialize(indata), dest::String, opts::Vector{String}, method::String, got_GMT_opts::Bool, d::Dict{Symbol, Any}) + # This second level helper function reduces the number of multiple compiles. + f = d_fun[:fun] # Get back the function name Vd::Int = ((val = find_in_dict(d, [:Vd])[1]) !== nothing) ? val : 0 # More gymns to avoid Anys (Vd > 0) && println(opts) @@ -459,7 +461,6 @@ function GMT_opts_to_GDAL(f::Function, opts::Vector{String}, d::Dict{Symbol, Any end end f == gdalgrid ? append!(opts, ["-txe", s[1], s[2], "-tye", s[3], s[4]]) : append!(opts, op) - #f == gdalgrid ? append!(opts, ["-txe", s[1], s[2], "-tye", s[3], s[4]]) : append!(opts, ["-projwin", split(opt_R[4:end], '/')[[1,4,2,3]]...]) # Ugly end x_srs = (f == gdaltranslate) ? "-a_srs" : "-t_srs" # But don't know if there are others that take -a_srs instead of -t_srs @@ -527,7 +528,7 @@ function default_gdopts!(f::Function, ds, opts::Vector{String}, dest::String) end # --------------------------------------------------------------------------------------------------- -function get_gdaldataset(data, opts, isVec::Bool=false)::Tuple{Gdal.AbstractDataset, Bool} +function get_gdaldataset(data, opts::Vector{String}, isVec::Bool=false)::Tuple{Gdal.AbstractDataset, Bool} # Get a GDAL dataset from either a file name, a GMT grid or image, or a dataset itself # In case of a file name we must be careful and deal with possible "+b" band requests from GMT. # isVec tells us if the filename 'data' is to be opened as a Vector or a Raster. @@ -540,11 +541,7 @@ function get_gdaldataset(data, opts, isVec::Bool=false)::Tuple{Gdal.AbstractData o = split(ext[ind[1]+2:end], ",") # But we must add 1 because GDAL band count is 1-based and GMT 0-based p = parse.(Int, o) .+ 1 o = [string(c) for c in p] - if (isa(opts, Vector{String})) - for k = 1:lastindex(o) append!(opts, ["-b", o[k]]) end - else - opts *= " -b" * join(o, " -b ") - end + for k = 1:lastindex(o) append!(opts, ["-b", o[k]]) end end flags = isVec ? GDAL_OF_VECTOR | GDAL_OF_VERBOSE_ERROR : GDAL_OF_READONLY | GDAL_OF_VERBOSE_ERROR _ext = lowercase(ext[2:end]) # Drop the leading dot too @@ -578,7 +575,7 @@ Convert a 24bit RGB image to 8bit paletted. """ function dither(indata, opts=String[]; n_colors::Integer=256, save::String="", gdataset::Bool=false) # ... - src_ds, needclose = get_gdaldataset(indata, "", false) + src_ds, needclose = get_gdaldataset(indata, String[], false) (nraster(src_ds) < 3) && error("Input image must have at least 3 bands") (isa(indata, GMTimage) && !startswith(indata.layout, "TRB")) && error("Image memory layout must be `TRB` and not $(indata.layout). Load image with gdaltranslate()") diff --git a/src/gdal_utils.jl b/src/gdal_utils.jl index f9909a685..006539583 100644 --- a/src/gdal_utils.jl +++ b/src/gdal_utils.jl @@ -957,7 +957,8 @@ Write a MxNxP `cube` object to disk as a multilayered file. """ function gdalwrite(fname::AbstractString, data, optsP=String[]; opts=String[], kw...) (fname == "") && error("Output file name is missing.") - (isempty(optsP) && !isempty(opts)) && (optsP = opts) # Accept either Positional or KW argument + (isempty(optsP) && !isempty(opts)) && (optsP = opts) # Accept either Positional or KW argument + isa(optsP, AbstractString) && (optsP = gdal_opts2vec(optsP)) # Guarantied to return a Vector{String} ds = Gdal.get_gdaldataset(data, optsP)[1] if (Gdal.GDALGetRasterCount(ds.ptr) >= 1) gdaltranslate(ds, optsP; dest=fname, kw...) diff --git a/src/gmt_types.jl b/src/gmt_types.jl index 6346733c4..678debde2 100644 --- a/src/gmt_types.jl +++ b/src/gmt_types.jl @@ -365,17 +365,20 @@ end mutable struct wrapGrids fname::String grd::GMTgrid + img::GMTimage function wrapGrids(arg1, arg2) - if (arg1 !== "") new(arg1, GMTgrid()) - elseif (isa(arg2, GMTgrid)) new("", arg2) - elseif (isa(arg2, Matrix{<:Real})) new("", mat2grid(arg2)) - elseif (arg1 === "" && arg2 === nothing) new("", GMTgrid()) # Less usual case in grdlandmask where only kwargs are given + tg, ti = GMTgrid(), GMTimage() + if (arg1 !== "") new(arg1, tg, ti) + elseif (isa(arg2, GMTgrid)) new("", arg2, ti) + elseif (isa(arg2, GMTimage)) new("", tg, arg2) + elseif (isa(arg2, Matrix{<:Real})) new("", mat2grid(arg2), ti) + elseif (arg1 === "" && arg2 === nothing) new("", tg, ti) # Less usual case in grdlandmask where only kwargs are given else error("Unknown types ($(typeof(arg1)), $(typeof(arg2))) in wrapGrids") end end end function unwrapGrids(w::wrapGrids) - return w.fname, !isempty(w.grd) ? w.grd : nothing + return w.fname, !isempty(w.grd) ? w.grd : !isempty(w.img) ? w.img : nothing end #= diff --git a/src/grdimage.jl b/src/grdimage.jl index eae29d36c..c28486a08 100644 --- a/src/grdimage.jl +++ b/src/grdimage.jl @@ -49,12 +49,14 @@ grdimage!(arg1, arg2=nothing, arg3=nothing; kw...) = grdimage_helper("", arg1, a function grdimage_helper(cmd0::String, arg1=nothing, arg2=nothing, arg3=nothing; first=true, kwargs...) d, K, O = init_module(first, kwargs...) # Also checks if the user wants ONLY the HELP mode (cmd0 != "" && arg1 === nothing && haskey(d, :inset)) && (arg1 = gmtread(cmd0); cmd0 = "") - grdimage_helper(cmd0, arg1, arg2, arg3, K, O, d) + (isa(arg1, Matrix{<:Real}) && isa(arg2, Matrix{<:Real}) && isa(arg3, Matrix{<:Real})) && + (arg2 = mat2grid(arg2); arg3 = mat2grid(arg3)) # Because than wrapGrids will convert arg1 to GMTgrid and other two must type agree + grdimage_helper(wrapGrids(cmd0, arg1), arg2, arg3, K, O, d) end # --------------------------------------------------------------------------------------------------- -#function grdimage(cmd0::String="", arg1=nothing, arg2=nothing, arg3=nothing; first=true, kwargs...) -function grdimage_helper(cmd0::String, arg1, arg2, arg3, K::Bool, O::Bool, d::Dict{Symbol, Any}) +function grdimage_helper(w::wrapGrids, arg2, arg3, K::Bool, O::Bool, d::Dict{Symbol, Any}) + cmd0, arg1 = unwrapGrids(w) common_insert_R!(d, O, cmd0, arg1) # Set -R in 'd' out of grid/images (with coords) if limits was not used @@ -84,10 +86,11 @@ function grdimage_helper(cmd0::String, arg1, arg2, arg3, K::Bool, O::Bool, d::Di (haskey(d, :stretch) || haskey(d, :histo_bounds)) && delete!(d, [:histo_bounds, :stretch]) end - _grdimage(cmd0, arg1, arg2, arg3, O, K, d) + _grdimage(wrapGrids(cmd0, arg1), arg2, arg3, O, K, d) end -function _grdimage(cmd0::String, arg1, arg2, arg3, O::Bool, K::Bool, d::Dict) +function _grdimage(w::wrapGrids, arg2, arg3, O::Bool, K::Bool, d::Dict{Symbol, Any}) + cmd0, arg1 = unwrapGrids(w) arg4 = nothing # For the r,g,b + intensity case diff --git a/src/imshow.jl b/src/imshow.jl index d439463d7..61e579082 100644 --- a/src/imshow.jl +++ b/src/imshow.jl @@ -180,7 +180,7 @@ function imshow(arg1::GItype; kw...) # This is a (poor) pach for a GMT bug that screws when plotting CPTs on the sides. margin = "0" if ((val = find_in_dict(d, [:colorbar], false)[1]) !== nothing) - tv = add_opt_module(Dict(:colorbar => val)) + tv = add_opt_module(Dict{Symbol,Any}(:colorbar => val)) t2 = scan_opt(tv[1], "-D") t2 = replace(t2, "JMR" => "JMC") !contains(t2, "+o") && (t2 *= "+o$(_w/2 + 0.3)/0") diff --git a/src/marker_name.jl b/src/marker_name.jl index 87c0d0b07..3f962542f 100644 --- a/src/marker_name.jl +++ b/src/marker_name.jl @@ -1,5 +1,5 @@ # Put this code in a separate file to permit access from future GMT_base module -function get_marker_name(d::Dict, arg1, symbs::Vector{Symbol}, is3D::Bool, del::Bool=true) +function get_marker_name(d::Dict, @nospecialize(arg1), symbs::Vector{Symbol}, is3D::Bool, del::Bool=true) marca::String = ""; N = 0 for symb in symbs if (haskey(d, symb)) @@ -118,7 +118,7 @@ function helper_markers(opt::String, ext, arg1::GMTdataset, N::Int, cst::Bool) if (size(ext,2) == N) # Here ARG1 is supposed to be a matrix that will be extended. S = Symbol(opt) t = arg1.data # Because we need to passa matrix to this method of add_opt() - marca, t = add_opt(add_opt, (Dict(S => (par=ext,)), opt, "", [S]), (par="|",), true, t) + marca, t = add_opt(add_opt, (Dict{Symbol,Any}(S => (par=ext,)), opt, "", [S]), (par="|",), true, t) arg1.data = t; add2ds!(arg1) elseif (cst && length(ext) == 1) marca = opt * "-" * string(ext)::String diff --git a/src/pcolor.jl b/src/pcolor.jl index 423edf25c..2b9e55864 100644 --- a/src/pcolor.jl +++ b/src/pcolor.jl @@ -211,7 +211,7 @@ function pcolor(G::GMTgrid, first::Bool, d::Dict{Symbol,Any}) if (find_in_dict(d, [:T :no_interp :tiles])[1] === nothing) # If no -T, make one here opt_T = "+s" if ((val = find_in_dict(d, [:outline])[1]) !== nothing) # -T+o is bugged for line styles - opt_T *= "+o" * add_opt_pen(Dict(:outline => val), [:outline]) + opt_T *= "+o" * add_opt_pen(Dict{Symbol,Any}(:outline => val), [:outline]) end d[:T] = opt_T end diff --git a/src/plot.jl b/src/plot.jl index e24c4b82e..2e24f05e5 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -840,8 +840,8 @@ function fill_between(arg1, arg2, first::Bool, d::Dict{Symbol, Any}) _D2 = one_array ? mat2ds(D1, (:,[1,3])) : D2 # Put second line in a unique var if (border > 0) # Plot a white border - one_array ? common_plot_xyz("", [mat2ds(D1, (:,[1,2])), _D2], "lines", false, false, Dict(:W => "$(border),white", :Vd => Vd)) : - common_plot_xyz("", [D1, _D2], "lines", false, false, Dict(:W => "$(border),white", :Vd => Vd)) + one_array ? common_plot_xyz("", [mat2ds(D1, (:,[1,2])), _D2], "lines", false, false, Dict{Symbol,Any}(:W => "$(border),white", :Vd => Vd)) : + common_plot_xyz("", [D1, _D2], "lines", false, false, Dict{Symbol,Any}(:W => "$(border),white", :Vd => Vd)) end do_stairs && (d[:stairs_step] = :pre) diff --git a/src/potential/gmtgravmag3d.jl b/src/potential/gmtgravmag3d.jl index 7c30a1f7b..68de894fb 100644 --- a/src/potential/gmtgravmag3d.jl +++ b/src/potential/gmtgravmag3d.jl @@ -80,9 +80,9 @@ function _gravmag3d_helper(arg1, d::Dict{Symbol,Any}) elseif ((val = find_in_dict(d, [:Ts :stl :STL], true, "String (file name)")[1]) !== nothing && val != "") opt = " -Ts" elseif ((val = find_in_dict(d, [:M :body], false, "String | NamedTuple")[1]) !== nothing && val != "") if (isa(val, Tuple)) - cmd = add_opt(Dict(:body => val[1]), cmd, "M", [:M :body], (shape="+s", params=",")) + cmd = add_opt(Dict{Symbol,Any}(:body => val[1]), cmd, "M", [:M :body], (shape="+s", params=",")) for n = 2:numel(val) - cmd = add_opt(Dict(:body => val[n]), cmd, "", [:M :body], (shape="+s", params=",")) + cmd = add_opt(Dict{Symbol,Any}(:body => val[n]), cmd, "", [:M :body], (shape="+s", params=",")) end delete!(d, [:M :body]) else diff --git a/src/pscoast.jl b/src/pscoast.jl index 35f2f3f54..69d4054e1 100644 --- a/src/pscoast.jl +++ b/src/pscoast.jl @@ -265,7 +265,7 @@ function parse_dcw(cmd::String, val::Tuple)::String for k = 1:numel(val) if (isa(val[k], NamedTuple) || isa(val[k], Dict)) isa(val[k], AbstractDict) && (val[k] = Base.invokelatest(dict2nt, val[k])) - cmd *= add_opt(Dict(:DCW => val[k]), "", "E", [:DCW], (country="", name="", continent="=", pen=("+p", add_opt_pen), + cmd *= add_opt(Dict{Symbol,Any}(:DCW => val[k]), "", "E", [:DCW], (country="", name="", continent="=", pen=("+p", add_opt_pen), fill=("+g", add_opt_fill), file=("+f"), inside=("_+c"), outside=("_+C"), adjust_r=("+r", arg2str), adjust_R=("+R", arg2str), adjust_e=("+e", arg2str), headers=("_+z"))) elseif (isa(val[k], Tuple)) cmd *= parse_dcw(val[k]) @@ -284,7 +284,7 @@ function parse_dcw(val::Tuple)::String else t *= string(val[2]) end if (length(val) > 2) - if (isa(val[3], Tuple)) t *= add_opt_fill("+g", Dict(fill => val[3]), [:fill]) + if (isa(val[3], Tuple)) t *= add_opt_fill("+g", Dict{Symbol,Any}(fill => val[3]), [:fill]) else t *= string(val[3]) end end diff --git a/src/pslegend.jl b/src/pslegend.jl index c750a818c..f00a42137 100644 --- a/src/pslegend.jl +++ b/src/pslegend.jl @@ -69,7 +69,7 @@ function legend(cmd0::String, arg1, O::Bool, K::Bool, d::Dict{Symbol, Any}) # Must also recreate a NT if any of 'fontsize' or 'font' is present in 'd' (because of how digests_legend_bag works) ((val = find_in_dict(d, [:fontsize])[1]) !== nothing) && (d[:leg] = (fontsize=val,)) ((val = find_in_dict(d, [:font])[1]) !== nothing) && (haskey(d, :leg) ? d[:leg] = (fontsize=d[:leg], font=val) : d[:leg] = (font=val,)) - ((val = find_in_dict(d, [:pos :position])[1]) !== nothing) && (LEGEND_TYPE[].optsDict = Dict(:pos => val)) + ((val = find_in_dict(d, [:pos :position])[1]) !== nothing) && (LEGEND_TYPE[].optsDict = Dict{Symbol,Any}(:pos => val)) digests_legend_bag(d) # It's over now, lets show up (or not) and return return (do_show || figname != "") ? showfig(show=do_show, savefig=figname) : nothing diff --git a/src/subplot.jl b/src/subplot.jl index 76e7c0d68..a6377b2bc 100644 --- a/src/subplot.jl +++ b/src/subplot.jl @@ -213,7 +213,7 @@ function mura_arg(arg)::Dict if (isa(arg, Tuple{Tuple, Real})) arg = (arg[1], (arg[2],)) end # This looks terribly type instable # Need first case because for example dims=(panels=((2,4),(2.5,5,1.25)),) shows up here only as # arg = ((2, 4), (2.5, 5, 1.25)) because this function was called from within add_opt() - if (isa(arg, Tuple{Tuple, Tuple})) d = Dict(:panels => arg) + if (isa(arg, Tuple{Tuple, Tuple})) d = Dict{Symbol,Any}(:panels => arg) else d = (isa(arg, NamedTuple)) ? nt2dict(arg) : arg end d diff --git a/src/trend1d.jl b/src/trend1d.jl index 0aa162940..fb42039f4 100644 --- a/src/trend1d.jl +++ b/src/trend1d.jl @@ -53,12 +53,12 @@ function trend1d(cmd0::String, arg1, d::Dict{Symbol, Any}) # can only be used once and in the last NT element. Hence, we must split execution in two parts. opt_N = " -N" for k = 1:length(val)-1 - t = add_opt(Dict(:N => val[k]), "", "N", [:N], + t = add_opt(Dict{Symbol,Any}(:N => val[k]), "", "N", [:N], (polynome=("p", arg2str, 1), polynomal=("p", arg2str, 1), fourier=("f", arg2str, 1), cosine=("c", arg2str, 1), sine=("s", arg2str, 1), single="_!")) contains(t, "!") && (t = replace(t, "!" => ""); t = replace(t, t[4] => uppercase(t[4]))) opt_N *= t[4:end] * "," end - t = add_opt(Dict(:N => val[end]), "", "N", [:N], + t = add_opt(Dict{Symbol,Any}(:N => val[end]), "", "N", [:N], (polynome=("p", arg2str, 1), polynomal=("p", arg2str, 1), fourier=("f", arg2str, 1), cosine=("c", arg2str, 1), sine=("s", arg2str, 1), length="+l", origin="+o", robust="+r", single="_!")) contains(t, "!") && (t = replace(t, "!" => ""); t = replace(t, t[4] => uppercase(t[4]))) opt_N *= t[4:end] diff --git a/src/utils_types.jl b/src/utils_types.jl index 3f50d3a45..edb07488b 100644 --- a/src/utils_types.jl +++ b/src/utils_types.jl @@ -2337,7 +2337,7 @@ function mat2grid(mat::Array{T,N}; reg=nothing, x=Float64[], y=Float64[], v=Floa geog = 1 (proj4 == "") && (proj4 = prj4WGS84) end - x, y, hdr, x_inc, y_inc = grdimg_hdr_xy(mat, reg_, hdr, x, y, is_transposed) + x, y, hdr, x_inc, y_inc = grdimg_hdr_xy(mat, reg_, vec(Float64.(hdr)), vec(Float64.(x)), vec(Float64.(y)), is_transposed) # Now we still must check if the method with no input MAT was called. In that case mat = [nothing val] # and the MAT must be finally computed. @@ -2442,18 +2442,17 @@ function grid2img(G::GMTgrid{<:Unsigned}) end # --------------------------------------------------------------------------------------------------- -function grdimg_hdr_xy(mat, reg::Int, hdr, x=Float64[], y=Float64[], is_transposed=false) +function grdimg_hdr_xy(@nospecialize(mat), reg::Int, hdr::Vector{Float64}, x::Vector{Float64}, y::Vector{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 + nx::Int = size(mat, col_dim); ny::Int = size(mat, row_dim) + 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) + mat_is_nothing = (ny == 1 && nx == 2 && mat[1] === nothing) + _grdimg_hdr_xy(reg, nx, ny, Float64(zmin), Float64(zmax), mat_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}) +function _grdimg_hdr_xy(reg::Int, nx::Int, ny::Int, zmin::Float64, zmax::Float64, mat_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 one_or_zero = reg == 0 ? 1 : 0 @@ -2487,7 +2486,7 @@ function _grdimg_hdr_xy(reg::Int, nx::Int, ny::Int, zmin::Float64, zmax::Float64 hdr = append!(hdr, [zmin, zmax, reg, x_inc, y_inc]) end one_or_zero = (hdr[7] == 0) ? 1 : 0 - if (mat1_is_nothing) + if (mat_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)) diff --git a/test/test_PSs.jl b/test/test_PSs.jl index 6b6daffda..5038b4284 100644 --- a/test/test_PSs.jl +++ b/test/test_PSs.jl @@ -229,10 +229,10 @@ ternary(d, R="0/100/0/100/0/100", B="afg", contour=(annot=20, cont=10), clockwis ternary(d, R="0/100/0/100/0/100", B="afg", contourf=true) ternary(d, R="0/100/0/100/0/100", B="afg", image=true, contour=true, Vd=dbg2) ternary() -d = Dict(:a=>"", :frame => (annot=:a, grid=8, alabel=:a, blabel=:b, clabel=:c, suffix=" %")); +d = Dict{Symbol,Any}(:a=>"", :frame => (annot=:a, grid=8, alabel=:a, blabel=:b, clabel=:c, suffix=" %")); GMT.parse_B4ternary!(d); @test d[:B] == " -Baag8+u\" %\"+la -Bbag8+u\" %\"+lb -Bcag8+u\" %\"+lc" -d = Dict(:a=>"", :labels => (:a, :b, :c)); +d = Dict{Symbol,Any}(:a=>"", :labels => (:a, :b, :c)); GMT.parse_B4ternary!(d); @test d[:B] == " -Baafg+la -Bbafg+lb -Bcafg+lc" diff --git a/test/test_common_opts.jl b/test/test_common_opts.jl index 9523906f3..5c94551e6 100644 --- a/test/test_common_opts.jl +++ b/test/test_common_opts.jl @@ -304,7 +304,7 @@ @test_throws ErrorException("Bad family type") GMT.GMT_Alloc_Segment(C_NULL, -1, 0, 0, "", C_NULL) #@test_throws ErrorException("Unknown family type") GMT.GMT_Create_Data(C_NULL, -99, 0, 0) @test_throws ErrorException("Expected a PS structure for input") GMT.ps_init(C_NULL, 0, 0) - @test_throws ErrorException("size of x,y vectors incompatible with 2D array size") GMT.grdimg_hdr_xy(rand(3,3), 0, Float64[], [1 2], [1]) + @test_throws ErrorException("size of x,y vectors incompatible with 2D array size") GMT.grdimg_hdr_xy(rand(3,3), 0, Float64[], [1.0, 2], [1.0]) GMT.strncmp("abcd", "ab", 2) GMT.parse_proj((name="blabla",center=(0,0)))