[GRASS-dev] new v.support metadata module

Hi,

I have written a new module to set/update vector map metadata
(we darkly remember this functionality from GRASS 5's v.digit):

v.support map=name [organization="phrase"] Invalid date
   [person="phrase"] [map_name="phrase"] [map_date="datestring"]
   [scale=value] [zone=value] [thresh=value] [comment="phrase"]
   [--verbose] [--quiet]

Flags:
--v Verbose module output
--q Quiet module output

Parameters:
           map Name of input vector map
  organization Organization where vector map was created
          date Date of vector map digitization (e.g., "15 Mar 2007")
        person Person who created vector map
      map_name Name of vector map
      map_date Date when the source map was originally produced
         scale Vector map scale number (e.g., 24000)
          zone Vector map projection zone
        thresh Vector map digitizing threshold number (e.g., 0.5)
       comment Text to append to the next line of the map's metadata file

and submitted to CVS.

Known bug: long comments are crashing it, I don't know why (C string programming
and me are somewhat orthogonal to each other) - please someone take a look.

Cheers,
Markus

Hi Markus,

great! Funny, today in the morning I decided to write this module. I
can look at the code.

Martin

2007/3/15, Markus Neteler <neteler@itc.it>:

Hi,

I have written a new module to set/update vector map metadata
(we darkly remember this functionality from GRASS 5's v.digit):

v.support map=name [organization="phrase"] Invalid date
   [person="phrase"] [map_name="phrase"] [map_date="datestring"]
   [scale=value] [zone=value] [thresh=value] [comment="phrase"]
   [--verbose] [--quiet]

Flags:
--v Verbose module output
--q Quiet module output

Parameters:
           map Name of input vector map
  organization Organization where vector map was created
          date Date of vector map digitization (e.g., "15 Mar 2007")
        person Person who created vector map
      map_name Name of vector map
      map_date Date when the source map was originally produced
         scale Vector map scale number (e.g., 24000)
          zone Vector map projection zone
        thresh Vector map digitizing threshold number (e.g., 0.5)
       comment Text to append to the next line of the map's metadata file

and submitted to CVS.

Known bug: long comments are crashing it, I don't know why (C string programming
and me are somewhat orthogonal to each other) - please someone take a look.

Cheers,
Markus

_______________________________________________
grass-dev mailing list
grass-dev@grass.itc.it
http://grass.itc.it/mailman/listinfo/grass-dev

--
Martin Landa <landa.martin@gmail.com> * http://gama.fsv.cvut.cz/~landa *

Hello Markus

On Thu, 15 Mar 2007, Markus Neteler wrote:

Known bug: long comments are crashing it, I don't know why (C string programming
and me are somewhat orthogonal to each other) - please someone take a look.

G_strcat() does not enlarge the memory allocated for the string you are appending to - it just adds the new string on to the end but the memory bytes after the end were probably reserved for something else, so that is a problem. You could enlarge the space allocated for Map.head.line_3 using perhaps G_realloc() before appending the new comment to it, but IMHO that would be a bad idea too as it is bad to modify the internal parameters of the struct Map_info without using vector library functions to do it.

I think it would be better to use a temporary string for the new comment. Something like:

char *temp;

G_asprintf(&temp, "%s%s", Map.head.line_3, comment->answer);

Vect_set_comment(&Map, temp);

Then you are never messing directly with the internals of the Map_info struct and G_asprintf() will ensure enough memory is allocated to hold the two strings concatenated together.

But I wonder too should there not be a newline character in there somewhere as the documentation says the comment text is added to the next line? Also don't understand the second example where a space " " is appended to the comment?

Also it might be useful to have a flag that would totally over-write the comment rather than appending, with a big warning in the description of course.

Paul

Hello Paul,

On Thu, Mar 15, 2007 at 11:49:13AM +0000, Paul Kelly wrote:

Hello Markus

On Thu, 15 Mar 2007, Markus Neteler wrote:

>Known bug: long comments are crashing it, I don't know why (C string
>programming
>and me are somewhat orthogonal to each other) - please someone take a look.

G_strcat() does not enlarge the memory allocated for the string you are
appending to - it just adds the new string on to the end but the memory
bytes after the end were probably reserved for something else, so that is
a problem. You could enlarge the space allocated for Map.head.line_3 using
perhaps G_realloc() before appending the new comment to it, but IMHO that
would be a bad idea too as it is bad to modify the internal parameters of
the struct Map_info without using vector library functions to do it.

ah, I see!

I think it would be better to use a temporary string for the new comment.
Something like:

char *temp;

G_asprintf(&temp, "%s%s", Map.head.line_3, comment->answer);

Vect_set_comment(&Map, temp);

Then you are never messing directly with the internals of the Map_info
struct and G_asprintf() will ensure enough memory is allocated to hold the
two strings concatenated together.

Very nice. Implemented like that.

But I wonder too should there not be a newline character in there
somewhere as the documentation says the comment text is added to the next
line?

Right, the documentation was wrong - updated.

Also don't understand the second example where a space " " is
appended to the comment?

