Skip to contents

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 tiles is a tileGroup. Syntactic sugar for setting the active group of the tileGroup before using it.

Value

A tileIterator function with attached methods

Methods

  • []/[]<- or $tiles/$tiles<-

    • get or set a tilePlan or tileGroup (with $active set). [] 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 advance param (default = TRUE) that advances iterator position.

      • When there are no more tiles, gracefully returns empty list

  • $peek_batch()/$peek_indices

    • Get next batch or indices without advancing position. When there are no more tiles, gracefully returns empty integer

  • $has_next

    • Return logical if there are still tiles left to iterate through (if position < max(bound)). Useful for while looping.

  • $total_tiles

    • Return total number of tiles in bound

  • $remaining

    • Return number of remaining indices to traverse.

  • $progress

    • Return current percentage of position traversal across bound

  • $reset()

    • Reset position to 1 before the lower bound

  • $copy()

    • Create a new tileIterator with 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

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
#>