Opened 5 years ago

Closed 4 years ago

# v.distance: 3d point inside area is classified as outside

Reported by: Owned by: annakrat grass-dev@… normal 7.0.4 Vector svn-trunk v.distance, box All All

### Description

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 distance.c, which calls 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.

### comment:1 Changed 5 years ago by wenzeslaus

On Wed, Oct 7, 2015 at 4:32 AM, Moritz Lennert wrote at 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 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()`.

### comment:2 Changed 5 years ago 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 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.

Version 0, edited 5 years ago by wenzeslaus (next)

### comment:3 Changed 5 years ago by neteler

Milestone: 7.0.2 → 7.0.3

Ticket retargeted after milestone closed

### comment:4 Changed 5 years ago by neteler

Milestone: 7.0.3

Ticket retargeted after milestone closed

### comment:5 Changed 5 years ago by neteler

Milestone: → 7.0.4

Ticket retargeted after 7.0.3 milestone closed

### comment:6 Changed 4 years ago 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.

### comment:7 Changed 4 years ago by wenzeslaus

Resolution: → fixed new → closed
Note: See TracTickets for help on using tickets.