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  {
80  if (header->point_data_format == 1 || header->point_data_format == 4)
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 
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 }
const LASheader * header
U8 edge_of_flight_line
int BOOL
Definition: mydefs.hpp:57
#define FALSE
Definition: mydefs.hpp:133
BOOL refile(FILE *file)
static void lidardouble2string(char *string, double value)
float F32
Definition: mydefs.hpp:51
U32 getSize() const
I64 close(BOOL update_npoints=true)
BOOL has_offset() const
short I16
Definition: mydefs.hpp:36
unsigned int U32
Definition: mydefs.hpp:39
BOOL unparse_extra_attribute(const LASpoint *point, I32 index)
U8 scan_direction_flag
F32 getXt() const
BOOL check_parse_string(const char *parse_string)
unsigned short U16
Definition: mydefs.hpp:40
long long I64
Definition: mydefs.hpp:48
F32 getYt() const
LASwavepacket wavepacket
unsigned char U8
Definition: mydefs.hpp:41
F32 getLocation() const
U8 getIndex() const
F32 getZt() const
U64 getOffset() const
SharedPointer p
char I8
Definition: mydefs.hpp:37
F64 get_y(const I32 y) const
FILE * file
I32 extra_attribute_array_offsets[10]
int I32
Definition: mydefs.hpp:35
I64 npoints
Definition: laswriter.hpp:51
F64 get_z(const I32 z) const
BOOL has_scale() const
#define TRUE
Definition: mydefs.hpp:137
I32 get_extra_attribute_array_offset(const char *name) const
F64 get_x(const I32 x) const
void get_extra_attribute(I32 index, U8 *data) const
BOOL update_header(const LASheader *header, BOOL use_inventory=TRUE, BOOL update_extra_bytes=FALSE)
I64 p_count
Definition: laswriter.hpp:52
LASattribute * extra_attributes
char printstring[512]
BOOL open(const char *file_name, const LASheader *header, const char *parse_string=0, const char *separator=0)
double F64
Definition: mydefs.hpp:52
U8 number_of_returns_of_given_pulse
char * parse_string
BOOL write_point(const LASpoint *point)


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 Mon Feb 28 2022 22:46:07