Skip to content

Commit

Permalink
✨ Split a layer into tiles
Browse files Browse the repository at this point in the history
Fixes #147
  • Loading branch information
tpoisot committed Feb 17, 2023
1 parent e0049b5 commit 22ca389
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 2 deletions.
2 changes: 1 addition & 1 deletion SimpleSDMLayers/Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "SimpleSDMLayers"
uuid = "2c645270-77db-11e9-22c3-0f302a89c64c"
authors = ["Timothée Poisot <timothee.poisot@umontreal.ca>", "Gabriel Dansereau <gabriel.dansereau@umontreal.ca>"]
version = "0.9.0"
version = "0.9.1"

[deps]
Distances = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"
Expand Down
3 changes: 2 additions & 1 deletion SimpleSDMLayers/src/SimpleSDMLayers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ include("operations/sliding.jl")
include("operations/mask.jl")
include("operations/rescale.jl")
include("operations/mosaic.jl")
export coarsen, slidingwindow, mask, rescale!, rescale, mosaic
include("operations/tiling.jl")
export coarsen, slidingwindow, mask, rescale!, rescale, mosaic, tile, tile!

end # module
57 changes: 57 additions & 0 deletions SimpleSDMLayers/src/operations/tiling.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"""
tile!(tiles::Matrix{T}, layer::T, s::Tuple{Integer, Integer} = (5, 5)) where {T <: SimpleSDMLayer}
Split a layer into a matrix of tiles (with size `s`), where the tiles are as
evenly sized as possible, and have strictly matching boundaries.
"""
function tile!(
tiles::Matrix{T},
layer::T,
s::Tuple{Integer, Integer} = (5, 5),
) where {T <: SimpleSDMLayer}
@assert s[1] < size(layer, 1)
@assert s[2] < size(layer, 2)
@assert size(tiles) == s
# Return type
RT = T <: SimpleSDMPredictor ? SimpleSDMPredictor : SimpleSDMResponse
# Boundaries from the bounding box
l = layer.left
r = layer.right
b = layer.bottom
t = layer.top
l_r_points = LinRange(l, r, s[2] + 1)
t_b_points = LinRange(t, b, s[1] + 1)
# Split the coordinates
dim_1_cutoff = floor.(Int, LinRange(1, size(layer, 1), s[1] + 1))
dim_2_cutoff = floor.(Int, LinRange(1, size(layer, 2), s[2] + 1))
# Add the layers to the tiles matrix
for i in eachindex(dim_1_cutoff)[2:end]
start1, stop1 = dim_1_cutoff[(i - 1):i]
for j in eachindex(dim_2_cutoff)[2:end]
start2, stop2 = dim_2_cutoff[(j - 1):j]
tiles[(i - 1), (j - 1)] =
RT(
layer.grid[start1:stop1, start2:stop2],
l_r_points[j - 1],
l_r_points[j],
t_b_points[i],
t_b_points[i - 1],
)
end
end
return tiles
end

"""
tile(layer::T, s::Tuple{Integer, Integer} = (5, 5)) where {T <: SimpleSDMLayer}
Split a layer into a matrix of tiles (with size `s`), where the tiles are as
evenly sized as possible, and have strictly matching boundaries. This function
will allocate the return matrix.
"""
function tile(layer::T, s::Tuple{Integer, Integer} = (5, 5)) where {T <: SimpleSDMLayer}
# Create the tiles
tiles = Matrix{T}(undef, s...)
tile!(tiles, layer, s)
return tiles
end
35 changes: 35 additions & 0 deletions docs/src/vignettes/layers/05_tiling.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# # Splitting layers in tiles

using SpeciesDistributionToolkit
using CairoMakie

# Get some data

dataprovider = RasterData(EarthEnv, LandCover)
spatial_extent = (left = -80.00, bottom = 43.19, right = -70.94, top = 46.93)
trees = sum([
SimpleSDMPredictor(dataprovider; layer = i, full = true, spatial_extent...) for
i in 1:4
])

# split into tiles

tiles = tile(trees, (4, 5))

# plot

tile_plot = heatmap(
tiles[1,2];
colormap = :Greens,
figure = (; resolution = (800, 350)),
axis = (;
aspect = DataAspect(),
xlabel = "Latitude",
ylabel = "Longitude",
title = "Relative tree cover",
),
)
Colorbar(tile_plot.figure[:, end + 1], tile_plot.plot; height = Relative(0.5))
current_figure()

#

0 comments on commit 22ca389

Please sign in to comment.