pub fn search_last_file_by_bounds_optimized<P: AsRef<Path>>(
    path: P,
    bounds: &AABB<f64>,
    result_collector: &mut dyn ResultCollector,
) -> Result<()> {
    let mut reader = open_file_reader(path.as_ref())?;

    let raw_header = parse_las_header(&mut reader)?;
    let header = Header::from_raw(raw_header.clone())?;
    let file_bounds = AABB::from_min_max(
        Point3::new(
            header.bounds().min.x,
            header.bounds().min.y,
            header.bounds().min.z,
        ),
        Point3::new(
            header.bounds().max.x,
            header.bounds().max.y,
            header.bounds().max.z,
        ),
    );

    let point_record_format = header.point_format().to_u8()?;
    let offset_to_classification_in_las_point = match point_record_format {
        0..=5 => 15,
        6..=10 => 16,
        _ => {
            return Err(anyhow!(
                "Invalid LAS format {} in file {}",
                point_record_format,
                path.as_ref().display()
            ))
        }
    };
    let offset_to_classification_block = raw_header.offset_to_point_data as u64
        + (header.number_of_points() * offset_to_classification_in_las_point);

    let offset_to_color_in_las_point = match point_record_format {
        2 => Some(20),
        3 => Some(28),
        5 => Some(28),
        _ => None,
    };
    let offset_to_color_block = offset_to_color_in_las_point
        .map(|o| raw_header.offset_to_point_data as u64 + (header.number_of_points() * o));

    if !file_bounds.intersects(bounds) {
        return Ok(());
    }

    // Convert bounds of query area into integer coordinates in local space of file. This makes intersection
    // checks very fast because they can be done on integer values
    let query_bounds_local = AABB::<i64>::from_min_max(
        Point3::<i64>::new(
            ((bounds.min().x - raw_header.x_offset) / raw_header.x_scale_factor) as i64,
            ((bounds.min().y - raw_header.y_offset) / raw_header.x_scale_factor) as i64,
            ((bounds.min().z - raw_header.z_offset) / raw_header.x_scale_factor) as i64,
        ),
        Point3::<i64>::new(
            ((bounds.max().x - raw_header.x_offset) / raw_header.x_scale_factor) as i64,
            ((bounds.max().y - raw_header.y_offset) / raw_header.y_scale_factor) as i64,
            ((bounds.max().z - raw_header.z_offset) / raw_header.z_scale_factor) as i64,
        ),
    );

    let size_of_single_position = 12;
    let size_of_single_color = 6;

    let offsets_to_positions_block: u64 = raw_header.offset_to_point_data as u64;
    reader.seek(SeekFrom::Start(offsets_to_positions_block))?;

    for idx in 0..header.number_of_points() {
        let offset_of_current_position = idx * size_of_single_position;
        reader.seek(SeekFrom::Start(
            offsets_to_positions_block + offset_of_current_position,
        ))?;
        let point_x = reader.read_i32::<LittleEndian>()? as i64;
        if point_x < query_bounds_local.min().x || point_x > query_bounds_local.max().x {
            continue;
        }

        let point_y = reader.read_i32::<LittleEndian>()? as i64;
        if point_y < query_bounds_local.min().y || point_y > query_bounds_local.max().y {
            continue;
        }

        let point_z = reader.read_i32::<LittleEndian>()? as i64;
        if point_z < query_bounds_local.min().z || point_z > query_bounds_local.max().z {
            continue;
        }

        // Read classification
        let offset_of_current_classification = idx;
        reader.seek(SeekFrom::Start(
            offset_to_classification_block + offset_of_current_classification,
        ))?;
        let class = reader.read_u8()?;

        // Read color (if it exists)
        let color = if let Some(color_offset) = offset_to_color_block {
            reader.seek(SeekFrom::Start((idx * size_of_single_color) + color_offset))?;
            let r = reader.read_u16::<LittleEndian>()?;
            let g = reader.read_u16::<LittleEndian>()?;
            let b = reader.read_u16::<LittleEndian>()?;
            Vector3::new(r, g, b)
        } else {
            Vector3::new(0, 0, 0)
        };

        result_collector.collect_one(Point {
            position: Vector3::new(
                (point_x as f64 * raw_header.x_scale_factor) + raw_header.x_offset,
                (point_y as f64 * raw_header.y_scale_factor) + raw_header.y_offset,
                (point_z as f64 * raw_header.z_scale_factor) + raw_header.z_offset,
            ),
            classification: class,
            color,
        });
    }
    Ok(())
}
/**
 * Each type of search is implemented twice, once by using the pointstream crate (simulating a real-world use-case)
 * and once with a hand-rolled solution (simulating maximum efficiency)
 */
