[GRASS-dev] [GRASS GIS] #28: v.out.ogr exports only attribute data in CSV format

#28: v.out.ogr exports only attribute data in CSV format
---------------------+------------------------------------------------------
Reporter: marisn | Owner: grass-dev@lists.osgeo.org
     Type: defect | Status: new
Priority: major | Milestone: 6.4.0
Component: default | Version: 6.3.0 RCs
Keywords: |
---------------------+------------------------------------------------------
Exporting vector data with v.out.ogr to CSV file will export only
attribute data without coordinate information. Coordinate information also
should be included in exported CSV file.

Spearfish example:
v.out.ogr input=bugsites@PERMANENT type=point dsn=/tmp/bugsites
olayer=bugsites layer=1 format=CSV

GRASS-6.3.0RC4[[br]]
GDAL 1.4.2.0[[br]]
Gentoo ~x86

--
Ticket URL: <http://trac.osgeo.org/grass/ticket/28&gt;
GRASS GIS <http://grass.osgeo.org>
GRASS Geographic Information System (GRASS GIS) - http://grass.osgeo.org/

#28: v.out.ogr exports only attribute data in CSV format
----------------------+-----------------------------------------------------
  Reporter: marisn | Owner: grass-dev@lists.osgeo.org
      Type: defect | Status: closed
  Priority: major | Milestone: 6.4.0
Component: default | Version: 6.3.0 RCs
Resolution: invalid | Keywords:
----------------------+-----------------------------------------------------
Changes (by neteler):

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

Comment:

I don't think that this is a GRASS problem but moreover an OGR problem:

{{{
# list available data
ogrinfo -so
/home/neteler/grassdata/spearfish60/PERMANENT/vector/bugsites/head
Warning 1: GRASS warning: GISBASE enviroment variable was not set, using:
/home/neteler/grass63/dist.x86_64-unknown-linux-gnu
INFO: Open of
`/home/neteler/grassdata/spearfish60/PERMANENT/vector/bugsites/head'
       using driver `GRASS' successful.
1: 1 (Point)

#generate CSV file:
ogr2ogr -f CSV bugsites.csv
/home/neteler/grassdata/spearfish60/PERMANENT/vector/bugsites/head
head bugsites.csv/1.csv
cat,str1
1,Beetle site
2,Beetle site
3,Beetle site
4,Beetle site
...
}}}

Better to report this here: http://trac.osgeo.org/gdal/wiki

Markus

--
Ticket URL: <http://trac.osgeo.org/grass/ticket/28#comment:1&gt;
GRASS GIS <http://grass.osgeo.org>
GRASS Geographic Information System (GRASS GIS) - http://grass.osgeo.org/

Hi,

I am looking for a library function to get the R,G,B values (0-255) for
an integer color number which was created with D_parse_color(). I don't
want to set the color for drawing, just get the RGB component values so
I can populate a RGBA_Color struct. Reparsing the original color string
isn't an option without a lot of re-fn prototyping as I'm operating in
a subordinate function with only the int color number available.

I've searched through the color functions in the display, raster, and
gis libraries without much luck. The closest I found was
D_raster_use_color().

any ideas?

Is a new D_number_to_RGB(int color, unsigned char &r,&g,&b) fn needed
in lib/display/tran_colr.c? Or some place better?

thanks,
Hamish

      ____________________________________________________________________________________
Never miss a thing. Make Yahoo your home page.
http://www.yahoo.com/r/hs

Hamish wrote:

I am looking for a library function to get the R,G,B values (0-255) for
an integer color number which was created with D_parse_color(). I don't
want to set the color for drawing, just get the RGB component values so
I can populate a RGBA_Color struct. Reparsing the original color string
isn't an option without a lot of re-fn prototyping as I'm operating in
a subordinate function with only the int color number available.

I've searched through the color functions in the display, raster, and
gis libraries without much luck. The closest I found was
D_raster_use_color().

any ideas?

That information isn't available at present.

Also, the concept of colour numbers is likely to go away entirely in
7.x. With the display drivers and raster library using R/G/B colours
exclusively, the only reason that colour numbers remain was to avoid
having to re-write all of the modules which parse a colour string to
an integer.

Is a new D_number_to_RGB(int color, unsigned char &r,&g,&b) fn needed
in lib/display/tran_colr.c?

Yes. E.g.:

int D_color_number_to_RGB(int color, int &r, int &g, int &b)
{
    const struct color_rgb *c;

    if (color <= 0)
        return 0;

    if (color >= ncolors)
        return 0;

    c = &colors[color];
    r = c->r;
    g = c->g;
    b = c->b;

    return 1;
}

