[GRASSLIST:6430] Re: Computing polygon area after/during
v.overlay
Hamish
hamish_nospam at yahoo.com
Tue Apr 12 08:15:56 EDT 2005
> > I would like to know the "coastline" lengths of some vector areas.
..
> > I'm trying to figure out a method to do this:
> >
> > v.to.db -p option=length type=boundary
> >
> > only works for lines (that is cat number -1 does report a length; if
> > type=boundary is not used then all real cats are listed with zero
> > length). I assume -1 length is sum of all boundaries? If so, I could
> > exploit the -1 length via v.extract in a loop for each cat, but that
> > seems like a bad solution.
>
> v.to.db works also for boundaries, but they must have a category
> (v.category type=boundary).
Yes, but how to assign the correct categories to them? (**see below**)
v.category just does step++, I want to use cat of touching area.
Note help page gives example with "v.to.db option=area" which doesn't
seem to be possible.
> How do you want to report length for elements without category?
Ok, understood. Just like v.extract will only grab features with a cat.
This works for sum of all boundaries in a normal area vector map where
only centroid has a cat:
# col= is needed with "-p"?
G6.1> v.to.db -p stew_sel op=length col=dummy
cat|length
-1|994040.209439
...
maybe v.extract for each AREA then above would work as a hack for what
I want to do (just report the perimeter length, not add to table).
> > so I use v.type to turn boundaries into lines, but as boundaries do
> > not have category numbers so result isn't worth much.
> >
> > How do I assign the category of the area next to the boundary as the
> > boundary's cat value? (all areas are islands which do not touch, so
> > no left/right side issues) v.distance?
>
> v.to.db option=sides, where is a problem?
v.to.db was failing because my boundaries did not have cats, but back
to the central problem:
To make a report of the perimeters of all areas it takes the following,
which is not easy! (maybe a bit simpler with use of 'v.reclass rules=' ?)
#!/bin/sh
# calc the coastline lengths of island groups
# (assume same fractal-depth; use for ratios only; yada, yada, yada)
# add categories to boundaries, starting with 1000 (something bigger
# than number of existing cats for clarity).
v.category in=t_area out=t_area_lab_bdy type=boundary cat=1000 step=1
# export sides to a text file; keep only existing side
# (areas do not touch so we can get away with this)
v.to.db t_area_lab_bdy -p op=sides col=l,r type=boundary | \
sed -e 's/|-1//' | sed -e 1d > t_area_bdy.prn
# extract only boundaries
v.extract in=t_area_lab_bdy out=t_area_bdy type=boundary
# convert to lines (optional)
v.type in=t_area_bdy out=t_area_line type=boundary,line
# add new column to hold the original area's cat number
map=t_area_line
echo "ALTER TABLE $map ADD area_cat integer" | db.execute
# create SQL command file
cat t_area_bdy.prn | \
awk -F'|' '{ printf("echo \"INSERT INTO $map (cat, area_cat) VALUES (%d, %d)\" | db.execute\n", $1, $2) }' \
> t_area_bdy_exe
# run the SQL command file (populate with a series of db.execute commands)
. t_area_bdy_exe
# make a new vector using the area_cat column from 'v.to.db op=sides' as
# the cat number
v.reclass in=t_area_line out=t_area_line2 column=area_cat
# copy original table to the new vector and connect it
db.copy from_table=t_area to_table=t_area_line2
v.db.connect map=t_area_line2 table=t_area_line2
# we now have a line vector file with the category numbers belonging to
# the original touching area as the cat!
# calculate the perimeter length for each area into new cstln_mtr column
echo "ALTER TABLE t_area_line2 ADD cstln_mtr double" | db.execute
v.to.db t_area_line2 option=length col=cstln_mtr
#remove cruft
rm t_area_bdy.prn t_area_bdy_exe
g.remove v=t_area_bdy,t_area_lab_bdy,t_area_line
# print results
v.db.select t_area_line2 | sort -n
# output:
#cat|name|cstln_mtr
#1|island group 1|15829.356619
#2|island group 2|19672.841857
#...
# success!
I'm sure you will now show me a way to do this in 1-2 commands.
:/
Hamish
More information about the grass-user
mailing list