Each type of search is implemented twice, once by using the pointstream crate (simulating a real-world use-case)
and once with a hand-rolled solution (simulating maximum efficiency)
Each type of search is implemented twice once by using the pointstream crate ( simulating a real - world use - case ) and once with a hand - rolled solution ( simulating maximum efficiency )
pub fn search_last_file_by_bounds_optimized<P: AsRef<Path>>(
    path: P,
    bounds: &AABB<f64>,
    result_collector: &mut dyn ResultCollector,
) -> Result<()> {
    let mut reader = open_file_reader(path.as_ref())?;
    let raw_header = parse_las_header(&mut reader)?;
    let header = Header::from_raw(raw_header.clone())?;
    let file_bounds = AABB::from_min_max(
        Point3::new(
            header.bounds().min.x,
            header.bounds().min.y,
            header.bounds().min.z,
        ),
        Point3::new(
            header.bounds().max.x,
            header.bounds().max.y,
            header.bounds().max.z,
        ),
    );
    let point_record_format = header.point_format().to_u8()?;
    let offset_to_classification_in_las_point = match point_record_format {
        0..=5 => 15,
        6..=10 => 16,
        _ => {
            return Err(anyhow!(
                "Invalid LAS format {} in file {}",
                point_record_format,
                path.as_ref().display()
            ))
        }
    };
    let offset_to_classification_block = raw_header.offset_to_point_data as u64
        + (header.number_of_points() * offset_to_classification_in_las_point);
    let offset_to_color_in_las_point = match point_record_format {
        2 => Some(20),
        3 => Some(28),
        5 => Some(28),
        _ => None,
    };
    let offset_to_color_block = offset_to_color_in_las_point
        .map(|o| raw_header.offset_to_point_data as u64 + (header.number_of_points() * o));
    if !file_bounds.intersects(bounds) {
        return Ok(());
    }
    // Convert bounds of query area into integer coordinates in local space of file. This makes intersection
    // checks very fast because they can be done on integer values
    let query_bounds_local = AABB::<i64>::from_min_max(
        Point3::<i64>::new(
            ((bounds.min().x - raw_header.x_offset) / raw_header.x_scale_factor) as i64,
            ((bounds.min().y - raw_header.y_offset) / raw_header.x_scale_factor) as i64,
            ((bounds.min().z - raw_header.z_offset) / raw_header.x_scale_factor) as i64,
        ),
        Point3::<i64>::new(
            ((bounds.max().x - raw_header.x_offset) / raw_header.x_scale_factor) as i64,
            ((bounds.max().y - raw_header.y_offset) / raw_header.y_scale_factor) as i64,
            ((bounds.max().z - raw_header.z_offset) / raw_header.z_scale_factor) as i64,
        ),
    );
    let size_of_single_position = 12;
    let size_of_single_color = 6;
    let offsets_to_positions_block: u64 = raw_header.offset_to_point_data as u64;
    reader.seek(SeekFrom::Start(offsets_to_positions_block))?;
    for idx in 0..header.number_of_points() {
        let offset_of_current_position = idx * size_of_single_position;
        reader.seek(SeekFrom::Start(
            offsets_to_positions_block + offset_of_current_position,
        ))?;
        let point_x = reader.read_i32::<LittleEndian>()? as i64;
        if point_x < query_bounds_local.min().x || point_x > query_bounds_local.max().x {
            continue;
        }
        let point_y = reader.read_i32::<LittleEndian>()? as i64;
        if point_y < query_bounds_local.min().y || point_y > query_bounds_local.max().y {
            continue;
        }
        let point_z = reader.read_i32::<LittleEndian>()? as i64;
        if point_z < query_bounds_local.min().z || point_z > query_bounds_local.max().z {
            continue;
        }
        // Read classification
        let offset_of_current_classification = idx;
        reader.seek(SeekFrom::Start(
            offset_to_classification_block + offset_of_current_classification,
        ))?;
        let class = reader.read_u8()?;
        // Read color (if it exists)
        let color = if let Some(color_offset) = offset_to_color_block {
            reader.seek(SeekFrom::Start((idx * size_of_single_color) + color_offset))?;
            let r = reader.read_u16::<LittleEndian>()?;
            let g = reader.read_u16::<LittleEndian>()?;
            let b = reader.read_u16::<LittleEndian>()?;
            Vector3::new(r, g, b)
        } else {
            Vector3::new(0, 0, 0)
        };
        result_collector.collect_one(Point {
            position: Vector3::new(
                (point_x as f64 * raw_header.x_scale_factor) + raw_header.x_offset,
                (point_y as f64 * raw_header.y_scale_factor) + raw_header.y_offset,
                (point_z as f64 * raw_header.z_scale_factor) + raw_header.z_offset,
            ),
            classification: class,
            color,
        });
    }
    Ok(())
}
pub fn search_last_file_by_bounds_optimized < P : AsRef < Path > > ( path : P , bounds : & AABB < f64 > , result_collector : & mut dyn ResultCollector , ) -> Result < ( ) > { let mut reader = open_file_reader ( path . as_ref ( ) ) ? ; let raw_header = parse_las_header ( & mut reader ) ? ; let header = Header :: from_raw ( raw_header . clone ( ) ) ? ; let file_bounds = AABB :: from_min_max ( Point3 :: new ( header . bounds ( ) . min . x , header . bounds ( ) . min . y , header . bounds ( ) . min . z , ) , Point3 :: new ( header . bounds ( ) . max . x , header . bounds ( ) . max . y , header . bounds ( ) . max . z , ) , ) ; let point_record_format = header . point_format ( ) . to_u8 ( ) ? ; let offset_to_classification_in_las_point = match point_record_format { 0 ..= 5 => 15 , 6 ..= 10 => 16 , _ => { return Err ( anyhow ! ( " " point_record_format path as_ref ( ) display ( ) ) ) } } ; let offset_to_classification_block = raw_header . offset_to_point_data as u64 + ( header . number_of_points ( ) * offset_to_classification_in_las_point ) ; let offset_to_color_in_las_point = match point_record_format { 2 => Some ( 20 ) , 3 => Some ( 28 ) , 5 => Some ( 28 ) , _ => None , } ; let offset_to_color_block = offset_to_color_in_las_point . map ( | o | raw_header . offset_to_point_data as u64 + ( header . number_of_points ( ) * o ) ) ; if ! file_bounds . intersects ( bounds ) { return Ok ( ( ) ) ; } // Convert bounds of query area into integer coordinates in local space of file. This makes intersection // checks very fast because they can be done on integer values let query_bounds_local = AABB :: < i64 > :: from_min_max ( Point3 :: < i64 > :: new ( ( ( bounds . min ( ) . x - raw_header . x_offset ) / raw_header . x_scale_factor ) as i64 , ( ( bounds . min ( ) . y - raw_header . y_offset ) / raw_header . x_scale_factor ) as i64 , ( ( bounds . min ( ) . z - raw_header . z_offset ) / raw_header . x_scale_factor ) as i64 , ) , Point3 :: < i64 > :: new ( ( ( bounds . max ( ) . x - raw_header . x_offset ) / raw_header . x_scale_factor ) as i64 , ( ( bounds . max ( ) . y - raw_header . y_offset ) / raw_header . y_scale_factor ) as i64 , ( ( bounds . max ( ) . z - raw_header . z_offset ) / raw_header . z_scale_factor ) as i64 , ) , ) ; let size_of_single_position = 12 ; let size_of_single_color = 6 ; let offsets_to_positions_block : u64 = raw_header . offset_to_point_data as u64 ; reader . seek ( SeekFrom :: Start ( offsets_to_positions_block ) ) ? ; for idx in 0 .. header . number_of_points ( ) { let offset_of_current_position = idx * size_of_single_position ; reader . seek ( SeekFrom :: Start ( offsets_to_positions_block + offset_of_current_position , ) ) ? ; let point_x = reader . read_i32 :: < LittleEndian > ( ) ? as i64 ; if point_x < query_bounds_local . min ( ) . x || point_x > query_bounds_local . max ( ) . x { continue ; } let point_y = reader . read_i32 :: < LittleEndian > ( ) ? as i64 ; if point_y < query_bounds_local . min ( ) . y || point_y > query_bounds_local . max ( ) . y { continue ; } let point_z = reader . read_i32 :: < LittleEndian > ( ) ? as i64 ; if point_z < query_bounds_local . min ( ) . z || point_z > query_bounds_local . max ( ) . z { continue ; } // Read classification let offset_of_current_classification = idx ; reader . seek ( SeekFrom :: Start ( offset_to_classification_block + offset_of_current_classification , ) ) ? ; let class = reader . read_u8 ( ) ? ; // Read color (if it exists) let color = if let Some ( color_offset ) = offset_to_color_block { reader . seek ( SeekFrom :: Start ( ( idx * size_of_single_color ) + color_offset ) ) ? ; let r = reader . read_u16 :: < LittleEndian > ( ) ? ; let g = reader . read_u16 :: < LittleEndian > ( ) ? ; let b = reader . read_u16 :: < LittleEndian > ( ) ? ; Vector3 :: new ( r , g , b ) } else { Vector3 :: new ( 0 , 0 , 0 ) } ; result_collector . collect_one ( Point { position : Vector3 :: new ( ( point_x as f64 * raw_header . x_scale_factor ) + raw_header . x_offset , ( point_y as f64 * raw_header . y_scale_factor ) + raw_header . y_offset , ( point_z as f64 * raw_header . z_scale_factor ) + raw_header . z_offset , ) , classification : class , color , } ) ; } Ok ( ( ) ) }
Each type of search is implemented twice, once by using the pointstream crate (simulating a real-world use-case)
 and once with a hand-rolled solution (simulating maximum efficiency)
Each type of search is implemented twice once by using the pointstream crate ( simulating a real - world use - case ) and once with a hand - rolled solution ( simulating maximum efficiency )
path
P
bounds
&AABB<f64>
result_collector
&mut dyn ResultCollector