[2488] | 1 | """ |
---|
[4451] | 2 | |
---|
[2488] | 3 | """ |
---|
| 4 | |
---|
| 5 | |
---|
| 6 | #FIXME: Ensure that all attributes of a georef are treated everywhere |
---|
| 7 | #and unit test |
---|
| 8 | |
---|
[2593] | 9 | import types, sys |
---|
[3514] | 10 | from anuga.utilities.numerical_tools import ensure_numeric |
---|
[6360] | 11 | from anuga.utilities.anuga_exceptions import ANUGAError, TitleError, \ |
---|
| 12 | ParsingError, ShapeError |
---|
[6304] | 13 | from anuga.config import netcdf_float, netcdf_int, netcdf_float32 |
---|
[2488] | 14 | |
---|
[6304] | 15 | import numpy as num |
---|
[2941] | 16 | |
---|
[6149] | 17 | |
---|
[2602] | 18 | DEFAULT_ZONE = -1 |
---|
[6360] | 19 | TITLE = '#geo reference' + "\n" # this title is referred to in the test format |
---|
[2488] | 20 | |
---|
[4387] | 21 | DEFAULT_PROJECTION = 'UTM' |
---|
| 22 | DEFAULT_DATUM = 'wgs84' |
---|
| 23 | DEFAULT_UNITS = 'm' |
---|
| 24 | DEFAULT_FALSE_EASTING = 500000 |
---|
[6360] | 25 | DEFAULT_FALSE_NORTHING = 10000000 # Default for southern hemisphere |
---|
[4387] | 26 | |
---|
[6360] | 27 | |
---|
| 28 | ## |
---|
| 29 | # @brief A class for ... |
---|
[2488] | 30 | class Geo_reference: |
---|
| 31 | """ |
---|
[6360] | 32 | Attributes of the Geo_reference class: |
---|
| 33 | .zone The UTM zone (default is -1) |
---|
| 34 | .false_easting ?? |
---|
| 35 | .false_northing ?? |
---|
| 36 | .datum The Datum used (default is wgs84) |
---|
| 37 | .projection The projection used (default is 'UTM') |
---|
| 38 | .units The units of measure used (default metres) |
---|
| 39 | .xllcorner The X coord of origin (default is 0.0 wrt UTM grid) |
---|
| 40 | .yllcorner The y coord of origin (default is 0.0 wrt UTM grid) |
---|
| 41 | .is_absolute ?? |
---|
| 42 | |
---|
[2488] | 43 | """ |
---|
| 44 | |
---|
[6360] | 45 | ## |
---|
| 46 | # @brief Instantiate an instance of class Geo_reference. |
---|
| 47 | # @param zone The UTM zone. |
---|
| 48 | # @param xllcorner X coord of origin of georef. |
---|
| 49 | # @param yllcorner Y coord of origin of georef. |
---|
| 50 | # @param datum ?? |
---|
| 51 | # @param projection The projection used (default UTM). |
---|
| 52 | # @param units Units used in measuring distance (default m). |
---|
| 53 | # @param false_easting ?? |
---|
| 54 | # @param false_northing ?? |
---|
| 55 | # @param NetCDFObject NetCDF file *handle* to write to. |
---|
| 56 | # @param ASCIIFile ASCII text file *handle* to write to. |
---|
| 57 | # @param read_title Title of the georeference text. |
---|
[2488] | 58 | def __init__(self, |
---|
[6360] | 59 | zone=DEFAULT_ZONE, |
---|
| 60 | xllcorner=0.0, |
---|
| 61 | yllcorner=0.0, |
---|
| 62 | datum=DEFAULT_DATUM, |
---|
| 63 | projection=DEFAULT_PROJECTION, |
---|
| 64 | units=DEFAULT_UNITS, |
---|
| 65 | false_easting=DEFAULT_FALSE_EASTING, |
---|
| 66 | false_northing=DEFAULT_FALSE_NORTHING, |
---|
[2488] | 67 | NetCDFObject=None, |
---|
| 68 | ASCIIFile=None, |
---|
| 69 | read_title=None): |
---|
| 70 | """ |
---|
| 71 | input: |
---|
[6360] | 72 | NetCDFObject - a handle to the netCDF file to be written to |
---|
[2488] | 73 | ASCIIFile - a handle to the text file |
---|
| 74 | read_title - the title of the georeference text, if it was read in. |
---|
[2941] | 75 | If the function that calls this has already read the title line, |
---|
| 76 | it can't unread it, so this info has to be passed. |
---|
| 77 | If you know of a way to unread this info, then tell us. |
---|
[2488] | 78 | |
---|
[4387] | 79 | Note, the text file only saves a sub set of the info the |
---|
| 80 | points file does. Currently the info not written in text |
---|
| 81 | must be the default info, since ANUGA assumes it isn't |
---|
| 82 | changing. |
---|
[6360] | 83 | """ |
---|
| 84 | |
---|
[4451] | 85 | if zone is None: |
---|
| 86 | zone = DEFAULT_ZONE |
---|
[2488] | 87 | self.false_easting = false_easting |
---|
[6360] | 88 | self.false_northing = false_northing |
---|
[2488] | 89 | self.datum = datum |
---|
| 90 | self.projection = projection |
---|
[6360] | 91 | self.zone = zone |
---|
[2488] | 92 | self.units = units |
---|
| 93 | self.xllcorner = xllcorner |
---|
[6360] | 94 | self.yllcorner = yllcorner |
---|
| 95 | #self.is_absolute = num.allclose([self.xllcorner, self.yllcorner], 0) |
---|
| 96 | |
---|
[2488] | 97 | if NetCDFObject is not None: |
---|
| 98 | self.read_NetCDF(NetCDFObject) |
---|
[6360] | 99 | |
---|
[2488] | 100 | if ASCIIFile is not None: |
---|
| 101 | self.read_ASCII(ASCIIFile, read_title=read_title) |
---|
| 102 | |
---|
[6360] | 103 | # # Might be better to have this method instead of the following 3. |
---|
| 104 | # def get_origin(self): |
---|
| 105 | # return (self.zone, self.xllcorner, self.yllcorner) |
---|
| 106 | |
---|
| 107 | ## |
---|
| 108 | # @brief Get the X coordinate of the origin of this georef. |
---|
[2488] | 109 | def get_xllcorner(self): |
---|
| 110 | return self.xllcorner |
---|
[6360] | 111 | |
---|
| 112 | ## |
---|
| 113 | # @brief Get the Y coordinate of the origin of this georef. |
---|
[2488] | 114 | def get_yllcorner(self): |
---|
| 115 | return self.yllcorner |
---|
[6360] | 116 | |
---|
| 117 | ## |
---|
| 118 | # @brief Get the zone of this georef. |
---|
[2488] | 119 | def get_zone(self): |
---|
| 120 | return self.zone |
---|
[6360] | 121 | |
---|
| 122 | ## |
---|
| 123 | # @brief Write <something> to an open NetCDF file. |
---|
| 124 | # @param outfile Handle to open NetCDF file. |
---|
[2488] | 125 | def write_NetCDF(self, outfile): |
---|
[6360] | 126 | outfile.xllcorner = self.xllcorner |
---|
[2488] | 127 | outfile.yllcorner = self.yllcorner |
---|
| 128 | outfile.zone = self.zone |
---|
| 129 | |
---|
| 130 | outfile.false_easting = self.false_easting |
---|
| 131 | outfile.false_northing = self.false_northing |
---|
| 132 | |
---|
[6360] | 133 | outfile.datum = self.datum |
---|
[2488] | 134 | outfile.projection = self.projection |
---|
| 135 | outfile.units = self.units |
---|
| 136 | |
---|
[6360] | 137 | ## |
---|
| 138 | # @brief Read data from an open NetCDF file. |
---|
| 139 | # @param infile Handle to open NetCDF file. |
---|
[2488] | 140 | def read_NetCDF(self, infile): |
---|
| 141 | self.xllcorner = infile.xllcorner[0] |
---|
[6360] | 142 | self.yllcorner = infile.yllcorner[0] |
---|
[2488] | 143 | self.zone = infile.zone[0] |
---|
| 144 | |
---|
| 145 | # Fix some assertion failures |
---|
[6304] | 146 | if isinstance(self.zone, num.ndarray) and self.zone.shape == (): |
---|
[2488] | 147 | self.zone = self.zone[0] |
---|
[6360] | 148 | if (isinstance(self.xllcorner, num.ndarray) and |
---|
| 149 | self.xllcorner.shape == ()): |
---|
[2488] | 150 | self.xllcorner = self.xllcorner[0] |
---|
[6360] | 151 | if (isinstance(self.yllcorner, num.ndarray) and |
---|
| 152 | self.yllcorner.shape == ()): |
---|
[2488] | 153 | self.yllcorner = self.yllcorner[0] |
---|
| 154 | |
---|
[6304] | 155 | assert (self.xllcorner.dtype.kind in num.typecodes['Float'] or |
---|
| 156 | self.xllcorner.dtype.kind in num.typecodes['Integer']) |
---|
| 157 | assert (self.yllcorner.dtype.kind in num.typecodes['Float'] or |
---|
| 158 | self.yllcorner.dtype.kind in num.typecodes['Integer']) |
---|
| 159 | assert (self.zone.dtype.kind in num.typecodes['Integer']) |
---|
[6360] | 160 | |
---|
[4389] | 161 | try: |
---|
| 162 | self.false_easting = infile.false_easting[0] |
---|
| 163 | self.false_northing = infile.false_northing[0] |
---|
[6360] | 164 | |
---|
| 165 | self.datum = infile.datum |
---|
[4389] | 166 | self.projection = infile.projection |
---|
| 167 | self.units = infile.units |
---|
| 168 | except: |
---|
| 169 | pass |
---|
[6360] | 170 | |
---|
| 171 | if self.false_easting != DEFAULT_FALSE_EASTING: |
---|
| 172 | print "WARNING: False easting of %f specified." % self.false_easting |
---|
| 173 | print "Default false easting is %f." % DEFAULT_FALSE_EASTING |
---|
[4451] | 174 | print "ANUGA does not correct for differences in False Eastings." |
---|
[6360] | 175 | |
---|
| 176 | if self.false_northing != DEFAULT_FALSE_NORTHING: |
---|
| 177 | print ("WARNING: False northing of %f specified." |
---|
| 178 | % self.false_northing) |
---|
| 179 | print "Default false northing is %f." % DEFAULT_FALSE_NORTHING |
---|
[4451] | 180 | print "ANUGA does not correct for differences in False Northings." |
---|
[6360] | 181 | |
---|
| 182 | if self.datum.upper() != DEFAULT_DATUM.upper(): |
---|
| 183 | print "WARNING: Datum of %s specified." % self.datum |
---|
| 184 | print "Default Datum is %s." % DEFAULT_DATUM |
---|
[4451] | 185 | print "ANUGA does not correct for differences in datums." |
---|
[6360] | 186 | |
---|
| 187 | if self.projection.upper() != DEFAULT_PROJECTION.upper(): |
---|
| 188 | print "WARNING: Projection of %s specified." % self.projection |
---|
| 189 | print "Default Projection is %s." % DEFAULT_PROJECTION |
---|
[4451] | 190 | print "ANUGA does not correct for differences in Projection." |
---|
[6360] | 191 | |
---|
| 192 | if self.units.upper() != DEFAULT_UNITS.upper(): |
---|
| 193 | print "WARNING: Units of %s specified." % self.units |
---|
| 194 | print "Default units is %s." % DEFAULT_UNITS |
---|
[4451] | 195 | print "ANUGA does not correct for differences in units." |
---|
[6360] | 196 | |
---|
| 197 | ################################################################################ |
---|
| 198 | # ASCII files with geo-refs are currently not used |
---|
| 199 | ################################################################################ |
---|
| 200 | |
---|
| 201 | ## |
---|
| 202 | # @brief Write georef data to an open text file. |
---|
| 203 | # @param fd Handle to open text file. |
---|
[2488] | 204 | def write_ASCII(self, fd): |
---|
| 205 | fd.write(TITLE) |
---|
[6360] | 206 | fd.write(str(self.zone) + "\n") |
---|
| 207 | fd.write(str(self.xllcorner) + "\n") |
---|
[2488] | 208 | fd.write(str(self.yllcorner) + "\n") |
---|
| 209 | |
---|
[6360] | 210 | ## |
---|
| 211 | # @brief Read georef data from an open text file. |
---|
| 212 | # @param fd Handle to open text file. |
---|
| 213 | def read_ASCII(self, fd, read_title=None): |
---|
[2942] | 214 | try: |
---|
| 215 | if read_title == None: |
---|
[6360] | 216 | read_title = fd.readline() # remove the title line |
---|
[2942] | 217 | if read_title[0:2].upper() != TITLE[0:2].upper(): |
---|
[6360] | 218 | msg = ('File error. Expecting line: %s. Got this line: %s' |
---|
| 219 | % (TITLE, read_title)) |
---|
| 220 | raise TitleError, msg |
---|
[2942] | 221 | self.zone = int(fd.readline()) |
---|
| 222 | self.xllcorner = float(fd.readline()) |
---|
| 223 | self.yllcorner = float(fd.readline()) |
---|
| 224 | except SyntaxError: |
---|
[6360] | 225 | msg = 'File error. Got syntax error while parsing geo reference' |
---|
| 226 | raise ParsingError, msg |
---|
| 227 | |
---|
[2488] | 228 | # Fix some assertion failures |
---|
[6304] | 229 | if isinstance(self.zone, num.ndarray) and self.zone.shape == (): |
---|
[2488] | 230 | self.zone = self.zone[0] |
---|
[6360] | 231 | if (isinstance(self.xllcorner, num.ndarray) and |
---|
| 232 | self.xllcorner.shape == ()): |
---|
[2488] | 233 | self.xllcorner = self.xllcorner[0] |
---|
[6360] | 234 | if (isinstance(self.yllcorner, num.ndarray) and |
---|
| 235 | self.yllcorner.shape == ()): |
---|
[2488] | 236 | self.yllcorner = self.yllcorner[0] |
---|
[6304] | 237 | |
---|
[6360] | 238 | ################################################################################ |
---|
[6304] | 239 | |
---|
[6360] | 240 | def change_points_geo_ref(self, points, points_geo_ref=None): |
---|
[2488] | 241 | """ |
---|
[6304] | 242 | Change the geo reference of a list or numeric array of points to |
---|
[2488] | 243 | be this reference.(The reference used for this object) |
---|
| 244 | If the points do not have a geo ref, assume 'absolute' values |
---|
| 245 | """ |
---|
[2594] | 246 | |
---|
[2488] | 247 | is_list = False |
---|
| 248 | if type(points) == types.ListType: |
---|
| 249 | is_list = True |
---|
[2594] | 250 | |
---|
[6304] | 251 | points = ensure_numeric(points, num.float) |
---|
[6360] | 252 | |
---|
[2594] | 253 | if len(points.shape) == 1: |
---|
[6360] | 254 | # One point has been passed |
---|
[2594] | 255 | msg = 'Single point must have two elements' |
---|
| 256 | assert len(points) == 2, msg |
---|
[6149] | 257 | points = num.reshape(points, (1,2)) |
---|
[2594] | 258 | |
---|
[6360] | 259 | msg = ('Points array must be two dimensional.\n' |
---|
| 260 | 'I got %d dimensions' % len(points.shape)) |
---|
[5665] | 261 | assert len(points.shape) == 2, msg |
---|
| 262 | |
---|
[6360] | 263 | msg = ('Input must be an N x 2 array or list of (x,y) values. ' |
---|
| 264 | 'I got an %d x %d array' % points.shape) |
---|
| 265 | assert points.shape[1] == 2, msg |
---|
[3071] | 266 | |
---|
[6360] | 267 | # FIXME (Ole): Could also check if zone, xllcorner, yllcorner |
---|
| 268 | # are identical in the two geo refs. |
---|
[2594] | 269 | if points_geo_ref is not self: |
---|
[5736] | 270 | # If georeferences are different |
---|
[2594] | 271 | if not points_geo_ref is None: |
---|
[5736] | 272 | # Convert points to absolute coordinates |
---|
[6360] | 273 | points[:,0] += points_geo_ref.xllcorner |
---|
| 274 | points[:,1] += points_geo_ref.yllcorner |
---|
| 275 | |
---|
[5736] | 276 | # Make points relative to primary geo reference |
---|
[6360] | 277 | points[:,0] -= self.xllcorner |
---|
[2594] | 278 | points[:,1] -= self.yllcorner |
---|
| 279 | |
---|
[6360] | 280 | # if we got a list, return a list |
---|
[2488] | 281 | if is_list: |
---|
| 282 | points = points.tolist() |
---|
[6360] | 283 | |
---|
[2488] | 284 | return points |
---|
[3129] | 285 | |
---|
[6360] | 286 | ## |
---|
| 287 | # @brief Is this georef absolute? |
---|
| 288 | # @return True if ??? |
---|
[3129] | 289 | def is_absolute(self): |
---|
[6360] | 290 | """Return True if xllcorner==yllcorner==0 |
---|
| 291 | indicating that points in question are absolute. |
---|
[3129] | 292 | """ |
---|
| 293 | |
---|
[6360] | 294 | return num.allclose([self.xllcorner, self.yllcorner], 0) |
---|
[3129] | 295 | |
---|
[6304] | 296 | ## |
---|
[6360] | 297 | # @brief Convert points to absolute points in this georef instance. |
---|
| 298 | # @param points |
---|
| 299 | # @return |
---|
| 300 | # @note |
---|
[2488] | 301 | def get_absolute(self, points): |
---|
[6304] | 302 | """Given a set of points geo referenced to this instance, |
---|
[2488] | 303 | return the points as absolute values. |
---|
| 304 | """ |
---|
[3071] | 305 | |
---|
[6304] | 306 | #if self.is_absolute: |
---|
[3134] | 307 | # return points |
---|
[6304] | 308 | |
---|
[6360] | 309 | # remember if we got a list |
---|
[2488] | 310 | is_list = False |
---|
| 311 | if type(points) == types.ListType: |
---|
| 312 | is_list = True |
---|
[3071] | 313 | |
---|
[6304] | 314 | points = ensure_numeric(points, num.float) |
---|
[3071] | 315 | if len(points.shape) == 1: |
---|
| 316 | #One point has been passed |
---|
[3134] | 317 | if not len(points) == 2: |
---|
[6360] | 318 | msg = 'Single point must have two elements' |
---|
| 319 | raise ShapeError, msg |
---|
[3134] | 320 | #points = reshape(points, (1,2)) |
---|
[3071] | 321 | |
---|
[3134] | 322 | if not points.shape[1] == 2: |
---|
[6360] | 323 | msg = ('Input must be an N x 2 array or list of (x,y) values. ' |
---|
| 324 | 'I got an %d x %d array' % points.shape) |
---|
| 325 | raise ShapeError, msg |
---|
| 326 | |
---|
[3134] | 327 | # Add geo ref to points |
---|
[6304] | 328 | #if not self.is_absolute: |
---|
[3134] | 329 | if not self.is_absolute(): |
---|
[6360] | 330 | points[:,0] += self.xllcorner |
---|
[3134] | 331 | points[:,1] += self.yllcorner |
---|
[6304] | 332 | #self.is_absolute = True |
---|
[6360] | 333 | |
---|
| 334 | # if we got a list, return a list |
---|
[2488] | 335 | if is_list: |
---|
| 336 | points = points.tolist() |
---|
[6360] | 337 | |
---|
[2488] | 338 | return points |
---|
| 339 | |
---|
[6360] | 340 | ## |
---|
| 341 | # @brief Convert points to relative measurement. |
---|
| 342 | # @param points Points to convert to relative measurements. |
---|
| 343 | # @return A set of points relative to the geo_reference instance. |
---|
[5288] | 344 | def get_relative(self, points): |
---|
[6360] | 345 | """Given a set of points in absolute UTM coordinates, |
---|
[5288] | 346 | make them relative to this geo_reference instance, |
---|
| 347 | return the points as relative values. |
---|
| 348 | |
---|
| 349 | This is the inverse of get_absolute. |
---|
| 350 | """ |
---|
| 351 | |
---|
| 352 | is_list = False |
---|
| 353 | if type(points) == types.ListType: |
---|
| 354 | is_list = True |
---|
| 355 | |
---|
[6304] | 356 | points = ensure_numeric(points, num.float) |
---|
[5288] | 357 | if len(points.shape) == 1: |
---|
| 358 | #One point has been passed |
---|
| 359 | if not len(points) == 2: |
---|
[6360] | 360 | msg = 'Single point must have two elements' |
---|
| 361 | raise ShapeError, msg |
---|
[5288] | 362 | #points = reshape(points, (1,2)) |
---|
| 363 | |
---|
[6360] | 364 | if not points.shape[1] == 2: |
---|
| 365 | msg = ('Input must be an N x 2 array or list of (x,y) values. ' |
---|
| 366 | 'I got an %d x %d array' % points.shape) |
---|
| 367 | raise ShapeError, msg |
---|
[5288] | 368 | |
---|
| 369 | # Subtract geo ref from points |
---|
| 370 | if not self.is_absolute(): |
---|
[6360] | 371 | points[:,0] -= self.xllcorner |
---|
[5288] | 372 | points[:,1] -= self.yllcorner |
---|
| 373 | |
---|
[6360] | 374 | # if we got a list, return a list |
---|
[5288] | 375 | if is_list: |
---|
| 376 | points = points.tolist() |
---|
[6360] | 377 | |
---|
[5288] | 378 | return points |
---|
| 379 | |
---|
[6360] | 380 | ## |
---|
| 381 | # @brief ?? |
---|
| 382 | # @param other ?? |
---|
[2594] | 383 | def reconcile_zones(self, other): |
---|
[4180] | 384 | if other is None: |
---|
| 385 | other = Geo_reference() |
---|
[6360] | 386 | if (self.zone == other.zone or |
---|
| 387 | self.zone == DEFAULT_ZONE and |
---|
| 388 | other.zone == DEFAULT_ZONE): |
---|
[2594] | 389 | pass |
---|
| 390 | elif self.zone == DEFAULT_ZONE: |
---|
| 391 | self.zone = other.zone |
---|
| 392 | elif other.zone == DEFAULT_ZONE: |
---|
[6360] | 393 | other.zone = self.zone |
---|
| 394 | else: |
---|
| 395 | msg = ('Geospatial data must be in the same ' |
---|
| 396 | 'ZONE to allow reconciliation. I got zone %d and %d' |
---|
| 397 | % (self.zone, other.zone)) |
---|
[2608] | 398 | raise ANUGAError, msg |
---|
[6360] | 399 | |
---|
[2488] | 400 | #def easting_northing2geo_reffed_point(self, x, y): |
---|
| 401 | # return [x-self.xllcorner, y - self.xllcorner] |
---|
| 402 | |
---|
| 403 | #def easting_northing2geo_reffed_points(self, x, y): |
---|
| 404 | # return [x-self.xllcorner, y - self.xllcorner] |
---|
| 405 | |
---|
[6360] | 406 | ## |
---|
| 407 | # @brief Get origin of this geo_reference. |
---|
| 408 | # @return (zone, xllcorner, yllcorner). |
---|
[2488] | 409 | def get_origin(self): |
---|
| 410 | return (self.zone, self.xllcorner, self.yllcorner) |
---|
[6360] | 411 | |
---|
| 412 | ## |
---|
| 413 | # @brief Get a string representation of this geo_reference instance. |
---|
[2488] | 414 | def __repr__(self): |
---|
[6360] | 415 | return ('(zone=%i easting=%f, northing=%f)' |
---|
| 416 | % (self.zone, self.xllcorner, self.yllcorner)) |
---|
| 417 | |
---|
| 418 | ## |
---|
| 419 | # @brief Compare two geo_reference instances. |
---|
| 420 | # @param self This geo_reference instance. |
---|
| 421 | # @param other Another geo_reference instance to compare against. |
---|
| 422 | # @return 0 if instances have the same attributes, else 1. |
---|
| 423 | # @note Attributes are: zone, xllcorner, yllcorner. |
---|
| 424 | def __cmp__(self, other): |
---|
[2488] | 425 | # FIXME (DSG) add a tolerence |
---|
| 426 | if other is None: |
---|
| 427 | return 1 |
---|
| 428 | cmp = 0 |
---|
| 429 | if not (self.xllcorner == self.xllcorner): |
---|
| 430 | cmp = 1 |
---|
| 431 | if not (self.yllcorner == self.yllcorner): |
---|
| 432 | cmp = 1 |
---|
| 433 | if not (self.zone == self.zone): |
---|
| 434 | cmp = 1 |
---|
| 435 | return cmp |
---|
[4387] | 436 | |
---|
[6360] | 437 | |
---|
| 438 | ## |
---|
| 439 | # @brief Write a geo_reference to a NetCDF file (usually SWW). |
---|
| 440 | # @param origin A georef instance or parameters to create a georef instance. |
---|
| 441 | # @param outfile Path to file to write. |
---|
| 442 | # @return A normalized geo_reference. |
---|
[4387] | 443 | def write_NetCDF_georeference(origin, outfile): |
---|
[6360] | 444 | """Write georeference info to a netcdf file, usually sww. |
---|
[4387] | 445 | |
---|
[6360] | 446 | The origin can be a georef instance or parameters for a geo_ref instance |
---|
[4387] | 447 | |
---|
| 448 | outfile is the name of the file to be written to. |
---|
| 449 | """ |
---|
[6360] | 450 | |
---|
[4451] | 451 | geo_ref = ensure_geo_reference(origin) |
---|
| 452 | geo_ref.write_NetCDF(outfile) |
---|
| 453 | return geo_ref |
---|
| 454 | |
---|
[6360] | 455 | |
---|
| 456 | ## |
---|
| 457 | # @brief Convert an object to a georeference instance. |
---|
| 458 | # @param origin A georef instance or (zone, xllcorner, yllcorner) |
---|
| 459 | # @return A georef object, or None if 'origin' was None. |
---|
[4451] | 460 | def ensure_geo_reference(origin): |
---|
| 461 | """ |
---|
| 462 | Given a list/tuple of zone, xllcorner and yllcorner of a geo-ref object, |
---|
| 463 | return a geo ref object. |
---|
| 464 | |
---|
| 465 | If the origin is None, return None, so calling this function doesn't |
---|
| 466 | effect code logic |
---|
| 467 | """ |
---|
[6360] | 468 | |
---|
| 469 | if isinstance(origin, Geo_reference): |
---|
[4387] | 470 | geo_ref = origin |
---|
[4451] | 471 | elif origin is None: |
---|
| 472 | geo_ref = None |
---|
[4387] | 473 | else: |
---|
[6360] | 474 | geo_ref = apply(Geo_reference, origin) |
---|
| 475 | |
---|
[4387] | 476 | return geo_ref |
---|
[4451] | 477 | |
---|
[6360] | 478 | |
---|
[2488] | 479 | #----------------------------------------------------------------------- |
---|
| 480 | |
---|
| 481 | if __name__ == "__main__": |
---|
| 482 | pass |
---|