Or some place better?

The array which holds the information isn't exported from
tran_color.c, so the code can't go anywhere else.

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

Hamish wrote:

> I am looking for a library function to get the R,G,B values (0-255)
> for an integer color number which was created with D_parse_color().

Glynn:

That information isn't available at present.

Also, the concept of colour numbers is likely to go away entirely in
7.x. With the display drivers and raster library using R/G/B colours
exclusively, the only reason that colour numbers remain was to avoid
having to re-write all of the modules which parse a colour string to
an integer.

In that case it would probably be better to rewrite the three color
variables in d.grid* to pass RGBA_color structs instead of color index
integers and not worry about D_number_to_RGB() now. But as it is
missing I think I'll add it anyway, it might be useful during the
transition.

[*] new -c and -f now added to d.grid, hardcoded as black. For
geo-grids the local mark rotation is working but finding confluences is
not as much harder. Also it would be nice to improve rendering of
geogrid lines into one fluid line rather than rough 100*G_plot_line()s.
Could R_cont_abs() be used or would it have to wait for punctuated arcs
in GRASS 7?

H:

> Is a new D_number_to_RGB(int color, unsigned char &r,&g,&b) fn
> needed in lib/display/tran_colr.c?

G:

Yes. E.g.:

int D_color_number_to_RGB(int color, int &r, int &g, int &b)
{
    const struct color_rgb *c;

    if (color <= 0)
        return 0;

    if (color >= ncolors)
        return 0;

    c = &colors[color];
    r = c->r;
    g = c->g;
    b = c->b;

    return 1;
}

Thanks.
Any reason you use int for the r,g,b type? color.h defines {}color_rgb
as unsigned char, as does gis.h's {}RGBA_Color. I'd like to avoid new
casting issues, and for GRASS 7 would like to settle on one consistent
type rather than the mix of two we have now.

> Or some place better?

The array which holds the information isn't exported from
tran_color.c, so the code can't go anywhere else.

ok.

If I pass the colors as a single RGBA_Color struct, I would like to
have a parsing lib fn to replace D_parse_color(). It would call
G_str_to_color() then fill the RGBA_Color struct, like set_last_color()
in d.graph. e.g.:
  G_str_to_RGBA(char* str, RGBA_Color color);

but for GRASS 7 does that belong in libgis? for now RGBA_Color is
defined in gis.h and does not depend on external libs so I'd call it
G_, but as libgis is already bloated I hesitate...

Hamish

      ____________________________________________________________________________________
Never miss a thing. Make Yahoo your home page.
http://www.yahoo.com/r/hs

Hamish wrote:

If I pass the colors as a single RGBA_Color struct, I would like to
have a parsing lib fn to replace D_parse_color(). It would call
G_str_to_color() then fill the RGBA_Color struct, like
set_last_color()
in d.graph. e.g.:
  G_str_to_RGBA(char* str, RGBA_Color color);

already done as set_RGBA_from_str() in
  display/d.paint.labels/color.c

but for GRASS 7 does that belong in libgis?

I suggest putting the RGBA helper functions found in d.paint.labels/
color.c into libgis (color_rgba.c), except for set_color_from_RGBA()
which is a frontend to R_RGB_color() and belongs in libraster(?).

Perhaps those fns could have more grass-consistent G_() names and
variable order, but I'm unsure of classic C conventions for those.
Normally I wouldn't care, but if these will be used commonly in GRASS 7
I'd like to spend the little extra discussion time now to get
everything clean and in its most-useful state, rather than just impose
my whim of the day and be cursed for it later.

As lib fns, the one G_fatal_error() would need to change to
G_warning().
Or is it better to be silent and rely on the module programmer to check
the fn's return code?

thanks,
Hamish

      ____________________________________________________________________________________
Looking for last minute shopping deals?
Find them fast with Yahoo! Search. http://tools.search.yahoo.com/newsearch/category.php?category=shopping

Hamish wrote:

> > Is a new D_number_to_RGB(int color, unsigned char &r,&g,&b) fn
> > needed in lib/display/tran_colr.c?
G:
> Yes. E.g.:
>
> int D_color_number_to_RGB(int color, int &r, int &g, int &b)
> {
> const struct color_rgb *c;
>
> if (color <= 0)
> return 0;
>
> if (color >= ncolors)
> return 0;
>
> c = &colors[color];
> r = c->r;
> g = c->g;
> b = c->b;
>
> return 1;
> }

