source: trunk/anuga_core/source/anuga/file_conversion/sdf2pts.py @ 8879

Last change on this file since 8879 was 8780, checked in by steve, 12 years ago

Some changes to allow netcdf4 use

File size: 5.1 KB
Line 
1
2from anuga.coordinate_transforms.geo_reference import Geo_reference
3from anuga.geospatial_data.geospatial_data import Geospatial_data
4
5def _read_hecras_cross_sections(lines):
6    """Return block of surface lines for each cross section
7    Starts with SURFACE LINE,
8    Ends with END CROSS-SECTION
9    """
10
11    points = []
12
13    reading_surface = False
14    for i, line in enumerate(lines):
15        if len(line.strip()) == 0:    #Ignore blanks
16            continue
17
18        if lines[i].strip().startswith('SURFACE LINE'):
19            reading_surface = True
20            continue
21
22        if lines[i].strip().startswith('END') and reading_surface:
23            yield points
24            reading_surface = False
25            points = []
26
27        if reading_surface:
28            fields = line.strip().split(',')
29            easting = float(fields[0])
30            northing = float(fields[1])
31            elevation = float(fields[2])
32            points.append([easting, northing, elevation])
33
34
35
36def sdf2pts(name_in,
37                              name_out=None,
38                              verbose=False):
39    """Read HEC-RAS Elevation datal from the following ASCII format (.sdf)
40
41    basename_in Sterm of input filename.
42    basename_out Sterm of output filename.
43    verbose True if this function is to be verbose.
44
45    Example:
46
47# RAS export file created on Mon 15Aug2005 11:42
48# by HEC-RAS Version 3.1.1
49
50BEGIN HEADER:
51  UNITS: METRIC
52  DTM TYPE: TIN
53  DTM: v:\1\cit\perth_topo\river_tin
54  STREAM LAYER: c:\local\hecras\21_02_03\up_canning_cent3d.shp
55  CROSS-SECTION LAYER: c:\local\hecras\21_02_03\up_can_xs3d.shp
56  MAP PROJECTION: UTM
57  PROJECTION ZONE: 50
58  DATUM: AGD66
59  VERTICAL DATUM:
60  NUMBER OF REACHES:  19
61  NUMBER OF CROSS-SECTIONS:  14206
62END HEADER:
63
64Only the SURFACE LINE data of the following form will be utilised
65  CROSS-SECTION:
66    STREAM ID:Southern-Wungong
67    REACH ID:Southern-Wungong
68    STATION:19040.*
69    CUT LINE:
70      405548.671603161 , 6438142.7594925
71      405734.536092045 , 6438326.10404912
72      405745.130459356 , 6438331.48627354
73      405813.89633823 , 6438368.6272789
74    SURFACE LINE:
75     405548.67,   6438142.76,   35.37
76     405552.24,   6438146.28,   35.41
77     405554.78,   6438148.78,   35.44
78     405555.80,   6438149.79,   35.44
79     405559.37,   6438153.31,   35.45
80     405560.88,   6438154.81,   35.44
81     405562.93,   6438156.83,   35.42
82     405566.50,   6438160.35,   35.38
83     405566.99,   6438160.83,   35.37
84     ...
85   END CROSS-SECTION
86
87    Convert to NetCDF pts format which is
88
89    points:  (Nx2) float array
90    elevation: N float array
91    """
92
93    import os
94    from anuga.file.netcdf import NetCDFFile
95
96    if name_in[-4:] != '.sdf':
97        raise IOError('Input file %s should be of type .sdf.' % name_in)
98
99    if name_out is None:
100        name_out = name_in[:-4] + '.pts'
101    elif name_out[-4:] != '.pts':
102        raise IOError('Input file %s should be of type .pts.' % name_out)
103
104    # Get ASCII file
105    infile = open(name_in, 'r')
106
107    if verbose: log.critical('Reading DEM from %s' % (root + '.sdf'))
108
109    lines = infile.readlines()
110    infile.close()
111
112    if verbose: log.critical('Converting to pts format')
113
114    # Scan through the header, picking up stuff we need.
115    i = 0
116    while lines[i].strip() == '' or lines[i].strip().startswith('#'):
117        i += 1
118
119    assert lines[i].strip().upper() == 'BEGIN HEADER:'
120    i += 1
121
122    assert lines[i].strip().upper().startswith('UNITS:')
123    units = lines[i].strip().split()[1]
124    i += 1
125
126    assert lines[i].strip().upper().startswith('DTM TYPE:')
127    i += 1
128
129    assert lines[i].strip().upper().startswith('DTM:')
130    i += 1
131
132    assert lines[i].strip().upper().startswith('STREAM')
133    i += 1
134
135    assert lines[i].strip().upper().startswith('CROSS')
136    i += 1
137
138    assert lines[i].strip().upper().startswith('MAP PROJECTION:')
139    projection = lines[i].strip().split(':')[1]
140    i += 1
141
142    assert lines[i].strip().upper().startswith('PROJECTION ZONE:')
143    zone = int(lines[i].strip().split(':')[1])
144    i += 1
145
146    assert lines[i].strip().upper().startswith('DATUM:')
147    datum = lines[i].strip().split(':')[1]
148    i += 1
149
150    assert lines[i].strip().upper().startswith('VERTICAL DATUM:')
151    i += 1
152
153    assert lines[i].strip().upper().startswith('NUMBER OF REACHES:')
154    i += 1
155
156    assert lines[i].strip().upper().startswith('NUMBER OF CROSS-SECTIONS:')
157    number_of_cross_sections = int(lines[i].strip().split(':')[1])
158    i += 1
159
160    # Now read all points
161    points = []
162    elevation = []
163    for j, entries in enumerate(_read_hecras_cross_sections(lines[i:])):
164        for k, entry in enumerate(entries):
165            points.append(entry[:2])
166            elevation.append(entry[2])
167
168    msg = 'Actual #number_of_cross_sections == %d, Reported as %d'\
169          %(j+1, number_of_cross_sections)
170    assert j+1 == number_of_cross_sections, msg
171
172    # Get output file, write PTS data
173    if name_out == None:
174        ptsname = name_in[:-4] + '.pts'
175    else:
176        ptsname = name_out
177
178    geo_ref = Geo_reference(zone, 0, 0, datum, projection, units)
179    geo = Geospatial_data(points, {"elevation":elevation},
180                          verbose=verbose, geo_reference=geo_ref)
181    geo.export_points_file(ptsname)
Note: See TracBrowser for help on using the repository browser.