[GRASS-SVN] r68469 - in grass/trunk/vector: v.in.lidar v.in.pdal v.out.lidar

svn_grass at osgeo.org svn_grass at osgeo.org
Thu May 19 14:19:00 PDT 2016


Author: wenzeslaus
Date: 2016-05-19 14:19:00 -0700 (Thu, 19 May 2016)
New Revision: 68469

Modified:
   grass/trunk/vector/v.in.lidar/lidar.c
   grass/trunk/vector/v.in.lidar/lidar.h
   grass/trunk/vector/v.in.lidar/main.c
   grass/trunk/vector/v.in.pdal/lidar.c
   grass/trunk/vector/v.in.pdal/lidar.h
   grass/trunk/vector/v.in.pdal/main.cpp
   grass/trunk/vector/v.out.lidar/main.c
Log:
v.in.lidar, v.out.lidar, v.in.pdal: unify layer and category handling

User has now option to store generated ID, first/mid/last
return info, class and RGB (as on number) as category 
in custom layers. Autogenerated ID/cat is stored by default
and can be disabled by setting option to empty string
(and unofficially also to 0).

This removes extra layers like red or return number
and also flags related to storing category.

User has now full control over creating layers
but the number of layers and options is minimal.

For v.out.lidar the created LAS is limited but
full options (e.g. arbitrary numbers for returns)
are possible using attribute table.

This simplifies r66343, r67159 in v.in.lidar.

v.in.pdal now stores ID/cat by default
to be consistent with v.in.lidar.


Modified: grass/trunk/vector/v.in.lidar/lidar.c
===================================================================
--- grass/trunk/vector/v.in.lidar/lidar.c	2016-05-19 20:26:04 UTC (rev 68468)
+++ grass/trunk/vector/v.in.lidar/lidar.c	2016-05-19 21:19:00 UTC (rev 68469)
@@ -39,3 +39,13 @@
     {7, "Withheld"},
     {0, 0}
 };
+
+int return_to_cat(int return_n, int n_returns)
+{
+    if (return_n == 1)
+        return LAS_FIRST;
+    else if (n_returns > 1 && return_n == n_returns)
+            return LAS_LAST;
+    else
+        return LAS_MID;
+}

Modified: grass/trunk/vector/v.in.lidar/lidar.h
===================================================================
--- grass/trunk/vector/v.in.lidar/lidar.h	2016-05-19 20:26:04 UTC (rev 68468)
+++ grass/trunk/vector/v.in.lidar/lidar.h	2016-05-19 21:19:00 UTC (rev 68469)
@@ -66,4 +66,6 @@
 extern struct class_table class_val[];
 extern struct class_table class_type[];
 
+int return_to_cat(int return_n, int n_returns);
+
 #endif /* GRASS_LIDAR_H */

Modified: grass/trunk/vector/v.in.lidar/main.c
===================================================================
--- grass/trunk/vector/v.in.lidar/main.c	2016-05-19 20:26:04 UTC (rev 68468)
+++ grass/trunk/vector/v.in.lidar/main.c	2016-05-19 21:19:00 UTC (rev 68469)
@@ -47,15 +47,14 @@
     float xmin = 0., ymin = 0., xmax = 0., ymax = 0.;
     struct GModule *module;
     struct Option *in_opt, *out_opt, *spat_opt, *filter_opt, *class_opt;
-    struct Option *id_layer_opt, *return_layer_opt, *n_returns_layer_opt;
+    struct Option *id_layer_opt;
+    struct Option *return_layer_opt;
     struct Option *class_layer_opt;
-    struct Option *red_layer_opt, *green_layer_opt, *blue_layer_opt;
     struct Option *rgb_layer_opt;
     struct Option *vector_mask_opt, *vector_mask_field_opt;
     struct Option *skip_opt, *preserve_opt, *offset_opt, *limit_opt;
     struct Option *outloc_opt, *zrange_opt;
     struct Flag *print_flag, *notab_flag, *region_flag, *notopo_flag;
-    struct Flag *nocats_flag;
     struct Flag *over_flag, *extend_flag, *no_import_flag;
     struct Flag *invert_mask_flag;
     char buf[2000];
@@ -119,58 +118,35 @@
     id_layer_opt = G_define_standard_option(G_OPT_V_FIELD);
     id_layer_opt->key = "id_layer";
     id_layer_opt->label = _("Layer number to store generated point ID as category");
