[GRASS-SVN] r67353 - in grass/trunk/vector/v.in.lidar: . testsuite

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Dec 23 18:29:05 PST 2015


Author: wenzeslaus
Date: 2015-12-23 18:29:05 -0800 (Wed, 23 Dec 2015)
New Revision: 67353

Added:
   grass/trunk/vector/v.in.lidar/filters.c
   grass/trunk/vector/v.in.lidar/filters.h
   grass/trunk/vector/v.in.lidar/testsuite/filter_test.py
Modified:
   grass/trunk/vector/v.in.lidar/main.c
Log:
v.in.lidar: move class and return filter code out of main

Files taken from r.in.lidar and extended.

Tests added for return and class filters and both together.


Copied: grass/trunk/vector/v.in.lidar/filters.c (from rev 67262, grass/trunk/raster/r.in.lidar/filters.c)
===================================================================
--- grass/trunk/vector/v.in.lidar/filters.c	                        (rev 0)
+++ grass/trunk/vector/v.in.lidar/filters.c	2015-12-24 02:29:05 UTC (rev 67353)
@@ -0,0 +1,89 @@
+/*
+ * v.in.lidar filtering functions
+ *
+ * Copyright 2011-2015 by Markus Metz, and The GRASS Development Team
+ * Authors:
+ *  Markus Metz (r.in.lidar)
+ *  Vaclav Petras (move code to a separate files)
+ *
+ * This program is free software licensed under the GPL (>=v2).
+ * Read the COPYING file that comes with GRASS for details.
+ *
+ */
+
+
+#include "filters.h"
+
+#include "lidar.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+void return_filter_create_from_string(struct ReturnFilter *return_filter,
+                                      const char *name)
+{
+    return_filter->filter = LAS_ALL;
+    if (name) {
+        if (strcmp(name, "first") == 0)
+            return_filter->filter = LAS_FIRST;
+        else if (strcmp(name, "last") == 0)
+            return_filter->filter = LAS_LAST;
+        else if (strcmp(name, "mid") == 0)
+            return_filter->filter = LAS_MID;
+        else
+            G_fatal_error(_("Unknown return filter value <%s>"), name);
+    }
+}
+
+int return_filter_is_out(struct ReturnFilter *return_filter, int return_n,
+                         int n_returns)
+{
+    if (return_filter->filter == LAS_ALL)
+        return FALSE;
+    int skipme = 1;
+
+    switch (return_filter->filter) {
+    case LAS_FIRST:
+        if (return_n == 1)
+            skipme = 0;
+        break;
+    case LAS_MID:
+        if (return_n > 1 && return_n < n_returns)
+            skipme = 0;
+        break;
+    case LAS_LAST:
+        if (n_returns > 1 && return_n == n_returns)
+            skipme = 0;
+        break;
+    }
+    if (skipme)
+        return TRUE;
+    return FALSE;
+}
+
+void class_filter_create_from_strings(struct ClassFilter *class_filter,
+                                      char **classes)
+{
+    class_filter->str_classes = classes;
+}
+
+int class_filter_is_out(struct ClassFilter *class_filter, int class_n)
+{
+    if (!class_filter->str_classes)
+        return FALSE;
+    int i = 0;
+    int skipme = TRUE;
+
+    while (class_filter->str_classes[i]) {
+        if (class_n == atoi(class_filter->str_classes[i])) {
+            skipme = FALSE;
+            break;
+        }
+        i++;
+    }
+    if (skipme)
+        return TRUE;
+    return FALSE;
+}

Copied: grass/trunk/vector/v.in.lidar/filters.h (from rev 67262, grass/trunk/raster/r.in.lidar/filters.h)
===================================================================
--- grass/trunk/vector/v.in.lidar/filters.h	                        (rev 0)
+++ grass/trunk/vector/v.in.lidar/filters.h	2015-12-24 02:29:05 UTC (rev 67353)
@@ -0,0 +1,37 @@
+/*
+ * v.in.lidar filtering functions
+ *
+ * Copyright 2011-2015 by Markus Metz, and The GRASS Development Team
+ * Authors:
+ *  Markus Metz (r.in.lidar)
+ *  Vaclav Petras (move code to a separate files)
+ *
+ * This program is free software licensed under the GPL (>=v2).
+ * Read the COPYING file that comes with GRASS for details.
+ *
+ */
+
+#ifndef __FILTERS_H__
+#define __FILTERS_H__
+
+struct ReturnFilter
+{
+    int filter;
+};
+
+struct ClassFilter
+{
+
+    /** NULL terminated list of class numbers represented as string */
+    char **str_classes;
+};
+
+void return_filter_create_from_string(struct ReturnFilter *return_filter,
+                                      const char *name);
+int return_filter_is_out(struct ReturnFilter *return_filter, int return_n,
+                         int n_returns);
+void class_filter_create_from_strings(struct ClassFilter *class_filter,
+                                      char **classes);
+int class_filter_is_out(struct ClassFilter *class_filter, int class_n);
+
+#endif /* __FILTERS_H__ */