From the API I have the impression that a comment may only have

one line - which is a severe limitation! So I used space to attach
one to the next (for now). Better ideas welcome.

We now need to to some string magic to make 'v.info' print comments
longer than 80 or so chars, currently they are cut.
r.info does some line wrapping magic for this (again, C string business...).

Also it might be useful to have a flag that would totally over-write the
comment rather than appending, with a big warning in the description of
course.

Good point: -r "replace" flag added for comments.

Markus

Hi,

I have added another parameter "cmdhist" to add strings (hist formatted) to the
command history in metadata (for 'v.info -h map').
This is useful for all vector *scripts* which so far do not extend
the vector history.

Example:

v.random rand n=20
v.db.addcol rand col="mycol integer"
v.info -h rand
COMMAND: v.random output="rand" n=20 zmin=0.0 zmax=0.0
GISDBASE: /home/neteler/grassdata
LOCATION: spearfish60 MAPSET: neteler USER: neteler DATE: Thu Mar 15 16:36:22 2007
# ... so far 'v.db.addcol' doesn't appear in the history file

# now:
v.support rand cmdhist="v.db.addcol rand col='mycol integer'"
v.info -h rand
COMMAND: v.random output="rand" n=20 zmin=0.0 zmax=0.0
GISDBASE: /home/neteler/grassdata
LOCATION: spearfish60 MAPSET: neteler USER: neteler DATE: Thu Mar 15 16:36:22 2007
---------------------------------------------------------------------------------
COMMAND: v.db.addcol rand col='mycol integer'
GISDBASE: /home/neteler/grassdata
LOCATION: spearfish60 MAPSET: neteler USER: neteler DATE: Thu Mar 15 16:44:01 2007

Question:
What's the best trick to construct the cmd line automatically in
g.parser supported scripts? Stuff like
CMDLINE="$0 $@"
fails since g.parser modifies the shell parameters. The solution should then
go into all scripts/v*/v* where appropriate.

Markus

Markus Neteler wrote:

Question:
What's the best trick to construct the cmd line automatically in
g.parser supported scripts? Stuff like
CMDLINE="$0 $@"
fails since g.parser modifies the shell parameters. The solution
should then go into all scripts/v*/v* where appropriate.

You either need to have
CMDLINE="$0 $@"
in every script before the g.parser call, or modify g.parser to putenv
that before it overwrites it.

see recent discussion WRT the d.path --script wrapper.
http://thread.gmane.org/gmane.comp.gis.grass.devel/18802/focus=18863

Hamish

Markus Neteler wrote:

I have added another parameter "cmdhist" to add strings (hist formatted) to the
command history in metadata (for 'v.info -h map').
This is useful for all vector *scripts* which so far do not extend
the vector history.

Example:

v.random rand n=20
v.db.addcol rand col="mycol integer"
v.info -h rand
COMMAND: v.random output="rand" n=20 zmin=0.0 zmax=0.0
GISDBASE: /home/neteler/grassdata
LOCATION: spearfish60 MAPSET: neteler USER: neteler DATE: Thu Mar 15 16:36:22 2007
# ... so far 'v.db.addcol' doesn't appear in the history file

# now:
v.support rand cmdhist="v.db.addcol rand col='mycol integer'"
v.info -h rand
COMMAND: v.random output="rand" n=20 zmin=0.0 zmax=0.0
GISDBASE: /home/neteler/grassdata
LOCATION: spearfish60 MAPSET: neteler USER: neteler DATE: Thu Mar 15 16:36:22 2007
---------------------------------------------------------------------------------
COMMAND: v.db.addcol rand col='mycol integer'
GISDBASE: /home/neteler/grassdata
LOCATION: spearfish60 MAPSET: neteler USER: neteler DATE: Thu Mar 15 16:44:01 2007

Question:
What's the best trick to construct the cmd line automatically in
g.parser supported scripts? Stuff like
CMDLINE="$0 $@"
fails since g.parser modifies the shell parameters. The solution should then
go into all scripts/v*/v* where appropriate.

A simple aproach such as CMDLINE="$0 $@" will fail if any of the
arguments contain spaces.

The following should work provided that none of the arguments contain
single quotes (quotes which get eaten by the shell don't count):

  CMDLINE="'$0'"
  for arg in "$@" ; do
      CMDLINE="$CMDLINE '$arg'"
  done

But you need to do this on the first pass (before g.parser is called)
and export it, e.g.:

  if [ "$1" != "@ARGS_PARSED@" ] ; then
      CMDLINE="'$0'"
      for arg in "$@" ; do
          CMDLINE="$CMDLINE '$arg'"
      done
      export CMDLINE
      exec g.parser "$0" "$@"
  fi

If you need to handle the case where an argument contains single
quotes, it gets ugly. It should work to replace:

          CMDLINE="$CMDLINE '$arg'"
with:
          CMDLINE="$CMDLINE '`echo "$arg" | sed "s/'/'\\\\\\\\''/g"`'"

This assumes that you want the COMMAND: entry to use shell syntax.

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