-    id_layer_opt->answer = NULL;
+    id_layer_opt->description =
+        _("Set empty to not store it. Required for attribute table.");
+    id_layer_opt->answer = "1";
     id_layer_opt->guisection = _("Categories");
 
     return_layer_opt = G_define_standard_option(G_OPT_V_FIELD);
     return_layer_opt->key = "return_layer";
     return_layer_opt->label =
-        _("Layer number to store return number as category");
+        _("Layer number to store return information as category");
+    return_layer_opt->description = _("Leave empty to not store it");
     return_layer_opt->answer = NULL;
     return_layer_opt->guisection = _("Categories");
 
-    n_returns_layer_opt = G_define_standard_option(G_OPT_V_FIELD);
-    n_returns_layer_opt->key = "n_returns_layer";
-    n_returns_layer_opt->label =
-        _("Layer number to store number of returns as category");
-    n_returns_layer_opt->answer = NULL;
-    n_returns_layer_opt->guisection = _("Categories");
-
     class_layer_opt = G_define_standard_option(G_OPT_V_FIELD);
     class_layer_opt->key = "class_layer";
     class_layer_opt->label =
         _("Layer number to store class number as category");
+    class_layer_opt->description = _("Leave empty to not store it");
     class_layer_opt->answer = NULL;
     class_layer_opt->guisection = _("Categories");
 
     rgb_layer_opt = G_define_standard_option(G_OPT_V_FIELD);
     rgb_layer_opt->key = "rgb_layer";
     rgb_layer_opt->label =
-        _("Layer number where RBG colors is stored as category");
+        _("Layer number where RBG colors are stored as category");
+    rgb_layer_opt->description = _("Leave empty to not store it");
     rgb_layer_opt->answer = NULL;
     rgb_layer_opt->guisection = _("Categories");
 
-    red_layer_opt = G_define_standard_option(G_OPT_V_FIELD);
-    red_layer_opt->key = "red_layer";
-    red_layer_opt->label =
-        _("Layer number where red color is stored as category");
-    red_layer_opt->answer = NULL;
-    red_layer_opt->guisection = _("Categories");
-
-    green_layer_opt = G_define_standard_option(G_OPT_V_FIELD);
-    green_layer_opt->key = "green_layer";
-    green_layer_opt->label =
-        _("Layer number where red color is stored as category");
-    green_layer_opt->answer = NULL;
-    green_layer_opt->guisection = _("Categories");
-
-    blue_layer_opt = G_define_standard_option(G_OPT_V_FIELD);
-    blue_layer_opt->key = "blue_layer";
-    blue_layer_opt->label =
-        _("Layer number where blue color is stored as category");
-    blue_layer_opt->answer = NULL;
-    blue_layer_opt->guisection = _("Categories");
-
     spat_opt = G_define_option();
     spat_opt->key = "spatial";
     spat_opt->type = TYPE_DOUBLE;
@@ -290,14 +266,6 @@
     notab_flag = G_define_standard_flag(G_FLG_V_TABLE);
     notab_flag->guisection = _("Speed");
 
-    nocats_flag = G_define_flag();
-    nocats_flag->key = 'c';
-    nocats_flag->label =
-        _("Store only the coordinates");
-    nocats_flag->description =
-        _("Do not add categories to points and do not create attribute table");
-    nocats_flag->guisection = _("Speed");
-
     notopo_flag = G_define_standard_flag(G_FLG_V_TOPO);
     notopo_flag->guisection = _("Speed");
 
@@ -316,9 +284,6 @@
     no_import_flag->suppress_required = YES;
 
     G_option_exclusive(skip_opt, preserve_opt, NULL);
