forked from LAStools/LAStools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlasmerge.cpp
358 lines (310 loc) · 10.3 KB
/
lasmerge.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
/*
===============================================================================
FILE: lasmerge.cpp
CONTENTS:
This tool merges multiple LAS file into a single LAS file and outputs it in
the LAS format. As input the user either provides multiple LAS file names or
a text file containing a list of LAS file names.
PROGRAMMERS:
[email protected] - http://rapidlasso.com
COPYRIGHT:
(c) 2007-12, martin isenburg, rapidlasso - fast tools to catch reality
This is free software; you can redistribute and/or modify it under the
terms of the GNU Lesser General Licence as published by the Free Software
Foundation. See the LICENSE.txt file for more information.
This software is distributed WITHOUT ANY WARRANTY and without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
CHANGE HISTORY:
20 August 2014 -- new option '-keep_lastiling' to preserve the LAStiling VLR
20 August 2014 -- copy VLRs from empty (zero points) LAS/LAZ files to others
5 August 2011 -- possible to add/change projection info in command line
13 May 2011 -- moved indexing, filtering, transforming into LASreader
21 January 2011 -- added LASreadOpener and reading of multiple LAS files
7 January 2011 -- added the LASfilter to drop or keep points
12 March 2009 -- updated to ask for input if started without arguments
07 November 2007 -- created after email from [email protected]
===============================================================================
*/
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include "lasreader.hpp"
#include "laswriter.hpp"
#include "geoprojectionconverter.hpp"
void usage(bool error=false, bool wait=false)
{
fprintf(stderr,"usage:\n");
fprintf(stderr,"lasmerge -i *.las -o out.las\n");
fprintf(stderr,"lasmerge -lof lasfiles.txt -o out.las\n");
fprintf(stderr,"lasmerge -i *.las -o out0000.laz -split 1000000000\n");
fprintf(stderr,"lasmerge -i file1.las file2.las file3.las -o out.las\n");
fprintf(stderr,"lasmerge -i file1.las file2.las -reoffset 600000 4000000 0 -olas > out.las\n");
fprintf(stderr,"lasmerge -lof lasfiles.txt -rescale 0.01 0.01 0.01 -verbose -o out.las\n");
fprintf(stderr,"lasmerge -h\n");
if (wait)
{
fprintf(stderr,"<press ENTER>\n");
getc(stdin);
}
exit(error);
}
static void byebye(bool error=false, bool wait=false)
{
if (wait)
{
fprintf(stderr,"<press ENTER>\n");
getc(stdin);
}
exit(error);
}
static double taketime()
{
return (double)(clock())/CLOCKS_PER_SEC;
}
#ifdef COMPILE_WITH_GUI
extern int lasmerge_gui(int argc, char *argv[], LASreadOpener* lasreadopener);
#endif
int main(int argc, char *argv[])
{
int i;
#ifdef COMPILE_WITH_GUI
bool gui = false;
#endif
bool verbose = false;
bool keep_lastiling = false;
U32 chopchop = 0;
bool projection_was_set = false;
double start_time = 0;
LASreadOpener lasreadopener;
GeoProjectionConverter geoprojectionconverter;
LASwriteOpener laswriteopener;
if (argc == 1)
{
#ifdef COMPILE_WITH_GUI
return lasmerge_gui(argc, argv, 0);
#else
fprintf(stderr,"%s is better run in the command line\n", argv[0]);
char file_name[256];
fprintf(stderr,"enter input file 1: "); fgets(file_name, 256, stdin);
file_name[strlen(file_name)-1] = '\0';
lasreadopener.add_file_name(file_name);
fprintf(stderr,"enter input file 2: "); fgets(file_name, 256, stdin);
file_name[strlen(file_name)-1] = '\0';
lasreadopener.add_file_name(file_name);
fprintf(stderr,"enter output file: "); fgets(file_name, 256, stdin);
file_name[strlen(file_name)-1] = '\0';
laswriteopener.set_file_name(file_name);
#endif
}
else
{
for (i = 1; i < argc; i++)
{
if (argv[i][0] == '–') argv[i][0] = '-';
}
if (!geoprojectionconverter.parse(argc, argv)) byebye(true);
if (!lasreadopener.parse(argc, argv)) byebye(true);
if (!laswriteopener.parse(argc, argv)) byebye(true);
}
for (i = 1; i < argc; i++)
{
if (argv[i][0] == '\0')
{
continue;
}
else if (strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"-help") == 0)
{
fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION);
usage();
}
else if (strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"-verbose") == 0)
{
verbose = true;
}
else if (strcmp(argv[i],"-version") == 0)
{
fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION);
byebye();
}
else if (strcmp(argv[i],"-gui") == 0)
{
#ifdef COMPILE_WITH_GUI
gui = true;
#else
fprintf(stderr, "WARNING: not compiled with GUI support. ignoring '-gui' ...\n");
#endif
}
else if (strcmp(argv[i],"-split") == 0)
{
if ((i+1) >= argc)
{
fprintf(stderr,"ERROR: '%s' needs 1 argument: size\n", argv[i]);
byebye(true);
}
i++;
chopchop = atoi(argv[i]);
}
else if (strcmp(argv[i],"-keep_lastiling") == 0)
{
keep_lastiling = true;
}
else if ((argv[i][0] != '-') && (lasreadopener.get_file_name_number() == 0))
{
lasreadopener.add_file_name(argv[i]);
argv[i][0] = '\0';
}
else
{
fprintf(stderr, "ERROR: cannot understand argument '%s'\n", argv[i]);
byebye(true);
}
}
#ifdef COMPILE_WITH_GUI
if (gui)
{
return lasmerge_gui(argc, argv, &lasreadopener);
}
#endif
// read all the input files merged
lasreadopener.set_merged(TRUE);
// maybe we want to keep the lastiling
if (keep_lastiling)
{
lasreadopener.set_keep_lastiling(TRUE);
}
// we need to precompute the bounding box
lasreadopener.set_populate_header(TRUE);
// check input and output
if (!lasreadopener.active())
{
fprintf(stderr, "ERROR: no input specified\n");
byebye(true, argc==1);
}
if (!laswriteopener.active())
{
fprintf(stderr, "ERROR: no output specified\n");
byebye(true, argc==1);
}
// make sure we do not corrupt the input file
if (lasreadopener.get_file_name() && laswriteopener.get_file_name() && (strcmp(lasreadopener.get_file_name(), laswriteopener.get_file_name()) == 0))
{
fprintf(stderr, "ERROR: input and output file name are identical\n");
usage(true);
}
// check if projection info was set in the command line
int number_of_keys;
GeoProjectionGeoKeys* geo_keys = 0;
int num_geo_double_params;
double* geo_double_params = 0;
if (geoprojectionconverter.has_projection())
{
projection_was_set = geoprojectionconverter.get_geo_keys_from_projection(number_of_keys, &geo_keys, num_geo_double_params, &geo_double_params);
}
if (verbose) start_time = taketime();
LASreader* lasreader = lasreadopener.open();
if (lasreader == 0)
{
fprintf(stderr, "ERROR: could not open lasreader\n");
byebye(true, argc==1);
}
#ifdef _WIN32
if (verbose) { fprintf(stderr,"merging headers took %g sec. there are %I64d points in total.\n", taketime()-start_time, lasreader->npoints); start_time = taketime(); }
#else
if (verbose) { fprintf(stderr,"merging headers took %g sec. there are %lld points in total.\n", taketime()-start_time, lasreader->npoints); start_time = taketime(); }
#endif
// prepare the header for the surviving points
strncpy(lasreader->header.system_identifier, "LAStools (c) by rapidlasso GmbH", 32);
lasreader->header.system_identifier[31] = '\0';
char temp[64];
sprintf(temp, "lasmerge (version %d)", LAS_TOOLS_VERSION);
strncpy(lasreader->header.generating_software, temp, 32);
lasreader->header.generating_software[31] = '\0';
if (projection_was_set)
{
lasreader->header.set_geo_keys(number_of_keys, (LASvlr_key_entry*)geo_keys);
free(geo_keys);
if (geo_double_params)
{
lasreader->header.set_geo_double_params(num_geo_double_params, geo_double_params);
free(geo_double_params);
}
else
{
lasreader->header.del_geo_double_params();
}
lasreader->header.del_geo_ascii_params();
}
if (chopchop)
{
I32 file_number = 0;
LASwriter* laswriter = 0;
// loop over the points
while (lasreader->read_point())
{
if (laswriter == 0)
{
// open the next writer
laswriteopener.make_file_name(0, file_number);
file_number++;
laswriter = laswriteopener.open(&lasreader->header);
}
laswriter->write_point(&lasreader->point);
laswriter->update_inventory(&lasreader->point);
if (laswriter->p_count == chopchop)
{
// close the current writer
laswriter->update_header(&lasreader->header, TRUE);
laswriter->close();
if (verbose) { fprintf(stderr,"splitting file '%s' took %g sec.\n", laswriteopener.get_file_name(), taketime()-start_time); start_time = taketime(); }
delete laswriter;
laswriter = 0;
}
}
if (laswriter && laswriter->p_count)
{
// close the current writer
laswriter->update_header(&lasreader->header, TRUE);
laswriter->close();
if (verbose) { fprintf(stderr,"splitting file '%s' took %g sec.\n", laswriteopener.get_file_name(), taketime()-start_time); start_time = taketime(); }
delete laswriter;
laswriter = 0;
}
}
else
{
if (lasreader->npoints > U32_MAX)
{
if (lasreader->header.version_minor < 4)
{
#ifdef _WIN32
fprintf(stderr, "ERROR: cannot merge %I64d points into single LAS 1.%d file. maximum is %u\n", lasreader->npoints, lasreader->header.version_minor, U32_MAX);
#else
fprintf(stderr, "ERROR: cannot merge %lld points into single LAS 1.%d file. maximum is %u\n", lasreader->npoints, lasreader->header.version_minor, U32_MAX);
#endif
byebye(true, argc==1);
}
}
// open the writer
LASwriter* laswriter = laswriteopener.open(&lasreader->header);
if (laswriter == 0)
{
fprintf(stderr, "ERROR: could not open laswriter\n");
byebye(true, argc==1);
}
// loop over the points
while (lasreader->read_point())
{
laswriter->write_point(&lasreader->point);
laswriter->update_inventory(&lasreader->point);
}
// close the writer
laswriter->update_header(&lasreader->header, TRUE);
laswriter->close();
if (verbose) fprintf(stderr,"merging files took %g sec.\n", taketime()-start_time);
delete laswriter;
}
lasreader->close();
delete lasreader;
byebye(false, argc==1);
return 0;
}