Skip to main content

TemporalCache

Struct TemporalCache 

Source
pub struct TemporalCache { /* private fields */ }
Expand description

Incrementally-loaded temporal index cache.

Implementations§

Source§

impl TemporalCache

Source

pub fn new() -> Self

Create an empty temporal cache.

Source

pub async fn from_reader<S: ByteSource>( reader: &CopcStreamingReader<S>, ) -> Result<Option<Self>, TemporalError>

Open the temporal index from a COPC reader.

Loads the temporal header and root page. Returns Ok(None) if no temporal EVLR exists in the file.

Source

pub async fn load_header( &mut self, source: &impl ByteSource, evlr_offset: u64, evlr_count: u32, ) -> Result<bool, TemporalError>

Scan EVLRs to find the temporal EVLR and read its header. Returns false if no temporal EVLR exists.

Source

pub async fn load_root_page( &mut self, source: &impl ByteSource, ) -> Result<(), TemporalError>

Load the root temporal page.

Source

pub async fn load_pages_for_time_range( &mut self, source: &impl ByteSource, start: GpsTime, end: GpsTime, ) -> Result<(), TemporalError>

Load child pages that overlap a time range, pruning by subtree bounds.

Source

pub async fn load_all_pages( &mut self, source: &impl ByteSource, ) -> Result<(), TemporalError>

Load ALL pending pages.

Source

pub async fn query( &mut self, source: &impl ByteSource, start: GpsTime, end: GpsTime, ) -> Result<Vec<&NodeTemporalEntry>, TemporalError>

Load relevant pages and return all nodes that overlap a time range.

This is the primary query method — it ensures the right pages are loaded before returning results. Equivalent to calling load_pages_for_time_range followed by nodes_in_range, but cannot return incomplete results.

Source

pub fn get(&self, key: &VoxelKey) -> Option<&NodeTemporalEntry>

Look up the temporal entry for a node.

Source

pub fn nodes_in_range( &self, start: GpsTime, end: GpsTime, ) -> Vec<&NodeTemporalEntry>

Return all loaded nodes whose time range overlaps [start, end].

Source

pub fn stride(&self) -> u32

The sampling stride (every N-th point is recorded in the index).

Source

pub fn header(&self) -> Option<&TemporalHeader>

The parsed temporal index header, if loaded.

Source

pub fn len(&self) -> usize

Number of loaded node entries.

Source

pub fn is_empty(&self) -> bool

Whether no node entries have been loaded.

Source

pub fn iter(&self) -> impl Iterator<Item = (&VoxelKey, &NodeTemporalEntry)>

Iterate all loaded entries.

Source

pub async fn query_chunks<S: ByteSource>( &mut self, reader: &mut CopcStreamingReader<S>, bounds: &Aabb, start: GpsTime, end: GpsTime, fields: Fields, ) -> Result<Vec<(Chunk, Range<u32>)>, TemporalError>

Query chunks by time range and spatial bounds.

Loads the relevant hierarchy and temporal pages, fetches every matching chunk with the caller’s fields mask, and returns (chunk, candidate_range) pairs. candidate_range is the sub-range of point indices in chunk whose GPS times could possibly fall within [start, end] based on the temporal index stride samples — points outside this range are guaranteed not to match and can be skipped.

The caller is responsible for the exact per-point intersection. Combine with Chunk::indices_in_bounds and indices_in_time_range to compute the precise matching set, then walk column accessors or call Chunk::points_at to materialize owned values.

use copc_streaming::Fields;

let chunks = temporal
    .query_chunks(
        &mut reader,
        &bbox,
        start,
        end,
        Fields::Z | Fields::GPS_TIME,
    )
    .await?;

for (chunk, range) in &chunks {
    let times = chunk.gps_time().unwrap();
    for (i, t) in times.enumerate().skip(range.start as usize)
                                   .take(range.len()) {
        if t >= start.0 && t <= end.0 {
            // ...
        }
    }
}
Source

pub async fn query_chunks_by_time<S: ByteSource>( &mut self, reader: &mut CopcStreamingReader<S>, start: GpsTime, end: GpsTime, fields: Fields, ) -> Result<Vec<(Chunk, Range<u32>)>, TemporalError>

Query chunks by time range only (no spatial filtering).

Like query_chunks but loads the full hierarchy and skips the bounding-box intersection test. Returns every chunk whose node temporal range overlaps [start, end], each paired with its candidate index range.

Source

pub async fn query_points<S: ByteSource>( &mut self, reader: &mut CopcStreamingReader<S>, bounds: &Aabb, start: GpsTime, end: GpsTime, ) -> Result<Vec<Point>, TemporalError>

Query points by time range and spatial bounds.

Loads the relevant hierarchy and temporal pages, fetches matching chunks, and returns only the points that fall inside both the time window and the bounding box.

Thin wrapper over query_chunks with Fields::ALL. Prefer query_chunks when you don’t need every field materialized as las::Point values.

let points = temporal.query_points(
    &mut reader, &query_box, start, end,
).await?;
Source

pub async fn query_points_by_time<S: ByteSource>( &mut self, reader: &mut CopcStreamingReader<S>, start: GpsTime, end: GpsTime, ) -> Result<Vec<Point>, TemporalError>

Query points by time range only (no spatial filtering).

Loads all hierarchy pages and temporal pages that overlap the time range, then returns points within the time window.

Thin wrapper over query_chunks_by_time with Fields::ALL.

Trait Implementations§

Source§

impl Default for TemporalCache

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.