Skip to content

Commit 70b018e

Browse files
miguelyermo-heidelbergmyermolwiniwar
authored
LAS v1.4 (#40)
* Added implementation of Las14SyncFileWriter Class to allow the writting of las/laz files following the ASPRS LAS Specification 1.4 - R14 * Added writing of extended point fields * Added LAS version selector through --las10 flag * Added SyncFileWriterFactory class to create the proper file writer based on input flags. Typos. * Added classification labels to match the LAS v1.4 r15 specification. Also, now the links point to the documents of that specification version. * Added function to choose the type of the writer to be created. * Fixed TRANSMISSION_TOWER class label. * Removed warning when using --lasOutput and --zipOutput at the same time. They are not mutually exclusive. * Set Global Encoding to match GPS Week time Co-authored-by: Miguel Yermo <[email protected]> Co-authored-by: Lukas Winiwarter <[email protected]>
1 parent 6b930de commit 70b018e

12 files changed

+396
-128
lines changed

src/LidarSim.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,10 @@ void printHelp(){
6262
<< "\n\t\t\tYYYY-mm-DD HH::MM::SS\n"
6363
<< "\t\t\t\tBy default: a random seed is generated\n\n"
6464
<< "\t\t--lasOutput : Use this flag to generate the output point cloud "
65-
"in LAS format (v 1.0)\n\n"
66-
<< "\t\t--zipOutput : Use this flag to generate compressed output\n\n"
67-
<< "\t\t--lasScale : Specify the decimal scale factor for LAS output"
65+
"in LAS format (v 1.4)\n\n"
66+
<< "\t\t--las10: Use this flag to write in LAS format (v 1.0)\n\n"
67+
<< "\t\t--zipOutput : Use this flag to generate compressed output\n\n"
68+
<< "\t\t--lasScale : Specify the decimal scale factor for LAS output"
6869
<< "\n\n"
6970
<< "\t\t-j or --njobs or --nthreads <integer> : Specify the number of"
7071
<< "\n\t\t\tjobs to be used to compute the simulation\n"
@@ -166,6 +167,7 @@ int main(int argc, char** argv) {
166167
ap.parseDisableLegNoise(),
167168
ap.parseRebuildScene(),
168169
ap.parseLasOutput(),
170+
ap.parseLas10(),
169171
ap.parseZipOutput(),
170172
ap.parseFixedIncidenceAngle(),
171173
ap.parseLasScale()
@@ -187,6 +189,7 @@ void LidarSim::init(
187189
bool legNoiseDisabled,
188190
bool rebuildScene,
189191
bool lasOutput,
192+
bool las10,
190193
bool zipOutput,
191194
bool fixedIncidenceAngle,
192195
double lasScale
@@ -196,13 +199,14 @@ void LidarSim::init(
196199
<< "assetsPath: \"" << assetsPath << "\"\n"
197200
<< "outputPath: \"" << outputPath << "\"\n"
198201
<< "writeWaveform: " << writeWaveform << "\n"
199-
<< "calcEchowidth: " << calcEchowidth << "\n"
202+
<< "calcEchowidth: " << calcEchowidth << "\n"
200203
<< "fullWaveNoise: " << fullWaveNoise << "\n"
201204
<< "njobs: " << njobs << "\n"
202205
<< "platformNoiseDisabled: " << platformNoiseDisabled << "\n"
203206
<< "legNoiseDisabled: " << legNoiseDisabled << "\n"
204207
<< "rebuildScene: " << rebuildScene << "\n"
205208
<< "lasOutput: " << lasOutput << "\n"
209+
<< "las10: " << las10 << "\n"
206210
<< "fixedIncidenceAngle: " << fixedIncidenceAngle << std::endl;
207211
logging::INFO(ss.str());
208212

@@ -220,6 +224,7 @@ void LidarSim::init(
220224
survey->scanner->setPlatformNoiseDisabled(platformNoiseDisabled);
221225
survey->scanner->setFixedIncidenceAngle(fixedIncidenceAngle);
222226
survey->scanner->detector->lasOutput = lasOutput;
227+
survey->scanner->detector->las10 = las10;
223228
survey->scanner->detector->zipOutput = zipOutput;
224229
survey->scanner->detector->lasScale = lasScale;
225230
if (survey == nullptr) {

src/LidarSim.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class LidarSim {
4949
bool legNoiseDisabled = false,
5050
bool rebuildScene = false,
5151
bool lasOutput = false,
52+
bool las10 = false,
5253
bool zipOutput = false,
5354
bool fixedIncidenceAngle = false,
5455
double lasScale = 0.0001

src/scanner/detector/AbstractDetector.cpp

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
#include <iostream>
66
using namespace std;
77

8-
#include <logging.hpp>
98
#include <boost/filesystem.hpp>
9+
#include <logging.hpp>
1010
namespace fs = boost::filesystem;
1111

1212
// *** CONSTRUCTION / DESTRUCTION *** //
@@ -22,37 +22,43 @@ void AbstractDetector::_clone(std::shared_ptr<AbstractDetector> ad){
2222
ad->outputFileLineFormatString = outputFileLineFormatString;
2323
ad->outputFilePath = outputFilePath;
2424
ad->lasOutput = lasOutput;
25+
ad->las10 = las10;
2526
ad->zipOutput = zipOutput;
2627
}
2728

2829
// *** M E T H O D S *** //
2930
// *********************** //
30-
// ATTENTION: This method needs to be synchronized since multiple threads are writing to the output file!
31+
WriterType AbstractDetector::chooseWriterType() {
32+
// Get the type of writer to be created
33+
WriterType wt;
34+
if (lasOutput) wt = las10 ? las10Type : las14Type;
35+
else if (zipOutput) wt = zipType;
36+
else wt = simpleType;
37+
38+
return wt;
39+
}
40+
// ATTENTION: This method needs to be synchronized since multiple threads are
41+
// writing to the output file!
3142
void AbstractDetector::setOutputFilePath(string path) {
32-
this->outputFilePath = path;
33-
logging::WARN("outputFilePath="+path);
34-
try {
35-
fs::create_directories(outputFilePath.parent_path());
36-
if (lasOutput) {
37-
sfw = std::make_shared<LasSyncFileWriter>(
38-
path, // Output path
39-
zipOutput, // Zip flag
40-
lasScale, // Scale factor
41-
scanner->platform->scene->getShift(), // Offset
42-
0.0, // Min intensity
43-
1000000.0 // Delta intensity
44-
);
45-
}
46-
else if (zipOutput) {
47-
sfw = std::make_shared<ZipSyncFileWriter>(path);
48-
}
49-
else {
50-
sfw = std::make_shared<SimpleSyncFileWriter>(path);
51-
}
52-
}
53-
catch (std::exception &e) {
54-
logging::WARN(e.what());
55-
}
43+
this->outputFilePath = path;
44+
logging::WARN("outputFilePath=" + path);
45+
try {
46+
fs::create_directories(outputFilePath.parent_path());
47+
48+
WriterType wt = chooseWriterType();
49+
// Create the Writer
50+
sfw = SyncFileWriterFactory::makeWriter(
51+
wt,
52+
path, // Output path
53+
zipOutput, // Zip flag
54+
lasScale, // Scale factor
55+
scanner->platform->scene->getShift(), // Offset
56+
0.0, // Min intensity
57+
1000000.0 // Delta intensity
58+
);
59+
} catch (std::exception &e) {
60+
logging::WARN(e.what());
61+
}
5662
}
5763

5864
void AbstractDetector::shutdown() {

src/scanner/detector/AbstractDetector.h

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ namespace fs = boost::filesystem;
1212
#include "MeasurementsBuffer.h"
1313
#include "SimpleSyncFileWriter.h"
1414
#include "LasSyncFileWriter.h"
15+
#include "Las14SyncFileWriter.h"
1516
#include "ZipSyncFileWriter.h"
17+
#include "SyncFileWriterFactory.h"
1618

1719
/**
1820
* @brief Base abstract class for detectors
@@ -50,6 +52,11 @@ class AbstractDetector {
5052
* @see AbstractDetector::lasScale
5153
*/
5254
bool lasOutput;
55+
/**
56+
* @brief Flag specifying if detect output must be writing in LAS 1.0
57+
* (LAS 1.4 is written by default)
58+
*/
59+
bool las10;
5360
/**
5461
* @brief Flag specifying if detector output must be zipped (true)
5562
* or not (false)
@@ -90,11 +97,12 @@ class AbstractDetector {
9097
double rangeMin_m
9198
){
9299
this->lasOutput = false;
100+
this->las10 = false;
93101
this->zipOutput = false;
94102
this->lasScale = 0.0001;
95-
this->cfg_device_accuracy_m = accuracy_m;
96-
this->cfg_device_rangeMin_m = rangeMin_m;
97-
this->scanner = std::move(scanner);
103+
this->cfg_device_accuracy_m = accuracy_m;
104+
this->cfg_device_rangeMin_m = rangeMin_m;
105+
this->scanner = std::move(scanner);
98106
}
99107
virtual ~AbstractDetector() {}
100108
virtual std::shared_ptr<AbstractDetector> clone() = 0;
@@ -115,11 +123,16 @@ class AbstractDetector {
115123
* @brief Write a list of measurements
116124
* @param m List of measurements to be written
117125
*/
118-
void writeMeasurements(std::list<Measurement*> & m);
119-
/**
120-
* @brief Apply scanner settings to the detector
121-
* @param settings Settings to be applied to de detector
122-
*/
126+
void writeMeasurements(std::list<Measurement*> & m);
127+
/**
128+
* @brief Choose a type of file writer based on input flags
129+
* @return Type of writer to be created
130+
*/
131+
WriterType chooseWriterType();
132+
/**
133+
* @brief Apply scanner settings to the detector
134+
* @param settings Settings to be applied to de detector
135+
*/
123136
virtual void applySettings(std::shared_ptr<ScannerSettings> & settings) {};
124137

125138
/**

src/util/ArgumentsParser.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ bool ArgumentsParser::parseLasOutput(){
120120
return findIndexOfArgument("--lasOutput") >= 0;
121121
}
122122

123+
bool ArgumentsParser::parseLas10(){
124+
return findIndexOfArgument("--las10") >= 0;
125+
}
126+
123127
bool ArgumentsParser::parseZipOutput(){
124128
return findIndexOfArgument("--zipOutput") >= 0;
125129
}

src/util/ArgumentsParser.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ class ArgumentsParser {
109109
* @return True if LAS output was requested, False otherwise.
110110
*/
111111
bool parseLasOutput();
112+
/**
113+
* @brief Parse the LAS version output specification
114+
* @return True if LAS v1.0 was requested, False otherwise.
115+
*/
116+
bool parseLas10();
112117
/**
113118
* @brief Parse the ZIP output specification
114119
* @return True if ZIP output was requested, False otherwise.

src/util/Las14SyncFileWriter.h

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#pragma once
2+
3+
// Includes
4+
#include "LasSyncFileWriter.h"
5+
6+
7+
8+
/**
9+
* @author Miguel Yermo García
10+
* @version 1.0
11+
* @brief LasSyncFileWriter implementation for LAS v1.4 format
12+
*/
13+
class Las14SyncFileWriter : public LasSyncFileWriter
14+
{
15+
public:
16+
17+
Las14SyncFileWriter();
18+
19+
explicit Las14SyncFileWriter(
20+
const std::string &path_,
21+
bool compress_ = false,
22+
double scaleFactor_ = 0.0001,
23+
glm::dvec3 offset_ = glm::dvec3(0, 0, 0),
24+
double minIntensity_ = 0.0,
25+
double deltaIntensity_ = 1000000.0
26+
) :
27+
LasSyncFileWriter() {
28+
path = path_;
29+
scaleFactor = scaleFactor_;
30+
offset = offset_;
31+
minIntensity = minIntensity_;
32+
deltaIntensity = deltaIntensity_;
33+
finished = false;
34+
35+
// Craft header and point format
36+
craft();
37+
38+
// Add extra attributes
39+
addExtraAttributes();
40+
41+
// Create LASWriter
42+
createLasWriter(path, compress_);
43+
};
44+
45+
// *** CRAFTING *** //
46+
/**
47+
* Crafting of header of the LAS file for version 1.4
48+
*/
49+
void craft()
50+
{
51+
// Craft version of LasSyncWriter LAS 1.0
52+
LasSyncFileWriter::craft();
53+
54+
// Update Header to 1.4 specification
55+
lwHeader.version_minor = U8(4);
56+
57+
// Update Point Data Format to support new return number / classes
58+
lwHeader.point_data_format = 6;
59+
lwHeader.point_data_record_length = 30;
60+
61+
// Adds the byte difference between LAS 1.4 and LAS 1.0 (350 - 227)
62+
lwHeader.header_size += 148;
63+
64+
// Adds the byte difference to the data point offset
65+
lwHeader.offset_to_point_data += 148;
66+
67+
}
68+
69+
70+
};

src/util/LasSpecification.h

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22

33
/**
44
* @brief Class representing LAS specification
5+
* Classes from 0 to 63 are defined by the specification
6+
* Classes from 64 to 255 are user definable.
57
*
68
* For more information visit:
7-
* https://www.asprs.org/a/society/committees/standards/LAS_1_4_r13.pdf
9+
* http://www.asprs.org/wp-content/uploads/2019/07/LAS_1_4_r15.pdf
810
*/
911
class LasSpecification {
10-
11-
// See https://www.asprs.org/a/society/committees/standards/LAS_1_4_r13.pdf
12+
13+
14+
// See http://www.asprs.org/wp-content/uploads/2019/07/LAS_1_4_r15.pdf
1215
public:
1316
// *** CONSTANTS *** //
1417
// ******************* //
@@ -67,9 +70,32 @@ class LasSpecification {
6770
/**
6871
* @brief Transmission tower class integer
6972
*/
70-
static const int TRANSMISSION_TOWER = 14;
73+
static const int TRANSMISSION_TOWER = 15;
7174
/**
7275
* @brief Wire structure class integer
7376
*/
7477
static const int WIRE_STRUCTURE = 16;
78+
/**
79+
* @brief Bridge Deck class integer
80+
*/
81+
static const int BRIDGE_DECK = 17;
82+
/**
83+
* @brief High Noise class integer
84+
*/
85+
static const int HIGH_NOISE = 18;
86+
/**
87+
* @brief Overhead Structure class integer
88+
* E.g. conveyors, mining equipment, traffic lights
89+
*/
90+
static const int OVERHEAD_STRUCTURE = 19;
91+
/**
92+
* @brief Ignored ground class integer
93+
* E.g. breakline proximity
94+
*/
95+
static const int IGNORED_GROUND = 20;
96+
/**
97+
* @brief Snow class integer
98+
*/
99+
static const int SNOW = 21;
100+
75101
};

0 commit comments

Comments
 (0)