[GRASS-dev] [GRASS GIS] #2734: v.distance: 3d point inside area is classified as outside

#2734: v.distance: 3d point inside area is classified as outside
-----------------------------+-------------------------
Reporter: annakrat | Owner: grass-dev@…
     Type: defect | Status: new
Priority: normal | Milestone: 7.0.2
Component: Vector | Version: svn-trunk
Keywords: v.distance, box | CPU: All
Platform: All |
-----------------------------+-------------------------
When a point is 3D and has different z coordinate than 0 and this point is
inside 2D area, v.distance reports that this point is outside the area.
The problem is in
[https://trac.osgeo.org/grass/browser/grass/trunk/vector/v.distance/distance.c#L293
distance.c], which calls
[https://trac.osgeo.org/grass/browser/grass/trunk/lib/vector/Vlib/box.c#L31
Vect_point_in_box] - the top and bottom of the area's box are 0, the z
coordinate (of the 3D point) is not.

One solution is to do something like this:
{{{
Index: distance.c

--- distance.c (revision 66134)
+++ distance.c (working copy)
@@ -291,7 +291,7 @@

      for (i = 0; i < Points->n_points; i++) {
         if (Vect_point_in_box(Points->x[i], Points->y[i],
- Points->z[i], abox)) {
+ with_z ? Points->z[i] : 0, abox)) {

             int poly;
}}}
but then the comparison of doubles (0 == 0) in Vect_point_in_box might not
always work.

Or we could introduce a 2D version of the Vect_point_in_box function which
checks x and y only.

--
Ticket URL: <https://trac.osgeo.org/grass/ticket/2734&gt;
GRASS GIS <https://grass.osgeo.org>

#2734: v.distance: 3d point inside area is classified as outside
-----------------------+-----------------------------
  Reporter: annakrat | Owner: grass-dev@…
      Type: defect | Status: new
  Priority: normal | Milestone: 7.0.2
Component: Vector | Version: svn-trunk
Resolution: | Keywords: v.distance, box
       CPU: All | Platform: All
-----------------------+-----------------------------

Comment (by wenzeslaus):

On Wed, Oct 7, 2015 at 4:32 AM, Moritz Lennert wrote at
[https://lists.osgeo.org/pipermail/grass-user/2015-October/073089.html
grass-user]:
> I have the feeling that the second proposed solution, i.e. "introduce a
2D version of the Vect_point_in_box function which checks x and y only" is
the better long-run solution.

Good idea. I could use this, e.g. in
[source:grass/trunk/vector/v.decimate/main.c?rev=66387#L86 v.decimate]
where I have now `point_in_region_2d()` and `point_in_region_3d`. I'm
using `Cell_head` as the region/bbox, but it doesn't contain any info
whether it is 2D or 3D, if something like `depths=0` (perhaps wrapped in
`G_is_cell_head_3d()`) would tell if it is 3D, then I could have just
`point_in_region()`.

--
Ticket URL: <https://trac.osgeo.org/grass/ticket/2734#comment:1&gt;
GRASS GIS <https://grass.osgeo.org>

#2734: v.distance: 3d point inside area is classified as outside
-----------------------+-----------------------------
  Reporter: annakrat | Owner: grass-dev@…
      Type: defect | Status: new
  Priority: normal | Milestone: 7.0.2
Component: Vector | Version: svn-trunk
Resolution: | Keywords: v.distance, box
       CPU: All | Platform: All
-----------------------+-----------------------------

Comment (by wenzeslaus):

In r66459 I have added `Vect_point_in_box_2d()` function which is simply a
2D version of `Vect_point_in_box()` function which is 3D only. Alternative
would be to add one function which would optionally consider ''z''.

Using `Vect_point_in_box_2d()` and existing `with_z` logic I have tried to
fix this ticket and [https://lists.osgeo.org/pipermail/grass-
user/2015-July/072809.html reported issue] in r66460 in ''v.decimate''.
The test written for ''v.decimate'' would suggest that the change helped.

`Vect_point_in_box()` function is used a lot in the modules and very often
with hardcoded `0.0` as ''z'' parameter (and there might be also cases
when ''z'' is optionally zero). These should be replaced by the new
function or its universal alternative.

If `Vect_point_in_box_2d()` will be useful for ''v.decimate'' remains
unclear. Usage of `Vect_region_box()` function would be necessary.

--
Ticket URL: <https://trac.osgeo.org/grass/ticket/2734#comment:2&gt;
GRASS GIS <https://grass.osgeo.org>

#2734: v.distance: 3d point inside area is classified as outside
-----------------------+-----------------------------
  Reporter: annakrat | Owner: grass-dev@…
      Type: defect | Status: new
  Priority: normal | Milestone: 7.0.4
Component: Vector | Version: svn-trunk
Resolution: | Keywords: v.distance, box
       CPU: All | Platform: All
-----------------------+-----------------------------

Comment (by wenzeslaus):

Changes to the library and ''v.distance'' backported to release branch 7.0
in r68143 and r68146. Test them using NC SPM full dataset:

{{{
v.distance -p from=precip_30ynormals_3d to=boundary_county dmax=0
upload=cat,dist
}}}

You should get:

{{{
from_cat|(null)|(null)
1|501|0
2|511|0
3|19|0
4|261|0
...
}}}

In previous versions you will get:

{{{
from_cat|(null)|(null)
1|null|null
2|null|null
3|null|null
4|null|null
...
}}}

The changes to rest of the modules are outside of scope of this ticket and
are tracked in #2970.

--
Ticket URL: <https://trac.osgeo.org/grass/ticket/2734#comment:6&gt;
GRASS GIS <https://grass.osgeo.org>

#2734: v.distance: 3d point inside area is classified as outside
-----------------------+-----------------------------
  Reporter: annakrat | Owner: grass-dev@…
      Type: defect | Status: closed
  Priority: normal | Milestone: 7.0.4
Component: Vector | Version: svn-trunk
Resolution: fixed | Keywords: v.distance, box
       CPU: All | Platform: All
-----------------------+-----------------------------
Changes (by wenzeslaus):

* status: new => closed
* resolution: => fixed

--
Ticket URL: <https://trac.osgeo.org/grass/ticket/2734#comment:7&gt;
GRASS GIS <https://grass.osgeo.org>