Modified: grass/trunk/vector/v.in.lidar/main.c
===================================================================
--- grass/trunk/vector/v.in.lidar/main.c	2015-12-24 01:05:14 UTC (rev 67352)
+++ grass/trunk/vector/v.in.lidar/main.c	2015-12-24 02:29:05 UTC (rev 67353)
@@ -33,6 +33,7 @@
 #include "attributes.h"
 #include "info.h"
 #include "vector_mask.h"
+#include "filters.h"
 
 #ifndef MAX
 #  define MIN(a,b)      ((a<b) ? a : b)
@@ -80,8 +81,6 @@
     double scale_x, scale_y, scale_z, offset_x, offset_y, offset_z;
     int las_point_format;
     int have_time, have_color;
-    int return_filter;
-    int skipme;
     int point_class;
 
     struct line_pnts *Points;
@@ -373,17 +372,10 @@
 	exit(EXIT_SUCCESS);
     }
 
-    return_filter = LAS_ALL;
-    if (filter_opt->answer) {
-	if (strcmp(filter_opt->answer, "first") == 0)
-	    return_filter = LAS_FIRST;
-	else if (strcmp(filter_opt->answer, "last") == 0)
-	    return_filter = LAS_LAST;
-	else if (strcmp(filter_opt->answer, "mid") == 0)
-	    return_filter = LAS_MID;
-	else
-	    G_fatal_error(_("Unknown filter option <%s>"), filter_opt->answer);
-    }
+    struct ReturnFilter return_filter_struct;
+    return_filter_create_from_string(&return_filter_struct, filter_opt->answer);
+    struct ClassFilter class_filter;
+    class_filter_create_from_strings(&class_filter, class_opt->answers);
 
     int id_layer = 0;
     int return_layer = 0;
@@ -657,47 +649,17 @@
             continue;
         }
     }
