[2488] | 1 | """ |
---|
| 2 | """ |
---|
| 3 | |
---|
| 4 | |
---|
| 5 | #FIXME: Ensure that all attributes of a georef are treated everywhere |
---|
| 6 | #and unit test |
---|
| 7 | |
---|
| 8 | import types |
---|
[2608] | 9 | from numpy import array, Float, ArrayType |
---|
[2488] | 10 | |
---|
[2608] | 11 | |
---|
[2488] | 12 | DEFAULT_ZONE = 56 |
---|
| 13 | TITLE = '#geo reference' + "\n" #this title is referred to in the .xya format |
---|
| 14 | |
---|
| 15 | class Geo_reference: |
---|
| 16 | """ |
---|
| 17 | """ |
---|
| 18 | |
---|
| 19 | def __init__(self, |
---|
| 20 | zone = DEFAULT_ZONE, |
---|
| 21 | xllcorner = 0.0, |
---|
| 22 | yllcorner = 0.0, |
---|
| 23 | datum = 'wgs84', |
---|
| 24 | projection = 'UTM', units = 'm', |
---|
| 25 | false_easting = 500000, |
---|
| 26 | false_northing = 10000000, #Default for southern hemisphere |
---|
| 27 | NetCDFObject=None, |
---|
| 28 | ASCIIFile=None, |
---|
| 29 | read_title=None): |
---|
| 30 | """ |
---|
| 31 | input: |
---|
| 32 | NetCDFObject - a handle to the netCDF file to be written to |
---|
| 33 | ASCIIFile - a handle to the text file |
---|
| 34 | read_title - the title of the georeference text, if it was read in. |
---|
| 35 | """ |
---|
| 36 | |
---|
| 37 | self.false_easting = false_easting |
---|
| 38 | self.false_northing = false_northing |
---|
| 39 | self.datum = datum |
---|
| 40 | self.projection = projection |
---|
| 41 | self.zone = zone |
---|
| 42 | self.units = units |
---|
| 43 | self.xllcorner = xllcorner |
---|
| 44 | self.yllcorner = yllcorner |
---|
| 45 | |
---|
| 46 | if NetCDFObject is not None: |
---|
| 47 | self.read_NetCDF(NetCDFObject) |
---|
| 48 | |
---|
| 49 | if ASCIIFile is not None: |
---|
| 50 | self.read_ASCII(ASCIIFile, read_title=read_title) |
---|
| 51 | |
---|
| 52 | def get_xllcorner(self): |
---|
| 53 | return self.xllcorner |
---|
| 54 | |
---|
| 55 | def get_yllcorner(self): |
---|
| 56 | return self.yllcorner |
---|
| 57 | |
---|
| 58 | def get_zone(self): |
---|
| 59 | return self.zone |
---|
| 60 | |
---|
| 61 | def write_NetCDF(self, outfile): |
---|
| 62 | outfile.xllcorner = self.xllcorner |
---|
| 63 | outfile.yllcorner = self.yllcorner |
---|
| 64 | outfile.zone = self.zone |
---|
| 65 | |
---|
| 66 | outfile.false_easting = self.false_easting |
---|
| 67 | outfile.false_northing = self.false_northing |
---|
| 68 | |
---|
| 69 | outfile.datum = self.datum |
---|
| 70 | outfile.projection = self.projection |
---|
| 71 | outfile.units = self.units |
---|
| 72 | |
---|
| 73 | def read_NetCDF(self, infile): |
---|
| 74 | self.xllcorner = infile.xllcorner[0] |
---|
| 75 | self.yllcorner = infile.yllcorner[0] |
---|
| 76 | self.zone = infile.zone[0] |
---|
| 77 | |
---|
| 78 | # Fix some assertion failures |
---|
| 79 | if type(self.zone) == ArrayType and self.zone.shape == (): |
---|
| 80 | self.zone = self.zone[0] |
---|
| 81 | if type(self.xllcorner) == ArrayType and self.xllcorner.shape == (): |
---|
| 82 | self.xllcorner = self.xllcorner[0] |
---|
| 83 | if type(self.yllcorner) == ArrayType and self.yllcorner.shape == (): |
---|
| 84 | self.yllcorner = self.yllcorner[0] |
---|
| 85 | |
---|
| 86 | assert (type(self.xllcorner) == types.FloatType or\ |
---|
| 87 | type(self.xllcorner) == types.IntType) |
---|
| 88 | assert (type(self.yllcorner) == types.FloatType or\ |
---|
| 89 | type(self.yllcorner) == types.IntType) |
---|
| 90 | assert (type(self.zone) == types.IntType) |
---|
| 91 | |
---|
| 92 | #FIXME (Ole) Read in the rest... |
---|
| 93 | |
---|
| 94 | |
---|
| 95 | def write_ASCII(self, fd): |
---|
| 96 | fd.write(TITLE) |
---|
| 97 | fd.write(str(self.zone) + "\n") |
---|
| 98 | fd.write(str(self.xllcorner) + "\n") |
---|
| 99 | fd.write(str(self.yllcorner) + "\n") |
---|
| 100 | |
---|
| 101 | def read_ASCII(self, fd,read_title=None): |
---|
| 102 | if read_title == None: |
---|
| 103 | read_title = fd.readline() # remove the title line |
---|
| 104 | #print "gr read_title[0:2].upper()",read_title[0:2].upper() |
---|
| 105 | #print "gr TITLE[0:2].upper()",TITLE[0:2].upper() |
---|
| 106 | if read_title[0:2].upper() != TITLE[0:2].upper(): |
---|
| 107 | raise SyntaxError |
---|
| 108 | self.zone = int(fd.readline()) |
---|
| 109 | self.xllcorner = float(fd.readline()) |
---|
| 110 | self.yllcorner = float(fd.readline()) |
---|
| 111 | |
---|
| 112 | # Fix some assertion failures |
---|
| 113 | if(type(self.zone) == ArrayType and self.zone.shape == ()): |
---|
| 114 | self.zone = self.zone[0] |
---|
| 115 | if type(self.xllcorner) == ArrayType and self.xllcorner.shape == (): |
---|
| 116 | self.xllcorner = self.xllcorner[0] |
---|
| 117 | if type(self.yllcorner) == ArrayType and self.yllcorner.shape == (): |
---|
| 118 | self.yllcorner = self.yllcorner[0] |
---|
| 119 | |
---|
| 120 | assert (type(self.xllcorner) == types.FloatType) |
---|
| 121 | assert (type(self.yllcorner) == types.FloatType) |
---|
| 122 | assert (type(self.zone) == types.IntType) |
---|
| 123 | |
---|
| 124 | #false_easting = infile.false_easting[0] |
---|
| 125 | #false_northing = infile.false_northing[0] |
---|
| 126 | |
---|
| 127 | def change_points_geo_ref(self, points, |
---|
| 128 | points_geo_ref=None): |
---|
| 129 | """ |
---|
| 130 | Change the geo reference of a list or Numeric array of points to |
---|
| 131 | be this reference.(The reference used for this object) |
---|
| 132 | If the points do not have a geo ref, assume 'absolute' values |
---|
| 133 | """ |
---|
| 134 | |
---|
| 135 | is_list = False |
---|
| 136 | if type(points) == types.ListType: |
---|
| 137 | is_list = True |
---|
| 138 | if len(points)>0 and type(points[0]) not in [types.ListType,types.TupleType]: |
---|
| 139 | #a single point is being passed. make it a list of lists |
---|
| 140 | points = [points] |
---|
| 141 | elif type(points) == ArrayType: |
---|
| 142 | if len(points.shape) == 1: |
---|
| 143 | points = [points] |
---|
| 144 | |
---|
| 145 | # FIXME: currently untested |
---|
| 146 | # Always returns a list of lists |
---|
| 147 | if points_geo_ref is self: |
---|
| 148 | return points |
---|
| 149 | |
---|
| 150 | #convert into array |
---|
| 151 | points = array(points).astype(Float) |
---|
| 152 | #add point geo ref to points |
---|
| 153 | if not points_geo_ref is None: |
---|
| 154 | points[:,0] += points_geo_ref.xllcorner |
---|
| 155 | points[:,1] += points_geo_ref.yllcorner |
---|
| 156 | |
---|
| 157 | #subtract primary geo ref from points |
---|
| 158 | points[:,0] -= self.xllcorner |
---|
| 159 | points[:,1] -= self.yllcorner |
---|
| 160 | if is_list: |
---|
| 161 | points = points.tolist() |
---|
| 162 | return points |
---|
| 163 | |
---|
| 164 | def get_absolute(self, points): |
---|
| 165 | """ |
---|
| 166 | Given a set of points geo referenced to this instance, |
---|
| 167 | return the points as absolute values. |
---|
| 168 | """ |
---|
| 169 | |
---|
| 170 | is_list = False |
---|
| 171 | if type(points) == types.ListType: |
---|
| 172 | is_list = True |
---|
| 173 | if len(points)>0 and type(points[0]) \ |
---|
| 174 | not in [types.ListType,types.TupleType]: |
---|
| 175 | #a single point is being passed. make it a list of lists |
---|
| 176 | points = [points] |
---|
| 177 | elif type(points) == ArrayType: |
---|
| 178 | if len(points.shape) == 1: |
---|
| 179 | points = [points] |
---|
| 180 | |
---|
| 181 | # convert into array |
---|
| 182 | points = array(points).astype(Float) |
---|
| 183 | # add primary geo ref from points |
---|
| 184 | points[:,0] += self.xllcorner |
---|
| 185 | points[:,1] += self.yllcorner |
---|
| 186 | if is_list: |
---|
| 187 | points = points.tolist() |
---|
| 188 | |
---|
| 189 | return points |
---|
| 190 | |
---|
| 191 | |
---|
| 192 | #def easting_northing2geo_reffed_point(self, x, y): |
---|
| 193 | # return [x-self.xllcorner, y - self.xllcorner] |
---|
| 194 | |
---|
| 195 | #def easting_northing2geo_reffed_points(self, x, y): |
---|
| 196 | # return [x-self.xllcorner, y - self.xllcorner] |
---|
| 197 | |
---|
| 198 | def get_origin(self): |
---|
| 199 | return (self.zone, self.xllcorner, self.yllcorner) |
---|
| 200 | |
---|
| 201 | def __repr__(self): |
---|
| 202 | return "(zone=%i easting=%f, northing=%f)" %(self.zone, self.xllcorner, self.yllcorner) |
---|
| 203 | |
---|
| 204 | def __cmp__(self,other): |
---|
| 205 | # FIXME (DSG) add a tolerence |
---|
| 206 | if other is None: |
---|
| 207 | return 1 |
---|
| 208 | cmp = 0 |
---|
| 209 | if not (self.xllcorner == self.xllcorner): |
---|
| 210 | cmp = 1 |
---|
| 211 | if not (self.yllcorner == self.yllcorner): |
---|
| 212 | cmp = 1 |
---|
| 213 | if not (self.zone == self.zone): |
---|
| 214 | cmp = 1 |
---|
| 215 | return cmp |
---|
| 216 | |
---|
| 217 | #----------------------------------------------------------------------- |
---|
| 218 | |
---|
| 219 | if __name__ == "__main__": |
---|
| 220 | pass |
---|