[GRASS5] reorder points so that little one are in front of big ones in d.vect.chart

Hello,

Trying to finish the map on survey responses per country, I have the following
problem:

I use a vector point file with the centroids of the countries. I have a
columns "respondents" in the accompanying dbf file. I display them as
proportionate circles using d.vect.chart's 'sizecol' option.

However, some of the smaller circles are covered by some of the larger ones.
Sorting the dbf file won't make a difference since it is the order of the
points in the vector file which is important. So, how can I sort the vector
file (or create a new one) in order to have them in the order of size of one
attribute column ?

Moritz

On Fri, December 17, 2004 0:03, Hamish said:

Trying to finish the map on survey responses per country, I have the
following problem:

I use a vector point file with the centroids of the countries. I have
a columns "respondents" in the accompanying dbf file. I display them
as proportionate circles using d.vect.chart's 'sizecol' option.

However, some of the smaller circles are covered by some of the larger
ones. Sorting the dbf file won't make a difference since it is the
order of the points in the vector file which is important. So, how can
I sort the vector file (or create a new one) in order to have them in
the order of size of one attribute column ?

possible crappy workaround:

open DBF in OpenOffice, sort, resave.

Just sorting the dbf file does not work, as this does not change the topology
file, and it is the latter that determines order of display. So, for the
records, this is what I did:

- create x and y column in dbf file:

echo "alter table countrypoints add column x double" | db.execute
echo "alter table countrypoints add column y double" | db.execute

- use v.to.db to add the point coordinates to the dbf table:
v.to.db map=countrypoints option=coor col=x,y

- cp this dbf table to the current directory

cp $GISDBASE/$LOCATION_NAME/$MAPSET/dbf/countrypoints.dbf countrypoints2.dbf

- use oocalc on the copy to reorder (in descending order !) according to the
values of the column that determines piechartsize

- use v.in.db to create a new vector point file in GRASS

v.in.db database=./ table=countrypoints2 x="x" y="y" cat="cat" out=countrypoints2

There you go !

better idea: someone fixes d.vect.chart

I've had a look at d.vect.chart. If I understand correctly, the pies plotting
is done via the pie() function defined in pie.c. And if I further understand
correctly, it should be enough to sort the Points structure, once all points
have been appended, i.e. after line 50. Points is defined in line 43 by

Points = Vect_new_line_struct ();

So we would need to sort this structure. Before I delve into the source code
and doxygen manual, could someone tell me if sorting functions for qsort
alreay exist for such structures ? And, whether I am on the right path ? :wink:

Moritz

On Fri, December 17, 2004 13:04, Moritz Lennert said:

On Fri, December 17, 2004 0:03, Hamish said:

better idea: someone fixes d.vect.chart

I've had a look at d.vect.chart. If I understand correctly, the pies plotting
is done via the pie() function defined in pie.c. And if I further understand
correctly, it should be enough to sort the Points structure, once all points
have been appended, i.e. after line 50. Points is defined in line 43 by

Points = Vect_new_line_struct ();

So we would need to sort this structure. Before I delve into the source code
and doxygen manual, could someone tell me if sorting functions for qsort
alreay exist for such structures ? And, whether I am on the right path ? :wink:

I've realised that above is completely wrong. It is in plot.c that all the
points are treated, pie.c creates individual pies.

The problem I see now, is that plot.c calls the database table for each vector
element, fetches the necessary data, calls pie to draw the relevant pie and
then goes on to the next element. This makes sorting impossible as the pies
are drawn one by one directly from the database table.

So I can see three possible solutions:

1) create a temporary table sorted in descending order by sizecol and fetch
the elements from there

2) read the complete elements into memory and sort them.

3) read cat and sizecol into memory, sort them and then fetch elements from
the database table in the order of the sorted cat/sizecol.

Solution 2 would certainly be the fastest, but would cause problems if there
are too many elements. So solution 3 sounds like the best to me, but I don't
know how much slower a fetch by cat would be then fetching the elements in
simple line order ?

Any reflections ? Anything I've missed or misunderstood ?

Moritz