@@ -391,11 +391,46 @@ fn validate_coordinate_inputs<S: CopcPointSource>(
391391 let fields = source. fields ( index) ?;
392392 validate_xyz_finite ( index, fields. x , fields. y , fields. z ) ?;
393393 quantize_xyz ( index, fields. x , fields. y , fields. z , scale, offset) ?;
394+ validate_point_flags ( index, & fields) ?;
394395 stats. record ( index, & fields) ?;
395396 }
396397 Ok ( stats)
397398}
398399
400+ fn validate_point_flags ( index : usize , fields : & CopcPointFields ) -> Result < ( ) > {
401+ validate_point_field_range ( index, "return_number" , fields. return_number , 0 , 15 ) ?;
402+ validate_point_field_range ( index, "number_of_returns" , fields. number_of_returns , 0 , 15 ) ?;
403+ validate_point_field_range ( index, "synthetic" , fields. synthetic , 0 , 1 ) ?;
404+ validate_point_field_range ( index, "key_point" , fields. key_point , 0 , 1 ) ?;
405+ validate_point_field_range ( index, "withheld" , fields. withheld , 0 , 1 ) ?;
406+ validate_point_field_range ( index, "overlap" , fields. overlap , 0 , 1 ) ?;
407+ validate_point_field_range ( index, "scan_channel" , fields. scan_channel , 0 , 3 ) ?;
408+ validate_point_field_range (
409+ index,
410+ "scan_direction_flag" ,
411+ fields. scan_direction_flag ,
412+ 0 ,
413+ 1 ,
414+ ) ?;
415+ validate_point_field_range (
416+ index,
417+ "edge_of_flight_line" ,
418+ fields. edge_of_flight_line ,
419+ 0 ,
420+ 1 ,
421+ )
422+ }
423+
424+ fn validate_point_field_range ( index : usize , name : & str , value : u8 , min : u8 , max : u8 ) -> Result < ( ) > {
425+ if ( min..=max) . contains ( & value) {
426+ Ok ( ( ) )
427+ } else {
428+ Err ( Error :: InvalidInput ( format ! (
429+ "point {index} {name} must be in {min}..={max}, got {value}"
430+ ) ) )
431+ }
432+ }
433+
399434fn validate_bounds ( bounds : Bounds ) -> Result < ( ) > {
400435 validate_finite_value ( "bounds min x" , bounds. min . 0 ) ?;
401436 validate_finite_value ( "bounds min y" , bounds. min . 1 ) ?;
@@ -1396,23 +1431,19 @@ fn encode_point_record(
13961431) -> Result < ( ) > {
13971432 let mut cursor = Cursor :: new ( buf) ;
13981433 let ( ix, iy, iz) = quantize_xyz ( point_index, fields. x , fields. y , fields. z , scale, offset) ?;
1399- let rn = fields. return_number & 0x0F ;
1400- let nr = fields. number_of_returns & 0x0F ;
1401- let flags = ( fields. synthetic & 1 )
1402- | ( ( fields. key_point & 1 ) << 1 )
1403- | ( ( fields. withheld & 1 ) << 2 )
1404- | ( ( fields. overlap & 1 ) << 3 ) ;
1405- let chan = fields. scan_channel & 0x03 ;
1406- let sd = fields. scan_direction_flag & 1 ;
1407- let eof = fields. edge_of_flight_line & 1 ;
1434+ let flags =
1435+ fields. synthetic | ( fields. key_point << 1 ) | ( fields. withheld << 2 ) | ( fields. overlap << 3 ) ;
14081436 let point = raw:: Point {
14091437 x : ix,
14101438 y : iy,
14111439 z : iz,
14121440 intensity : fields. intensity ,
14131441 flags : raw:: point:: Flags :: ThreeByte (
1414- rn | ( nr << 4 ) ,
1415- flags | ( chan << 4 ) | ( sd << 6 ) | ( eof << 7 ) ,
1442+ fields. return_number | ( fields. number_of_returns << 4 ) ,
1443+ flags
1444+ | ( fields. scan_channel << 4 )
1445+ | ( fields. scan_direction_flag << 6 )
1446+ | ( fields. edge_of_flight_line << 7 ) ,
14161447 fields. classification ,
14171448 ) ,
14181449 scan_angle : raw:: point:: ScanAngle :: from ( fields. scan_angle_rank as f32 ) ,
0 commit comments