r-lidar / rlas

R package to read and write las and laz files used to store LiDAR data
https://cran.r-project.org/package=rlas
GNU General Public License v3.0
34 stars 14 forks source link

lasfilter.cpp -thin_with_voxel #32

Closed Jean-Romain closed 5 years ago

Jean-Romain commented 5 years ago

This is only to remember the code that must be modified in lasfilter.cpp in case I would update LASlib

#include <unordered_set>
#include <boost/functional/hash.hpp>

After class LAScriterionThinWithGrid

class LAScriterionThinWithVoxel : public LAScriterion
{
typedef std::array<I32,3> Array;

public:
  inline const CHAR* name() const { return "thin_with_voxel"; };
  inline I32 get_command(CHAR* string) const { return sprintf(string, "-%s ", name()); };
  inline U32 get_decompress_selective() const { return LASZIP_DECOMPRESS_SELECTIVE_CHANNEL_RETURNS_XY | LASZIP_DECOMPRESS_SELECTIVE_Z; };
  inline BOOL filter(const LASpoint* point)
  {
    if(voxel_spacing < 0)
    {
      xoffset = point->get_x();
      yoffset = point->get_y();
      zoffset = point->get_z();
      voxel_spacing = -voxel_spacing;
    }

    I32 nx = I32_FLOOR((point->get_x() - xoffset) / voxel_spacing);
    I32 ny = I32_FLOOR((point->get_y() - yoffset) / voxel_spacing);
    I32 nz = I32_FLOOR((point->get_z() - zoffset) / voxel_spacing);
    Array key = {nx, ny, nz};

    return !dynamic_registry.insert(key).second;
  };
  void reset()
  {
    voxel_spacing = -voxel_spacing;
    xoffset = 0;
    yoffset = 0;
    zoffset = 0;
    dynamic_registry.clear();
  };
  LAScriterionThinWithVoxel(F32 voxel_spacing)
  {
    this->voxel_spacing = voxel_spacing < 0 ? voxel_spacing : -voxel_spacing;
    xoffset = 0;
    yoffset = 0;
    zoffset = 0;
  };
  ~LAScriterionThinWithVoxel(){ reset(); };

private:
  double voxel_spacing;
  double xoffset;
  double yoffset;
  double zoffset;
  std::unordered_set<Array, boost::hash<Array> > dynamic_registry;
};

In LASfilter::parse()

      else if (strcmp(argv[i],"-thin_with_voxel") == 0)
      {
        if ((i+1) >= argc)
        {
          REprintf("ERROR: '%s' needs 1 argument: voxel_side_length\n", argv[i]);
          return FALSE;
        }
        add_criterion(new LAScriterionThinWithVoxel((F32)atof(argv[i+1])));
        *argv[i]='\0'; *argv[i+1]='\0'; i+=1;
      }

In LASfilter::usage()

REprintf("  -thin_with_voxel 0.1\n");