Skip to content

Commit

Permalink
feat(sdt): keep integrating to occ interf
Browse files Browse the repository at this point in the history
  • Loading branch information
tpoisot committed Oct 8, 2024
1 parent f2de0e8 commit d3b5fea
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 92 deletions.
3 changes: 3 additions & 0 deletions src/SpeciesDistributionToolkit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ include("integrations/makie.jl")
# SDeMo
include("integrations/sdemo.jl")

# OccurrencesInterface
include("integrations/occurrence_interface.jl")

# Functions for pseudo-absence generation
include("pseudoabsences.jl")
export WithinRadius, SurfaceRangeEnvelope, RandomSelection, DistanceToEvent
Expand Down
87 changes: 6 additions & 81 deletions src/integrations/gbif_layers.jl
Original file line number Diff line number Diff line change
@@ -1,86 +1,11 @@
import Base: getindex
import Base: setindex!
import SimpleSDMLayers: mask!, mask

"""
Base.getindex(p::T, occurrence::GBIF.GBIFRecord) where {T <: SimpleSDMLayer}
Extracts the value of a layer at a given position for a `GBIFRecord`. If the
`GBIFRecord` has no latitude or longitude, this will return `nothing`.
"""
function Base.getindex(layer::SDMLayer, record::GBIF.GBIFRecord)
ismissing(record.latitude) && return nothing
ismissing(record.longitude) && return nothing
return layer[record.longitude, record.latitude]
end

"""
Base.setindex!(layer::SDMLayer, v, record::GBIFRecord)
Changes the values of the cell including the point at the requested latitude and
longitude.
"""
function Base.setindex!(
layer::SDMLayer{T},
v::T,
record::GBIF.GBIFRecord,
) where {T}
ismissing(record.latitude) && return nothing
ismissing(record.longitude) && return nothing
return setindex!(layer, v, record.longitude, record.latitude)
end

"""
Base.getindex(layer::T, records::GBIF.GBIFRecords) where {T <: SimpleSDMLayer}
Returns the values of a layer at all occurrences in a `GBIFRecords` collection.
"""
function Base.getindex(layer::SDMLayer, records::GBIF.GBIFRecords)
K = eltype(layer)
return convert(
Vector{K},
filter(!isnothing, [layer[r] for r in records]),
)
end

"""
Base.getindex(layer::SDMLayer, records::Vector{GBIF.GBIFRecord})
Returns the values of a layer at all occurrences in a `GBIFRecord` array.
"""
function Base.getindex(layer::SDMLayer, records::Vector{GBIF.GBIFRecord})
return [layer[record] for record in records]
end

function SimpleSDMLayers.quantize(layer::SDMLayer, records::GBIFRecords)
ef = StatsBase.ecdf(layer[records])
return ef.(layer)
end

function SimpleSDMLayers.mask(layer::SDMLayer, records::GBIF.GBIFRecords)
out = zeros(layer, Bool)
for record in records
out[record] = true
end
return out
end

function SimpleSDMLayers.mask(
layer::SDMLayer,
records::GBIF.GBIFRecords,
::Type{T},
) where {T <: Number}
out = zeros(layer, T)
for record in records
out[record] += one(T)
end
return out
end

function _bbox_from_layer(layer::SDMLayer)
EL = eastings(layer)
NL = northings(layer)
prj = SimpleSDMLayers.Proj.Transformation(layer.crs, "+proj=longlat +datum=WGS84 +no_defs"; always_xy = true)
prj = SimpleSDMLayers.Proj.Transformation(
layer.crs,
"+proj=longlat +datum=WGS84 +no_defs";
always_xy = true,
)

b1 = [prj(EL[1], n) for n in NL]
b2 = [prj(EL[end], n) for n in NL]
Expand All @@ -107,4 +32,4 @@ function GBIF.occurrences(layer::SDMLayer, query::Pair...)
query = (query..., "decimalLongitude" => (spatial_extent.left, spatial_extent.right))
query = (query..., "hasCoordinate" => true)
return occurrences(query...)
end
end
16 changes: 5 additions & 11 deletions src/integrations/makie.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,9 @@ function sprinkle(layer::SDMLayer)
)
end

function sprinkle(records::GBIFRecords)
lon = Float32.(replace(longitudes(records), missing => NaN))
lat = Float32.(replace(latitudes(records), missing => NaN))
return (lon, lat)
end

function sprinkle(records::Vector{GBIFRecord})
lon = Float32.(replace(longitudes.(records), missing => NaN))
lat = Float32.(replace(latitudes.(records), missing => NaN))
function sprinkle(coll::T) where {T <: AbstractOccurrenceCollection}
lon = Float32.(replace(longitudes(coll), missing => NaN))
lat = Float32.(replace(latitudes(coll), missing => NaN))
return (lon, lat)
end

Expand All @@ -42,7 +36,7 @@ end

function MakieCore.convert_arguments(
P::MakieCore.PointBased,
layer::T
layer::T,
) where {T <: SDMLayer{Bool}}
return MakieCore.convert_arguments(P, sprinkle(ones(nodata(layer, false), Float32))...)
end
end
73 changes: 73 additions & 0 deletions src/integrations/occurrence_interface.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import Base: getindex
import Base: setindex!
import SimpleSDMLayers: mask!, mask

"""
Base.getindex(p::T, occ::AbstractOccurrence)
Extracts the value of a layer at a given position for a `AbstractOccurrence`. If the
`AbstractOccurrence` has no latitude or longitude, this will return `nothing`.
"""
function Base.getindex(layer::SDMLayer, occ:T) where {T <: AbstractOccurrence}
ismissing(place(occ)) && return nothing
return layer[place(occ)...]
end

"""
Base.setindex!(layer::SDMLayer, v, occ::T) where {T <: AbstractOccurrence}
Changes the values of the cell including the point at the requested latitude and
longitude.
"""
function Base.setindex!(
layer::SDMLayer{T},
v::T,
occ::O,
) where {T, O <: AbstractOccurrence}
ismissing(place(occ)) && return nothing
return setindex!(layer, v, place(occ)...)
end

"""
Base.getindex(layer::SDMLayer, occ::T) where {T <: AbstractOccurrenceCollection}
Returns the values of a layer at all occurrences in a `AbstractOccurrenceCollection`.
"""
function Base.getindex(layer::SDMLayer, occ::T) where {T <: AbstractOccurrenceCollection}
K = eltype(layer)
return convert(
Vector{K},
filter(!isnothing, [layer[o] for o in elements(occ)]),
)
end

function SimpleSDMLayers.quantize(
layer::SDMLayer,
occ:T,
) where {T <: AbstractOccurrenceCollection}
ef = StatsBase.ecdf(layer[occ])
return ef.(layer)
end

function SimpleSDMLayers.mask(
layer::SDMLayer,
occ::T,
) where {T <: AbstractOccurrenceCollection}
out = zeros(layer, Bool)
for record in elements(occ)
out[record] = presence(occ)
end
return out
end

function SimpleSDMLayers.mask(
layer::SDMLayer,
occ::O,
::Type{T},
) where {T <: Number, O <: AbstractOccurrenceCollection}
out = zeros(layer, T)
for record in elements(occ)
out[record] += one(T)
end
return out
end

0 comments on commit d3b5fea

Please sign in to comment.