0

I'm adding to a python script for GRASS v.transects.py. I want to set a variable to equal a value from a field in the vector's attribute table using a for loop to cycle through each row. This is one of my first GRASS scripts, I'm much more comfortable with arc. For arcpy I would use a search cursor and getValue:

vector = "river.shp"
lines = arcpy.SearchCursor(vector)
for line in lines:
     attributeValue = str(line.getValue("FIELD"))

The existing script has the right for loop already (for line in vector), its just a matter of figuring out the last line, how to have it read the field in the attribute table of the line segment it is currently cycling through.

3

You have two options, one in pure Python and the second, more classical, parsing the commands of GRASS GIS.

1) in pure Python

If I look at GRASS Programmer's Manual: Python (with the version 6.4.3) I still haven't found a way to write data (attributes) to GRASS vectors from Python.

But it's possible and easier with the version 7: GRASS 7 Programmer's Manual and PyGRASS

2) more classical: parsing the commands of GRASS GIS

You can use Python to run the standard GRASS vector commands (db.execute, v.db, v.db.update, etc., look for example at the Python scripts of Antonio Alliegro in Programatione and GIS: Python (in Italian) , Python Scripts For GRASS GIS or pgis with the class gVect()

They use SQL (SQL support in GRASS GIS) but if you use the dbf driver, due to his limitations, some commands as v.to.db.update are not supported (no problem if you use the SQLite driver).

As an example of the process with the dbf driver:

  1. creation of a new column with the sum of two attributes values

  2. change an attribute value

A table:

enter image description here

# first column
ZN = grass.read_command("v.db.select", flags="c", map="geochimcal", col="ZN")
ZN=(ZN.split("\n"))
ZN= ZN[0:(len(ZN)-1)]
print ZN
['40', '55', '65', '158', '44', '282', '62', '83', '84', '97', '61', '58', '40', '54', '75', '129', '77', '87', '74', '47', '58', '73', '64', '46', '63']

# second column
PB=grass.read_command("v.db.select", flags="c", map="geochimcal", col="PB")
PB=(PB.split("\n"))
PB= PB[0:(len(PB)-1)]
print PB
['17', '9', '16', '40', '16', '166', '18', '22', '37', '69', '62', '19', '17', '23', '33', '72', '19', '19', '39', '21', '30', '8', '37', '21', '20']

#add a column to the table:
grass.read_command("v.db.addcol",map="geochimcal",col="SOMME int")

# sum calculation
SOMME = range(len(PB))
for i in range(len(PB)):
    SOMME[i]=int(ZN[i])+int(PB[i])
print SOMME
[57, 64, 81, 198, 60, 448, 80, 105, 121, 166, 123, 77, 57, 77, 108, 201, 96, 106, 113, 68, 88, 81, 101, 67, 83]

# populate the new column
for i in range(len(ZN)):
     query="UPDATE geochimcal SET SOMME=" + str(SOMME[i]) + " WHERE cat = " + str(i+1)
     grass.write_command("db.execute", stdin = query)

enter image description here

Change a value:

query="UPDATE geochimcal SET SOMME=" + str(0) + "WHERE PH =" + str(6.9) 
grass.write_command("db.execute", stdin = query)

enter image description here

It is much easier with GRASS GIS 7 and PyGRASS (vector attributes) or workshop pygrass

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.