[GRASS5] [bug #920] (grass) d.vect.line does not draw lines

this bug's URL: http://intevation.de/rt/webrt?serial_num=920
-------------------------------------------------------------------------

Subject: d.vect.line does not draw lines

Platform: Linux/Intel
Linux distro: Debian
linux cpu: Intel (i486, i586, pentium ...)
Xwindows version: Xfree 4.0.x
Xwindows manager: WindowMaker
TclTk version: tcl/tk 8.2
grass downloaded at: Trento site
grass binary for platform: I compiled the sources myself
grass sources source: exp_snap_13202
c compiler name: gcc

When I launch

d.vect.line mapname

I just get a line saying

drawing lines ... 0%

and then it exits without anything on the monitor.

With

d.vect mapname

I see the map, just as with

d.vect.area mapname

I had to compile d.vect.line individually with gmake5/gmakelinks5 after the general compilation with make (see relevant message in grass-developers list), so maybe that causes the problem.

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

On Fri, Feb 15, 2002 at 11:59:05AM +0100, Request Tracker wrote:

this bug's URL: http://intevation.de/rt/webrt?serial_num=920
-------------------------------------------------------------------------

Subject: d.vect.line does not draw lines

Platform: Linux/Intel
Linux distro: Debian
linux cpu: Intel (i486, i586, pentium ...)
Xwindows version: Xfree 4.0.x
Xwindows manager: WindowMaker
TclTk version: tcl/tk 8.2
grass downloaded at: Trento site
grass binary for platform: I compiled the sources myself
grass sources source: exp_snap_13202
c compiler name: gcc

When I launch

d.vect.line mapname

I just get a line saying

drawing lines ... 0%

and then it exits without anything on the monitor.

With

d.vect mapname

I see the map, just as with

d.vect.area mapname

I had to compile d.vect.line individually with gmake5/gmakelinks5 after the general compilation with make (see relevant message in grass-developers list), so maybe that causes the problem.

d.vect.line only draws labelled lines. If the line doesn't have a
category number, it doesn't get drawn. This is so area boundaries may
be distinguished from lines representing things.

--
Eric G. Miller <egm2@jps.net>

On Fri, Feb 15, 2002 at 08:14:00AM -0800, Eric G. Miller wrote:

On Fri, Feb 15, 2002 at 11:59:05AM +0100, Request Tracker wrote:
> this bug's URL: http://intevation.de/rt/webrt?serial_num=920
> -------------------------------------------------------------------------
>
> Subject: d.vect.line does not draw lines
>
> Platform: Linux/Intel
> Linux distro: Debian
> linux cpu: Intel (i486, i586, pentium ...)
> Xwindows version: Xfree 4.0.x
> Xwindows manager: WindowMaker
> TclTk version: tcl/tk 8.2
> grass downloaded at: Trento site
> grass binary for platform: I compiled the sources myself
> grass sources source: exp_snap_13202
> c compiler name: gcc
>
> When I launch
>
> d.vect.line mapname
>
> I just get a line saying
>
> drawing lines ... 0%
>
> and then it exits without anything on the monitor.
>
> With
>
> d.vect mapname
>
> I see the map, just as with
>
> d.vect.area mapname
>
> I had to compile d.vect.line individually with gmake5/gmakelinks5 after the general compilation with make (see relevant message in grass-developers list), so maybe that causes the problem.

d.vect.line only draws labelled lines. If the line doesn't have a
category number, it doesn't get drawn. This is so area boundaries may
be distinguished from lines representing things.

Probably the module could output a message if *no* labeled lines
were found? Then the situation becomes clear to the user.

Markus

On 15 Feb 02, at 8:14, Eric G. Miller wrote:

On Fri, Feb 15, 2002 at 11:59:05AM +0100, Request Tracker wrote:
> this bug's URL: http://intevation.de/rt/webrt?serial_num=920
> -------------------------------------------------------------------------
>
>
> When I launch
>
> d.vect.line mapname
>
> I just get a line saying
>
> drawing lines ... 0%
>
> and then it exits without anything on the monitor.
>
> With
>
> d.vect mapname
>
> I see the map, just as with
>
> d.vect.area mapname
>
> I had to compile d.vect.line individually with gmake5/gmakelinks5 after the general compilation with make (see relevant message in grass-developers list), so maybe that causes the problem.

d.vect.line only draws labelled lines. If the line doesn't have a
category number, it doesn't get drawn. This is so area boundaries may
be distinguished from lines representing things.

So when I just want to draw the boundaries of areas without filling them, I have to use either d.vect or d.vect.area with fillcolor=backgroundcolor (which is slow since it "fills" the areas even though they are the same
color as the background) ?

Moritz

On Fri, Feb 15, 2002 at 04:25:25PM +0000, M Lennert wrote:
[snip]

So when I just want to draw the boundaries of areas without filling
them, I have to use either d.vect or d.vect.area with
fillcolor=backgroundcolor (which is slow since it "fills" the areas
even though they are the same color as the background) ?

This is a shortcoming of the current modules. Originally, I was
planning on having four, possibly five, vector drawing modules.

d.vect -- Just draws all the line work in some color
d.vect.area.fill -- Just draws area fill
d.vect.area.lines -- Just draws area boundaries
d.vect.lines -- Just draws labelled lines
d.vect.points ? -- Just draws vector points (like d.sites)

Then comes the idea to make d.vect.area more like d.area and
also to make d.vect do more than it formerly did (i.e. consolidate
everything into d.vect). It wouldn't be too hard to consolidate
all of the functionality into d.vect, but would require some
slight changes to the interface, and either a more general
"legend" file concept or scrapping that.

One way to extend the d.vect to meet most of those needs would
be via a couple extra flags and one parameter. Currently there's
an 'f' flag for filling areas. If we add an 'a' flag for area
lines, an 'l' flag for labelled lines, and a "fillcolor" argument,
then it would work something like:

If "fillcolor" Then
   Define 'f'
End If
If Exists 'f', 'a', or 'l' Then
  If "catnum" Then
     Setup category filter
  End If
  If 'f' and "fillcolor" Then
     Fill labelled areas with "fillcolor" (filter by cats?)
  Else If 'f' Then
      Fill labelled areas with "color" (filter by cats?)
  End If
  If 'a' Then
     Draw labelled area boundaries using "color" (filter by cats?)
  End If
  If 'l' Then
     Draw labelled lines using "color" (filter by cats?)
  End If
Else
  If "catnum" Then
     Warn "Need to specify one or more of 'f', 'a', 'l'"
  End If
  Draw all lines using "color"
End If

It'd be on the user to understand that the same category number
can mean different things (area, line, point), so mixing 'f' or
'a' with 'l', might not make sense.

Also: Currently, d.vect falls back to just drawing lines if
level 2 support is not present. I'm thinking it should
just exit with an error message ("Run v.support!").

$ d.vect help
  Draws vector maps

Usage:
  d.vect -aflv map=name [color=name] [fillcolor=name] [catnum=value[,value,...]]

Flags:
  -a Draw area boundaries with "color"
  -f Fill areas with "fillcolor" (falls back to "color")
  -l Draw labelled lines with "color"
  -v Be verbose

Parameters:
      map Name of existing vector map to display
    color Color to draw with
           options: red,orange,yellow,green,blue,indigo,violet,white,black,
              gray,brown,magenta,aqua,grey,R:G:B
           default: white
fillcolor Draw filled areas with this color (implies -f)
           options: red,orange,yellow,green,blue,indigo,violet,white,black,
              gray,brown,magenta,aqua,grey,R:G:B
   catnum List of category number(s) to be displayed

I would still like to preserve some kind of "legend" file capability.
But, to have it be more generic, it'll need some extra sections or
ways be more specific about what is being specified:

defaults ::= line_color_spec?, area_color_spec?
line_color_spec ::= color_spec
area_color_spec ::= color_spec?, line_color_spec?
color_spec ::= named_color | rgb_triplet
rgb_triplet ::= "<red>:<green>:<blue>" (0-255)
named_color ::= Standard GRASS colors
area_spec ::= categories, area_color_spec
line_spec ::= categories, line_color_spec
categories ::= single_category | category_range | category_list
single_category ::= Integer > 0
category_range ::= "single_category1-single_category2",
                     single_category2 > single_category1
category_list ::= "single_category1,single_category2,...,single_categoryN"

Sorry for the Backus-Naur DTD mishmash :wink:

--
Eric G. Miller <egm2@jps.net>

Eric,

This does sound pretty complicated and I'm not sure it is really necessary to put all in one module. From my experience most of the time one would either be displaying and area file in which boundaries are
normally all the same color or a line file with different colors for different lines. So separating the two might be easier.

But if you we go for one unified d.vect:

$ d.vect help
  Draws vector maps

Usage:
  d.vect -aflv map=name [color=name] [fillcolor=name] [catnum=value[,value,...]]

couldn't you rather do the following (since I find the combination of -aflv plus different color options a bit confusing):

Usage:
  d.vect map=name [color=name] [fillcolor=name] [acatnum=value[,value,...]] [lcatnum=value[,value,...]] [alegend=filename] [llegend=filename]

Where

if "fillcolor" then
  if "acatnum" then
  fill acatnum areas with fillcolor
  else
  fill areas with fillcolor
  end if
end if

if "linecolor" then
  if "lcatnum" then
  draw lcatnum lines with linecolor
  else
  draw all labelled lines with linecolor
  end if
end if

if "color" then
  draw all lines (area boundary or not) with color
end if

alegend = legend for areas
llegend = legend for labelled lines

It would be interesting to be able to give an alegend file but still give a "color" option to define the boundary lines color.

default, i.e. 'd.vect mapname' : no fillcolor and white line color for all lines

Just for information: the drawing of the boundaries with d.vect.area is much slower than when done through d.vect. Any idea why ?

Moritz

On Sun, Feb 17, 2002 at 01:06:48PM +0000, M Lennert wrote:

Eric,

This does sound pretty complicated and I'm not sure it is really
necessary to put all in one module. From my experience most of the
time one would either be displaying and area file in which boundaries
are normally all the same color or a line file with different colors
for different lines. So separating the two might be easier.

The more complicated interface is the reason I was thinking a few
modules with simple interfaces might be easier for users.

But if you we go for one unified d.vect:

>
> $ d.vect help Draws vector maps
>
> Usage: d.vect -aflv map=name [color=name] [fillcolor=name]
> [catnum=value[,value,...]]
>

couldn't you rather do the following (since I find the combination of
-aflv plus different color options a bit confusing):

