Skip to content

Commit dcc4f05

Browse files
authored
Rework the 3D bodies code to work with the new GMTfv type. (#1559)
* Remove temporary wrappers. * Identify the new GMTfv type * When buffergeo is given single point, don't try to do distance to line. * Remove the now obsolete isFV function * DEclare and export the new GMTfv type. * Chande the dataset_init_FV to deal with the new GMTfv type * Add fv2fv function and methods to create instances of GMTfv * Be aware of GMTfv types * Return the solids as GMTfv types. * Rework the 3D bodies code to work with the new GMTfv type.
1 parent c28660a commit dcc4f05

File tree

12 files changed

+158
-107
lines changed

12 files changed

+158
-107
lines changed

src/GMT.jl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ if isdefined(Base, :Experimental) && isdefined(Base.Experimental, Symbol("@optle
112112
end
113113

114114
export
115-
GMTgrid, GMTimage, GMTdataset, GMTcpt, GItype, GDtype, GMTver, FMT, TMPDIR_USR, gmt, libgdal,
115+
GMTgrid, GMTimage, GMTdataset, GMTfv, GMTcpt, GItype, GDtype, GMTver, FMT, TMPDIR_USR, gmt, libgdal,
116116
arrows, arrows!, bar, bar!, bar3, bar3!, band, band!, bubblechart, bubblechart!, feather, feather!, hband, hband!,
117117
hlines, hlines!, lines, lines!, legend, legend!, quiver, quiver!, radar, radar!, stairs, stairs!, stem, stem!,vlines,
118118
vlines!, vband, vband!, hspan, hspan!, vspan, vspan!,
@@ -186,8 +186,7 @@ export
186186

187187
cube, dodecahedron, icosahedron, sphere, octahedron, tetrahedron, replicant,
188188

189-
df2ds, ODE2ds,
190-
sprintf,
189+
df2ds, ds2df, ODE2ds,
191190
@?, @dir
192191

193192
include("common_docs.jl")

src/common_options.jl

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3643,6 +3643,14 @@ end
36433643
# ---------------------------------------------------------------------------------------------------
36443644
function read_data(d::Dict, fname::String, cmd::String, arg, opt_R::String="", is3D::Bool=false, get_info::Bool=false)
36453645
# Use 'get_info=true' to force reading the file when fname != ""
3646+
3647+
if (isa(arg, GMTfv)) # A quick and dirty way to parse the GMTfv type
3648+
is_geo = isgeog(arg.proj4) # MUST make isgeog sniff in GMTfv types
3649+
_wesn = round_wesn(arg.bbox, is_geo) # Add a pad if not-tight
3650+
opt_R = @sprintf(" -R%.12g/%.12g/%.12g/%.12g/%.12g/%.12g", _wesn[1], _wesn[2], _wesn[3], _wesn[4], _wesn[5], _wesn[6])
3651+
return cmd * opt_R, arg, opt_R, _wesn, "" # A GMTfv is already read
3652+
end
3653+
36463654
cmd::String, opt_i::String = parse_i(d, cmd) # If data is to be read with some column order
36473655
cmd, opt_bi::String = parse_bi(d, cmd) # If data is to be read as binary
36483656
cmd, opt_di::String = parse_di(d, cmd) # If data missing data other than NaN
@@ -3660,7 +3668,7 @@ function read_data(d::Dict, fname::String, cmd::String, arg, opt_R::String="", i
36603668
if (opt_yx != "" && !isempty(arg.colnames)) arg.colnames[2], arg.colnames[1] = arg.colnames[1], arg.colnames[2] end
36613669
# Try guess if ascii file has time columns and if yes leave trace of it in GMTdadaset metadata.
36623670
(opt_bi == "") && file_has_time!(fname, arg) # If fname is a .gmt file this does not make much sense.
3663-
# Remove the these options from cmd. Their job is done
3671+
# Remove these options from cmd. Their job is done
36643672
if (opt_i != "") cmd = replace(cmd, opt_i => ""); opt_i = "" end
36653673
if (opt_h != "") cmd = replace(cmd, opt_h => ""); opt_h = "" end
36663674
else # No need to find -R so let the GMT module read the file
@@ -3714,9 +3722,9 @@ function _read_data(d::Dict, cmd::String, arg, opt_R::String="", is3D::Bool=fals
37143722

37153723
have_info = false
37163724
no_R = (opt_R == "" || opt_R[1] == '/' || opt_R == " -Rtight")
3717-
prj::String = (isGMTdataset(arg)) ? getproj(arg, proj4=true) : ""
3725+
prj::String = (isa(arg, GDtype)) ? getproj(arg, proj4=true) : ""
37183726
is_geo = isgeog(prj)
3719-
ds_bbox = isGMTdataset(arg) ? (isa(arg, GMTdataset) ? arg.ds_bbox : arg[1].ds_bbox) : Float64[]
3727+
ds_bbox = isa(arg, GDtype) ? (isa(arg, GMTdataset) ? arg.ds_bbox : arg[1].ds_bbox) : Float64[]
37203728

37213729
if (no_R && !isempty(ds_bbox)) # If arg is a GMTdataset of polygons, use the ds_bbox directly
37223730
geom = isa(arg, Vector) ? arg[1].geom : arg.geom
@@ -3943,17 +3951,6 @@ function isgeog(in)::Bool
39433951
(prj != "" && (contains(prj, "=lon") || contains(prj, "=lat")))
39443952
end
39453953

3946-
# ---------------------------------------------------------------------------------------------------
3947-
"""
3948-
isFV(D)::Bool
3949-
3950-
Check if D is a Face-Vertices ensemble (a 2 elements vector of GMTdataset).
3951-
"""
3952-
function isFV(D)::Bool
3953-
(isa(D, Vector{<:GMTdataset}) && length(D) > 1) &&
3954-
(D[1].geom == wkbPoint || D[1].geom == wkbPointZ) && eltype(D[2].data) <: Integer
3955-
end
3956-
39573954
# ---------------------------------------------------------------------------------------------------
39583955
"""
39593956
is_gridtri(D)::Bool

src/gmt_main.jl

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,8 @@ function GMTJL_Set_Object(API::Ptr{Nothing}, X::GMT_RESOURCE, ptr, pad)::GMT_RES
722722
end
723723
elseif (isa(ptr, Vector{<:GMTdataset}))
724724
X.object = dataset_init(API, ptr, X.direction)
725+
elseif (isa(ptr, GMTfv))
726+
X.object = dataset_init_FV(API, ptr)
725727
else
726728
if (X.direction == GMT_OUT) # Here we accept ptr === nothing
727729
X.object = convert(Ptr{GMT_DATASET}, GMT_Create_Data(API, GMT_IS_DATASET, GMT_IS_PLP, GMT_IS_OUTPUT, NULL, NULL, NULL, 0, 0, NULL))
@@ -1017,8 +1019,6 @@ function dataset_init(API::Ptr{Nothing}, Darr::Vector{<:GMTdataset}, direction::
10171019

10181020
(Darr == C_NULL || length(Darr) == 0) && error("Input is empty where it can't be.")
10191021

1020-
isFV(Darr) && return dataset_init_FV(API, Darr) # Special case for Face-Vertices obj.
1021-
10221022
# We come here if we did not receive a matrix
10231023
dim = [1, 0, 0, 0]
10241024
dim[GMT_SEG+1] = length(Darr) # Number of segments
@@ -1091,33 +1091,31 @@ end
10911091

10921092
# ---------------------------------------------------------------------------------------------------
10931093
function dataset_init_FV(API::Ptr{Nothing}, FV)::Ptr{GMT_MATRIX}
1094-
V::GMTdataset{Float64,2}, F::GMTdataset{Int,2} = FV[1], FV[2]
1095-
n_segs = size(F.data, 1) # Number of segments or faces (polygons)
1096-
n_rows = size(F.data, 2) # Number of rows (vertexes of the polygon)
1097-
n_cols = size(V.data, 2) # Number of columns (2 for x,y; 3 for x,y,z)
1098-
dim = [1, n_segs, n_rows, n_cols] # [1, GMT_SEG+1, GMT_ROW+1, GMT_COL+1]
1094+
n_segs = size(FV.faces[1], 1) # Number of segments or faces (polygons)
1095+
n_rows = size(FV.faces[1], 2) # Number of rows (vertices of the polygon)
1096+
dim = [1, n_segs, n_rows, 3] # [1, GMT_SEG+1, GMT_ROW+1, GMT_COL+1]
10991097

11001098
pdim = pointer(dim)
11011099
D = convert(Ptr{GMT_DATASET}, GMT_Create_Data(API, GMT_IS_DATASET, GMT_IS_PLP, GMT_NO_STRINGS, pdim, NULL, NULL, 0, 0, NULL))
11021100
DS::GMT_DATASET = unsafe_load(D)
1103-
DT = unsafe_load(unsafe_load(DS.table)) # GMT_DATATABLE
1101+
DT = unsafe_load(unsafe_load(DS.table)) # GMT_DATATABLE
11041102

11051103
n_records = 0
1106-
tmp = zeros(n_rows, n_cols)
1104+
tmp = zeros(n_rows, 3)
11071105

1108-
for seg = 1:n_segs # Each row in F (a face) is a new data segment (a polygon)
1106+
for seg = 1:n_segs # Each row in a face is a new data segment (a polygon)
11091107
DSv = convert(Ptr{Nothing}, unsafe_load(DT.segment, seg)) # DT.segment = Ptr{Ptr{GMT_DATASEGMENT}}
1110-
S = GMT_Alloc_Segment(API, GMT_NO_STRINGS, n_rows, n_cols, "", DSv) # Ptr{GMT_DATASEGMENT}
1111-
Sb = unsafe_load(S) # GMT_DATASEGMENT; Sb.data -> Ptr{Ptr{Float64}}
1112-
1113-
for c = 1:n_cols, r = 1:n_rows
1114-
tmp[r,c] = V.data[F.data[seg, r], c]
1108+
S = GMT_Alloc_Segment(API, GMT_NO_STRINGS, n_rows, 3, "", DSv) # Ptr{GMT_DATASEGMENT}
1109+
Sb = unsafe_load(S) # GMT_DATASEGMENT; Sb.data -> Ptr{Ptr{Float64}}
1110+
1111+
for c = 1:3, r = 1:n_rows
1112+
tmp[r,c] = FV.verts[FV.faces[1][seg, r], c]
11151113
end
1116-
for col = 1:n_cols # Copy the data columns
1114+
for col = 1:3 # Copy the data columns
11171115
unsafe_copyto!(unsafe_load(Sb.data, col), pointer(tmp[:,col]), n_rows)
11181116
end
11191117

1120-
n_records += n_rows # Must manually keep track of totals
1118+
n_records += n_rows # Must manually keep track of totals
11211119
DS.type_ = GMT_READ_DATA
11221120
unsafe_store!(S, Sb)
11231121
unsafe_store!(DT.segment, S, seg)
@@ -1579,6 +1577,11 @@ end
15791577
Base.:show(io::IO, ::MIME"text/plain", D::GMTdataset) = show(D)
15801578
Base.:display(D::GMTdataset) = show(D) # Otherwise the default prints nothing when text only (data == [])
15811579

1580+
# ---------------------------------------------------------------------------------------------------
1581+
function Base.:show(io::IO, ::MIME"text/plain", FV::GMTfv)
1582+
println("Face-Vertices with a total of ", sum(size.(FV.faces,1)), " faces and $(size(FV.verts,1)) vertices")
1583+
end
1584+
15821585
# ---------------------------------------------------------------------------------------------------
15831586
function Base.show(io::IO, C::GMTcpt)
15841587
isempty(C) && return

src/gmt_types.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,17 @@ GMTdataset(data::Array{Float32,2}, text::String) =
292292
GMTdataset(data::Array{Float32,2}) =
293293
GMTdataset(data, Float64[], Float64[], DictSvS(), String[], String[], "", String[], "", "", 0, 0)
294294

295+
Base.@kwdef struct GMTfv{T<:AbstractFloat} <: AbstractMatrix{T}
296+
verts::AbstractMatrix{T}=Matrix{Float64}(undef,0,0)
297+
faces::Vector{<:AbstractMatrix{Int}}=Vector{<:AbstractMatrix{Int}}(undef,0)
298+
faces_view::Vector{Matrix{Int}}=Vector{Matrix{Int}}(undef,0)
299+
bbox::Vector{Float64}=zeros(6)
300+
proj4::String=""
301+
wkt::String=""
302+
epsg::Int=0
303+
end
304+
Base.size(FV::GMTfv) = sum(size.(FV.faces))
305+
295306
#=
296307
Base.@kwdef struct GMTtypes
297308
stored::String = ""

src/gmtreadwrite.jl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ end
679679

680680
# --------------------------------------------------------------------------------------------------------
681681
"""
682-
VF = read_obj(fname)
682+
VF = read_obj(fname)::GMTfv
683683
684684
Read a Wavefront .obj file and return the result in a FaceVertices object.
685685
"""
@@ -725,9 +725,7 @@ function read_obj(fname)
725725
end
726726
end
727727
close(fid)
728-
DV = GMTdataset(data=V, geom=wkbPointZ)
729-
set_dsBB!(DV)
730-
return [DV, GMTdataset(data=F)]
728+
fv2fv(F, V)
731729
end
732730

733731
# --------------------------------------------------------------------------------------------------------

src/imshow.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,14 @@ function imshow(arg1, x::AbstractVector{Float64}=Float64[], y::AbstractVector{Fl
6565
elseif (isa(arg1, Array{UInt8}) || isa(arg1, Array{UInt16,3}))
6666
Gi = mat2img(arg1; kw...)
6767
call_img = true
68-
elseif (isGMTdataset(arg1) || (isa(arg1, Matrix{<:Real}) && size(arg1,2) <= 4) || (isa(arg1, Gdal.AbstractDataset) || isa(arg1, Gdal.AbstractGeometry)))
68+
elseif (isa(arg1, GDtype) || isa(arg1, GMTfv) || (isa(arg1, Matrix{<:Real}) && size(arg1,2) <= 4) || (isa(arg1, Gdal.AbstractDataset) || isa(arg1, Gdal.AbstractGeometry)))
6969
(isa(arg1, Gdal.AbstractDataset) || isa(arg1, Gdal.AbstractGeometry)) && (arg1 = gd2gmt(arg1))
7070
isa(arg1, Matrix{<:Real}) && (arg1 = mat2ds(arg1))
71-
ginfo = isa(arg1, GMTdataset) ? arg1.bbox : arg1[1].ds_bbox
71+
ginfo = (isa(arg1, GMTdataset) || isa(arg1, GMTfv)) ? arg1.bbox : arg1[1].ds_bbox
7272
CTRL.limits[1:4] = ginfo[1:4]; CTRL.limits[7:10] = ginfo[1:4]
7373
call_plot3 = ((isa(arg1, GMTdataset) && arg1.geom == Gdal.wkbPolygonZM) ||
7474
(isa(arg1, Vector{<:GMTdataset}) && arg1[1].geom == Gdal.wkbPolygonZM) ||
75-
isFV(arg1)) ? true : false # Should evolve into a fun that detects the several plot3d cases.
75+
isa(arg1, GMTfv)) ? true : false # Should evolve into a fun that detects the several plot3d cases.
7676
!call_plot3 && (call_plot3 = isplot3(kw))
7777
return (call_plot3) ? plot3d(arg1; show=see, kw...) : plot(arg1; show=see, kw...)
7878
elseif (isa(arg1, GMTcpt))

src/libgmt.jl

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -418,14 +418,6 @@ function gmt_get_rgb_from_z(API::Ptr{Cvoid}, P::Ptr{GMT_PALETTE}, value, rgb)
418418
ccall((:gmt_get_rgb_from_z, libgmt), Cint, (Cstring, Ptr{Cvoid}, Cdouble, Ptr{Cdouble}), GMT_Get_Ctrl(API), P, value, rgb)
419419
end
420420

421-
function gmt_get_index(API::Ptr{Cvoid}, P::Ptr{GMT_PALETTE}, value)
422-
ccall((:gmt_get_index, libgmt), Cint, (Cstring, Ptr{Cvoid}, Ptr{Cdouble}), GMT_Get_Ctrl(API), P, value)
423-
end
424-
425-
function gmt_get_rgb_lookup(API::Ptr{Cvoid}, P::Ptr{GMT_PALETTE}, ind, value, rgb)
426-
ccall((:gmt_get_rgb_lookup, libgmt), Cint, (Cstring, Ptr{Cvoid}, Cint, Cdouble, Ptr{Cdouble}), GMT_Get_Ctrl(API), P, ind, value, rgb)
427-
end
428-
429421
function gmt_illuminate(API::Ptr{Cvoid}, intensity, rgb::Vector{Float64})
430422
ccall((:gmt_illuminate, libgmt), Cvoid, (Cstring, Cdouble, Ptr{Cdouble}), GMT_Get_Ctrl(API), intensity, rgb)
431423
end

src/plot.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,6 +1811,7 @@ const psevents = events # Alias
18111811
cat_1_arg(arg::GMTdataset, toDS::Bool=false) = return arg # Miserable attempts to force type stability
18121812
cat_1_arg(arg::Vector{<:GMTdataset}, toDS::Bool=false) = return arg
18131813
function cat_1_arg(arg, toDS::Bool=false)
1814+
isa(arg, GMTfv) && return arg # A FV type. Nothing to here
18141815
# Add a first column with 1:n to all args that are not GMTdatasets
18151816
if (isa(arg, Vector) || typeof(arg) <: AbstractRange)
18161817
if isa(arg, Vector{<:Vector{<:Real}})

src/proj_utils.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,10 @@ function buffergeo(line::Matrix{<:Real}; width=0, unit=:m, np=120, flatstart=fal
323323
#(line[1, 1:2] == line[end, 1:2]) && (flatstart = flatend = false) # Polygons can't have start/end flat edges
324324
width *= unit_factor(unit)
325325
n_seg = length(azim)
326+
327+
# --------------------- When 'line' is actually a single point --------------------------------------------
328+
n_seg == 0 && return mat2ds(circgeo(line, radius=width, np=np, proj=proj, epsg=epsg), proj=proj, epsg=epsg)
329+
326330
D, _D = GMTdataset(), GMTdataset()
327331
for n = 1:n_seg
328332
seg = [geod(line[n,:], azim[n], 0:width/4:dist[n], proj=proj, epsg=epsg)[1]; line[n+1:n+1,:]]

0 commit comments

Comments
 (0)