Thanks.
Any reason you use int for the r,g,b type? color.h defines {}color_rgb
as unsigned char, as does gis.h's {}RGBA_Color. I'd like to avoid new
casting issues, and for GRASS 7 would like to settle on one consistent
type rather than the mix of two we have now.

It's unusual to have variables smaller than an "int". "short" and
"char" are normally reserved for array indices and structure fields,
where you may want to conserve space, either because you have an array
which may contain thousands of elements or a structure which you want
to fit into a 32-bit word.

If you want the values stored in variables, the variables are
typically going to be integers, so you may as well pass pointers to
the variables themselves. Note that G_str_to_color() uses ints.

If you want the values stored in an RGBA_Color, it would make more
sense to pass a pointer to the structure rather than to individual
fields.

AFAICT, there's no fundamental reason why tran_color.c can't be
changed to use RGBA_Color instead of the color_rgb structure.

> > Or some place better?
>
> The array which holds the information isn't exported from
> tran_color.c, so the code can't go anywhere else.

ok.

If I pass the colors as a single RGBA_Color struct, I would like to
have a parsing lib fn to replace D_parse_color(). It would call
G_str_to_color() then fill the RGBA_Color struct, like set_last_color()
in d.graph. e.g.:
  G_str_to_RGBA(char* str, RGBA_Color color);

but for GRASS 7 does that belong in libgis? for now RGBA_Color is
defined in gis.h and does not depend on external libs so I'd call it
G_, but as libgis is already bloated I hesitate...

I would be inclined to simply replace color_rgb with RGBA_Color.

Also, I'm not sure why we have lib/gis/named_colr.c with its own table
of named colours, but using floats for the R/G/B components.

All of this should really be harmonised; I'm just wondering whether
it's too late to do it for 6.4.

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

Hamish wrote:
> > > Is a new D_number_to_RGB(int color, unsigned char &r,&g,&b) fn
> > > needed in lib/display/tran_colr.c?

Glynn:

> > Yes. E.g.:

[...]
Hamish:

> Any reason you use int for the r,g,b type? color.h defines
> {}color_rgb as unsigned char, as does gis.h's {}RGBA_Color. I'd
> like to avoid new casting issues, and for GRASS 7 would like to
> settle on one consistent type rather than the mix of two we have
> now.

Glynn:

It's unusual to have variables smaller than an "int". "short" and
"char" are normally reserved for array indices and structure fields,
where you may want to conserve space, either because you have an
array which may contain thousands of elements or a structure which
you want to fit into a 32-bit word.

If you want the values stored in variables, the variables are
typically going to be integers, so you may as well pass pointers to
the variables themselves. Note that G_str_to_color() uses ints.

If you want the values stored in an RGBA_Color, it would make more
sense to pass a pointer to the structure rather than to individual
fields.

ok, that makes sense: either use int or struct but not unsigned char
for a public function.

AFAICT, there's no fundamental reason why tran_color.c can't be
changed to use RGBA_Color instead of the color_rgb structure.

If tran_color.c is to be dumped in GRASS 7, for risk-vs-benefit reasons
I'd prefer to leave it the old way as a historical artifact. (see
below)

Hamish:

> If I pass the colors as a single RGBA_Color struct, I would like to
> have a parsing lib fn to replace D_parse_color(). It would call
> G_str_to_color() then fill the RGBA_Color struct, like
> set_last_color() in d.graph. e.g.:
> G_str_to_RGBA(char* str, RGBA_Color color);

[written before I remembered I'd already done that for d.paint.labels,
see previous email]

Ha:

> but for GRASS 7 does that belong in libgis? for now RGBA_Color is
> defined in gis.h and does not depend on external libs so I'd call
> it G_, but as libgis is already bloated I hesitate...

Gl:

I would be inclined to simply replace color_rgb with RGBA_Color.

see 6.4 vs 7 comments above and below.

Also, I'm not sure why we have lib/gis/named_colr.c with its own
table of named colours, but using floats for the R/G/B components.

