[GRASS-dev] [bug #2765] (grass) v.buffer produces strange results

hamish_nospam@yahoo.com wrote (Fri, Nov 24 2006 03:39:17):

Maciej Sieczka wrote:

g.region ditches_buf

Which one is that? It's not there in the package I sent you.

It is the saved region:

Oh, right. Sorry, my bad. I thought you meant some vector map (I missed the
fact you didn't put "vect=" into your g.region call).

can you isolate the problem with:

...

clearer: if you can extract it to a few simple areas & export with
v.out.ascii it is easier to follow step by step in the debugger. Also
you can post that to the bug's history and others can try without
needing you to send them the 1mb location download- more data points.

You are right, should have thought of using v.out.ascii for debugging.

maybe it is a FP epsilon problem, which is slightly different
machine to machine + compiler to compiler? e.g. 123.4000000000002 vs
123.4.

Would that mean v.buffer is supposed to work on some Linuces and not
on the other? That would be a nightmare.

I don't know. It is just a guess of why our two systems would be
different. I am testing with a Pent4 32bit debian/stable machine.
Is yours 64bit?

No. 32 bit, Pentium M 750 (Dothan). Ubuntu Dapper 2.6.15-27-686. I'm not using
any optimization at the build time. GCC 4.0.3-1ubuntu5.

v.buffer will try and do the same calculation, but the
computer may give a slightly different results. That will happen with
any 32bit and 64bit system doing FP math, with any program. It would be
a v.buffer bug if e.g. if it tests FP1==FP2 when it should test
"fabs(FP2-FP1) <= EPSILON"

This is propably not the case here. But I have a lead :). Please read at the
bottom.

does "d.what.vect -f" (or without -f check area size) show the original
as a closed area?

Yes:

$ d.vect ditches; d.what.vect -f

map: 'ditches'
mapset: 'vbuffer_bugs'
feature type: Area
area size: 475.449658

Layer: 1
category: 1205
Database connection not defined

Please watch the swf at [3], where I present step-by-step the two runs
of v.buffer on the problematic dataset - before and after the required
"edit", including how the "edit" looks like. I'm just moving vertex of
a topologically clean boundary a bit and snapping it back. Strange...

sorry, I don't have flash installed. But I trust you are honest and we
have tried the same commands :slight_smile:

Following your v.out.ascii hint here's what I found out.

Extract the problematic area 1205:
$ v.extract in=ditches out=ditch_1205 type=area list=1205

Buffer it:
$ v.buffer ditch_1205 out=ditch_1205_b1 type=area buffer=1
$ v.buffer ditch_1205 out=ditch_1205_b4 type=area buffer=4

As expected, both outputs are wrong, see [2] and [3], respectively.

Running the ditch_1205 through ascii vector, like:
$ v.out.ascii ditch_1205 form=standard | v.in.ascii format=standard
out=ditch_1205_asciied

doesn't change anything - buffering the ditch_1205_asciied still yields wrong
results, exactly the same as seen on [2] and [3].

However, after "editing" the ditch_1205 in v.digit, like shown on [4],[5],[6],
ie. dissjoining the boundary and snapping the vertex back,

$ g.copy vect=ditch_1205,ditch_1205_edt
$ v.digit ditch_1205_edt #see [4],[5],[6]

buffering this resulting vector yields correct results; see [7],[8], respectively:

$ v.buffer ditch_1205_edt out=ditch_1205_edt_b1 type=area buffer=1
$ v.buffer ditch_1205_edt out=ditch_1205_edt_b4 type=area buffer=4

Now, why does this "touch" of v.digit help? The *only* difference between
ditch_1205 and the "edited" ditch_1205_edt according to v.out.ascii is where
the boundary no #4 is mentioned, see:

$ v.out.ascii ditch_1205 form=standard | awk 'NR>10'
B 4
600727.68682251 5677973.32091602
600739.16582305 5678137.49568095
600736.32863997 5678140.4618269
600730.63832718 5678056.67823368
B 2
600730.63832718 5678056.67823368
600725.02385533 5677974.01131491
C 1 1
600730.04890192 5678035.56666655
1 1205
B 2
600727.68682251 5677973.32091602
600725.02385533 5677974.01131491

compared to:

$ v.out.ascii ditch_1205_edt form=standard | awk 'NR>10'
B 2
600730.63832718 5678056.67823368
600725.02385533 5677974.01131491
C 1 1
600730.04890192 5678035.56666655
1 1205
B 2
600727.68682251 5677973.32091602
600725.02385533 5677974.01131491
B 4
600727.68682251 5677973.32091602
600739.16582305 5678137.49568095
600736.32863997 5678140.4618269
600730.63832718 5678056.67823368

Note there is no single difference between the 2 *besides* the order in which
boundaries are listed. Somehow, the ditch_1205 having boundary #4 listed as
first is wrong for v.buffer (on my machine), while the ditch_1205_edt, having
the same boundary listed as the last one, is OK.

Does this finding help?

Maciek

[0]http://kufaya.googlepages.com/v.bufferbug%232765

[1]http://kufaya.googlepages.com/ditch_1205.png

[2]http://kufaya.googlepages.com/ditch_1205_b1.png
[3]http://kufaya.googlepages.com/ditch_1205_b4.png
[4]http://kufaya.googlepages.com/ditch_1205_edt1.png
[5]http://kufaya.googlepages.com/ditch_1205_edt2.png
[6]http://kufaya.googlepages.com/ditch_1205_edt3.png
[7]http://kufaya.googlepages.com/ditch_1205_edt_b1.png
[8]http://kufaya.googlepages.com/ditch_1205_edt_b4.png

-------------------------------------------- Managed by Request Tracker

Maciek Sieczka via RT wrote:

Note there is no single difference between the 2 *besides* the order
in which boundaries are listed. Somehow, the ditch_1205 having
boundary #4 listed as first is wrong for v.buffer (on my machine),
while the ditch_1205_edt, having the same boundary listed as the last
one, is OK.

Does this finding help?

Yes. It is excellent information. (but no solution yet)

another test:
  v.build.polylines in=ditch_1205 out=ditch_1205_single
  v.buffer ditch_1205_single out=ditch_1205_single_b4 type=area buffer=4

Could others try buffering this area? Maybe it fails for someone else?

GRASS> v.in.ascii out=ditch_1205 form=standard -n << EOF
B 4
600727.68682251 5677973.32091602
600739.16582305 5678137.49568095
600736.32863997 5678140.4618269
600730.63832718 5678056.67823368
B 2
600730.63832718 5678056.67823368
600725.02385533 5677974.01131491
C 1 1
600730.04890192 5678035.56666655
1 1205
B 2
600727.68682251 5677973.32091602
600725.02385533 5677974.01131491
EOF

# and then:
GRASS> v.buffer ditch_1205 out=ditch_1205_b1 type=area buffer=1
GRASS> v.buffer ditch_1205 out=ditch_1205_b4 type=area buffer=4

?
Hamish

On Sun, Nov 26, 2006 at 10:38:08PM +0100, Maciek Sieczka via RT wrote:

$ v.out.ascii ditch_1205 form=standard | awk 'NR>10'
B 4
600727.68682251 5677973.32091602
600739.16582305 5678137.49568095
600736.32863997 5678140.4618269
600730.63832718 5678056.67823368
B 2
600730.63832718 5678056.67823368
600725.02385533 5677974.01131491
C 1 1
600730.04890192 5678035.56666655
1 1205
B 2
600727.68682251 5677973.32091602
600725.02385533 5677974.01131491

compared to:

$ v.out.ascii ditch_1205_edt form=standard | awk 'NR>10'
B 2
600730.63832718 5678056.67823368
600725.02385533 5677974.01131491
C 1 1
600730.04890192 5678035.56666655
1 1205
B 2
600727.68682251 5677973.32091602
600725.02385533 5677974.01131491
B 4
600727.68682251 5677973.32091602
600739.16582305 5678137.49568095
600736.32863997 5678140.4618269
600730.63832718 5678056.67823368

Note there is no single difference between the 2 *besides* the order in which
boundaries are listed. Somehow, the ditch_1205 having boundary #4 listed as
first is wrong for v.buffer (on my machine), while the ditch_1205_edt, having
the same boundary listed as the last one, is OK.

FWIW, it seems clear that the problem is a snapping one, that is that a
node, whose coordinates appear to be the very same as a previous node
entered is _not_ snapped and is created as a new node. Hence even if
visually the area edges are connected, they are not since they end with
distinct nodes (that are equal but not identical).

I suspect that the offending node is:
600727.68682251 5677973.32091602

I imagine that with the new vector engine you still have a '-s' option
to v.support(1) or equivalent.
Take the non working case, and before buffering snap nodes with a very
small threshold. The problem shall disappear (this is indeed what you do
in v.digit(1), except that for v.digit(1) the snapping threshold is
usually relatively high).

If the diagnostic is correct, one thing to look in your code is the
handling of the 'C' record, I imagine this is the centroid?
I guess that centroid are not snapped, so that the code disallow
snapping when entering a centroid and that this is still in effect with
the next coordinates entered.

Hence, when the 'C' record is---first example, non working---before a
coordinate that is already a node, it is not snapped.

In the second example, since the next coordinate is not already a node
(it is a creation), no snapping is done but this is no harm.

You can confirm by moving the 'C' record in the first example last. It
should then work.

If people that can't reproduce the bug are snapping node before trying,
the difference is understandable.

If they are not snapping nodes before trying, what is to be checked is
is the floating point support linked to the hardware type (FPU, ieee754
support or not etc.).

HTH
--
Thierry Laronde (Alceste) <tlaronde +AT+ polynum +dot+ com>
                 http://www.kergis.com/
Key fingerprint = 0FF7 E906 FBAF FE95 FD89 250D 52B1 AE95 6006 F40C