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