~ubuntu-branches/ubuntu/vivid/grass/vivid-proposed

« back to all changes in this revision

Viewing changes to scripts/v.report/v.report.py

  • Committer: Package Import Robot
  • Author(s): Bas Couwenberg
  • Date: 2015-02-20 23:12:08 UTC
  • mfrom: (8.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20150220231208-1u6qvqm84v430b10
Tags: 7.0.0-1~exp1
* New upstream release.
* Update python-ctypes-ternary.patch to use if/else instead of and/or.
* Drop check4dev patch, rely on upstream check.
* Add build dependency on libpq-dev to grass-dev for libpq-fe.h.
* Drop patches applied upstream, refresh remaining patches.
* Update symlinks for images switched from jpg to png.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
#
 
3
############################################################################
 
4
#
 
5
# MODULE:       v.report
 
6
# AUTHOR(S):    Markus Neteler, converted to Python by Glynn Clements
 
7
#               Bug fixed by Huidae Cho <grass4u gmail.com>
 
8
# PURPOSE:      Reports geometry statistics for vector maps
 
9
# COPYRIGHT:    (C) 2005, 2007-2009 by MN and the GRASS Development Team
 
10
#
 
11
#               This program is free software under the GNU General Public
 
12
#               License (>=v2). Read the file COPYING that comes with GRASS
 
13
#               for details.
 
14
#
 
15
#############################################################################
 
16
 
 
17
#%module
 
18
#% description: Reports geometry statistics for vector maps.
 
19
#% keyword: vector
 
20
#% keyword: geometry
 
21
#% keyword: statistics
 
22
#%end
 
23
#%option G_OPT_V_MAP
 
24
#%end
 
25
#%option G_OPT_V_FIELD
 
26
#% guisection: Selection
 
27
#%end
 
28
#%option
 
29
#% key: option
 
30
#% type: string
 
31
#% description: Value to calculate
 
32
#% options: area,length,coor
 
33
#% required: yes
 
34
#%end
 
35
#%option G_OPT_M_UNITS
 
36
#% options: miles,feet,meters,kilometers,acres,hectares,percent
 
37
#%end
 
38
#%option
 
39
#% key: sort
 
40
#% type: string
 
41
#% description: Sort the result
 
42
#% options: asc,desc
 
43
#% descriptions: asc;Sort in ascending order;desc;Sort in descending order
 
44
#%end
 
45
 
 
46
import sys
 
47
import os
 
48
import grass.script as grass
 
49
 
 
50
def uniq(l):
 
51
    result = []
 
52
    last = None
 
53
    for i in l:
 
54
        if i != last:
 
55
            result.append(i)
 
56
            last = i
 
57
    return result
 
58
 
 
59
def main():
 
60
    mapname = options['map']
 
61
    option = options['option']
 
62
    layer = options['layer']
 
63
    units = options['units']
 
64
 
 
65
    nuldev = file(os.devnull, 'w')
 
66
 
 
67
    if not grass.find_file(mapname, 'vector')['file']:
 
68
        grass.fatal(_("Vector map <%s> not found") % mapname)
 
69
 
 
70
    if int(layer) in grass.vector_db(mapname):
 
71
        colnames = grass.vector_columns(mapname, layer, getDict=False, stderr=nuldev)
 
72
        isConnection = True
 
73
    else:
 
74
        isConnection = False
 
75
        colnames = ['cat']
 
76
 
 
77
    if option == 'coor':
 
78
        columns = ['dummy1','dummy2','dummy3']
 
79
        extracolnames = ['x','y','z']
 
80
    else:
 
81
        columns = ['dummy1']
 
82
        extracolnames = [option]
 
83
 
 
84
    if units in ['p','percent']:
 
85
        unitsp = 'meters'
 
86
    elif units:
 
87
        unitsp = units
 
88
    else:
 
89
        unitsp = None
 
90
 
 
91
    # NOTE: we suppress -1 cat and 0 cat
 
92
    if isConnection:
 
93
        p = grass.pipe_command('v.db.select', quiet = True, flags='c', map = mapname, layer = layer)
 
94
        records1 = []
 
95
        for line in p.stdout:
 
96
            cols = line.rstrip('\r\n').split('|')
 
97
            if cols[0] == '0':
 
98
                continue
 
99
            records1.append([int(cols[0])] + cols[1:])
 
100
        p.wait()
 
101
        if p.returncode != 0:
 
102
            sys.exit(1)
 
103
        
 
104
        records1.sort()
 
105
 
 
106
        if len(records1) == 0:
 
107
            try:
 
108
                f = grass.vector_db(map = mapname)[int(layer)]
 
109
                grass.fatal(_("There is a table connected to input vector map '%s', but"
 
110
                              "there are no categories present in the key column '%s'. Consider using"
 
111
                              "v.to.db to correct this.") % (mapname, f['key']))
 
112
            except KeyError:
 
113
                pass
 
114
 
 
115
        #fetch the requested attribute sorted by cat:
 
116
        p = grass.pipe_command('v.to.db', flags = 'p',
 
117
                               quiet = True,
 
118
                               map = mapname, option = option, columns = columns,
 
119
                               layer = layer, units = unitsp)
 
120
        records2 = []
 
121
        for line in p.stdout:
 
122
            fields = line.rstrip('\r\n').split('|')
 
123
            if fields[0] in ['cat', '-1', '0']:
 
124
                continue
 
125
            records2.append([int(fields[0])] + fields[1:-1] + [float(fields[-1])])
 
126
        p.wait()
 
127
        records2.sort()
 
128
 
 
129
        #make pre-table
 
130
        # len(records1) may not be the same as len(records2) because
 
131
        # v.db.select can return attributes that are not linked to features.
 
132
        records3 = []
 
133
        for r2 in records2:
 
134
            records3.append(filter(lambda r1: r1[0] == r2[0], records1)[0] + r2[1:])
 
135
    else:
 
136
        records1 = []
 
137
        p = grass.pipe_command('v.category', inp = mapname, layer = layer, option = 'print')
 
138
        for line in p.stdout:
 
139
            field = int(line.rstrip())
 
140
            if field > 0:
 
141
                records1.append(field)
 
142
        p.wait()
 
143
        records1.sort()
 
144
        records1 = uniq(records1)
 
145
 
 
146
        #make pre-table
 
147
        p = grass.pipe_command('v.to.db', flags = 'p',
 
148
                               map = mapname, option = option, columns = columns,
 
149
                               layer = layer, units = unitsp)
 
150
        records3 = []
 
151
        for line in p.stdout:
 
152
            fields = line.split('|')
 
153
            if fields[0] in ['cat', '-1', '0']:
 
154
                continue
 
155
            records3.append([int(fields[0])] + fields[1:])
 
156
        p.wait()
 
157
        records3.sort()
 
158
 
 
159
    # print table header
 
160
    sys.stdout.write('|'.join(colnames + extracolnames) + '\n')
 
161
 
 
162
    #make and print the table:
 
163
    numcols = len(colnames) + len(extracolnames)
 
164
 
 
165
    # calculate percents if requested
 
166
    if units != '' and units in ['p','percent']:
 
167
        # calculate total area value
 
168
        areatot = 0
 
169
        for r in records3:
 
170
            areatot += float(r[-1])
 
171
 
 
172
        # calculate area percentages
 
173
        records4 = [float(r[-1]) * 100 / areatot for r in records3]
 
174
        records3 = [r1 + [r4] for r1, r4 in zip(records1, records4)]
 
175
 
 
176
    # sort results
 
177
    if options['sort']:
 
178
        if options['sort'] == 'asc':
 
179
            records3.sort(key = lambda r: r[-1])
 
180
        else:
 
181
            records3.sort(key = lambda r: r[-1], reverse = True)
 
182
    
 
183
    for r in records3:
 
184
        sys.stdout.write('|'.join(map(str,r)) + '\n')
 
185
 
 
186
if __name__ == "__main__":
 
187
    options, flags = grass.parser()
 
188
    main()