1 | """ Load a DEM file, decimate it, and resave it. |
---|
2 | """ |
---|
3 | |
---|
4 | import numpy as num |
---|
5 | import os |
---|
6 | |
---|
7 | from anuga.config import netcdf_mode_r, netcdf_mode_w, netcdf_float |
---|
8 | |
---|
9 | def grd2array(filename, verbose=False): |
---|
10 | """Read Digital Elevation model from the following ASCII format (.asc or .grd) |
---|
11 | |
---|
12 | Example: |
---|
13 | ncols 3121 |
---|
14 | nrows 1800 |
---|
15 | xllcorner 722000 |
---|
16 | yllcorner 5893000 |
---|
17 | cellsize 25 |
---|
18 | NODATA_value -9999 |
---|
19 | 138.3698 137.4194 136.5062 135.5558 .......... |
---|
20 | |
---|
21 | |
---|
22 | An accompanying file with same basename but extension .prj must exist |
---|
23 | and is used to fix the UTM zone, datum, false northings and eastings. |
---|
24 | |
---|
25 | The prj format is assumed to be as |
---|
26 | |
---|
27 | Projection UTM |
---|
28 | Zone 56 |
---|
29 | Datum WGS84 |
---|
30 | Zunits NO |
---|
31 | Units METERS |
---|
32 | Spheroid WGS84 |
---|
33 | Xshift 0.0000000000 |
---|
34 | Yshift 10000000.0000000000 |
---|
35 | Parameters |
---|
36 | """ |
---|
37 | |
---|
38 | |
---|
39 | |
---|
40 | msg = 'Filename must be a text string' |
---|
41 | assert isinstance(filename, basestring), msg |
---|
42 | |
---|
43 | msg = 'Extension should be .grd or asc' |
---|
44 | assert os.path.splitext(filename)[1] in ['.grd', '.asc'], msg |
---|
45 | |
---|
46 | |
---|
47 | |
---|
48 | |
---|
49 | root = filename[:-4] |
---|
50 | |
---|
51 | |
---|
52 | #Read DEM data |
---|
53 | datafile = open(filename) |
---|
54 | |
---|
55 | if verbose: log.critical('Reading data from %s' % (filename)) |
---|
56 | |
---|
57 | lines = datafile.readlines() |
---|
58 | datafile.close() |
---|
59 | |
---|
60 | if verbose: log.critical('Got %d lines' % len(lines)) |
---|
61 | |
---|
62 | |
---|
63 | ncols = int(lines[0].split()[1].strip()) |
---|
64 | nrows = int(lines[1].split()[1].strip()) |
---|
65 | |
---|
66 | |
---|
67 | # Do cellsize (line 4) before line 2 and 3 |
---|
68 | cellsize = float(lines[4].split()[1].strip()) |
---|
69 | |
---|
70 | # Checks suggested by Joaquim Luis |
---|
71 | # Our internal representation of xllcorner |
---|
72 | # and yllcorner is non-standard. |
---|
73 | xref = lines[2].split() |
---|
74 | if xref[0].strip() == 'xllcorner': |
---|
75 | xllcorner = float(xref[1].strip()) # + 0.5*cellsize # Correct offset |
---|
76 | elif xref[0].strip() == 'xllcenter': |
---|
77 | xllcorner = float(xref[1].strip()) |
---|
78 | else: |
---|
79 | msg = 'Unknown keyword: %s' % xref[0].strip() |
---|
80 | raise Exception, msg |
---|
81 | |
---|
82 | yref = lines[3].split() |
---|
83 | if yref[0].strip() == 'yllcorner': |
---|
84 | yllcorner = float(yref[1].strip()) # + 0.5*cellsize # Correct offset |
---|
85 | elif yref[0].strip() == 'yllcenter': |
---|
86 | yllcorner = float(yref[1].strip()) |
---|
87 | else: |
---|
88 | msg = 'Unknown keyword: %s' % yref[0].strip() |
---|
89 | raise Exception, msg |
---|
90 | |
---|
91 | NODATA_value = int(float(lines[5].split()[1].strip())) |
---|
92 | |
---|
93 | assert len(lines) == nrows + 6 |
---|
94 | |
---|
95 | |
---|
96 | #Store data |
---|
97 | import numpy |
---|
98 | |
---|
99 | datafile = open(filename) |
---|
100 | Z = numpy.loadtxt(datafile, skiprows=6) |
---|
101 | datafile.close() |
---|
102 | |
---|
103 | #print Z.shape |
---|
104 | #print Z |
---|
105 | |
---|
106 | # For raster data we need to a flip and transpose |
---|
107 | Z = numpy.flipud(Z) |
---|
108 | |
---|
109 | # Transpose z to have y coordinates along the first axis and x coordinates |
---|
110 | # along the second axis |
---|
111 | Z = Z.transpose() |
---|
112 | |
---|
113 | x = num.linspace(xllcorner, xllcorner+cellsize*(ncols-1), ncols) |
---|
114 | y = num.linspace(yllcorner, yllcorner+cellsize*(nrows-1), nrows) |
---|
115 | |
---|
116 | # get rid of NODATA |
---|
117 | import numpy |
---|
118 | Z = numpy.where(Z == NODATA_value , numpy.nan, Z) |
---|
119 | |
---|
120 | return x,y, Z |
---|
121 | |
---|
122 | |
---|