laswriter_txt.cpp
Go to the documentation of this file.
1 /*
2 ===============================================================================
3 
4  FILE: laswriter_txt.cpp
5 
6  CONTENTS:
7 
8  see corresponding header file
9 
10  PROGRAMMERS:
11 
12  martin.isenburg@gmail.com
13 
14  COPYRIGHT:
15 
16  (c) 2007-2011, Martin Isenburg, LASSO - tools to catch reality
17 
18  This is free software; you can redistribute and/or modify it under the
19  terms of the GNU Lesser General Licence as published by the Free Software
20  Foundation. See the COPYING file for more information.
21 
22  This software is distributed WITHOUT ANY WARRANTY and without even the
23  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
24 
25  CHANGE HISTORY:
26 
27  see corresponding header file
28 
29 ===============================================================================
30 */
31 #include "laswriter_txt.hpp"
32 
33 #include <stdlib.h>
34 #include <string.h>
35 
37 {
38  this->file = file;
39  return TRUE;
40 }
41 
42 BOOL LASwriterTXT::open(const char* file_name, const LASheader* header, const char* parse_string, const char* separator)
43 {
44  if (file_name == 0)
45  {
46  fprintf(stderr,"ERROR: file name pointer is zero\n");
47  return FALSE;
48  }
49 
50  file = fopen(file_name, "w");
51 
52  if (file == 0)
53  {
54  fprintf(stderr, "ERROR: cannot open file '%s'\n", file_name);
55  return FALSE;
56  }
57 
58  close_file = TRUE;
59 
60  return open(file, header, parse_string, separator);
61 }
62 
63 BOOL LASwriterTXT::open(FILE* file, const LASheader* header, const char* parse_string, const char* separator)
64 {
65  if (file == 0)
66  {
67  fprintf(stderr,"ERROR: file pointer is zero\n");
68  return FALSE;
69  }
70 
71  this->file = file;
72  this->header = header;
73 
74  if (parse_string)
75  {
76  this->parse_string = strdup(parse_string);
77  }
78  else
79  {
81  {
82  this->parse_string = strdup("xyzt");
83  }
84  else if (header->point_data_format == 2)
85  {
86  this->parse_string = strdup("xyzRGB");
87  }
88  else if (header->point_data_format == 3 || header->point_data_format == 5)
89  {
90  this->parse_string = strdup("xyztRGB");
91  }
92  else
93  {
94  this->parse_string = strdup("xyz");
95  }
96  }
97 
98  if (!check_parse_string(this->parse_string))
99  {
100  return FALSE;
101  }
102 
103  if (separator)
104  {
105  if (strcmp(separator, "comma") == 0)
106  {
107  separator_sign = ',';
108  }
109  else if (strcmp(separator, "tab") == 0)
110  {
111  separator_sign = '\t';
112  }
113  else if (strcmp(separator, "dot") == 0 || strcmp(separator, "period") == 0)
114  {
115  separator_sign = '.';
116  }
117  else if (strcmp(separator, "colon") == 0)
118  {
119  separator_sign = ':';
120  }
121  else if (strcmp(separator, "semicolon") == 0)
122  {
123  separator_sign = ';';
124  }
125  else if (strcmp(separator, "hyphen") == 0 || strcmp(separator, "minus") == 0)
126  {
127  separator_sign = '-';
128  }
129  else if (strcmp(separator, "space") == 0)
130  {
131  separator_sign = ' ';
132  }
133  else
134  {
135  fprintf(stderr, "ERROR: unknown seperator '%s'\n", separator);
136  return FALSE;
137  }
138  }
139 
140  return TRUE;
141 }
142 
143 static void lidardouble2string(char* string, double value)
144 {
145  int len;
146  len = sprintf(string, "%.15f", value) - 1;
147  while (string[len] == '0') len--;
148  if (string[len] != '.') len++;
149  string[len] = '\0';
150 }
151 
152 static void lidardouble2string(char* string, double value, double precision)
153 {
154  if (precision == 0.1)
155  sprintf(string, "%.1f", value);
156  else if (precision == 0.01)
157  sprintf(string, "%.2f", value);
158  else if (precision == 0.001)
159  sprintf(string, "%.3f", value);
160  else if (precision == 0.0001)
161  sprintf(string, "%.4f", value);
162  else if (precision == 0.00001)
163  sprintf(string, "%.5f", value);
164  else if (precision == 0.000001)
165  sprintf(string, "%.6f", value);
166  else if (precision == 0.0000001)
167  sprintf(string, "%.7f", value);
168  else if (precision == 0.00000001)
169  sprintf(string, "%.8f", value);
170  else if (precision == 0.000000001)
171  sprintf(string, "%.9f", value);
172  else
173  lidardouble2string(string, value);
174 }
175 
177 {
178  if (index >= header->number_extra_attributes)
179  {
180  return FALSE;
181  }
182  if (header->extra_attributes[index].data_type == 1)
183  {
184  U8 value;
187  {
188  F64 temp_d = header->extra_attributes[index].scale[0]*value + header->extra_attributes[index].offset[0];
189  fprintf(file, "%g", temp_d);
190  }
191  else
192  {
193  fprintf(file, "%d", (I32)value);
194  }
195  }
196  else if (header->extra_attributes[index].data_type == 2)
197  {
198  I8 value;
201  {
202  F64 temp_d = header->extra_attributes[index].scale[0]*value + header->extra_attributes[index].offset[0];
203  fprintf(file, "%g", temp_d);
204  }
205  else
206  {
207  fprintf(file, "%d", (I32)value);
208  }
209  }
210  else if (header->extra_attributes[index].data_type == 3)
211  {
212  U16 value;
215  {
216  F64 temp_d = header->extra_attributes[index].scale[0]*value + header->extra_attributes[index].offset[0];
217  fprintf(file, "%g", temp_d);
218  }
219  else
220  {
221  fprintf(file, "%d", (I32)value);
222  }
223  }
224  else if (header->extra_attributes[index].data_type == 4)
225  {
226  I16 value;
229  {
230  F64 temp_d = header->extra_attributes[index].scale[0]*value + header->extra_attributes[index].offset[0];
231  fprintf(file, "%g", temp_d);
232  }
233  else
234  {
235  fprintf(file, "%d", (I32)value);
236  }
237  }
238  else if (header->extra_attributes[index].data_type == 5)
239  {
240  U32 value;
243  {
244  F64 temp_d = header->extra_attributes[index].scale[0]*value + header->extra_attributes[index].offset[0];
245  fprintf(file, "%g", temp_d);
246  }
247  else
248  {
249  fprintf(file, "%d", (I32)value);
250  }
251  }
252  else if (header->extra_attributes[index].data_type == 6)
253  {
254  I32 value;
257  {
258  F64 temp_d = header->extra_attributes[index].scale[0]*value + header->extra_attributes[index].offset[0];
259  fprintf(file, "%g", temp_d);
260  }
261  else
262  {
263  fprintf(file, "%d", value);
264  }
265  }
266  else if (header->extra_attributes[index].data_type == 9)
267  {
268  F32 value;
271  {
272  F64 temp_d = header->extra_attributes[index].scale[0]*value + header->extra_attributes[index].offset[0];
273  fprintf(file, "%g", temp_d);
274  }
275  else
276  {
277  fprintf(file, "%g", value);
278  }
279  }
280  else if (header->extra_attributes[index].data_type == 10)
281  {
282  F64 value;
285  {
286  F64 temp_d = header->extra_attributes[index].scale[0]*value + header->extra_attributes[index].offset[0];
287  fprintf(file, "%g", temp_d);
288  }
289  else
290  {
291  fprintf(file, "%g", value);
292  }
293  }
294  else
295  {
296  fprintf(stderr, "WARNING: extra attribute %d not (yet) implemented.\n", index);
297  return FALSE;
298  }
299  return TRUE;
300 }
301 
303 {
304  p_count++;
305  int i = 0;
306  while (true)
307  {
308  switch (parse_string[i])
309  {
310  case 'x': // the x coordinate
312  break;
313  case 'y': // the y coordinate
315  break;
316  case 'z': // the z coordinate
318  break;
319  case 't': // the gps-time
320  lidardouble2string(printstring,point->gps_time); fprintf(file, "%s", printstring);
321  break;
322  case 'i': // the intensity
323  fprintf(file, "%d", point->intensity);
324  break;
325  case 'a': // the scan angle
326  fprintf(file, "%d", point->scan_angle_rank);
327  break;
328  case 'r': // the number of the return
329  fprintf(file, "%d", point->return_number);
330  break;
331  case 'c': // the classification
332  fprintf(file, "%d", point->classification);
333  break;
334  case 'u': // the user data
335  fprintf(file, "%d", point->user_data);
336  break;
337  case 'n': // the number of returns of given pulse
338  fprintf(file, "%d", point->number_of_returns_of_given_pulse);
339  break;
340  case 'p': // the point source ID
341  fprintf(file, "%d", point->point_source_ID);
342  break;
343  case 'e': // the edge of flight line flag
344  fprintf(file, "%d", point->edge_of_flight_line);
345  break;
346  case 'd': // the direction of scan flag
347  fprintf(file, "%d", point->scan_direction_flag);
348  break;
349  case 'R': // the red channel of the RGB field
350  fprintf(file, "%d", point->rgb[0]);
351  break;
352  case 'G': // the green channel of the RGB field
353  fprintf(file, "%d", point->rgb[1]);
354  break;
355  case 'B': // the blue channel of the RGB field
356  fprintf(file, "%d", point->rgb[2]);
357  break;
358  case 'm': // the index of the point (count starts at 0)
359 #ifdef _WIN32
360  fprintf(file, "%I64d", p_count-1);
361 #else
362  fprintf(file, "%lld", p_count-1);
363 #endif
364  break;
365  case 'M': // the index of the point (count starts at 1)
366 #ifdef _WIN32
367  fprintf(file, "%I64d", p_count);
368 #else
369  fprintf(file, "%lld", p_count);
370 #endif
371  break;
372  case 'w': // the wavepacket descriptor index
373  fprintf(file, "%d", point->wavepacket.getIndex());
374  break;
375  case 'W': // all wavepacket attributes
376  fprintf(file, "%d%c%d%c%d%c%g%c%.15g%c%.15g%c%.15g", point->wavepacket.getIndex(), separator_sign, (U32)point->wavepacket.getOffset(), separator_sign, point->wavepacket.getSize(), separator_sign, point->wavepacket.getLocation(), separator_sign, point->wavepacket.getXt(), separator_sign, point->wavepacket.getYt(), separator_sign, point->wavepacket.getZt());
377  break;
378  case 'X': // the unscaled and unoffset integer X coordinate
379  fprintf(file, "%d", point->x);
380  break;
381  case 'Y': // the unscaled and unoffset integer Y coordinate
382  fprintf(file, "%d", point->y);
383  break;
384  case 'Z': // the unscaled and unoffset integer Z coordinate
385  fprintf(file, "%d", point->z);
386  break;
387  default:
388  unparse_extra_attribute(point, (I32)(parse_string[i]-'0'));
389  }
390  i++;
391  if (parse_string[i])
392  {
393  fprintf(file, "%c", separator_sign);
394  }
395  else
396  {
397  fprintf(file, "\012");
398  break;
399  }
400  }
401  return TRUE;
402 }
403 
404 BOOL LASwriterTXT::update_header(const LASheader* header, BOOL use_inventory, BOOL update_extra_bytes)
405 {
406  return TRUE;
407 }
408 
410 {
411  U32 bytes = (U32)ftell(file);
412 
413  if (file)
414  {
415  if (close_file)
416  {
417  fclose(file);
418  close_file = FALSE;
419  }
420  file = 0;
421  }
422  if (parse_string)
423  {
424  free(parse_string);
425  parse_string = 0;
426  }
427 
428  npoints = p_count;
429  p_count = 0;
430 
431  return bytes;
432 }
433 
435 {
436  close_file = FALSE;
437  file = 0;
438  parse_string = 0;
439  separator_sign = ' ';
440 }
441 
443 {
444  if (file) close();
445 }
446 
447 BOOL LASwriterTXT::check_parse_string(const char* parse_string)
448 {
449  const char* p = parse_string;
450  while (p[0])
451  {
452  if ((p[0] != 'x') && // the x coordinate
453  (p[0] != 'y') && // the y coordinate
454  (p[0] != 'z') && // the x coordinate
455  (p[0] != 't') && // the gps time
456  (p[0] != 'R') && // the red channel of the RGB field
457  (p[0] != 'G') && // the green channel of the RGB field
458  (p[0] != 'B') && // the blue channel of the RGB field
459  (p[0] != 's') && // a string or a number that we don't care about
460  (p[0] != 'i') && // the intensity
461  (p[0] != 'a') && // the scan angle
462  (p[0] != 'n') && // the number of returns of given pulse
463  (p[0] != 'r') && // the number of the return
464  (p[0] != 'c') && // the classification
465  (p[0] != 'u') && // the user data
466  (p[0] != 'p') && // the point source ID
467  (p[0] != 'e') && // the edge of flight line flag
468  (p[0] != 'd') && // the direction of scan flag
469  (p[0] != 'm') && // the index of the point (count starts at 0)
470  (p[0] != 'M') && // the index of the point (count starts at 1)
471  (p[0] != 'w') && // the wavepacket descriptor index
472  (p[0] != 'W') && // all wavepacket attributes
473  (p[0] != 'X') && // the unscaled and unoffset integer x coordinate
474  (p[0] != 'Y') && // the unscaled and unoffset integer y coordinate
475  (p[0] != 'Z')) // the unscaled and unoffset integer z coordinate
476  {
477  if (p[0] >= '0' && p[0] <= '9')
478  {
479  I32 index = (I32)(p[0] - '0');
480  if (index >= header->number_extra_attributes)
481  {
482  fprintf(stderr, "ERROR: extra attribute '%d' does not exist.\n", index);
483  return FALSE;
484  }
486  }
487  else
488  {
489  fprintf(stderr, "ERROR: unknown symbol '%c' in parse string. valid are\n", p[0]);
490  fprintf(stderr, " 'x' : the x coordinate\n");
491  fprintf(stderr, " 'y' : the y coordinate\n");
492  fprintf(stderr, " 'z' : the x coordinate\n");
493  fprintf(stderr, " 't' : the gps time\n");
494  fprintf(stderr, " 'R' : the red channel of the RGB field\n");
495  fprintf(stderr, " 'G' : the green channel of the RGB field\n");
496  fprintf(stderr, " 'B' : the blue channel of the RGB field\n");
497  fprintf(stderr, " 's' : a string or a number that we don't care about\n");
498  fprintf(stderr, " 'i' : the intensity\n");
499  fprintf(stderr, " 'a' : the scan angle\n");
500  fprintf(stderr, " 'n' : the number of returns of that given pulse\n");
501  fprintf(stderr, " 'r' : the number of the return\n");
502  fprintf(stderr, " 'c' : the classification\n");
503  fprintf(stderr, " 'u' : the user data\n");
504  fprintf(stderr, " 'p' : the point source ID\n");
505  fprintf(stderr, " 'e' : the edge of flight line flag\n");
506  fprintf(stderr, " 'd' : the direction of scan flag\n");
507  fprintf(stderr, " 'M' : the index of the point\n");
508  fprintf(stderr, " 'w' : the wavepacket descriptor index\n");
509  fprintf(stderr, " 'W' : all wavepacket attributes\n");
510  fprintf(stderr, " 'X' : the unscaled and unoffset integer x coordinate\n");
511  fprintf(stderr, " 'Y' : the unscaled and unoffset integer y coordinate\n");
512  fprintf(stderr, " 'Z' : the unscaled and unoffset integer z coordinate\n");
513  return FALSE;
514  }
515  }
516  p++;
517  }
518  return TRUE;
519 }
LASheader
Definition: lasdefinitions.hpp:952
LASpoint::edge_of_flight_line
U8 edge_of_flight_line
Definition: lasdefinitions.hpp:485
LASattribute::has_scale
BOOL has_scale() const
Definition: lasdefinitions.hpp:218
LASpoint::user_data
U8 user_data
Definition: lasdefinitions.hpp:488
LASquantizer::get_y
F64 get_y(const I32 y) const
Definition: lasdefinitions.hpp:100
LASpoint::gps_time
F64 gps_time
Definition: lasdefinitions.hpp:497
LASpoint::scan_angle_rank
I8 scan_angle_rank
Definition: lasdefinitions.hpp:487
LASpoint::scan_direction_flag
U8 scan_direction_flag
Definition: lasdefinitions.hpp:484
LASwriterTXT::check_parse_string
BOOL check_parse_string(const char *parse_string)
Definition: laswriter_txt.cpp:447
LASpoint
Definition: lasdefinitions.hpp:472
LASpoint::point_source_ID
U16 point_source_ID
Definition: lasdefinitions.hpp:489
LASwriterTXT::extra_attribute_array_offsets
I32 extra_attribute_array_offsets[10]
Definition: laswriter_txt.hpp:63
LASwriterTXT::file
FILE * file
Definition: laswriter_txt.hpp:58
LASwavepacket::getZt
F32 getZt() const
Definition: lasdefinitions.hpp:76
LASwriterTXT::parse_string
char * parse_string
Definition: laswriter_txt.hpp:60
I8
char I8
Definition: mydefs.hpp:37
LASwriterTXT::~LASwriterTXT
~LASwriterTXT()
Definition: laswriter_txt.cpp:442
LASattribute::scale
F64 scale[3]
Definition: lasdefinitions.hpp:151
I64
long long I64
Definition: mydefs.hpp:48
LASattributer::get_extra_attribute_array_offset
I32 get_extra_attribute_array_offset(const char *name) const
Definition: lasdefinitions.hpp:403
LASquantizer::get_z
F64 get_z(const I32 z) const
Definition: lasdefinitions.hpp:101
F64
double F64
Definition: mydefs.hpp:52
LASwriter::p_count
I64 p_count
Definition: laswriter.hpp:52
LASquantizer::x_scale_factor
F64 x_scale_factor
Definition: lasdefinitions.hpp:92
I32
int I32
Definition: mydefs.hpp:35
laswriter_txt.hpp
LASpoint::wavepacket
LASwavepacket wavepacket
Definition: lasdefinitions.hpp:499
TRUE
#define TRUE
Definition: mydefs.hpp:137
LASwriterTXT::update_header
BOOL update_header(const LASheader *header, BOOL use_inventory=TRUE, BOOL update_extra_bytes=FALSE)
Definition: laswriter_txt.cpp:404
p
SharedPointer p
Definition: ConvertShared.hpp:42
LASattribute::data_type
U8 data_type
Definition: lasdefinitions.hpp:144
LASwavepacket::getSize
U32 getSize() const
Definition: lasdefinitions.hpp:72
LASwriterTXT::write_point
BOOL write_point(const LASpoint *point)
Definition: laswriter_txt.cpp:302
LASwriterTXT::close
I64 close(BOOL update_npoints=true)
Definition: laswriter_txt.cpp:409
LASwriterTXT::LASwriterTXT
LASwriterTXT()
Definition: laswriter_txt.cpp:434
LASattributer::number_extra_attributes
I32 number_extra_attributes
Definition: lasdefinitions.hpp:308
LASpoint::y
I32 y
Definition: lasdefinitions.hpp:479
LASwavepacket::getYt
F32 getYt() const
Definition: lasdefinitions.hpp:75
LASpoint::classification
U8 classification
Definition: lasdefinitions.hpp:486
LASpoint::rgb
U16 rgb[4]
Definition: lasdefinitions.hpp:498
lidardouble2string
static void lidardouble2string(char *string, double value)
Definition: laswriter_txt.cpp:143
LASpoint::return_number
U8 return_number
Definition: lasdefinitions.hpp:482
LASheader::point_data_format
U8 point_data_format
Definition: lasdefinitions.hpp:971
LASpoint::get_extra_attribute
void get_extra_attribute(I32 index, U8 *data) const
Definition: lasdefinitions.hpp:842
LASwavepacket::getXt
F32 getXt() const
Definition: lasdefinitions.hpp:74
LASattribute::has_offset
BOOL has_offset() const
Definition: lasdefinitions.hpp:219
U16
unsigned short U16
Definition: mydefs.hpp:40
LASwriterTXT::unparse_extra_attribute
BOOL unparse_extra_attribute(const LASpoint *point, I32 index)
Definition: laswriter_txt.cpp:176
LASattribute::offset
F64 offset[3]
Definition: lasdefinitions.hpp:152
U8
unsigned char U8
Definition: mydefs.hpp:41
BOOL
int BOOL
Definition: mydefs.hpp:57
LASpoint::z
I32 z
Definition: lasdefinitions.hpp:480
LASwriterTXT::close_file
BOOL close_file
Definition: laswriter_txt.hpp:57
LASwriterTXT::printstring
char printstring[512]
Definition: laswriter_txt.hpp:62
FALSE
#define FALSE
Definition: mydefs.hpp:133
file
FILE * file
Definition: arithmeticencoder.cpp:77
F32
float F32
Definition: mydefs.hpp:51
LASwriterTXT::header
const LASheader * header
Definition: laswriter_txt.hpp:59
LASwavepacket::getLocation
F32 getLocation() const
Definition: lasdefinitions.hpp:73
LASwriter::npoints
I64 npoints
Definition: laswriter.hpp:51
LASpoint::number_of_returns_of_given_pulse
U8 number_of_returns_of_given_pulse
Definition: lasdefinitions.hpp:483
U32
unsigned int U32
Definition: mydefs.hpp:39
LASwavepacket::getIndex
U8 getIndex() const
Definition: lasdefinitions.hpp:70
LASquantizer::get_x
F64 get_x(const I32 x) const
Definition: lasdefinitions.hpp:99
LASpoint::x
I32 x
Definition: lasdefinitions.hpp:478
LASattributer::extra_attributes
LASattribute * extra_attributes
Definition: lasdefinitions.hpp:309
LASwriterTXT::refile
BOOL refile(FILE *file)
Definition: laswriter_txt.cpp:36
LASwriterTXT::open
BOOL open(const char *file_name, const LASheader *header, const char *parse_string=0, const char *separator=0)
Definition: laswriter_txt.cpp:42
LASquantizer::y_scale_factor
F64 y_scale_factor
Definition: lasdefinitions.hpp:93
LASquantizer::z_scale_factor
F64 z_scale_factor
Definition: lasdefinitions.hpp:94
LASwriterTXT::separator_sign
char separator_sign
Definition: laswriter_txt.hpp:61
LASpoint::intensity
U16 intensity
Definition: lasdefinitions.hpp:481
I16
short I16
Definition: mydefs.hpp:36
LASwavepacket::getOffset
U64 getOffset() const
Definition: lasdefinitions.hpp:71


lvr2
Author(s): Thomas Wiemann , Sebastian Pütz , Alexander Mock , Lars Kiesow , Lukas Kalbertodt , Tristan Igelbrink , Johan M. von Behren , Dominik Feldschnieders , Alexander Löhr
autogenerated on Wed Mar 2 2022 00:37:24