Create a stateful iterator that maintains an internal position and yields batches of tiles on demand. Uses closures for serializable stateful behavior without external dependencies. Useful for streaming processing, memory-constrained environments, or when you want to process tiles in smaller chunks.
This is a structure that works with any underlying tilePlan. tileGroup
is also accepted when an $active group has already been set, or a group
is specified via tileIterator(active_group)
Note that tileIterator contains its own state and an independent copy of it
cannot be generated by assigning to a new variable. Instead, use either the
$copy() method or iterSplit().
Usage
# S4 method for class 'tileIterator'
x$name
# S4 method for class 'tileIterator'
x$name <- value
tileIterator(
tiles = NULL,
position = 0,
bound = NULL,
batch_size = 1,
active_group = NULL
)Arguments
- x
tileIterator- name
Name of method or attribute to access (See Methods section)
- value
value to set for an attribute (See Methods section)
- tiles
A tile* object
- position
numeric. Set the starting position of the iterator. Default is 0.
- bound
numeric, length of 2. Min and max indexing bounds through which to iterate. Default is
c(1, length(tiles))- batch_size
Integer. Number of tiles to return per call to next_batch()
- active_group
character (optional). Only used when
tilesis atileGroup. Syntactic sugar for setting the active group of thetileGroupbefore using it.
Methods
[]/[]<-or$tiles/$tiles<-get or set a
tilePlanortileGroup(with$activeset).[]notation is just shorthand.
$position/$position<-get and set current position of iterator
$batch_size/$batch_size<-get and set batch size.
$bound/$bound<-get and set iteration tile index bounds. This is a numeric vector of 2 (min, max)
$next_batch()/$next_indices()get next batch or just their tile indices.
Has an
advanceparam (default =TRUE) that advances iterator position.When there are no more tiles, gracefully returns empty
list
$peek_batch()/$peek_indicesGet next batch or indices without advancing position. When there are no more tiles, gracefully returns empty
integer
$has_nextReturn
logicalif there are still tiles left to iterate through (ifposition<max(bound)). Useful forwhilelooping.
$total_tilesReturn total number of tiles in
bound
$remainingReturn number of remaining indices to traverse.
$progressReturn current percentage of
positiontraversal acrossbound
$reset()Reset position to 1 before the lower
bound
$copy()Create a new
tileIteratorwith the same settings (deep copy)
Usage Patterns
Stream processing large datasets
Memory-constrained batch processing
Progressive/incremental analysis
Checkpoint and resume workflows
Parallel processing with foreach
See also
Other tile orchestration:
iterSplit(),
tileGroup,
tileGroup-class,
tileIterator-class
Examples
# Create a spatial tile iterator
tp <- tilePlan("spatial")
ext(tp) <- c(0, 100, 0, 100)
length(tp) <- 16
# Create a iterator that processes 3 tiles at a time
iter <- tileIterator(tp, batch_size = 3)
# Check status
iter
#> Object of class tileIterator
#> tiles : spatialTilePlan
#> position : 0
#> bound : [1, 16]
#> batch_size : 3
#> progress : 0%
#> remaining : 16
iter$has_next
#> [1] TRUE
iter$remaining
#> [1] 16
iter$progress
#> [1] 0
# Get next batch
batch1 <- iter$next_batch()
length(batch1) # 3 tiles
#> [1] 3
# Check updated status
iter$progress # position has advanced
#> [1] 18.75
# Peek at next batch without advancing
peek <- iter$peek_batch()
peek
#> [[1]]
#> SpatExtent : 75, 100, 0, 25 (xmin, xmax, ymin, ymax)
#>
#> [[2]]
#> SpatExtent : 0, 25, 25, 50 (xmin, xmax, ymin, ymax)
#>
#> [[3]]
#> SpatExtent : 25, 50, 25, 50 (xmin, xmax, ymin, ymax)
#>
#> attr(,"batch_start")
#> [1] 4
#> attr(,"batch_end")
#> [1] 6
#> attr(,"batch_size")
#> [1] 3
#> attr(,"iterator_position")
#> [1] 3
iter$position # unchanged
#> [1] 3
# serialize and unserialize, preserving state
temp <- tempfile()
saveRDS(iter, temp)
rm(iter)
iter <- readRDS(temp)
# Next batch of indices
iter$next_indices()
#> [1] 4 5 6
# Peek next batch of indices
iter$peek_indices()
#> [1] 7 8 9
# Process all remaining batches
while (iter$has_next) {
batch <- iter$next_batch()
cat("Processing batch of", length(batch), "tiles\n")
}
#> Processing batch of 3 tiles
#> Processing batch of 3 tiles
#> Processing batch of 3 tiles
#> Processing batch of 1 tiles
# Reset and try different batch size
iter$reset()
iter$batch_size <- 5
# Apply function across all batches
while (iter$has_next) {
batch <- iter$next_batch()
cat("Processing batch of", length(batch), "tiles\n")
}
#> Processing batch of 5 tiles
#> Processing batch of 5 tiles
#> Processing batch of 5 tiles
#> Processing batch of 1 tiles
# tileIterator with tileGroup
tg <- tileGroup(tp, groups = list(
"g1" = c(2, 4, 6, 8, 10, 12, 14, 16),
"g2" = 1:16
))
tg$active <- "g1"
iter <- tileIterator(tg, batch_size = 3)
iter
#> Object of class tileIterator
#> tiles : tileGroup
#> position : 0
#> bound : [1, 8]
#> batch_size : 3
#> progress : 0%
#> remaining : 8
iter$next_batch()
#> [[1]]
#> SpatExtent : 25, 50, 0, 25 (xmin, xmax, ymin, ymax)
#>
#> [[2]]
#> SpatExtent : 75, 100, 0, 25 (xmin, xmax, ymin, ymax)
#>
#> [[3]]
#> SpatExtent : 25, 50, 25, 50 (xmin, xmax, ymin, ymax)
#>
#> attr(,"batch_start")
#> [1] 1
#> attr(,"batch_end")
#> [1] 3
#> attr(,"batch_size")
#> [1] 3
#> attr(,"iterator_position")
#> [1] 3
# iterator splitting
siter <- iterSplit(iter, n = 2)
siter
#> [[1]]
#> Object of class tileIterator
#> tiles : tileGroup
#> position : 3
#> bound : [4, 6]
#> batch_size : 3
#> progress : 0%
#> remaining : 3
#>
#> [[2]]
#> Object of class tileIterator
#> tiles : tileGroup
#> position : 6
#> bound : [7, 8]
#> batch_size : 3
#> progress : 0%
#> remaining : 2
#>