[GRASS-dev] d.vect render= and corrupted vector display

Glynn Clements glynn at gclements.plus.com
Sun Apr 8 16:18:22 EDT 2007


Maciej Sieczka wrote:

> >>> I've changed the clipping/culling code to handle this particular case
> >>> (i.e. use <= 0 rather than < 0), so #4 and #5 now match the other
> >>> three.
> >>> Beyond that, the main issue is that the code which sets up the
> >>> coordinate mapping (D_setup/D_do_conversions) maps the current region
> >>> to the current frame *exactly*, without any margin. This is arguably
> >>> the right thing, even if the net result isn't always ideal (and the
> >>> result of v.in.region is the worst possible case).
> >> Don't you think it is confussing for the user? If I do v.in.region, I'm
> >> right to expect that the whole vector will be displayed when my working
> >> region matches the v.in.region's output extent.
> 
> > Hmm; not really. v.in.region generates a vector map corresponding to
> > the region's boundary. d.vect displays the portion of a vector map
> > which lies inside the region.
> > 
> > Is a region's boundary *inside* the region?
> 
> 1. This is not a boundary, but a line (v.in.region output=frame type=line).

Note that I mean "boundary" in the general sense, not specifically
GV_BOUNDARY.

> 2. Even if it was a boundary - either the *whole* boundary should be
> displayed, or not. Currently, 75% of the boundary is displayed, while
> the other 25% is not. This looks strange to the user.

Typically, two of the region edges will be coincident with the
corresponding edges of the display frame, while the other two won't
(unless the region's aspect ratio exactly matches that of the display
frame).

For a vertical or horizontal line segment which is concident with an
edge of the display frame, it's essentially a 50/50 chance as to
whether that edge will lie inside or outside the frame; even the
slightest rounding error can decide it. Note that it is not guaranteed
that (x/y)*y == x when using floating point.

If you go out of your way to create lines which lie exactly on a
boundary, the results are bound to be unpredictable. Unfortunately,
that's exactly what v.in.region does.

Ultimately, the only solution is to stick to even line widths (i.e. 
width=2, width=4 etc), or use the PS driver. Then you're guaranteed to
get exactly half of a line on each side (if you don't, that *is* a
bug).

> > How do you propose "fixing" this case
> 
> I can't know that. I thought you might, so I asked.
> 
> > without breaking more sensible cases.
> 
> What could be broken?

Well, that depends upon what you change. AFAICT, changing anything
which is likely to affect the result of v.in.region type=line + d.vect
amounts to introducing an error.

One solution is to expand the region used by D_do_conversions()
(either pass in an expanded region or have D_do_conversions() expand
it) so that data which lies either within the current region or
exactly on its bounds always lies comfortably within the expanded
region.

But expanded by how much? A metre, a pixel, 1%, ...? It would have to
be consistent if you want to overlay maps.

Also, that would cause problems for any external code which attempts
to reproduce the conversion; ISTR that gis.m does this to convert
mouse coordinates to geographic coordinates.

> > Bear in mind that this is
> > (quite literally) a "boundary case".
> 
> I don't agree. This issue might bias user's understanding of GRASS'
> region, which is not trivial:

That doesn't have any effect upon whether this is a boundary case.

> g.region vect=frame; d.vect frame
> 
> In a result, 25% of lines is missing on display, while region and
> display were ordered to encompass the whole vector "frame". As the 3/4
> of lines is displayed while 1/4 is not, it just looks "not good" to the
> user, thus might incline him to think there is a defect somewhere
> underneath.
> 
> Please note that if you decide this cannot be fixed/too intrusive to do
> so/to much work compared to profit, please be sure I'm perfectly OK
> with your decision. Yet, the issue would remain.

If it was critical, it could be trivially fixed by prohibiting odd
line widths in the X and PNG drivers. Unfortunately, a line width of 2
may be much slower than a line width of 1 for the X driver, as it uses
a completely different (and more complex) algorithm.

But this is just a single (albeit rather striking) example of an
inevitable problem with raster graphics: aliasing. Even if you fix
this specific case by means of some fudge, there are an unlimited
number of similar cases.

-- 
Glynn Clements <glynn at gclements.plus.com>




More information about the grass-dev mailing list