diff --git a/doc/grid_radius_search.md b/doc/grid_radius_search.md index 09b385b..cd62bd5 100755 --- a/doc/grid_radius_search.md +++ b/doc/grid_radius_search.md @@ -43,3 +43,9 @@ Options **output_name_attribut**: The name of the new attribut. [Default: radius] +**3d_search**: Search in 3d (as a ball). [Default: false] + +**2d_search_above**: If 3d_search is false, take points only if exists points between the referent point and a distance above. [Default: 0.] + +**2d_search_bellow**: If 3d_search is false, take points only if exists points between the referent point and a distance bellow. [Default: 0.] + diff --git a/src/filter_radius_search/radius_searchFilter.cpp b/src/filter_radius_search/radius_searchFilter.cpp index 82fb455..4566181 100644 --- a/src/filter_radius_search/radius_searchFilter.cpp +++ b/src/filter_radius_search/radius_searchFilter.cpp @@ -37,6 +37,8 @@ void RadiusSearchFilter::addArgs(ProgramArgs& args) args.add("radius", "Distance of neighbors to consult", m_args->m_radius, 1.); args.add("output_name_attribute", "Name of the added attribut", m_args->m_nameAddAttribute, "radius" ); args.add("3d_search", "Search in 3d", m_args->search3d, false ); + args.add("2d_search_above", "if search in 2d : filter point above the distance", m_args->m_search_bellow, 0. ); + args.add("2d_search_bellow", "if search in 2d : filter point bellow the distance", m_args->m_search_above, 0. ); } void RadiusSearchFilter::addDimensions(PointLayoutPtr layout) @@ -68,7 +70,7 @@ void RadiusSearchFilter::ready(PointTableRef) void RadiusSearchFilter::doOneNoDomain(PointRef &point) { - // build3dIndex and build2dIndex are buuild once + // build3dIndex and build2dIndex are build once PointIdList iNeighbors; if (m_args->search3d) iNeighbors = refView->build3dIndex().radius(point, m_args->m_radius); else iNeighbors = refView->build2dIndex().radius(point, m_args->m_radius); @@ -76,6 +78,22 @@ void RadiusSearchFilter::doOneNoDomain(PointRef &point) if (iNeighbors.size() == 0) return; + if (!m_args->search3d) + { + double Zref = point.getFieldAs(Dimension::Id::Z); + if (m_args->m_search_bellow>0 || m_args->m_search_above>0) + { + bool take (false); + for (PointId ptId : iNeighbors) + { + double Zpt = refView->point(ptId).getFieldAs(Dimension::Id::Z); + if (m_args->m_search_bellow>0 && Zpt>Zref && (Zpt-Zref)m_search_bellow) {take=true; break;} + if (m_args->m_search_above>0 && Zptm_search_above) {take=true; break;} + } + if (!take) return; + } + } + m_args->m_ptsToUpdate.push_back(point.pointId()); } diff --git a/src/filter_radius_search/radius_searchFilter.hpp b/src/filter_radius_search/radius_searchFilter.hpp index 515c155..3a4346e 100644 --- a/src/filter_radius_search/radius_searchFilter.hpp +++ b/src/filter_radius_search/radius_searchFilter.hpp @@ -32,6 +32,7 @@ class PDAL_DLL RadiusSearchFilter : public Filter Dimension::Id m_dim; bool search3d; Dimension::Id m_dim_ref, m_dim_src; + double m_search_bellow, m_search_above; }; std::unique_ptr m_args; PointViewPtr refView; diff --git a/test/test_radius_search.py b/test/test_radius_search.py index 2e077e2..cb35c0d 100755 --- a/test/test_radius_search.py +++ b/test/test_radius_search.py @@ -35,6 +35,7 @@ def distance3d(pt1, pt2): nb_points = randint(10, 20) nb_points_take_2d = 0 nb_points_take_3d = 0 + nb_points_take_2d_above_bellow = 0 for i in range(nb_points): pti_x = pt_x + rand.uniform(-1.5, 1.5) @@ -51,6 +52,10 @@ def distance3d(pt1, pt2): if distance_i_2d < distance_radius: nb_points_take_2d += 1 + if pti_z>pt_z and pti_z-pt_z>0.5: + nb_points_take_2d_above_bellow += 1 + if pti_z0.5: + nb_points_take_2d_above_bellow += 1 if distance_i_3d < distance_radius: nb_points_take_3d += 1 @@ -86,7 +91,17 @@ def distance3d(pt1, pt2): "src_domain": "SRS_DOMAIN", "reference_domain": "REF_DOMAIN", "output_name_attribute": "radius_2D", - "3d_search":False + "3d_search":False, + }, + { + "type": filter, + "radius": "1.", + "src_domain": "SRS_DOMAIN", + "reference_domain": "REF_DOMAIN", + "output_name_attribute": "radius_2D_above_bellow", + "3d_search": False, + "2d_search_above": 0.5, + "2d_search_bellow": 0.5, }, { "type": filter, @@ -107,11 +122,15 @@ def distance3d(pt1, pt2): nb_pts_radius_2d = 0 nb_pts_radius_3d = 0 + nb_pts_radius_2d_above_bellow = 0 for pt in array: + if pt["radius_2D_above_bellow"] > 0: + nb_pts_radius_2d_above_bellow += 1 if pt["radius_2D"] > 0: nb_pts_radius_2d += 1 if pt["radius_3D"] > 0: nb_pts_radius_3d += 1 assert nb_pts_radius_2d == nb_points_take_2d - assert nb_pts_radius_3d == nb_points_take_3d \ No newline at end of file + assert nb_pts_radius_3d == nb_points_take_3d + assert nb_pts_radius_2d_above_bellow == nb_points_take_2d_above_bellow \ No newline at end of file