Skip to content

Commit

Permalink
Fix parsing 2-byte LAS scan angle
Browse files Browse the repository at this point in the history
  • Loading branch information
dvdkon authored and wonder-sk committed Oct 8, 2024
1 parent 8a61127 commit 91d5676
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 20 deletions.
11 changes: 9 additions & 2 deletions src/core/pointcloud/qgslazdecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,9 @@ void decodePoint( char *buf, int lasPointFormat, char *dataBuffer, std::size_t &
lazperf::las::nir14 nir;
lazperf::las::point14 p14;

bool isLas14 = ( lasPointFormat == 6 || lasPointFormat == 7 || lasPointFormat == 8 );
// Does the point record start with the common fields for formats introduced
// in the LAS 1.4 spec?
const bool isLas14 = ( lasPointFormat == 6 || lasPointFormat == 7 || lasPointFormat == 8 || lasPointFormat == 9 || lasPointFormat == 10 );

switch ( lasPointFormat )
{
Expand Down Expand Up @@ -397,7 +399,12 @@ void decodePoint( char *buf, int lasPointFormat, char *dataBuffer, std::size_t &
lazStoreToStream_<unsigned char>( dataBuffer, outputOffset, requestedAttribute.type, isLas14 ? p14.eofFlag() : p10.edge_of_flight_line );
break;
case QgsLazDecoder::LazAttribute::ScanAngleRank:
lazStoreToStream_<char>( dataBuffer, outputOffset, requestedAttribute.type, char( isLas14 ? p14.scanAngle() : p10.scan_angle_rank ) );
lazStoreToStream_<float>( dataBuffer, outputOffset, requestedAttribute.type,
isLas14
// Formats from LAS 1.4 spec store the angle in 0.006 degree increments
? p14.scanAngle() * 0.006f
// Older formats store integer values
: p10.scan_angle_rank );
break;
case QgsLazDecoder::LazAttribute::UserData:
lazStoreToStream_<unsigned char>( dataBuffer, outputOffset, requestedAttribute.type, isLas14 ? p14.userData() : p10.user_data );
Expand Down
2 changes: 1 addition & 1 deletion src/core/pointcloud/qgslazinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ void QgsLazInfo::parseLazAttributes()
mAttributes.push_back( QgsPointCloudAttribute( "ScanDirectionFlag", QgsPointCloudAttribute::Char ) );
mAttributes.push_back( QgsPointCloudAttribute( "EdgeOfFlightLine", QgsPointCloudAttribute::Char ) );
mAttributes.push_back( QgsPointCloudAttribute( "Classification", QgsPointCloudAttribute::UChar ) );
mAttributes.push_back( QgsPointCloudAttribute( "ScanAngleRank", QgsPointCloudAttribute::Short ) );
mAttributes.push_back( QgsPointCloudAttribute( "ScanAngleRank", QgsPointCloudAttribute::Float ) );
mAttributes.push_back( QgsPointCloudAttribute( "UserData", QgsPointCloudAttribute::UChar ) );
mAttributes.push_back( QgsPointCloudAttribute( "PointSourceId", QgsPointCloudAttribute::UShort ) );
mAttributes.push_back( QgsPointCloudAttribute( "Synthetic", QgsPointCloudAttribute::UChar ) );
Expand Down
2 changes: 1 addition & 1 deletion src/core/pointcloud/qgspointcloudlayerexporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ void QgsPointCloudLayerExporter::ExporterPdal::handlePoint( double x, double y,
mView->setField( pdal::Dimension::Id::NumberOfReturns, pointNumber, map[ QStringLiteral( "NumberOfReturns" ) ].toInt() );
mView->setField( pdal::Dimension::Id::ScanDirectionFlag, pointNumber, map[ QStringLiteral( "ScanDirectionFlag" ) ].toInt() );
mView->setField( pdal::Dimension::Id::EdgeOfFlightLine, pointNumber, map[ QStringLiteral( "EdgeOfFlightLine" ) ].toInt() );
mView->setField( pdal::Dimension::Id::ScanAngleRank, pointNumber, map[ QStringLiteral( "ScanAngleRank" ) ].toInt() );
mView->setField( pdal::Dimension::Id::ScanAngleRank, pointNumber, map[ QStringLiteral( "ScanAngleRank" ) ].toFloat() );
mView->setField( pdal::Dimension::Id::UserData, pointNumber, map[ QStringLiteral( "UserData" ) ].toInt() );
mView->setField( pdal::Dimension::Id::PointSourceId, pointNumber, map[ QStringLiteral( "PointSourceId" ) ].toInt() );

Expand Down
2 changes: 1 addition & 1 deletion src/core/providers/vpc/qgsvirtualpointcloudprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ void QgsVirtualPointCloudProvider::populateAttributeCollection( QSet<QString> na
if ( names.contains( QLatin1String( "Classification" ) ) )
mAttributes.push_back( QgsPointCloudAttribute( QStringLiteral( "Classification" ), QgsPointCloudAttribute::UChar ) );
if ( names.contains( QLatin1String( "ScanAngleRank" ) ) )
mAttributes.push_back( QgsPointCloudAttribute( QStringLiteral( "ScanAngleRank" ), QgsPointCloudAttribute::Short ) );
mAttributes.push_back( QgsPointCloudAttribute( QStringLiteral( "ScanAngleRank" ), QgsPointCloudAttribute::Float ) );
if ( names.contains( QLatin1String( "UserData" ) ) )
mAttributes.push_back( QgsPointCloudAttribute( QStringLiteral( "UserData" ), QgsPointCloudAttribute::Char ) );
if ( names.contains( QLatin1String( "PointSourceId" ) ) )
Expand Down
28 changes: 14 additions & 14 deletions tests/src/providers/testqgscopcprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ void TestQgsCopcProvider::attributes()
QCOMPARE( attributes.at( 8 ).name(), QStringLiteral( "Classification" ) );
QCOMPARE( attributes.at( 8 ).type(), QgsPointCloudAttribute::UChar );
QCOMPARE( attributes.at( 9 ).name(), QStringLiteral( "ScanAngleRank" ) );
QCOMPARE( attributes.at( 9 ).type(), QgsPointCloudAttribute::Short );
QCOMPARE( attributes.at( 9 ).type(), QgsPointCloudAttribute::Float );
QCOMPARE( attributes.at( 10 ).name(), QStringLiteral( "UserData" ) );
QCOMPARE( attributes.at( 10 ).type(), QgsPointCloudAttribute::UChar );
QCOMPARE( attributes.at( 11 ).name(), QStringLiteral( "PointSourceId" ) );
Expand Down Expand Up @@ -404,7 +404,7 @@ void TestQgsCopcProvider::testIdentify()
expected[ QStringLiteral( "PointSourceId" ) ] = 7041;
expected[ QStringLiteral( "Red" ) ] = 0;
expected[ QStringLiteral( "ReturnNumber" ) ] = 1;
expected[ QStringLiteral( "ScanAngleRank" ) ] = -59;
expected[ QStringLiteral( "ScanAngleRank" ) ] = -28.0020008087;
expected[ QStringLiteral( "ScanDirectionFlag" ) ] = 1;
expected[ QStringLiteral( "UserData" ) ] = 17;
expected[ QStringLiteral( "X" ) ] = 498062.52;
Expand Down Expand Up @@ -443,7 +443,7 @@ void TestQgsCopcProvider::testIdentify()
point[ QStringLiteral( "PointSourceId" ) ] = "7041" ;
point[ QStringLiteral( "Red" ) ] = "0" ;
point[ QStringLiteral( "ReturnNumber" ) ] = "1" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "-59" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "-28.0020008087" ;
point[ QStringLiteral( "ScanDirectionFlag" ) ] = "1" ;
point[ QStringLiteral( "UserData" ) ] = "17" ;
point[ QStringLiteral( "X" ) ] = "498066.27" ;
Expand Down Expand Up @@ -486,7 +486,7 @@ void TestQgsCopcProvider::testIdentify()
point[ QStringLiteral( "PointSourceId" ) ] = "7041" ;
point[ QStringLiteral( "Red" ) ] = "0" ;
point[ QStringLiteral( "ReturnNumber" ) ] = "1" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "-59" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "-28.0020008087" ;
point[ QStringLiteral( "ScanDirectionFlag" ) ] = "1" ;
point[ QStringLiteral( "UserData" ) ] = "17" ;
point[ QStringLiteral( "X" ) ] = "498063.14" ;
Expand All @@ -506,7 +506,7 @@ void TestQgsCopcProvider::testIdentify()
point[ QStringLiteral( "PointSourceId" ) ] = "7042" ;
point[ QStringLiteral( "Red" ) ] = "0" ;
point[ QStringLiteral( "ReturnNumber" ) ] = "1" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "48" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "-12" ;
point[ QStringLiteral( "ScanDirectionFlag" ) ] = "1" ;
point[ QStringLiteral( "UserData" ) ] = "17" ;
point[ QStringLiteral( "X" ) ] = "498063.11" ;
Expand Down Expand Up @@ -597,7 +597,7 @@ void TestQgsCopcProvider::testExtraBytesAttributesValues()
point[ QStringLiteral( "Red" ) ] = "0" ;
point[ QStringLiteral( "Reflectance" ) ] = "-8.050000190734863" ;
point[ QStringLiteral( "ReturnNumber" ) ] = "3" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "24" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "-6" ;
point[ QStringLiteral( "ScanDirectionFlag" ) ] = "0" ;
point[ QStringLiteral( "UserData" ) ] = "0" ;
point[ QStringLiteral( "X" ) ] = "527919.11" ;
Expand All @@ -620,7 +620,7 @@ void TestQgsCopcProvider::testExtraBytesAttributesValues()
point[ QStringLiteral( "Red" ) ] = "0" ;
point[ QStringLiteral( "Reflectance" ) ] = "-17.829999923706055" ;
point[ QStringLiteral( "ReturnNumber" ) ] = "2" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "24" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "-6" ;
point[ QStringLiteral( "ScanDirectionFlag" ) ] = "0" ;
point[ QStringLiteral( "UserData" ) ] = "0" ;
point[ QStringLiteral( "X" ) ] = "527919.1799999999" ;
Expand Down Expand Up @@ -681,7 +681,7 @@ void TestQgsCopcProvider::testClassFlagsValues()
point[ QStringLiteral( "Red" ) ] = "0" ;
point[ QStringLiteral( "Reflectance" ) ] = "-8.050000190734863" ;
point[ QStringLiteral( "ReturnNumber" ) ] = "3" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "24" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "-6" ;
point[ QStringLiteral( "ScanDirectionFlag" ) ] = "0" ;
point[ QStringLiteral( "UserData" ) ] = "0" ;
point[ QStringLiteral( "Synthetic" ) ] = "1" ;
Expand All @@ -708,7 +708,7 @@ void TestQgsCopcProvider::testClassFlagsValues()
point[ QStringLiteral( "Red" ) ] = "0" ;
point[ QStringLiteral( "Reflectance" ) ] = "-17.829999923706055" ;
point[ QStringLiteral( "ReturnNumber" ) ] = "2" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "24" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "-6" ;
point[ QStringLiteral( "ScanDirectionFlag" ) ] = "0" ;
point[ QStringLiteral( "UserData" ) ] = "0" ;
point[ QStringLiteral( "Synthetic" ) ] = "1" ;
Expand All @@ -735,7 +735,7 @@ void TestQgsCopcProvider::testClassFlagsValues()
point[ QStringLiteral( "Red" ) ] = "0" ;
point[ QStringLiteral( "Reflectance" ) ] = "-14.720000267028809" ;
point[ QStringLiteral( "ReturnNumber" ) ] = "2" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "24" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "-6" ;
point[ QStringLiteral( "ScanDirectionFlag" ) ] = "0" ;
point[ QStringLiteral( "UserData" ) ] = "0" ;
point[ QStringLiteral( "Synthetic" ) ] = "1" ;
Expand All @@ -762,7 +762,7 @@ void TestQgsCopcProvider::testClassFlagsValues()
point[ QStringLiteral( "Red" ) ] = "0" ;
point[ QStringLiteral( "Reflectance" ) ] = "-6.829999923706055" ;
point[ QStringLiteral( "ReturnNumber" ) ] = "3" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "24" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "-6" ;
point[ QStringLiteral( "ScanDirectionFlag" ) ] = "0" ;
point[ QStringLiteral( "UserData" ) ] = "0" ;
point[ QStringLiteral( "Synthetic" ) ] = "1" ;
Expand All @@ -789,7 +789,7 @@ void TestQgsCopcProvider::testClassFlagsValues()
point[ QStringLiteral( "Red" ) ] = "0" ;
point[ QStringLiteral( "Reflectance" ) ] = "-10.550000190734863" ;
point[ QStringLiteral( "ReturnNumber" ) ] = "1" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "24" ;
point[ QStringLiteral( "ScanAngleRank" ) ] = "-6" ;
point[ QStringLiteral( "ScanDirectionFlag" ) ] = "0" ;
point[ QStringLiteral( "UserData" ) ] = "0" ;
point[ QStringLiteral( "Synthetic" ) ] = "0" ;
Expand Down Expand Up @@ -1035,8 +1035,8 @@ void TestQgsCopcProvider::testStatsCalculator()

{
QgsPointCloudAttributeStatistics s = stats.statisticsOf( QStringLiteral( "ScanAngleRank" ) );
QCOMPARE( ( float )s.minimum, -65 );
QCOMPARE( ( float )s.maximum, 125 );
QCOMPARE( ( float )s.minimum, -10.998000145f );
QCOMPARE( ( float )s.maximum, -4.001999855f );
}

{
Expand Down
2 changes: 1 addition & 1 deletion tests/src/providers/testqgsvirtualpointcloudprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ void TestQgsVirtualPointCloudProvider::attributes()
QCOMPARE( attributes.at( 8 ).name(), QStringLiteral( "Classification" ) );
QCOMPARE( attributes.at( 8 ).type(), QgsPointCloudAttribute::UChar );
QCOMPARE( attributes.at( 9 ).name(), QStringLiteral( "ScanAngleRank" ) );
QCOMPARE( attributes.at( 9 ).type(), QgsPointCloudAttribute::Short );
QCOMPARE( attributes.at( 9 ).type(), QgsPointCloudAttribute::Float );
QCOMPARE( attributes.at( 10 ).name(), QStringLiteral( "UserData" ) );
QCOMPARE( attributes.at( 10 ).type(), QgsPointCloudAttribute::Char );
QCOMPARE( attributes.at( 11 ).name(), QStringLiteral( "PointSourceId" ) );
Expand Down

0 comments on commit 91d5676

Please sign in to comment.