Skip to content

Commit f6bbbb4

Browse files
authored
Merge pull request #1981 from GenericMappingTools/fix-core-boxes
Fix Core.Boxes and labellines simplifications.
2 parents 1e7258c + bc8501d commit f6bbbb4

6 files changed

Lines changed: 42 additions & 45 deletions

File tree

src/gadm.jl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,24 +89,17 @@ function gadm(country, subregions...; children::Bool=false, names::Bool=false, c
8989
error("Asked data for a level ($(plevel+1)) that is lower than lowest data level ($(_nlayers))")
9090
end
9191

92-
function _get_attrib(feature)
93-
n = Gdal.nfield(feature)
94-
attrib = DictSvS()
95-
[attrib[Gdal.getname(Gdal.getfielddefn(feature, i))] = string(Gdal.getfield(feature, i)) for i = 0:n-1]
96-
attrib
97-
end
98-
9992
function _get_polygs(gdfeature)
10093
D = gd2gmt(getgeom(gdfeature[1], 0),"")
10194
isa(D, GMTdataset) && (D = [D]) # Hopefully not too wasteful but it simplifies a lot the whole algo
102-
att = _get_attrib(gdfeature[1])
95+
att = helper_get_attrib(gdfeature[1])
10396
for k = 1:numel(D) D[k].attrib = att; D[k].colnames = ["Lon", "Lat"] end
104-
D[1].attrib = _get_attrib(gdfeature[1])
97+
D[1].attrib = helper_get_attrib(gdfeature[1])
10598
((prj = getproj(Gdal.getlayer(data, 0))) != C_NULL) && (D[1].proj4 = toPROJ4(prj))
10699
for n = 2:numel(gdfeature)
107100
_D = gd2gmt(getgeom(gdfeature[n], 0),"")
108101
isa(_D, GMTdataset) && (_D = [_D])
109-
att = _get_attrib(gdfeature[n])
102+
att = helper_get_attrib(gdfeature[n])
110103
for k = 1:numel(_D) _D[k].attrib = att; _D[k].colnames = ["Lon", "Lat"] end
111104
append!(D, _D)
112105
end
@@ -141,6 +134,13 @@ function gadm(country, subregions...; children::Bool=false, names::Bool=false, c
141134
end
142135
end
143136

137+
function helper_get_attrib(feature)
138+
n = Gdal.nfield(feature)
139+
attrib = DictSvS()
140+
[attrib[Gdal.getname(Gdal.getfielddefn(feature, i))] = string(Gdal.getfield(feature, i)) for i = 0:n-1]
141+
attrib
142+
end
143+
144144
# ------------------------------------------------------------------------------------------------------
145145
# Tells whether or not `str` is a valid ISO 3166 Alpha 3 country code. Valid code examples are "IND", "USA", "BRA".
146146
isvalidcode(str) = match(r"\b[A-Z]{3}\b", str) !== nothing

src/legend_funs.jl

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -444,9 +444,9 @@ function _best_label_pos(D::Vector{<:GMTdataset}, labels::Vector{String}, nc::In
444444
end
445445

446446
# Text half-dimensions in cm
447-
pt2cm = 2.54 / 72
448-
char_w = 0.55 * fontsize * pt2cm
449-
char_h = fontsize * pt2cm
447+
fs = fontsize * 2.54 / 72
448+
char_w = 0.55 * fs
449+
char_h = fs
450450
hws = [length(l) * char_w / 2 for l in labels] # half-width per label
451451
hh = char_h * 0.9 # half-height (shared)
452452

@@ -820,7 +820,7 @@ Called from `_common_plot_xyz()` when the `labellines` keyword is used.
820820
- `val` can be a `Vector{<:AbstractString}` with one label per curve, or a NamedTuple with fields
821821
`labels` (required), `fontsize` (default 8), and `prefer` (`:begin`, `:middle`, or `:end`; default `:middle`).
822822
"""
823-
function add_labellines!(curves, d::Dict{Symbol,Any}, _cmd::Vector{String})
823+
function add_labellines!(curves, d::Dict{Symbol,Any}, _cmd::Vector{String})::Nothing
824824
val = find_in_dict(d, [:labellines])[1]
825825
if isa(val, Vector{<:AbstractString})
826826
labels = [string(l) for l in val]
@@ -835,7 +835,7 @@ function add_labellines!(curves, d::Dict{Symbol,Any}, _cmd::Vector{String})
835835
else
836836
_add_labellines(curves, _cmd, labels, 8, :middle)
837837
end
838-
return curves
838+
return nothing
839839
end
840840
# NamedTuple path — dispatch to the right inner function based on which options are set
841841
dd = nt2dict(val)
@@ -845,7 +845,7 @@ function add_labellines!(curves, d::Dict{Symbol,Any}, _cmd::Vector{String})
845845
if get(dd, :outside, false) == true
846846
text_cmd = _inject_outside_labels!(d, curves, labels, fnt, _cmd)
847847
push!(_cmd, text_cmd)
848-
return curves
848+
return nothing
849849
end
850850
xv = get(dd, :xvals, nothing)
851851
yv = get(dd, :yvals, nothing)
@@ -855,10 +855,10 @@ function add_labellines!(curves, d::Dict{Symbol,Any}, _cmd::Vector{String})
855855
_yv::Vector{Float64} = yv === nothing ? Float64[] : isa(yv, Real) ? fill(Float64(yv), nc) : Float64.(yv)
856856
pos = _label_pos_at_vals(curves, nc, _xv, _yv)
857857
_add_labellines_apply(curves, _cmd, labels, fnt, pos)
858-
return curves
858+
return nothing
859859
end
860860
_add_labellines(curves, _cmd, labels, fnt, prefer)
861-
return curves
861+
return nothing
862862
end
863863

864864
function _add_labellines(arg1::Vector{<:GMTdataset}, _cmd::Vector{String}, labels::Vector{String}, fontsize::Int, prefer::Symbol)
@@ -908,11 +908,7 @@ function _outside_label_data(D::Vector{<:GMTdataset}, labels::Vector{String}, fo
908908
(ymax - ymin) < 1e-10 && (ymin -= 0.5; ymax += 0.5) # degenerate range fallback
909909

910910
# x positions: at the right edge of the plot region so labels start just beyond the axis
911-
if CTRL.limits[7] != 0
912-
xmax = CTRL.limits[8]
913-
else
914-
_, xmax, _, _ = getregion(D)
915-
end
911+
xmax = (CTRL.limits[7] != 0) ? CTRL.limits[8] : getregion(D)[2]
916912
xs = Vector{Float64}(undef, nc)
917913
ys = Vector{Float64}(undef, nc)
918914
colors = Vector{String}(undef, nc)
@@ -925,8 +921,7 @@ function _outside_label_data(D::Vector{<:GMTdataset}, labels::Vector{String}, fo
925921
# Repel overlapping labels vertically
926922
pw, ph = _get_plotsize()
927923
sy = ph / (ymax - ymin)
928-
pt2cm = 2.54 / 72
929-
label_h = fontsize * pt2cm * 1.4 # label height in cm with some padding
924+
label_h = fontsize * 2.54 / 72 * 1.4 # label height in cm with some padding
930925
min_sep = label_h / sy # minimum separation in data units
931926

932927
order = sortperm(ys)
@@ -1012,9 +1007,9 @@ function text_repel(points, labels::Vector{<:AbstractString}; fontsize::Int=10,
10121007
ay = (py .- ymin) .* sy
10131008

10141009
# Text box half-dimensions in cm (with padding)
1015-
pt2cm = 2.54 / 72
1016-
char_w = 0.55 * fontsize * pt2cm
1017-
char_h = fontsize * pt2cm
1010+
fs = fontsize * 2.54 / 72
1011+
char_w = 0.55 * fs
1012+
char_h = fs
10181013
pad = Float64(padding)
10191014
hws = [length(l) * char_w / 2 + pad for l in labels]
10201015
hhs = fill(char_h / 2 + pad, n)

src/psxy.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ function _common_plot_xyz(w::wrapDatasets, caller::String, O::Bool, K::Bool, is3
241241

242242
if haskey(d, :labellines)
243243
_cmd = gmt_proggy .* _cmd # In any case we need this
244-
arg1 = add_labellines!(arg1, d, _cmd)
244+
add_labellines!(arg1, d, _cmd)
245245
else
246246
(!IamModern[]) && put_in_legend_bag(d, _cmd, arg1, O, opt_l)
247247
_cmd = gmt_proggy .* _cmd

src/rasterpolygonfuns.jl

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,6 @@ function rasterzones!(GI::GItype, shapes::GDtype, fun::Function; isRaster=true,
5151
function within(bbox_p::Vector{Float64}, bbox_R::Vector{Float64}) # Check if the polygon BB is contained inside the image's region.
5252
bbox_p[1] >= bbox_R[1] && bbox_p[2] <= bbox_R[2] && bbox_p[3] >= bbox_R[3] && bbox_p[4] <= bbox_R[4]
5353
end
54-
function maskit(GI_, mask, band)
55-
t = (band > 0) ? skipnan(GI_[mask, band]) : skipnan(GI_[mask])
56-
return (eltype(GI_) <: Integer) ? round(eltype(GI_), fun(t)) : fun(t)
57-
end
5854
function get_the_mask(D, nx, ny, touches, layout)::Union{Nothing, Matrix{Bool}}
5955
# Compute the mask matrix
6056
local mask
@@ -71,11 +67,11 @@ function rasterzones!(GI::GItype, shapes::GDtype, fun::Function; isRaster=true,
7167
end
7268
function mask_GI!(GI, _GI, pix_x, pix_y, mask, n_layers) # Apply the mask to a Grid/Image
7369
if (n_layers == 1)
74-
_GI[mask] .= maskit(_GI, mask, 0)
70+
_GI[mask] .= helper_maskit(_GI, mask, 0, fun)
7571
GI[pix_y[1]:pix_y[2], pix_x[1]:pix_x[2]] = _GI
7672
else
7773
for n = 1:n_layers
78-
_GI[mask, n] .= maskit(_GI, mask, n)
74+
_GI[mask, n] .= helper_maskit(_GI, mask, n, fun)
7975
GI[pix_y[1]:pix_y[2], pix_x[1]:pix_x[2], n] = _GI[:,:,n]
8076
end
8177
end
@@ -101,7 +97,7 @@ function rasterzones!(GI::GItype, shapes::GDtype, fun::Function; isRaster=true,
10197
((mask = get_the_mask(Dt, size(_GI, col_dim), size(_GI, row_dim), touches, layout)) === nothing) && continue
10298

10399
if (isRaster) mask_GI!(GI, _GI, pix_x, pix_y, mask, n_layers)
104-
else for n = 1:n_layers mat[k,n] = maskit(_GI, mask, n-1) end
100+
else for n = 1:n_layers mat[k,n] = helper_maskit(_GI, mask, n-1, fun) end
105101
end
106102
end
107103
else # Compute the result (stats or raster) on a per polygon basis
@@ -116,14 +112,20 @@ function rasterzones!(GI::GItype, shapes::GDtype, fun::Function; isRaster=true,
116112
((mask = get_the_mask(shapes[k], size(_GI, col_dim), size(_GI, row_dim), touches, layout)) === nothing) && continue
117113

118114
if (isRaster) mask_GI!(GI, _GI, pix_x, pix_y, mask, n_layers)
119-
else for n = 1:n_layers mat[k,n] = maskit(_GI, mask, n-1) end
115+
else for n = 1:n_layers mat[k,n] = helper_maskit(_GI, mask, n-1, fun) end
120116
end
121117
end
122118
names = String[] # We need something to return
123119
end
124120
return isRaster ? nothing : (mat, names)
125121
end
126122

123+
function helper_maskit(GI_, mask, band, fun::Function)
124+
# Move it out of a nested fun because it was Core.Boxed when called from another nested
125+
t = (band > 0) ? skipnan(GI_[mask, band]) : skipnan(GI_[mask])
126+
return (eltype(GI_) <: Integer) ? round(eltype(GI_), fun(t)) : fun(t)
127+
end
128+
127129
# ---------------------------------------------------------------------------------------------------
128130
"""
129131
GI = rasterzones(GI::GItype, shapes::GDtype, fun::Function; touches=false)

src/utils_types.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,8 +1059,8 @@ function df2ds(arg)::GMTdataset
10591059
if (isempty(col_time_names)) # Simple case, no time columns
10601060
D = mat2ds(mat, colnames=colnames)
10611061
else # We have time columns. Need to convert them to unix time AND insert them in the matrix 'mat'
1062-
colnames = [i for i in names(arg) if Base.nonmissingtype(eltype(arg[!,i])) <: Union{Real, TimeType}] # all of the names
1063-
inds_time = [findfirst(col_time_names[k] .== colnames) for k = 1:numel(col_time_names)]
1062+
colnames2 = [i for i in names(arg) if Base.nonmissingtype(eltype(arg[!,i])) <: Union{Real, TimeType}] # all of the names
1063+
inds_time = [findfirst(col_time_names[k] .== colnames2) for k = 1:numel(col_time_names)]
10641064
new_mat = Matrix{Float64}(undef, size(mat, 1), size(mat, 2) + numel(inds_time))
10651065
new_inds = zeros(Int, size(mat, 2) + numel(inds_time))
10661066
for k = 1:numel(inds_time) # Insert the time columns first.

test/test_labellines.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,19 +105,19 @@ d12 = Dict{Symbol,Any}(:labellines => ["sin", "cos"]);
105105
cmd12 = ["psxy -R0/10/-1.5/1.5 -JX15c/10c -Baf -BWSen"];
106106
Dl2 = GMT.add_labellines!(Dl, d12, cmd12);
107107
@test occursin("-Sq", cmd12[1])
108-
@test occursin("-Sql", Dl2[1].header)
109-
@test occursin("sin", Dl2[1].header)
110-
@test occursin("cos", Dl2[2].header)
108+
@test occursin("-Sql", Dl[1].header)
109+
@test occursin("sin", Dl[1].header)
110+
@test occursin("cos", Dl[2].header)
111111
# Line colors should appear in the -Sq font spec
112-
@test occursin("red", Dl2[1].header)
112+
@test occursin("red", Dl[1].header)
113113

114114
# 13) add_labellines! with xvals via NamedTuple
115115
Dl3 = [mat2ds(hcat(x, sin.(x)), header="-W1,red"), mat2ds(hcat(x, cos.(x)), header="-W1,blue")]
116116
d13 = Dict{Symbol,Any}(:labellines => (labels=["sin", "cos"], xvals=5.0))
117117
cmd13 = ["psxy -R0/10/-1.5/1.5 -JX15c/10c -Baf -BWSen"]
118-
Dl3b = GMT.add_labellines!(Dl3, d13, cmd13)
118+
GMT.add_labellines!(Dl3, d13, cmd13)
119119
@test occursin("-Sq", cmd13[1])
120-
@test occursin("sin", Dl3b[1].header)
120+
@test occursin("sin", Dl3[1].header)
121121

122122
# 14) add_labellines! replaces previous -Sq (not appends)
123123
Dl4 = [mat2ds(hcat(x, sin.(x)), header="-W1,red -Sql1/2/3/4:+l\"old\"+f8p+v")]

0 commit comments

Comments
 (0)