I would have guessed for use in ps.map (or old GRASS 5 p.* modules),
but that uses its own table in ps/ps.map/ps_colors.c.
(see old RT bug about "the color purple" and Cedric's changes)

For now I only see G_color_*() used in d.rast, r.colors, and libgis:
$ grep -rI G_color_ * | grep -v '\.svn\|swig\|dist.i686'

All of this should really be harmonised;

Yes please.

I'm just wondering whether it's too late to do it for 6.4.

For 6.x I would suggest it is wasted effort to do so, and against the
goal of pre-release stabilization.

<2 cents>
My hope is that we release 6.3.0 soon so we can focus on new business.

ie soon after that is away cut a new releasebranch_6_4 and declare
svn-trunk to be for GRASS 7 --- why wait? AFAIK no one has plans for a
6.6 release, and if one day they do, that can be hewn from
releasebranch_6_4.

I think it is a big mistake to try and do two development branches at
the same time then try and merge changes between them.

wxGUI is the anomaly, but luckily it is a somewhat independent beast. I
would suggest continuing to work on it in releasebranch_6_4 until such
time as we tag 6.4.0pre1 and move into bugfix-only mode. At that point
we would port the GUI to GRASS 7 and move all new GUI development
there.
This presupposes that in the early days of GRASS 7 (the radical change
period) we only need a disposable barebones GUI.

Continuing development on native MS-Windows support for 6.4 is more
entwined with the C code, but I hope we are past the bulk of those
changes already and can limit the multi-branch merges to those (and
bugs of course).

It is unclear to me where new documentation and translation efforts
should be focused during that period. 6.4 branch until the GUI freezes?
</2 cents>

Hamish

      ____________________________________________________________________________________
Be a better friend, newshound, and
know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ

Glynn Clements <glynn@gclements.plus.com> writes:

[...]

>> Is a new D_number_to_RGB(int color, unsigned char &r,&g,&b) fn
>> needed in lib/display/tran_colr.c?

> Yes. E.g.:

> int D_color_number_to_RGB(int color, int &r, int &g, int &b)
> {

  That looks a lot like C++. Surely it will work with C89?

> const struct color_rgb *c;

> if (color <= 0)
> return 0;

  BTW, is it a GRASS convention to use 0 to indicate failure?
  Standard C library functions tend to use -1 for failure, while
  using non-negative values to indicate success.

  Also, it seems feasible to set `errno' in the library functions
  like this. Do I understand correctly that it isn't done (with
  any regularity) in GRASS?

> if (color >= ncolors)
> return 0;

> c = &colors[color];
> r = c->r;
> g = c->g;
> b = c->b;

> return 1;
> }

[...]

  I'd suggest the following, but I don't know (yet) the
  appropriate conventions for the D_* functions.

int
D_color_number_to_RGB (int color, int *r, int *g, int *b)
{
    const struct color_rgb *c;

    if (color <= 0 || color >= ncolors) {
  errno = EINVAL;
        return -1;
    }

    c = &colors[color];
    if (r != 0) *r = c->r;
    if (g != 0) *g = c->g;
    if (b != 0) *b = c->b;

    return 0;
}

  With the `if (X != 0)' guards, the function may be used to query
  whether the given color index exists, while not asking for its
  components to be returned, like:

   if (D_color_number_to_RGB (INDEX, 0, 0, 0) < 0) {
       /* color INDEX doesn't exist */
   }

  If `struct color_rgb' is a ``public'' data type, then it might
  be appropriate to code this function as:

int
D_color_number_to_RGB (int color, struct color_rgb *components)
{
    ...
}

  instead, and use a guarded `memmove' to copy `colors[color]' to
  `*components'.

On 30/01/08 07:15, Ivan Shmakov wrote:

Glynn Clements <glynn@gclements.plus.com> writes:

[...]

>> Is a new D_number_to_RGB(int color, unsigned char &r,&g,&b) fn
>> needed in lib/display/tran_colr.c?

> Yes. E.g.:

> int D_color_number_to_RGB(int color, int &r, int &g, int &b)
> {

  That looks a lot like C++. Surely it will work with C89?

> const struct color_rgb *c;

> if (color <= 0)
> return 0;

  BTW, is it a GRASS convention to use 0 to indicate failure?
  Standard C library functions tend to use -1 for failure, while
  using non-negative values to indicate success.

The SUBMITTING file in the source code says:

8. Exit status is defined as EXIT_SUCCESS or EXIT_FAILURE, e.g.

     {
       ...
       if (G_parser (argc, argv))
           exit (EXIT_FAILURE);

       ...
       exit (EXIT_SUCCESS);
     }

AFAIU, these are defined in stlib as being respectively 0 and 1.

Moritz

Moritz Lennert <mlennert@club.worldonline.be> writes:

[...]

>>> int D_color_number_to_RGB(int color, int &r, int &g, int &b)

[...]

>>> if (color <= 0) return 0;

>> BTW, is it a GRASS convention to use 0 to indicate failure?
>> Standard C library functions tend to use -1 for failure, while using
>> non-negative values to indicate success.

> The SUBMITTING file in the source code says:

> 8. Exit status is defined as EXIT_SUCCESS or EXIT_FAILURE, e.g.

> {
> ...
> if (G_parser (argc, argv))
> exit (EXIT_FAILURE);

> ...
> exit (EXIT_SUCCESS);
> }

> AFAIU, these are defined in stlib as being respectively 0 and 1.

  Yes. But the conventions for the exit code of a program are
  hardly applicable to the return value of a function.

  Consider, e. g. (from ``The GNU C Library Reference Manual''):

--cut: (libc) Opening and Closing Files--
-- Function: int open (const char *FILENAME, int FLAGS[, mode_t MODE])

[...]

     The normal return value from `open' is a non-negative integer file
     descriptor. In the case of an error, a value of -1 is returned
     instead. [...]
--cut: (libc) Opening and Closing Files--

  Note that there's useful, and always non-negative, value to be
  returned on success. Negative values are therefore reserved for
  errors (from the point of view of the application programmer;
  the only value which may actually be returned by the function in
  the case of error is `-1'.)

--cut: (libc) Process Group Functions--
-- Function: int setpgid (pid_t PID, pid_t PGID)

[...]

     If the operation is successful, `setpgid' returns zero. Otherwise
     it returns `-1'. [...]
--cut: (libc) Process Group Functions--

  And there is no such a value, so zero is used to indicate
  success. Negative values are again reserved for errors.

Hamish wrote:

> If I pass the colors as a single RGBA_Color struct, I would like to
> have a parsing lib fn to replace D_parse_color(). It would call
> G_str_to_color() then fill the RGBA_Color struct, like
> set_last_color()
> in d.graph. e.g.:
> G_str_to_RGBA(char* str, RGBA_Color color);

already done as set_RGBA_from_str() in
  display/d.paint.labels/color.c

> but for GRASS 7 does that belong in libgis?

I suggest putting the RGBA helper functions found in d.paint.labels/
color.c into libgis (color_rgba.c), except for set_color_from_RGBA()
which is a frontend to R_RGB_color() and belongs in libraster(?).

Anything which calls R_RGB_color() belongs in either libraster or
possibly libdisplay. libgis doesn't require either of those, so it
can't go into libgis.

Perhaps those fns could have more grass-consistent G_() names and
variable order, but I'm unsure of classic C conventions for those.
Normally I wouldn't care, but if these will be used commonly in GRASS 7
I'd like to spend the little extra discussion time now to get
everything clean and in its most-useful state, rather than just impose
my whim of the day and be cursed for it later.

As lib fns, the one G_fatal_error() would need to change to
G_warning().
Or is it better to be silent and rely on the module programmer to check
the fn's return code?

If it's conceivable that the module will continue in the event of an
error, the function should just return a status code.

If it's likely that the module is just going to call G_fatal_error()
anyhow, the library function may as well call it itself, thereby
providing a "infallible" interface (i.e. the function never fails; it
either succeeds, or the process is no longer running so the failure is
moot).

The advantage of the latter is that individual modules don't have to
concern themselves with error handling, and you are guaranteed to have
consistent error messages (rather than a slightly different messsage
for each module which uses the function).

The former is only an advantage if there's a situation where a module
doesn't just call G_fatal_error() when an invalid colour occurs. Given
that invalid user input is usually a fatal error, I can't immediately
think of a situation where you might get an invalid colour string
without it resulting in a fatal error.

BTW, another "bulk" change for 7.x: eliminate bogus "int" return
types. Many of these stem from pre-ANSI C, which didn't have "void".
Functions which always return zero should be changed to have "void"
return type.

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

Hamish wrote:

> All of this should really be harmonised;

Yes please.

> I'm just wondering whether it's too late to do it for 6.4.

For 6.x I would suggest it is wasted effort to do so, and against the
goal of pre-release stabilization.

<2 cents>
My hope is that we release 6.3.0 soon so we can focus on new business.

Duh; I forgot that it's 6.3.0 that's imminent, not 6.4. There isn't
any fundamental reason why it can't be done within 6.x, as it's not
externally visible.

ie soon after that is away cut a new releasebranch_6_4 and declare
svn-trunk to be for GRASS 7 --- why wait? AFAIK no one has plans for a
6.6 release, and if one day they do, that can be hewn from
releasebranch_6_4.

I think it is a big mistake to try and do two development branches at
the same time then try and merge changes between them.

We can't easily merge changes, but 7.x could be essentially unusable
for a long period. We may not be able to leave users with 6.3.x for
all of that time.

[I see the process as something akin to renovating a house, at the
level of stripping it down to bare brickwork: no wiring, no plumbing,
no windows. You aren't going to be able to live in it while it's in
that state.]

wxGUI is the anomaly, but luckily it is a somewhat independent beast. I
would suggest continuing to work on it in releasebranch_6_4 until such
time as we tag 6.4.0pre1 and move into bugfix-only mode. At that point
we would port the GUI to GRASS 7 and move all new GUI development
there.
This presupposes that in the early days of GRASS 7 (the radical change
period) we only need a disposable barebones GUI.

We don't necessarily even need a GUI. For testing, an image viewer
that automatically updates whenever map.png changes would suffice.

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

Ivan Shmakov wrote:

>> Is a new D_number_to_RGB(int color, unsigned char &r,&g,&b) fn
>> needed in lib/display/tran_colr.c?

> Yes. E.g.:

> int D_color_number_to_RGB(int color, int &r, int &g, int &b)
> {

  That looks a lot like C++. Surely it will work with C89?

Oops. I meant:

  int D_color_number_to_RGB(int color, int *r, int *g, int *b)

> const struct color_rgb *c;

> if (color <= 0)
> return 0;

  BTW, is it a GRASS convention to use 0 to indicate failure?
  Standard C library functions tend to use -1 for failure, while
  using non-negative values to indicate success.

The GRASS convention is to use a different convention for each
function :wink:

More seriously: functions which only return a success/failure
indication typically (but not always) return 1 for success and 0 for
failure, so that conditionals read naturally, i.e. "if (foo(...))"
means "if it succeeds" and "if (!foo(...))" means "if it fails".

Functions which normally return a non-negative integer normally return
a negative integer to indicate failure.

Functions which return 0 for success should ideally be tested using
"if (foo(...) == 0)" rather than "if (!foo(...))", as the use of "!"
connotes a negative (i.e. failure).

  Also, it seems feasible to set `errno' in the library functions
  like this. Do I understand correctly that it isn't done (with
  any regularity) in GRASS?

AFAIK, GRASS itself never sets errno.

> if (color >= ncolors)
> return 0;

> c = &colors[color];
> r = c->r;
> g = c->g;
> b = c->b;

> return 1;
> }

[...]

  I'd suggest the following, but I don't know (yet) the
  appropriate conventions for the D_* functions.

int
D_color_number_to_RGB (int color, int *r, int *g, int *b)
{
    const struct color_rgb *c;

    if (color <= 0 || color >= ncolors) {
  errno = EINVAL;
        return -1;
    }

    c = &colors[color];
    if (r != 0) *r = c->r;
    if (g != 0) *g = c->g;
    if (b != 0) *b = c->b;

    return 0;
}

  With the `if (X != 0)' guards, the function may be used to query
  whether the given color index exists, while not asking for its
  components to be returned, like:

   if (D_color_number_to_RGB (INDEX, 0, 0, 0) < 0) {
       /* color INDEX doesn't exist */
   }

That makes sense, although I would omit the "!= 0", and just use e.g.
"if (r) ...". Generally, I prefer "if (x)" and "if (!x)" if zero/NULL
is a false/unset/etc indicator.

  If `struct color_rgb' is a ``public'' data type, then it might
  be appropriate to code this function as:

The problem is that we have both color_rgb (colors.h) and RGBA_Color
(gis.h) structures, and we should deprecate one of them (probably
color_rgb).

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

Glynn Clements <glynn@gclements.plus.com> writes:

[...]

>> As lib fns, the one G_fatal_error() would need to change to
>> G_warning(). Or is it better to be silent and rely on the module
>> programmer to check the fn's return code?

> If it's conceivable that the module will continue in the event of an
> error, the function should just return a status code.

> If it's likely that the module is just going to call G_fatal_error()
> anyhow, the library function may as well call it itself, thereby
> providing a "infallible" interface (i.e. the function never fails; it
> either succeeds, or the process is no longer running so the failure
> is moot).

[...]

> The former is only an advantage if there's a situation where a module
> doesn't just call G_fatal_error() when an invalid colour
> occurs. Given that invalid user input is usually a fatal error, I
> can't immediately think of a situation where you might get an invalid
> colour string without it resulting in a fatal error.

  Did you consider the use of the function from within a GUI
  application? Hardly calling exit () on incorrect input from the
  user is a friendly behaviour for a GUI application.

  Actually, I see calling G_fatal_error () from a library function
  to imply such a marginal improvement on the caller's side, so
  I'd not bother with this issue at all and rather never call a
  function implying exit () from the library code (with the
  exception for the functions clearly intended to call exit (),
  or, may be, for the out-of-memory conditions.)

  As an additional benefit, it allows the libraries to be used
  from high-level languages (like Python or Scheme.) Calling exit
  () behind the back of the language implementation (or the
  interface author) doesn't sound very friendly, too.

[...]

Glynn Clements <glynn@gclements.plus.com> writes:

[...]

>>> if (color <= 0) return 0;

>> BTW, is it a GRASS convention to use 0 to indicate failure?
>> Standard C library functions tend to use -1 for failure, while using
>> non-negative values to indicate success.

> The GRASS convention is to use a different convention for each
> function :wink:

> More seriously: functions which only return a success/failure
> indication typically (but not always) return 1 for success and 0 for
> failure, so that conditionals read naturally, i.e. "if (foo(...))"
> means "if it succeeds" and "if (!foo(...))" means "if it fails".

> Functions which normally return a non-negative integer normally
> return a negative integer to indicate failure.

  ACK, thanks.

> Functions which return 0 for success should ideally be tested using
> "if (foo(...) == 0)" rather than "if (!foo(...))", as the use of "!"
> connotes a negative (i.e. failure).

  I completely agree with this point.

>> Also, it seems feasible to set `errno' in the library functions like
>> this. Do I understand correctly that it isn't done (with any
>> regularity) in GRASS?

> AFAIK, GRASS itself never sets errno.

  But, IIUC, it doesn't prevent `errno' from being set by the
  standard library functions it calls?

  Setting `errno' would make sense should there be a demand to use
  the standard C means of error reporting in the GRASS code. And
  I can see a point in it.

[...]

>> With the `if (X != 0)' guards, the function may be used to query
>> whether the given color index exists, while not asking for its
>> components to be returned, like:

>> if (D_color_number_to_RGB (INDEX, 0, 0, 0) < 0) {
>> /* color INDEX doesn't exist */
>> }

> That makes sense, although I would omit the "!= 0", and just use e.g.
> "if (r) ...". Generally, I prefer "if (x)" and "if (!x)" if zero/NULL
> is a false/unset/etc indicator.

  Oh, and I prefer both the ``success'' and the ``null'' tests to
  be written explicitly. But I see a little difference anyway.

>> If `struct color_rgb' is a ``public'' data type, then it might be
>> appropriate to code this function as:

> The problem is that we have both color_rgb (colors.h) and RGBA_Color
> (gis.h) structures, and we should deprecate one of them (probably
> color_rgb).

  Although I know no details, having two similar facilities
  usually implies having the code base doubled, with only a slight
  increase of functionality.

  As for a generic color facility, I'd suggest looking at the
  following for the inspiration:

http://www-swiss.ai.mit.edu/~jaffer/slib_5#Color
http://www-swiss.ai.mit.edu/~jaffer/Color/Color-Scheme

Ivan:

>> BTW, is it a GRASS convention to use 0 to indicate failure?
>> Standard C library functions tend to use -1 for failure, while
>> using non-negative values to indicate success.

Glynn:

> The GRASS convention is to use a different convention for each
> function :wink:

> More seriously: functions which only return a success/failure
> indication typically (but not always) return 1 for success and 0
> for failure, so that conditionals read naturally, i.e. "if
> (foo(...))" means "if it succeeds" and "if (!foo(...))" means
> "if it fails".

.... and it's nice to call these functions like G_is_valid_mapname()

Ivan:

ACK, thanks.

OT: everytime I see ACK I get this picture of Bill The Cat in my head
and chuckle

Glynn:

> The problem is that we have both color_rgb (colors.h) and
> RGBA_Color (gis.h) structures, and we should deprecate one of
> them (probably color_rgb).

Ivan:

Although I know no details, having two similar facilities
usually implies having the code base doubled, with only a slight
increase of functionality.

RGBA_Color was recently added (as was RGB support for modules' CLI
options) so 1) it could be used to pass RGB arround without having to
call the display library and 2) we could handle a color value of 'none'
without needing to pass a separate variable or rely on the palette
index number set to -1. Currently the alpha channel is just set to 0 or
255 for full-transparency ('none') or full-opacity.

Hamish

      ____________________________________________________________________________________
Looking for last minute shopping deals?
Find them fast with Yahoo! Search. http://tools.search.yahoo.com/newsearch/category.php?category=shopping

Hamish wrote:

> Is a new D_number_to_RGB(int color, unsigned char &r,&g,&b) fn
> needed in lib/display/tran_colr.c?

Glynn:

Yes. E.g.:

int D_color_number_to_RGB(int color, int *r, int *g, int *b)
{
    const struct color_rgb *c;

    if (color <= 0)
        return 0;

    if (color >= ncolors)
        return 0;

    c = &colors[color];
    r = c->r;
    g = c->g;
    b = c->b;

    return 1;
}

there is a problem: for some reason ncolors's value is 0 so the fn
always returns 0.

Hamish

      ____________________________________________________________________________________
Looking for last minute shopping deals?
Find them fast with Yahoo! Search. http://tools.search.yahoo.com/newsearch/category.php?category=shopping

Ivan Shmakov wrote:

>> As lib fns, the one G_fatal_error() would need to change to
>> G_warning(). Or is it better to be silent and rely on the module
>> programmer to check the fn's return code?

> If it's conceivable that the module will continue in the event of an
> error, the function should just return a status code.

> If it's likely that the module is just going to call G_fatal_error()
> anyhow, the library function may as well call it itself, thereby
> providing a "infallible" interface (i.e. the function never fails; it
> either succeeds, or the process is no longer running so the failure
> is moot).

[...]

> The former is only an advantage if there's a situation where a module
> doesn't just call G_fatal_error() when an invalid colour
> occurs. Given that invalid user input is usually a fatal error, I
> can't immediately think of a situation where you might get an invalid
> colour string without it resulting in a fatal error.

  Did you consider the use of the function from within a GUI
  application? Hardly calling exit () on incorrect input from the
  user is a friendly behaviour for a GUI application.

GRASS simply doesn't work in such a context. One more function doesn't
make any difference unless you're going to fix the thousands that
already behave this way.

BTW, we seem to have had this discussion at least once a year for as
long as I have been subscribed to these lists (~7 years).

  Actually, I see calling G_fatal_error () from a library function
  to imply such a marginal improvement on the caller's side, so
  I'd not bother with this issue at all and rather never call a
  function implying exit () from the library code (with the
  exception for the functions clearly intended to call exit (),
  or, may be, for the out-of-memory conditions.)

  As an additional benefit, it allows the libraries to be used
  from high-level languages (like Python or Scheme.) Calling exit
  () behind the back of the language implementation (or the
  interface author) doesn't sound very friendly, too.

If we were writing GRASS from scratch, that would be a reasonable
argument. But we aren't writing GRASS from scratch.

Apart from calling exit() via G_fatal_error()[1], there are some other
obstacles to making the GRASS libraries behave like normal libraries.
The most significant is the amount of static data which cannot be
multiply instantiated, most of which is initialised at first use and
often cannot be reset or otherwise modified thereafter.

The GRASS libraries are fundamentally designed to be used in
"one-shot" modules. Errors are handled by printing a message then
exiting. Variables are either initialised at startup from the .data
and .bss segments or are initialised upon first use. Memory doesn't
get explicitly de-allocated, as the operating system will do that when
the module terminates.

Making library functions suitable for use in persistent applications
amounts to a complete re-write. If you're interested in taking that
route, please let us know when you've finished.

[1] You can use G_set_error_routine() to install an error handler, but
the handler mustn't return (or else exit() will still get called). The
reason is that code which calls G_fatal_error() doesn't expect it to
return.

Calling G_fatal_error() solves any and all problems without any
further effort from the caller. Normally, this is achieved by calling
exit(), but if you want to supply your own error handler which takes a
different approach to solving any problem which may have occurred, you
are free to do so.

However, the handler must solve all problems itself. You can't just
push the responsibility onto the ~650 different files which call that
function.

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

Hamish wrote:

> > Is a new D_number_to_RGB(int color, unsigned char &r,&g,&b) fn
> > needed in lib/display/tran_colr.c?
Glynn:
> Yes. E.g.:
>
> int D_color_number_to_RGB(int color, int *r, int *g, int *b)
> {
> const struct color_rgb *c;
>
> if (color <= 0)
> return 0;
>
> if (color >= ncolors)
> return 0;
>
> c = &colors[color];
> r = c->r;
> g = c->g;
> b = c->b;
>
> return 1;
> }

there is a problem: for some reason ncolors's value is 0 so the fn
always returns 0.

It also needs:

  if (color < G_num_standard_colors())
  {
    struct color_rgb col = G_standard_color_rgb(color);
    *r = col.r;
    *g = col.g;
    *b = col.b;
  }

These colours are stored in the table, but only when the first "r:g:b"
colour is added.

Alternatively, you could modify translate_or_add_color() to always
create the table, by removing the lines:

    preallocated = D_translate_color(lowerstr);
    if (preallocated)
  return preallocated;

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