-	if (return_filter != LAS_ALL) {
-	    int return_no = LASPoint_GetReturnNumber(LAS_point);
-	    int n_returns = LASPoint_GetNumberOfReturns(LAS_point);
-	    skipme = 1;
-
-	    switch (return_filter) {
-	    case LAS_FIRST:
-		if (return_no == 1)
-		    skipme = 0;
-		break;
-	    case LAS_MID:
-		if (return_no > 1 && return_no < n_returns)
-		    skipme = 0;
-		break;
-	    case LAS_LAST:
-		if (n_returns > 1 && return_no == n_returns)
-		    skipme = 0;
-		break;
-	    }
-	    
-	    if (skipme) {
-		n_filtered++;
-		continue;
-	    }
-	}
-	if (class_opt->answer) {
-	    point_class = (int) LASPoint_GetClassification(LAS_point);
-	    i = 0;
-	    skipme = TRUE;
-	    while (class_opt->answers[i]) {
-		if (point_class == atoi(class_opt->answers[i])) {
-		    skipme = FALSE;
-		    break;
-		}
-		i++;
-	    }
-	    if (skipme) {
-		n_class_filtered++;
-		continue;
-	    }
-	}
+        int return_n = LASPoint_GetReturnNumber(LAS_point);
+        int n_returns = LASPoint_GetNumberOfReturns(LAS_point);
+        if (return_filter_is_out(&return_filter_struct, return_n, n_returns)) {
+            n_filtered++;
+            continue;
+        }
+        point_class = (int) LASPoint_GetClassification(LAS_point);
+        if (class_filter_is_out(&class_filter, point_class)) {
+            n_class_filtered++;
+            continue;
+        }
         if (use_zrange) {
             if (z < zrange_min || z > zrange_max) {
                 zrange_filtered++;

Added: grass/trunk/vector/v.in.lidar/testsuite/filter_test.py
===================================================================
--- grass/trunk/vector/v.in.lidar/testsuite/filter_test.py	                        (rev 0)
+++ grass/trunk/vector/v.in.lidar/testsuite/filter_test.py	2015-12-24 02:29:05 UTC (rev 67353)
@@ -0,0 +1,164 @@
+"""
+Name:      decimation_test
+Purpose:   v.in.lidar decimation test
+
+Author:    Vaclav Petras
+Copyright: (C) 2015 by Vaclav Petras and the GRASS Development Team
+Licence:   This program is free software under the GNU General Public
+           License (>=v2). Read the file COPYING that comes with GRASS
+           for details.
+"""
+
+import os
+from grass.gunittest.case import TestCase
+from grass.gunittest.main import test
+
+
+POINTS = """\
+17.46938776,18.67346939,143,1,1,2
+20.93877551,17.44897959,125,1,1,2
+18.89795918,14.18367347,130,1,1,3
+15.91836735,10.67346939,126,1,1,3
+21.26530612,11.04081633,128,1,2,3
+22.24489796,13.89795918,123,2,2,3
+23.79591837,17.12244898,151,1,2,3
+17.2244898,16.34693878,124,2,2,4
+17.14285714,14.10204082,144,1,3,4
+19.87755102,11.81632653,146,2,3,4
+18.48979592,11.48979592,140,2,3,4
+21.26530612,15.73469388,147,3,3,5
+21.18367347,19.32653061,138,1,3,5
+23.91836735,18.83673469,144,2,3,5
+23.51020408,13.65306122,143,3,3,5
+23.55102041,11.32653061,123,1,4,5
+18.41009273,14.51618034,140,2,4,5
+22.13996161,17.2278263,147,3,4,5
+21.41013052,11.05432488,142,4,4,5
+"""
+
+
+class BasicTest(TestCase):
+    """Test case for watershed module
+
+    This tests expects v.random and v.out.lidar to work properly.
+    """
+
+    # Setup variables to be used for outputs
+    vector_points = 'vinlidar_filters_original'
+    imported_points = 'vinlidar_filters_imported'
+    las_file = 'vinlidar_filters_points.las'
+    npoints = 300
+
+    @classmethod
+    def setUpClass(cls):
+        """Ensures expected computational region and generated data"""
+        cls.use_temp_region()
+        cls.runModule('g.region', n=20, s=10, e=25, w=15, res=1)
+        cls.runModule('v.in.ascii', input='-', stdin_=POINTS,
+                      flags='z', z=3, cat=0, separator='comma',
+                      output=cls.vector_points,
+                      columns="x double precision, y double precision,"
+                              " z double precision, return_n integer,"
+                              " n_returns integer, class_n integer")
+        cls.runModule('v.out.lidar',
+                      input=cls.vector_points, layer=1,
+                      output=cls.las_file,
+                      return_column='return_n',
+                      n_returns_column='n_returns',
+                      class_column='class_n')
+
+    @classmethod
+    def tearDownClass(cls):
+        """Remove the temporary region and generated data"""
+        cls.runModule('g.remove', flags='f', type='vector',
+            name=cls.vector_points)
+        if os.path.isfile(cls.las_file):
+            os.remove(cls.las_file)
+        cls.del_temp_region()
+
+    def tearDown(self):
+        """Remove the outputs created by the import
+
+        This is executed after each test run.
+        """
+        self.runModule('g.remove', flags='f', type='vector',
+            name=self.imported_points)
+
+    def test_no_filter(self):
+        """Test to see if the standard outputs are created"""
+        self.assertModule('v.in.lidar', input=self.las_file,
+            output=self.imported_points, flags='bt')
+        self.assertVectorExists(self.imported_points)
+        self.assertVectorFitsTopoInfo(
+            vector=self.imported_points,
+            reference=dict(points=19))
+
+    def return_filter(self, name, npoints):
+        """Mid return filter test"""
+        self.assertModule('v.in.lidar', input=self.las_file,
+            output=self.imported_points, flags='bt',
+            return_filter=name)
+        self.assertVectorExists(self.imported_points)
+        self.assertVectorFitsTopoInfo(
+            vector=self.imported_points,
+            reference=dict(points=npoints))
+
+    def test_first_return_filter(self):
+        """First return filter test"""
+        self.return_filter('first', 9)
+
+    def test_mid_return_filter(self):
+        """Mid return filter test"""
+        self.return_filter('mid', 5)
+
+    def test_last_return_filter(self):
+        """Last return filter test"""
+        self.return_filter('last', 5)
+
+    def class_filter(self, class_n, npoints):
+        """Actual code for testing class filter"""
+        self.assertModule('v.in.lidar', input=self.las_file,
+            output=self.imported_points, flags='bt',
+            class_filter=class_n)
+        self.assertVectorExists(self.imported_points)
+        self.assertVectorFitsTopoInfo(
+            vector=self.imported_points,
+            reference=dict(points=npoints))
+
+    def test_class_2_filter(self):
+        """Test to filter classes"""
+        self.class_filter(2, 2)
+
+    def test_class_3_filter(self):
+        """Test to filter classes"""
+        self.class_filter(3, 5)
+
+    def test_class_4_filter(self):
+        """Test to filter classes"""
+        self.class_filter(4, 4)
+
+    def test_class_5_filter(self):
+        """Test to filter classes"""
+        self.class_filter(5, 8)
+
+    def return_and_class_filter(self, return_name, class_n, npoints):
+        """Mid return filter test"""
+        self.assertModule('v.in.lidar', input=self.las_file,
+            output=self.imported_points, flags='bt',
+            return_filter=return_name, class_filter=class_n)
+        self.assertVectorExists(self.imported_points)
+        self.assertVectorFitsTopoInfo(
+            vector=self.imported_points,
+            reference=dict(points=npoints))
+
+    def test_first_return_and_class_filter(self):
+        """Combined test for return and class"""
+        self.return_and_class_filter('first', 2, 2)
+
+    def test_last_return_and_class_filter(self):
+        """Combined test for return and class"""
+        self.return_and_class_filter('last', 5, 3)
+
+
+if __name__ == '__main__':
+    test()


Property changes on: grass/trunk/vector/v.in.lidar/testsuite/filter_test.py
___________________________________________________________________
Added: svn:mime-type
   + text/x-python
Added: svn:eol-style
   + native



More information about the grass-commit mailing list