Usage: d.vect map=name [color=name] [fillcolor=name]
[acatnum=value[,value,...]] [lcatnum=value[,value,...]]
[alegend=filename] [llegend=filename]

Where

if "fillcolor" then if "acatnum" then fill acatnum areas with
fillcolor else fill areas with fillcolor end if end if

if "linecolor" then if "lcatnum" then draw lcatnum lines with
linecolor else draw all labelled lines with linecolor end if end if

if "color" then draw all lines (area boundary or not) with color end
if

alegend = legend for areas llegend = legend for labelled lines

It would be interesting to be able to give an alegend file but still
give a "color" option to define the boundary lines color.

default, i.e. 'd.vect mapname' : no fillcolor and white line color
for all lines

I have no problem with that formulation. I'd like to get some
consensus on whether people feel one or several modules are appropriate.

Just for information: the drawing of the boundaries with d.vect.area
is much slower than when done through d.vect. Any idea why ?

Well, d.vect.area currently always does the fill, then rewinds the
vector file to draw the boundaries. It's the fill part that is
slowest. I think I have an unneeded line clipping routine in there,
which G_plot_line() repeats (so, mine should come out). The line
clipping algorithm is pretty fast, so I'd bet it's mostly the
fill part that is slowing things down (there are a lot of malloc
and free calls, then a quicksort for the scan line conversion --
the bigger the data set and the greater the number of islands,
the slower it will be. I don't think the rasterizer can get
much faster, but I could look at reusing memory, which would
probably help considerably. A higher level interface to the
plotting routines could also reduce the number of memory
copies that occur -- could be down to zero copies.)