-    G_option_excludes(nocats_flag, id_layer_opt, return_layer_opt,
-        n_returns_layer_opt, class_layer_opt, rgb_layer_opt,
-        red_layer_opt, green_layer_opt, blue_layer_opt, NULL);
 
     /* The parser checks if the map already exists in current mapset, this is
      * wrong if location options is used, so we switch out the check and do it
@@ -328,10 +293,6 @@
     if (G_parser(argc, argv))
 	exit(EXIT_FAILURE);
 
-    /* no cats implies no table */
-    if (nocats_flag->answer)
-        notab_flag->answer = 1;
-
     /* Don't crash on cmd line if file not found */
     if (access(in_opt->answer, F_OK) != 0) {
 	G_fatal_error(_("Input file <%s> does not exist"), in_opt->answer);
@@ -379,62 +340,20 @@
 
     int id_layer = 0;
     int return_layer = 0;
-    int n_returns_layer = 0;
     int class_layer = 0;
     int rgb_layer = 0;
-    int red_layer = 0;
-    int green_layer = 0;
-    int blue_layer = 0;
     if (id_layer_opt->answer)
         id_layer = atoi(id_layer_opt->answer);
     if (return_layer_opt->answer)
         return_layer = atoi(return_layer_opt->answer);
-    if (n_returns_layer_opt->answer)
-        n_returns_layer = atoi(n_returns_layer_opt->answer);
     if (class_layer_opt->answer)
         class_layer = atoi(class_layer_opt->answer);
     if (rgb_layer_opt->answer)
         rgb_layer = atoi(rgb_layer_opt->answer);
-    if (red_layer_opt->answer)
-        red_layer = atoi(red_layer_opt->answer);
-    if (green_layer_opt->answer)
-        green_layer = atoi(green_layer_opt->answer);
-    if (blue_layer_opt->answer)
-        blue_layer = atoi(blue_layer_opt->answer);
-    /* If no layer specified by user, force 1 to be used for ids.
-     * If id_layer not specified by the attributes table was, find a layer.
-     * nocats implies notab and we don't add any layers.
-     * Also when layers are set to zero by user, we consider it as if
-     * the nocats flag would be specified. We use !id_layer_opt->answer
-     * to see that user was the one not setting the id_layer which are
-     * are about to turn on.
-     * Later on, layer set to 0 is considered as no layer set.
-     */
-    if (!nocats_flag->answer && !id_layer_opt->answer && !return_layer
-        && !n_returns_layer && !class_layer && !rgb_layer && !red_layer
-        && !green_layer && !blue_layer) {
-        id_layer = 1;
-        G_message(_("Storing generated point IDs as categories in the layer %d"), id_layer);
-    }
     /* no cats forces no table earlier */
     if (!notab_flag->answer && !id_layer) {
-        /* get the maximum layer number used */
-        int max_used_layer;
-        max_used_layer = MAX(return_layer, n_returns_layer);
-        max_used_layer = MAX(max_used_layer, class_layer);
-        max_used_layer = MAX(max_used_layer, rgb_layer);
-        max_used_layer = MAX(max_used_layer, red_layer);
-        max_used_layer = MAX(max_used_layer, green_layer);
-        max_used_layer = MAX(max_used_layer, blue_layer);
-        /* get the first free layer number */
-        for (i = 1; i <= max_used_layer + 1; i++) {
-            if (i != return_layer && i != n_returns_layer
-                && i != class_layer && i != rgb_layer
-                && i != red_layer && i != green_layer && i != blue_layer)
-                break;
-        }
-        id_layer = i;
-        G_message(_("Storing generated point IDs as categories in the layer %d"), id_layer);
+        G_message(_("-%c flag is not set but ID layer is not specified"), notab_flag->key);
+        G_fatal_error(_("ID layer is required to store attribute table"));
     }
 
     double zrange_min, zrange_max;
@@ -672,15 +591,14 @@
 	Vect_append_point(Points, x, y, z);
         if (id_layer)
             Vect_cat_set(Cats, id_layer, cat);
-        if (return_layer)
-            Vect_cat_set(Cats, return_layer, LASPoint_GetReturnNumber(LAS_point));
-        if (n_returns_layer)
-            Vect_cat_set(Cats, n_returns_layer, LASPoint_GetNumberOfReturns(LAS_point));
+        if (return_layer) {
+            int return_c = return_to_cat(return_n, n_returns);
+            Vect_cat_set(Cats, return_layer, return_c);
+        }
         if (class_layer)
-            Vect_cat_set(Cats, class_layer, LASPoint_GetClassification(LAS_point));
-        if (have_color && (rgb_layer || red_layer || green_layer || blue_layer)) {
+            Vect_cat_set(Cats, class_layer, point_class);
+        if (have_color && rgb_layer) {
             /* TODO: if attr table, acquired again, performance difference? */
-            /* TODO: the getters are called too when separate layers are used */
             LASColorH LAS_color = LASPoint_GetColor(LAS_point);
             if (rgb_layer) {
                 int red = LASColor_GetRed(LAS_color);
@@ -691,12 +609,6 @@
                 rgb = (rgb << 8) + blue;
                 Vect_cat_set(Cats, rgb_layer, rgb);
             }
-            if (red_layer)
-                Vect_cat_set(Cats, red_layer, LASColor_GetRed(LAS_color));
-            if (green_layer)
-                Vect_cat_set(Cats, green_layer, LASColor_GetGreen(LAS_color));
-            if (blue_layer)
-                Vect_cat_set(Cats, blue_layer, LASColor_GetBlue(LAS_color));
         }
 	Vect_write_line(&Map, GV_POINT, Points, Cats);
 

Modified: grass/trunk/vector/v.in.pdal/lidar.c
===================================================================
--- grass/trunk/vector/v.in.pdal/lidar.c	2016-05-19 20:26:04 UTC (rev 68468)
+++ grass/trunk/vector/v.in.pdal/lidar.c	2016-05-19 21:19:00 UTC (rev 68469)
@@ -15,40 +15,12 @@
 
 #include "lidar.h"
 
-void GLidarLayers_set_default_layers(struct GLidarLayers *layers)
-{
-    layers->id_layer = 0;
-    layers->return_layer = G_RETURN_LAYER;
-    layers->n_returns_layer = G_NUM_RETURNS_LAYER;
-    layers->class_layer = G_CLASS_LAYER;
-    layers->rgb_layer = G_RGB_LAYER;
-    layers->red_layer = 0;
-    layers->green_layer = 0;
-    layers->blue_layer = 0;
-}
-
-void GLidarLayers_set_all_layers(struct GLidarLayers *layers)
-{
-    layers->id_layer = G_ID_LAYER;
-    layers->return_layer = G_RETURN_LAYER;
-    layers->n_returns_layer = G_NUM_RETURNS_LAYER;
-    layers->class_layer = G_CLASS_LAYER;
-    layers->rgb_layer = G_RGB_LAYER;
-    layers->red_layer = G_RED_LAYER;
-    layers->green_layer = G_GREEN_LAYER;
-    layers->blue_layer = G_BLUE_LAYER;
-}
-
 void GLidarLayers_set_no_layers(struct GLidarLayers *layers)
 {
     layers->id_layer = 0;
     layers->return_layer = 0;
-    layers->n_returns_layer = 0;
     layers->class_layer = 0;
     layers->rgb_layer = 0;
-    layers->red_layer = 0;
-    layers->green_layer = 0;
-    layers->blue_layer = 0;
 }
 
 struct class_table class_val[] = {
@@ -75,3 +47,13 @@
     {7, "Withheld"},
     {0, 0}
 };
+
+int return_to_cat(int return_n, int n_returns)
+{
+    if (return_n == 1)
+        return LAS_FIRST;
+    else if (n_returns > 1 && return_n == n_returns)
+            return LAS_LAST;
+    else
+        return LAS_MID;
+}

Modified: grass/trunk/vector/v.in.pdal/lidar.h
===================================================================
--- grass/trunk/vector/v.in.pdal/lidar.h	2016-05-19 20:26:04 UTC (rev 68468)
+++ grass/trunk/vector/v.in.pdal/lidar.h	2016-05-19 21:19:00 UTC (rev 68469)
@@ -21,29 +21,14 @@
 #define LAS_LAST 2
 #define LAS_MID 3
 
-#define G_ID_LAYER 1
-#define G_RETURN_LAYER 2
-#define G_NUM_RETURNS_LAYER 3
-#define G_CLASS_LAYER 4
-#define G_RGB_LAYER 5
-#define G_RED_LAYER 6
-#define G_GREEN_LAYER 7
-#define G_BLUE_LAYER 8
-
 struct GLidarLayers
 {
     int id_layer;
     int return_layer;
-    int n_returns_layer;
     int class_layer;
     int rgb_layer;
-    int red_layer;
-    int green_layer;
-    int blue_layer;
 };
 
-void GLidarLayers_set_default_layers(struct GLidarLayers *layers);
-void GLidarLayers_set_all_layers(struct GLidarLayers *layers);
 void GLidarLayers_set_no_layers(struct GLidarLayers *layers);
 
 /*
@@ -91,4 +76,6 @@
 extern struct class_table class_val[];
 extern struct class_table class_type[];
 
+int return_to_cat(int return_n, int n_returns);
+
 #endif /* GRASS_LIDAR_H */

Modified: grass/trunk/vector/v.in.pdal/main.cpp
===================================================================
--- grass/trunk/vector/v.in.pdal/main.cpp	2016-05-19 20:26:04 UTC (rev 68468)
+++ grass/trunk/vector/v.in.pdal/main.cpp	2016-05-19 21:19:00 UTC (rev 68469)
@@ -42,17 +42,17 @@
     double y = point_view->getFieldAs<double>(Y, idx);
     double z = point_view->getFieldAs<double>(dim_to_use_as_z, idx);
 
+    /* TODO: optimize for case with no layers, by adding
+     * and if to skip all the other ifs */
     if (layers->id_layer) {
         Vect_cat_set(cats, layers->id_layer, cat);
     }
     if (layers->return_layer) {
-        Vect_cat_set(cats, layers->return_layer,
-                     point_view->getFieldAs<int>(ReturnNumber, idx));
+        int return_n = point_view->getFieldAs<int>(ReturnNumber, idx);
+        int n_returns = point_view->getFieldAs<int>(NumberOfReturns, idx);
+        int return_c = return_to_cat(return_n, n_returns);
+        Vect_cat_set(cats, layers->return_layer, return_c);
     }
-    if (layers->n_returns_layer) {
-        Vect_cat_set(cats, layers->n_returns_layer,
-                     point_view->getFieldAs<int>(NumberOfReturns, idx));
-    }
     if (layers->class_layer) {
         Vect_cat_set(cats, layers->class_layer,
                      point_view->getFieldAs<int>(Classification, idx));
@@ -66,18 +66,6 @@
         rgb = (rgb << 8) + blue;
         Vect_cat_set(cats, layers->rgb_layer, rgb);
     }
-    if (layers->red_layer) {
-        Vect_cat_set(cats, layers->red_layer,
-                     point_view->getFieldAs<int>(Red, idx));
-    }
-    if (layers->green_layer) {
-        Vect_cat_set(cats, layers->green_layer,
-                     point_view->getFieldAs<int>(Green, idx));
-    }
-    if (layers->blue_layer) {
-        Vect_cat_set(cats, layers->blue_layer,
-                     point_view->getFieldAs<int>(Blue, idx));
-    }
 
     Vect_append_point(points, x, y, z);
     Vect_write_line(output_vector, GV_POINT, points, cats);
@@ -102,6 +90,38 @@
 
     Option *out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
 
+    Option *id_layer_opt = G_define_standard_option(G_OPT_V_FIELD);
+    id_layer_opt->key = "id_layer";
+    id_layer_opt->label = _("Layer number to store generated point ID as category");
+    id_layer_opt->description =
+        _("Set empty to not store it. Required for attribute table.");
+    id_layer_opt->answer = "1";
+    id_layer_opt->guisection = _("Categories");
+
+    Option *return_layer_opt = G_define_standard_option(G_OPT_V_FIELD);
+    return_layer_opt->key = "return_layer";
+    return_layer_opt->label =
+        _("Layer number to store return information as category");
+    return_layer_opt->description = _("Leave empty to not store it");
+    return_layer_opt->answer = NULL;
+    return_layer_opt->guisection = _("Categories");
+
+    Option *class_layer_opt = G_define_standard_option(G_OPT_V_FIELD);
+    class_layer_opt->key = "class_layer";
+    class_layer_opt->label =
+        _("Layer number to store class number as category");
+    class_layer_opt->description = _("Leave empty to not store it");
+    class_layer_opt->answer = NULL;
+    class_layer_opt->guisection = _("Categories");
+
+    Option *rgb_layer_opt = G_define_standard_option(G_OPT_V_FIELD);
+    rgb_layer_opt->key = "rgb_layer";
+    rgb_layer_opt->label =
+        _("Layer number where RBG colors are stored as category");
+    rgb_layer_opt->description = _("Leave empty to not store it");
+    rgb_layer_opt->answer = NULL;
+    rgb_layer_opt->guisection = _("Categories");
+
     Option *spatial_opt = G_define_option();
     spatial_opt->key = "spatial";
     spatial_opt->type = TYPE_DOUBLE;
@@ -220,20 +240,6 @@
     region_flag->guisection = _("Selection");
     region_flag->description = _("Limit import to the current region");
 
-    Flag *nocats_flag = G_define_flag();
-    nocats_flag->key = 'c';
-    nocats_flag->label =
-        _("Store only the coordinates");
-    nocats_flag->description =
-        _("Do not add any categories to points");
-    nocats_flag->guisection = _("Categories");
-
-    Flag *idcat_flag = G_define_flag();
-    idcat_flag->key = 'd';
-    idcat_flag->label =
-        _("Store generated unique ID for each point");
-    idcat_flag->guisection = _("Categories");
-
     Flag *extract_ground_flag = G_define_flag();
     extract_ground_flag->key = 'j';
     extract_ground_flag->label =
@@ -268,7 +274,6 @@
 
     G_option_exclusive(spatial_opt, region_flag, NULL);
     G_option_exclusive(reproject_flag, over_flag, NULL);
-    G_option_exclusive(nocats_flag, idcat_flag, NULL);
     G_option_exclusive(extract_ground_flag, classify_ground_flag, NULL);
 
     if (G_parser(argc, argv))
@@ -281,6 +286,17 @@
     // we use full qualification because the dim ns conatins too general names
     pdal::Dimension::Id::Enum dim_to_use_as_z = pdal::Dimension::Id::Z;
 
+    struct GLidarLayers layers;
+    GLidarLayers_set_no_layers(&layers);
+    if (id_layer_opt->answer && id_layer_opt->answer[0] != '\0')
+        layers.id_layer = std::stoi(id_layer_opt->answer);
+    if (return_layer_opt->answer && return_layer_opt->answer[0] != '\0')
+        layers.return_layer = std::stoi(return_layer_opt->answer);
+    if (class_layer_opt->answer && class_layer_opt->answer[0] != '\0')
+        layers.class_layer = std::stoi(class_layer_opt->answer);
+    if (rgb_layer_opt->answer && rgb_layer_opt->answer[0] != '\0')
+        layers.rgb_layer = std::stoi(rgb_layer_opt->answer);
+
     double xmin = 0;
     double ymin = 0;
     double xmax = 0;
@@ -417,9 +433,6 @@
     // TODO: the falses for filters should be perhaps fatal error
     // (bad input) or warning if filter was requested by the user
 
-    struct GLidarLayers layers;
-    GLidarLayers_set_default_layers(&layers);
-
     // update layers we are writting based on what is in the data
     // update usage of our filters as well
     if (point_view->hasDim(pdal::Dimension::Id::ReturnNumber) &&
@@ -427,8 +440,11 @@
         use_return_filter = true;
     }
     else {
-        layers.return_layer = 0;
-        layers.n_returns_layer = 0;
+        if (layers.return_layer) {
+            layers.return_layer = 0;
+            G_warning(_("Cannot store return information because the"
+                        " input does not have a return dimensions"));
+        }
         use_return_filter = false;
     }
 
@@ -436,28 +452,24 @@
         use_class_filter = true;
     }
     else {
-        layers.class_layer = 0;
+        if (layers.class_layer) {
+            layers.class_layer = 0;
+            G_warning(_("Cannot store class because the input"
+                        " does not have a classification dimension"));
+        }
         use_class_filter = false;
     }
 
     if (!(point_view->hasDim(pdal::Dimension::Id::Red) &&
-            point_view->hasDim(pdal::Dimension::Id::Green) &&
-            point_view->hasDim(pdal::Dimension::Id::Blue) &&
-            (layers.rgb_layer || layers.red_layer
-             || layers.green_layer || layers.blue_layer))) {
-        layers.rgb_layer = 0;
-        layers.red_layer = 0;
-        layers.green_layer = 0;
-        layers.blue_layer = 0;
+          point_view->hasDim(pdal::Dimension::Id::Green) &&
+          point_view->hasDim(pdal::Dimension::Id::Blue))) {
+        if (layers.rgb_layer) {
+            layers.rgb_layer = 0;
+            G_warning(_("Cannot store RGB colors because the input"
+                        " does not have a RGB dimensions"));
+        }
     }
