[GRASSLIST:6385] Computing polygon area after/during v.overlay

Hi folks,

I have not been able to compute the area of vector polygons after a v.overlay operation. Here's what I've done in the 6.0.0 release of GRASS, running OS X 10.3.8:

1. Import ESRI GRID data (2.5-degree pixels, r.in.arc input=name.txt output=name1 type=CELL title=name1 mult=1.0 )
2. Import ESRI shapefile (global political boundaries, v.in.ogr dsn=cntry92.shp output=esri92shp layer=cntry92 min_area=0.0001 snap=-1 location=esri92shp -o )
3. Convert the raster file into vector polygons (r.to.vect input=name1 output=name2 feature=area )
4. Overlay the two vector files (v.overlay ainput=name2 atype=area alayer=1 binput=esri92shp btype=area blayer=1 output=name2_overlay operator=or olayer=1,0,0 )

All the data are lat-long format, as is the location. After the v.overlay, I get topology and the .dbf file shows that I've successfully merged the data, but I haven't found a way to compute the areas of each clipped polygon. Ultimately, I need to create weighted averages (first by area, later by other variables) for each country.

I have 1608 GRID files to import, convert, and overlay. So, it is less desirable to convert the files in Maptitude or ARC/INFO and then re-import the data, as I can script in Perl/bash but have not learned Maptitude's GISDK or the Arc Macro Language (or whatever it's called these days--I quit using ARC 6 around 1998...).

I've bought Neteler & Mitasova (2004), I've read through the tutorials I could find, and I have searched Google, groups.google, and the gmane archive of the GRASS list. Am I missing something? Is there another manual I should read for the answer?

Many thanks,

Jesse

Jesse Hamner
Department of Political Science
Emory University
Atlanta, Georgia USA

I have not been able to compute the area of vector polygons after a
v.overlay operation. Here's what I've done in the 6.0.0 release of
GRASS, running OS X 10.3.8:

...

4. Overlay the two vector files (v.overlay ainput=name2 atype=area
alayer=1 binput=esri92shp btype=area blayer=1 output=name2_overlay
operator=or olayer=1,0,0 )

All the data are lat-long format, as is the location. After the
v.overlay, I get topology and the .dbf file shows that I've
successfully merged the data, but I haven't found a way to compute the
areas of each clipped polygon. Ultimately, I need to create weighted
averages (first by area, later by other variables) for each country.

d.vect overlay_output
d.what.vect

should show you the area quickly.

I think it is possible to make a report by using v.to.db. (same with line
length, ..)

examples from the help page:
  http://grass.ibiblio.org/grass60/manuals/html60_user/v.to.db.html

Printing reports

Report all area sizes of a map:
v.to.db -p soils option=area type=boundary units=h

Report all area sizes of a map, sorted by category number:
v.to.db -p soils option=area type=boundary units=h | sort -n

Hamish

d.vect overlay_output
d.what.vect

should show you the area quickly.

I think it is possible to make a report by using v.to.db. (same with
line length, ..)

I would like to know the "coastline" lengths of some vector areas.

Yes, it's a fractal problem, so we assume constant smoothness and only
use results as ratios vs other areas within same dataset.

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.

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.category option=add
just assigns cats sequentially without regard to original area's cat.

also, what does cat=0 answer mean in v.to.db output when option=area?
Area of holes within a polygon? The true categoried polygon sums do not
include that, correct?

also, why does v.to.db insist on the col= option? You just need to feed
it 'col=foo' or you get "ERROR: This option requires one column"

thanks,
Hamish

Hamish!

Hamish wrote:

I would like to know the "coastline" lengths of some vector areas.

Yes, it's a fractal problem, so we assume constant smoothness and only
use results as ratios vs other areas within same dataset.

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). How do you want to report length for elements without category?

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?

Radim

v.category option=add
just assigns cats sequentially without regard to original area's cat.

also, what does cat=0 answer mean in v.to.db output when option=area?
Area of holes within a polygon? The true categoried polygon sums do not
include that, correct?

also, why does v.to.db insist on the col= option? You just need to feed
it 'col=foo' or you get "ERROR: This option requires one column"

thanks,
Hamish

2005-04-11
Cc: GRASSLIST@baylor.edu

Remove me from your mailing list (Heikki.Laurila@helsinki.fi)
Heikki Laurila

HI,
   What Units is the Area calculated in ?

D.

d.vect overlay_output
d.what.vect

should show you the area quickly.

-----------------------------------------
Stay ahead of the information curve.
Receive GIS news and jobs on your desktop daily.
Subscribe today to the GIS CafeNews newsletter.
[ http://www10.giscafe.com/nl/newsletter_subscribe.php ]
It's informative and essential.

Remove me from your mailing list

From the mailing list webpage:

To unsubscribe from the GRASS Users List, send email to:
listproc@baylor.edu
In the body of the message, write the command:
unsubscribe GRASSLIST
Please do not send "unsubscribe" messages to the user mailing list -
this won't work. You have to use the "listproc@baylor.edu" email
address.

Hamish

>> d.vect overlay_output
>> d.what.vect
>>
>> should show you the area quickly.

..

   What Units is the Area calculated in ?

Usually meters^2, but check units with 'g.proj -p'?

I guess the unit should really be appended to the output.

Hamish

GRASS usually calculates in map units (if the user doesn't
select anything else).

g.proj -p

reports them for the current location.

Markus

On Mon, Apr 11, 2005 at 07:49:12AM -0400, DrakeGis wrote:

HI,
   What Units is the Area calculated in ?

D.

>> d.vect overlay_output
>> d.what.vect
>>
>> should show you the area quickly.

-----------------------------------------
Stay ahead of the information curve.
Receive GIS news and jobs on your desktop daily.
Subscribe today to the GIS CafeNews newsletter.
[ http://www10.giscafe.com/nl/newsletter_subscribe.php ]
It's informative and essential.

--
Markus Neteler <neteler itc it> http://mpa.itc.it
ITC-irst - Centro per la Ricerca Scientifica e Tecnologica
MPBA - Predictive Models for Biol. & Environ. Data Analysis
Via Sommarive, 18 - 38050 Povo (Trento), Italy

> 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.
:confused:

Hamish