Skip to content

Commit 8fed54b

Browse files
authored
Let the extracted DCW countries have 2 attributes: CODE and NAME. (#1790)
* Let the extracted DCW countries have 2 attributes: CODE and NAME. * Let also extract country states and assigned attribs. Fix in unique detection (when only one group) * Fix typo
1 parent f7627dc commit 8fed54b

4 files changed

Lines changed: 24 additions & 7 deletions

File tree

src/gmt_main.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -624,8 +624,11 @@ function get_dataset(API::Ptr{Nothing}, object::Ptr{Nothing})::GDtype
624624
if (!isempty(POSTMAN[1]))
625625
min_pts = (get(POSTMAN[1], "minpts", "") != "") ? parse(Int, POSTMAN[1]["minpts"]) - 1 : 0
626626
(min_pts > 0) && delete!(POSTMAN[1], "minpts")
627-
DCWnames = (get(POSTMAN[1], "DCWnames", "") != "") ? true : false # If DCW country names will turn into attribs
628-
(DCWnames) && delete!(POSTMAN[1], "DCWnames")
627+
if ((t = get(POSTMAN[1], "DCWnames", "")) != "") # If DCW country names will turn into attribs
628+
codelen = parse(Int, t)
629+
delete!(POSTMAN[1], "DCWnames")
630+
end
631+
DCWnames = (t !== "") ? true : false
629632
plusZzero = (get(POSTMAN[1], "plusZzero", "") != "") ? true : false # To eventually add an extra column with 0's
630633
(plusZzero) && delete!(POSTMAN[1], "plusZzero")
631634
else
@@ -687,7 +690,7 @@ function get_dataset(API::Ptr{Nothing}, object::Ptr{Nothing})::GDtype
687690
Darr[seg_out].header = hdrstr
688691
else
689692
(DCWnames && (ind = findfirst(" Segment", hdrstr)) !== nothing) &&
690-
(Darr[seg_out].attrib["NAME"] = hdrstr[2:ind[1]-1])
693+
(Darr[seg_out].attrib["CODE"] = hdrstr[4:4+codelen-1]; Darr[seg_out].attrib["NAME"] = hdrstr[7+codelen-2:ind[1]-1])
691694
end
692695
end
693696
if (seg == 1)

src/pscoast.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ function _coast(cmd0::String, O::Bool, K::Bool, clip::String, d::Dict)
9494
cmd = add_opt(d, "", "M", [:M :dump])
9595
have_opt_M = (cmd != "")
9696
cmd = parse_E_coast(d, [:E, :DCW], cmd) # Process first to avoid warning about "guess"
97+
twoORfour = have_opt_M && contains(cmd, "+z") && contains(cmd, '.') ? "4" : "2" # To use in gmt_main to decide CODE attrib
9798
if (cmd != "") # Check for a minimum of points that segments must have
9899
if ((val = find_in_dict(d, [:minpts])[1]) !== nothing) POSTMAN[1]["minpts"] = string(val)::String
99100
elseif (get(POSTMAN[1], "minpts", "") != "") delete!(POSTMAN[1], "minpts")
@@ -104,7 +105,7 @@ function _coast(cmd0::String, O::Bool, K::Bool, clip::String, d::Dict)
104105
toTrack::Union{String, GMTgrid} = ""
105106
if (have_opt_M)
106107
O = true
107-
POSTMAN[1]["DCWnames"] = "s" # When dumping, we want to add the country name as attribute
108+
POSTMAN[1]["DCWnames"] = twoORfour # When dumping, we want to add the country name as attribute
108109
if ((val = find_in_dict(d, [:Z])[1]) !== nothing)
109110
toTrack = (isa(val, GMTgrid) || (isa(val, String) && length(val) > 4)) ? val : ""
110111
toTrack == "" && (POSTMAN[1]["plusZzero"] = "y")# If toTrack the extra column is added by the grdtrack call below
@@ -213,12 +214,13 @@ end
213214
function parse_E_coast(d::Dict, symbs::Vector{Symbol}, cmd::String)
214215
(SHOW_KWARGS[1]) && return print_kwarg_opts(symbs, "NamedTuple | Tuple | Dict | String")
215216
if ((val = find_in_dict(d, symbs, false)[1]) !== nothing)
216-
if (isa(val, String) || isa(val, Symbol)) # Simple case, ex E="PT,+gblue" or E=:PT
217+
if (isa(val, StrSymb)) # Simple cases, ex E="PT,+gblue" or E=:PT
217218
t::String = string(" -E", val)
218219
startswith(t, " -EWD") && (t = " -E=" * t[4:end]) # Let E="WD" work
219220
(t == " -E") && (delete!(d, [:E, :DCW]); return cmd) # This lets use E="" like earthregions may do
220221
(!contains(cmd, " -M") && is_in_dict(d, [:R :region :limits :region_llur :limits_llur :limits_diag :region_diag]) === nothing) &&
221222
(d[:R] = t[4:end]) # Must also see what to do for the other elseif branches
223+
contains(cmd, " -M") && !contains(t, "+") && (t *= "+z")# If Dump always add country names as attribs
222224
!contains(t, "+") && (t *= "+p0.5") # If only code(s), append pen
223225
cmd *= t
224226
elseif (isa(val, NamedTuple) || isa(val, AbstractDict))

src/spatial_funs.jl

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,9 @@ NOTE: Instead of ``getbyattrib`` one case use instead ``filter`` (...,`index=fal
184184
a bit special and is meant to be used when more than one polygon share the same attribute value (e.g. countries with islands).
185185
In that case, set the value of `_unique` to the name of the attribute that is shared by the polygons (e.g. `_unique="NAME"`).
186186
By default (e.g. `_unique=true`), the attribute name is `Feature_ID` which is the one used by GMT when creating unique
187-
IDs for polygons read from OGR formats (.shp, .geojson, etc). The uniqueness is determined by selecting the polygon
187+
IDs for polygons read from OGR formats (.shp, .geojson, etc). If this attrib name is not found, we search for `CODE` which is
188+
the one assigned by GMT when extracting polygons from the internal GMT coasts database. If none of these is found,
189+
it is users responsibility to provide a valid attribute name. The uniqueness is determined by selecting the polygon
188190
with the largest area.
189191
190192
- `invert, or reverse, or not`: If `true` return all segments that do NOT match the query condition(s).
@@ -245,6 +247,9 @@ function getbyattrib(D::Vector{<:GMTdataset}, ind_::Bool; kw...)::Vector{Int}
245247
if (atts[kk] == "_unique")
246248
# If we can't parse the arg as a number then it must be an attribute name. If not, an error will be raised later.
247249
(vals[kk] != "true" && (tryparse(Int, vals[kk]) === nothing) && (tryparse(Float64, vals[kk]) === nothing)) && (attrib_name = vals[kk])
250+
if (get(D[1].attrib, attrib_name, "") === "")
251+
attrib_name = (get(D[1].attrib, "CODE", "") !== "") ? "CODE" : error("Attribute name '$attrib_name' or 'CODE' not found in dataset.")
252+
end
248253
vals[kk] = "0" # If _unique the value doesn't matter but must be parseable to float
249254
end
250255
kk += 1
@@ -276,13 +281,19 @@ function getbyattrib(D::Vector{<:GMTdataset}, ind_::Bool; kw...)::Vector{Int}
276281
((ind_name = findfirst(att_names .== name)) === nothing) && error("Attribute name $name not found in dataset.")
277282
_, ind = gunique(att_tbl[:,ind_name])
278283
for k = 1:numel(ind) _tf[ind[k]] = true end # Set the unique values to true.
284+
285+
if (numel(ind) == 1) # The single group case is simpler but must be dealt separately.
286+
_tf[1] = false; _tf[argmax(areas_)] = true
287+
return _tf
288+
end
289+
279290
k = 1
280291
while (k <= numel(ind)-1)
281292
((ind[k+=1] - ind[k-1]) == 1) && continue
282293
n_start, n_end = ind[k - 1], ind[k] - 1
283294
# Here we have a group (from n_start to n_end) of the same type of attribute
284295
this_ind = argmax(view(areas_,n_start:n_end,1)) + n_start - 1 # Get the index of the largest area
285-
_tf[n_start], _tf[this_ind] = false, true # Turn off the first and turn on the largest of this group
296+
_tf[n_start], _tf[this_ind] = false, true # Turn off the first and turn on the largest of this group
286297
end
287298
_tf
288299
end

test/test_B-GMTs.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@
148148
@test gmtselect([1 2], C="aa+d0", Vd=dbg2) == "gmtselect -Caa+d0"
149149
@test gmtselect([1 2], C=(pts=[1 2],dist=10), L=(line=[1 2;3 4], dist=10), Vd=dbg2) == "gmtselect -C+d10 -L+d10"
150150
cl = coast(dump=:true, res=:c, region=:global);
151+
@test length(coast(M=true, DCW="WD+z")) > 0
151152
cc = GMT.clipbyrect(cl, (-180,0,-90,90));
152153

153154
println(" GMTSET")

0 commit comments

Comments
 (0)