--
Eric G. Miller <egm2@jps.net>

On 17 Feb 02, at 12:58, Eric G. Miller wrote:

I have no problem with that formulation. I'd like to get some
consensus on whether people feel one or several modules are appropriate.

I would prefer seperate modules.

> Just for information: the drawing of the boundaries with d.vect.area
> is much slower than when done through d.vect. Any idea why ?

Well, d.vect.area currently always does the fill, then rewinds the
vector file to draw the boundaries. It's the fill part that is
slowest. I think I have an unneeded line clipping routine in there,
which G_plot_line() repeats (so, mine should come out). The line
clipping algorithm is pretty fast, so I'd bet it's mostly the
fill part that is slowing things down (there are a lot of malloc
and free calls, then a quicksort for the scan line conversion --
the bigger the data set and the greater the number of islands,
the slower it will be. I don't think the rasterizer can get
much faster, but I could look at reusing memory, which would
probably help considerably. A higher level interface to the
plotting routines could also reduce the number of memory
copies that occur -- could be down to zero copies.)

I was actually talking about the part after the "rewind", i.e. once the areas have been filled and the module draws the boundaries. At least in the example I am working right now, this second part takes longer than
when I draw the boundaries with d.vect.

Moritz

On Mon, Feb 18, 2002 at 10:44:01AM +0000, M Lennert wrote:

