Quellcode durchsuchen

v.in.lidar, r.in.lidar and r3.in.lidar: make validity check an additional filter but always warn about presence of invalid points (see https://trac.osgeo.org/grass/ticket/3038)

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@68951 15284696-431f-4ddb-bdfa-cd5b030d7da7
Vaclav Petras vor 8 Jahren
Ursprung
Commit
cdc4b79a41
4 geänderte Dateien mit 101 neuen und 17 gelöschten Zeilen
  1. 1 3
      raster/r.in.lidar/info.c
  2. 27 1
      raster/r.in.lidar/main.c
  3. 28 3
      raster3d/r3.in.lidar/main.c
  4. 45 10
      vector/v.in.lidar/main.c

+ 1 - 3
raster/r.in.lidar/info.c

@@ -112,9 +112,7 @@ int scan_bounds(LASReaderH LAS_reader, int shell_style, int extents, int update,
     while ((LAS_point = LASReader_GetNextPoint(LAS_reader)) != NULL) {
         line++;
 
-        if (!LASPoint_IsValid(LAS_point)) {
-            continue;
-        }
+        /* we don't do any filtering here */
 
         x = LASPoint_GetX(LAS_point);
         y = LASPoint_GetY(LAS_point);

+ 27 - 1
raster/r.in.lidar/main.c

@@ -60,6 +60,7 @@ int main(int argc, char *argv[])
     int pass, npasses;
     unsigned long line, line_total;
     unsigned int counter;
+    unsigned long n_invalid;
     char buff[BUFFSIZE];
     double x, y, z;
     double intensity;
@@ -87,6 +88,7 @@ int main(int argc, char *argv[])
     struct Flag *intens_flag, *intens_import_flag;
     struct Flag *set_region_flag;
     struct Flag *base_rast_res_flag;
+    struct Flag *only_valid_flag;
 
     /* LAS */
     LASReaderH LAS_reader;
@@ -330,11 +332,24 @@ int main(int argc, char *argv[])
         _("For getting values from base raster, use its actual"
           " resolution instead of computational region resolution");
 
+    only_valid_flag = G_define_flag();
+    only_valid_flag->key = 'v';
+    only_valid_flag->label = _("Use only valid points");
+    only_valid_flag->description =
+        _("Points invalid according to APSRS LAS specification will be"
+          " filtered out");
+    only_valid_flag->guisection = _("Selection");
+
     G_option_exclusive(intens_flag, intens_import_flag, NULL);
 
     if (G_parser(argc, argv))
 	exit(EXIT_FAILURE);
 
+    int only_valid = FALSE;
+    n_invalid = 0;
+    if (only_valid_flag->answer)
+        only_valid = TRUE;
+
     /* we could use rules but this gives more info and allows continuing */
     if (set_region_flag->answer && !(extents_flag->answer || res_opt->answer)) {
         G_warning(_("Flag %c makes sense only with %s option or -%c flag"),
@@ -634,8 +649,13 @@ int main(int argc, char *argv[])
                     counter = 0;
                 }
 
+                /* We always count them and report because behavior
+                 * changed in between 7.0 and 7.2 from undefined (but skipping
+                 * invalid points) to filtering them out only when requested. */
                 if (!LASPoint_IsValid(LAS_point)) {
-                    continue;
+                    n_invalid++;
+                    if (only_valid)
+                        continue;
                 }
 
                 x = LASPoint_GetX(LAS_point);
@@ -763,6 +783,12 @@ int main(int argc, char *argv[])
     if (set_region_flag->answer)
         G_put_window(&region);
 
+    if (n_invalid && only_valid)
+        G_message(_("%lu input points were invalid and filtered out"),
+                  n_invalid);
+    if (n_invalid && !only_valid)
+        G_message(_("%lu input points were invalid, use -%c flag to filter"
+                    " them out"), n_invalid, only_valid_flag->key);
     if (infiles.num_items > 1) {
         sprintf(buff, _("Raster map <%s> created."
                         " %lu points from %d files found in region."),

+ 28 - 3
raster3d/r3.in.lidar/main.c

@@ -118,6 +118,7 @@ int main(int argc, char *argv[])
     struct Option *filter_opt, *class_opt;
     struct Option *base_raster_opt;
     struct Flag *base_rast_res_flag;
+    struct Flag *only_valid_flag;
 
     G_gisinit(argv[0]);
 
@@ -211,11 +212,23 @@ int main(int argc, char *argv[])
     base_rast_res_flag->description =
         _("Use base raster actual resolution instead of computational region");
 
+    only_valid_flag = G_define_flag();
+    only_valid_flag->key = 'v';
+    only_valid_flag->label = _("Use only valid points");
+    only_valid_flag->description =
+        _("Points invalid according to APSRS LAS specification will be"
+          " filtered out");
+    only_valid_flag->guisection = _("Selection");
+
     G_option_requires(base_rast_res_flag, base_raster_opt, NULL);
 
     if (G_parser(argc, argv))
         exit(EXIT_FAILURE);
 
+    int only_valid = FALSE;
+    if (only_valid_flag->answer)
+        only_valid = TRUE;
+
     LASReaderH LAS_reader;
 
     LAS_reader = LASReader_Create(input_opt->answer);
@@ -332,11 +345,17 @@ int main(int argc, char *argv[])
     long unsigned in_nulls = 0; /* or outside */
     long unsigned n_return_filtered = 0;
     long unsigned n_class_filtered = 0;
+    long unsigned n_invalid = 0;
 
     while ((LAS_point = LASReader_GetNextPoint(LAS_reader)) != NULL) {
-        if (!LASPoint_IsValid(LAS_point))
-            continue;
-
+        /* We always count them and report because r.in.lidar behavior
+         * changed in between 7.0 and 7.2 from undefined (but skipping
+         * invalid points) to filtering them out only when requested. */
+        if (!LASPoint_IsValid(LAS_point)) {
+            n_invalid++;
+            if (only_valid)
+                continue;
+        }
         if (use_return_filter) {
             int return_n = LASPoint_GetReturnNumber(LAS_point);
             int n_returns = LASPoint_GetNumberOfReturns(LAS_point);
@@ -397,10 +416,16 @@ int main(int argc, char *argv[])
              outside + in_nulls);
     else
         G_message("Number of points outside: %lu", outside);
+    if (n_invalid && only_valid)
+        G_message(_("%lu input points were not valid and filtered out"),
+                  n_invalid);
     if (n_return_filtered)
         G_message(_("%lu input points were filtered out by return number"), n_return_filtered);
     if (n_class_filtered)
         G_message(_("%lu input points were filtered out by class number"), n_class_filtered);
+    if (n_invalid && !only_valid)
+        G_message(_("%lu input points were not valid, use -%c flag to filter"
+                    " them out"), n_invalid, only_valid_flag->key);
 
     Rast3d_close(binning.prop_sum_raster);
     Rast3d_close(binning.prop_count_raster);

+ 45 - 10
vector/v.in.lidar/main.c

@@ -85,6 +85,7 @@ int main(int argc, char *argv[])
     struct Flag *nocats_flag;
     struct Flag *over_flag, *extend_flag, *no_import_flag;
     struct Flag *invert_mask_flag;
+    struct Flag *only_valid_flag;
     char buf[2000];
     struct Key_Value *loc_proj_info = NULL, *loc_proj_units = NULL;
     struct Key_Value *proj_info, *proj_units;
@@ -285,6 +286,14 @@ int main(int argc, char *argv[])
     invert_mask_flag->description = _("Invert mask when selecting points");
     invert_mask_flag->guisection = _("Selection");
 
+    only_valid_flag = G_define_flag();
+    only_valid_flag->key = 'v';
+    only_valid_flag->label = _("Use only valid points");
+    only_valid_flag->description =
+        _("Points invalid according to APSRS LAS specification will be"
+          " filtered out");
+    only_valid_flag->guisection = _("Selection");
+
     extend_flag = G_define_flag();
     extend_flag->key = 'e';
     extend_flag->description =
@@ -373,6 +382,10 @@ int main(int argc, char *argv[])
 	exit(EXIT_SUCCESS);
     }
 
+    int only_valid = FALSE;
+    if (only_valid_flag->answer)
+        only_valid = TRUE;
+
     struct ReturnFilter return_filter_struct;
     return_filter_create_from_string(&return_filter_struct, filter_opt->answer);
     struct ClassFilter class_filter;
@@ -598,11 +611,15 @@ int main(int argc, char *argv[])
 	double x, y, z;
 
 	G_percent(feature_count++, n_features, 1);	/* show something happens */
-	
-	if (!LASPoint_IsValid(LAS_point)) {
-	    not_valid++;
-	    continue;
-	}
+
+        /* We always count them and report because r.in.lidar behavior
+         * changed in between 7.0 and 7.2 from undefined (but skipping
+         * invalid points) to filtering them out only when requested. */
+        if (!LASPoint_IsValid(LAS_point)) {
+            not_valid++;
+            if (only_valid)
+                continue;
+        }
 
 	Vect_reset_line(Points);
 	Vect_reset_cats(Cats);
@@ -709,10 +726,18 @@ int main(int argc, char *argv[])
 	Vect_build(&Map);
     Vect_close(&Map);
 
+#ifdef HAVE_LONG_LONG_INT
+    unsigned long long not_valid_filtered = 0;
+#else
+    unsigned long not_valid_filtered = 0;
+#endif
+    if (only_valid)
+        not_valid_filtered = not_valid;
+
     /* can be easily determined only when iterated over all points */
     if (!count_decimation_control.limit_n && !cat_max_reached
             && points_imported != n_features
-            - not_valid - n_outside - n_filtered - n_class_filtered
+            - not_valid_filtered - n_outside - n_filtered - n_class_filtered
             - n_outside_mask - count_decimation_control.offset_n_counter
             - count_decimation_control.n_count_filtered - zrange_filtered)
         G_warning(_("The underlying libLAS library is at its limits."
@@ -728,8 +753,8 @@ int main(int argc, char *argv[])
     else {
         G_message(_("%llu points imported"), points_imported);
     }
-    if (not_valid)
-	G_message(_("%llu input points were not valid"), not_valid);
+    if (not_valid && only_valid)
+        G_message(_("%llu input points were not valid and filtered out"), not_valid);
     if (n_outside)
 	G_message(_("%llu input points were outside of the selected area"), n_outside);
     if (n_outside_mask)
@@ -753,8 +778,8 @@ int main(int argc, char *argv[])
                   count_decimation_control.limit_n);
     else
         G_message(_("%lu points imported"), points_imported);
-    if (not_valid)
-	G_message(_("%lu input points were not valid"), not_valid);
+    if (not_valid && only_valid)
+        G_message(_("%lu input points were not valid and filtered out"), not_valid);
     if (n_outside)
 	G_message(_("%lu input points were outside of the selected area"), n_outside);
     if (n_outside_mask)
@@ -776,6 +801,16 @@ int main(int argc, char *argv[])
     if (count_decimation_control.limit_n)
         G_message(_("The rest of points was ignored"));
 
+#ifdef HAVE_LONG_LONG_INT
+    if (not_valid && !only_valid)
+        G_message(_("%llu input points were not valid, use -%c flag to filter"
+                    " them out"), not_valid, only_valid_flag->key);
+#else
+    if (not_valid && !only_valid)
+        G_message(_("%lu input points were not valid, use -%c flag to filter"
+                    " them out"), not_valid, only_valid_flag->key);
+#endif
+
     if (cat_max_reached)
         G_warning(_("Maximum number of categories reached (%d). Import ended prematurely."
                     " Try to import without using category as an ID."), GV_CAT_MAX);