[GRASS-user] v.centroids and cat values

Moritz Lennert mlennert at club.worldonline.be
Tue Jan 6 11:19:58 EST 2009


On 03/01/09 17:29, Micha Silver wrote:
> I'd like to better understand the way cat values are assigned to 
> centroids when using v.centroids. I came across a problem when I created 
> a new vector and digitized boundaries (v.digit -n) .  Before beginning 
> to digitize, I added some columns to the attribute table within v.digit, 
> so that on completing each feature, I could fill in the values for that 
> feature. I had one column for the label, and one column, GRASSRGB for 
> coloring. I did not bother to digitize centroids, but rather, after 
> completing the boundaries, and exiting v.digit, I ran v.centroids.
> 
> I was surprised to see that the cat value assigned to each centroid 
> *does not correspond* to the cat values of the surrounding boundary. 
> This has the unfortunate effect of showing incorrect labels when running 
> d.vect with the display=shape,attr option, since the attribute is taken 
> from centroid, and not from its surrounding boundary. In addition, when 
> coloring with the d.vect -a option, the boundaries get the correct color 
> from the GRASSRGB column, but the fill color is also wrong, since the 
> fill color is again taken from the attributes of the centroid. And the 
> centroid, with a different cat value, goes to the wrong row of the 
> attached attribute table.  This behavior is certainly undesirable, 
> unless I'm missing something basic??
> 
> My workaround was to delete all centroids, then go back into v.digit, 
> and digitize each centroid, while being careful to choose it's cat value 
> manually, and set each one to the correct cat of the surrounding 
> boundary by choosing "Manual Entry" instead of "Next not used" mode for 
> categories.
> 
> So, is there some way to create centroids, such that they automatically 
> get the same cat value as the boundary?

Normally, the "best practice" is to digitize boundaries without category 
values (unless you specifically want information concerning the 
boundary, not the area it contains) and then digitize the centroids with 
category values and relevant attribute data.

In your case, the easiest way out would seem to be v.distance, i.e.:

- v.centroid in=YourBoundaries out=YourMap
- v.db.addcol YourMap column="b_cat int"
- v.distance from=YourMap from_type=centroid to=YourMap to_type=boundary 
upload=cat column=b_cat #this should find the nearest boundary for each 
centroid
- v.category in=YourMap out=YourMap2 option=del type=boundary
- v.reclass in=YourMap2 out=YourMap3 type=centroid column=b_cat
- db.copy from_table=YourMap2 to_table=YourMap3
- db.dropcol YourMap3 col=b_cat
- Now you should have a YourMap3 with centroids that are linked to the 
correct attributes. If this is the case, you can safely do the next step:
- g.remove vect=YourMap,YourMap2

This should be quite easy to make into a script module, or maybe extend 
v.centroids to optionally do this for you.

Moritz


More information about the grass-user mailing list