On 17 Feb 02, at 12:58, Eric G. Miller wrote:

> I have no problem with that formulation. I'd like to get some
> consensus on whether people feel one or several modules are appropriate.

I would prefer seperate modules.

Me too.

I was actually talking about the part after the "rewind", i.e. once
the areas have been filled and the module draws the boundaries. At
least in the example I am working right now, this second part takes
longer than when I draw the boundaries with d.vect.

I'll look into it. Need to make some changes for just drawing
boundaries anyway (fillcolor=none).

--
Eric G. Miller <egm2@jps.net>

On Mon, Feb 18, 2002 at 02:10:29PM -0800, Eric G. Miller wrote:

> I was actually talking about the part after the "rewind", i.e. once
> the areas have been filled and the module draws the boundaries. At
> least in the example I am working right now, this second part takes
> longer than when I draw the boundaries with d.vect.

I'll look into it. Need to make some changes for just drawing
boundaries anyway (fillcolor=none).

I've looked into why d.vect.area is a bit slower to draw lines than
d.vect. I'm not sure it can be made much faster. There is a
significant difference between what d.vect is drawing and what
d.vect.area is drawing. When d.vect draws lines relative to categories,
it is looking at the line category number. So, d.vect only has to
look at each line once. However, this method will likely not cause
all area boundaries to be drawn. When d.vect.area draws lines, it is
drawing all of the boundaries for a given area. This may result in
lines being drawn twice, but guarantees the interior boundaries, if
any, will always be drawn.

The fill drawing code is still much slower than the line drawing code.
I played with a custom memory pool to minimize the malloc calls, but
it only shaved a second or less off of program execution time for a
dataset taking about 22 seconds to draw. That's program execution
time, elapsed time was about 1.5 minutes.

Anyway, the only way I can think of to speed up the line drawing code
is to add a mechanism for tracking which lines have already been
drawn. The most time efficient way, would probably be to read all
of the line numbers into a sorted array, and then mark them when
they have been drawn. That'd add a bit to memory consumption, and
I'm not sure that the speed up would be too significant.

It might be possible to use left/right polygon numbers, so that lines
only have to be inspected once. This method seems the most promising,
but there's a question about which line color should win for the
drawing color. Right now, the last area boundary drawn wins (overwrites
previous color).

I'll try to get a fix in for drawing only fill or boundaries via the
"none" color argument in the next day or so.

--
Eric G. Miller <egm2@jps.net>

I believe I've corrected the slow line drawing. Also "none" will now
disable fill or line drawing (or both!).

--
Eric G. Miller <egm2@jps.net>

On 24 Feb 02, at 20:36, Eric G. Miller wrote:

I believe I've corrected the slow line drawing. Also "none" will now
disable fill or line drawing (or both!).

I finally got around to trying this. Yes, the line drawing is now the same speed as with d.vect.

Thanks a lot !

Moritz