-    if (idcat_flag->answer)
-        layers.id_layer = G_ID_LAYER;
 
-    // we just force it without any checking (we rely on the options)
-    if (nocats_flag->answer) {
-        GLidarLayers_set_no_layers(&layers);
-    }
-
     G_important_message(_("Scanning points..."));
     struct Map_info output_vector;
 
@@ -534,7 +546,7 @@
         pdal_point_to_grass(&output_vector, points, cats, point_view,
                             idx, &layers, cat, dim_to_use_as_z);
         if (layers.id_layer) {
-            // TODO: perhaps it would be better to use the max cat afterwords
+            // TODO: perhaps it would be better to use the max cat afterwards
             if (cat == GV_CAT_MAX) {
                 cat_max_reached = true;
                 break;

Modified: grass/trunk/vector/v.out.lidar/main.c
===================================================================
--- grass/trunk/vector/v.out.lidar/main.c	2016-05-19 20:26:04 UTC (rev 68468)
+++ grass/trunk/vector/v.out.lidar/main.c	2016-05-19 21:19:00 UTC (rev 68469)
@@ -27,6 +27,9 @@
 
 #include <liblas/capi/liblas.h>
 
+#define LAS_FIRST 1
+#define LAS_LAST 2
+#define LAS_MID 3
 
 struct WriteContext
 {
@@ -36,12 +39,8 @@
     struct Colors *color_table;
     int layer;
     int return_layer;
-    int n_returns_layer;
     int class_layer;
     int rgb_layer;
-    int red_layer;
-    int green_layer;
-    int blue_layer;
     dbCatValArray *return_column_values;
     dbCatValArray *n_returns_column_values;
     dbCatValArray *class_column_values;
@@ -393,20 +392,24 @@
     if (context->return_layer) {
         if (!Vect_cat_get(cats, context->return_layer, &cat))
             return;             /* TODO: is this an error? */
-        LASPoint_SetReturnNumber(las_point, cat);
+        /* TODO: use LAS... as constants for numbers */
+        if (cat == LAS_FIRST) {
+            LASPoint_SetReturnNumber(las_point, 1);
+            LASPoint_SetNumberOfReturns(las_point, 3);
+        } else if (cat == LAS_LAST) {
+            LASPoint_SetReturnNumber(las_point, 3);
+            LASPoint_SetNumberOfReturns(las_point, 3);
+        } else {
+            LASPoint_SetReturnNumber(las_point, 2);
+            LASPoint_SetNumberOfReturns(las_point, 3);
+        }
     }
-    if (context->n_returns_layer) {
-        if (!Vect_cat_get(cats, context->n_returns_layer, &cat))
-            return;             /* TODO: is this an error? */
-        LASPoint_SetNumberOfReturns(las_point, cat);
-    }
     if (context->class_layer) {
         if (!Vect_cat_get(cats, context->class_layer, &cat))
             return;             /* TODO: is this an error? */
         LASPoint_SetClassification(las_point, cat);
     }
-    if (context->rgb_layer || context->red_layer || context->green_layer ||
-        context->blue_layer) {
+    if (context->rgb_layer) {
         LASColorH las_color = context->las_color;
 
         /* TODO: defaults for the color are what? */
@@ -422,21 +425,6 @@
             LASColor_SetGreen(las_color, green);
             LASColor_SetBlue(las_color, blue);
         }                       /* TODO: else all the others? */
-        if (context->red_layer) {
-            if (!Vect_cat_get(cats, context->red_layer, &cat))
-                return;         /* TODO: is this an error? */
-            LASColor_SetRed(las_color, cat);
-        }                       /* TODO: else set 0, or by default? */
-        if (context->green_layer) {
-            if (!Vect_cat_get(cats, context->green_layer, &cat))
-                return;         /* TODO: is this an error? */
-            LASColor_SetGreen(las_color, cat);
-        }
-        if (context->blue_layer) {
-            if (!Vect_cat_get(cats, context->blue_layer, &cat))
-                return;         /* TODO: is this an error? */
-            LASColor_SetBlue(las_color, cat);
-        }
         LASPoint_SetColor(las_point, las_color);
     }
 
@@ -462,9 +450,9 @@
     struct GModule *module;
     struct Option *map_opt, *foutput_opt;
     struct Option *field_opt, *cats_opt;
-    struct Option *id_layer_opt, *class_layer_opt;
-    struct Option *return_layer_opt, *n_returns_layer_opt;
-    struct Option *red_layer_opt, *green_layer_opt, *blue_layer_opt;
+    struct Option *id_layer_opt;
+    struct Option *return_layer_opt;
+    struct Option *class_layer_opt;
     struct Option *rgb_layer_opt;
     struct Option *return_column_opt, *n_returns_column_opt;
     struct Option *class_column_opt;
@@ -514,13 +502,6 @@
     return_layer_opt->answer = NULL;
     return_layer_opt->guisection = _("Categories");
 
-    n_returns_layer_opt = G_define_standard_option(G_OPT_V_FIELD);
-    n_returns_layer_opt->key = "n_returns_layer";
-    n_returns_layer_opt->label =
-        _("Layer number to store return number as category");
-    n_returns_layer_opt->answer = NULL;
-    n_returns_layer_opt->guisection = _("Categories");
-
     class_layer_opt = G_define_standard_option(G_OPT_V_FIELD);
     class_layer_opt->key = "class_layer";
     class_layer_opt->label =
@@ -535,27 +516,6 @@
     rgb_layer_opt->answer = NULL;
     rgb_layer_opt->guisection = _("Categories");
 
-    red_layer_opt = G_define_standard_option(G_OPT_V_FIELD);
-    red_layer_opt->key = "red_layer";
-    red_layer_opt->label =
-        _("Layer number where red color is stored as category");
-    red_layer_opt->answer = NULL;
-    red_layer_opt->guisection = _("Categories");
-
-    green_layer_opt = G_define_standard_option(G_OPT_V_FIELD);
-    green_layer_opt->key = "green_layer";
-    green_layer_opt->label =
-        _("Layer number where red color is stored as category");
-    green_layer_opt->answer = NULL;
-    green_layer_opt->guisection = _("Categories");
-
-    blue_layer_opt = G_define_standard_option(G_OPT_V_FIELD);
-    blue_layer_opt->key = "blue_layer";
-    blue_layer_opt->label =
-        _("Layer number where blue color is stored as category");
-    blue_layer_opt->answer = NULL;
-    blue_layer_opt->guisection = _("Categories");
-
     /* TODO: probably replace the option by standardized/expected column names */
 
     return_column_opt = G_define_standard_option(G_OPT_DB_COLUMN);
@@ -663,26 +623,14 @@
     struct WriteContext write_context;
 
     write_context.return_layer = 0;
-    write_context.n_returns_layer = 0;
     write_context.class_layer = 0;
     write_context.rgb_layer = 0;
-    write_context.red_layer = 0;
-    write_context.green_layer = 0;
-    write_context.blue_layer = 0;
     if (return_layer_opt->answer)
         write_context.return_layer = atoi(return_layer_opt->answer);
-    if (n_returns_layer_opt->answer)
-        write_context.n_returns_layer = atoi(n_returns_layer_opt->answer);
     if (class_layer_opt->answer)
         write_context.class_layer = atoi(class_layer_opt->answer);
     if (rgb_layer_opt->answer)
         write_context.rgb_layer = atoi(rgb_layer_opt->answer);
-    if (red_layer_opt->answer)
-        write_context.red_layer = atoi(red_layer_opt->answer);
-    if (green_layer_opt->answer)
-        write_context.green_layer = atoi(green_layer_opt->answer);
-    if (blue_layer_opt->answer)
-        write_context.blue_layer = atoi(blue_layer_opt->answer);
 
     /* get GRASS loc proj info */
     struct Key_Value *proj_info;
@@ -758,8 +706,11 @@
 
     struct Colors color_table;
     write_context.color_table = 0;
-    if (!use_color_attributes && !no_color_table_flag->answer && !(write_context.rgb_layer || write_context.red_layer || write_context.green_layer || write_context.blue_layer)) {
-        int has_colors = Vect_read_colors(Vect_get_name(&vinput), Vect_get_mapset(&vinput), &color_table);
+    if (!use_color_attributes && !no_color_table_flag->answer
+        && !(write_context.rgb_layer)) {
+        int has_colors = Vect_read_colors(Vect_get_name(&vinput),
+                                          Vect_get_mapset(&vinput),
+                                          &color_table);
         if (has_colors)
             write_context.color_table = &color_table;
     }



More information about the grass-commit mailing list