def getutmzoneshift(self, e, n): ''' Given UTM easting and northing values, check if they fall outside the reference point's zone boundary. Return the UTM coordinates in a different zone and the new zone if they do. Zone lettering is only changed when the reference point is in the opposite hemisphere. ''' zone = self.refutm[0] (rlat, rlon, ralt) = self.refgeo if e > 834000 or e < 166000: num_zones = (int(e) - 166000) / (utm.R/10) # estimate number of zones to shift, E (positive) or W (negative) rlon2 = self.refgeo[1] + (num_zones * 6) (e2, n2, zonen2, zonel2) = utm.from_latlon(rlat, rlon2) xshift = utm.haversine(rlon, rlat, rlon2, rlat) # after >3 zones away from refpt, the above estimate won't work # (the above estimate could be improved) if not 100000 <= (e - xshift) < 1000000: # move one more zone away num_zones = (abs(num_zones)+1) * (abs(num_zones)/num_zones) rlon2 = self.refgeo[1] + (num_zones * 6) (e2, n2, zonen2, zonel2) = utm.from_latlon(rlat, rlon2) xshift = utm.haversine(rlon, rlat, rlon2, rlat) e = e - xshift zone = (zonen2, zonel2) if n < 0: # refpt in northern hemisphere and we crossed south of equator n += 10000000 zone = (zone[0], 'M') elif n > 10000000: # refpt in southern hemisphere and we crossed north of equator n -= 10000000 zone = (zone[0], 'N') return (e, n, zone)
def getutmzoneshift(self, e, n): ''' Given UTM easting and northing values, check if they fall outside the reference point's zone boundary. Return the UTM coordinates in a different zone and the new zone if they do. Zone lettering is only changed when the reference point is in the opposite hemisphere. ''' zone = self.refutm[0] (rlat, rlon, ralt) = self.refgeo if e > 834000 or e < 166000: num_zones = (int(e) - 166000) / (utm.R / 10) # estimate number of zones to shift, E (positive) or W (negative) rlon2 = self.refgeo[1] + (num_zones * 6) (e2, n2, zonen2, zonel2) = utm.from_latlon(rlat, rlon2) xshift = utm.haversine(rlon, rlat, rlon2, rlat) # after >3 zones away from refpt, the above estimate won't work # (the above estimate could be improved) if not 100000 <= (e - xshift) < 1000000: # move one more zone away num_zones = (abs(num_zones) + 1) * (abs(num_zones) / num_zones) rlon2 = self.refgeo[1] + (num_zones * 6) (e2, n2, zonen2, zonel2) = utm.from_latlon(rlat, rlon2) xshift = utm.haversine(rlon, rlat, rlon2, rlat) e = e - xshift zone = (zonen2, zonel2) if n < 0: # refpt in northern hemisphere and we crossed south of equator n += 10000000 zone = (zone[0], 'M') elif n > 10000000: # refpt in southern hemisphere and we crossed north of equator n -= 10000000 zone = (zone[0], 'N') return (e, n, zone)
def geteastingshift(self, zonen, zonel): """ If the lat, lon coordinates being converted are located in a different UTM zone than the canvas reference point, the UTM meters may need to be shifted. This picks a reference point in the same longitudinal band (UTM zone number) as the provided zone, to calculate the shift in meters for the x coordinate. :param zonen: zonen :param zonel: zone1 :return: the x shift value """ rzonen = int(self.refutm[0][0]) # same zone number, no x shift required if zonen == rzonen: return None z = (zonen, zonel) # x shift already calculated, cached if z in self.zoneshifts and self.zoneshifts[z][0] is not None: return self.zoneshifts[z][0] rlat, rlon, _ralt = self.refgeo # ea. zone is 6deg band lon2 = rlon + 6 * (zonen - rzonen) # ignore northing e2, _n2, _zonen2, _zonel2 = utm.from_latlon(rlat, lon2) # NOTE: great circle distance used here, not reference ellipsoid! xshift = utm.haversine(rlon, rlat, lon2, rlat) - e2 # cache the return value yshift = None if z in self.zoneshifts: yshift = self.zoneshifts[z][1] self.zoneshifts[z] = (xshift, yshift) return xshift
def getnorthingshift(self, zonen, zonel): ''' If the lat, lon coordinates being converted are located in a different UTM zone than the canvas reference point, the UTM meters may need to be shifted. This picks a reference point in the same latitude band (UTM zone letter) as the provided zone, to calculate the shift in meters for the y coordinate. ''' rzonel = self.refutm[0][1] if zonel == rzonel: return None # same zone letter, no y shift required z = (zonen, zonel) if z in self.zoneshifts and self.zoneshifts[z][1] is not None: return self.zoneshifts[z][1] # y shift already calculated, cached (rlat, rlon, ralt) = self.refgeo # zonemap is used to calculate degrees difference between zone letters latshift = self.zonemap[zonel] - self.zonemap[rzonel] lat2 = rlat + latshift # ea. latitude band is 8deg high (e2, n2, zonen2, zonel2) = utm.from_latlon(lat2, rlon) # NOTE: great circle distance used here, not reference ellipsoid yshift = -(utm.haversine(rlon, rlat, rlon, lat2) + n2) # cache the return value xshift = None if z in self.zoneshifts: xshift = self.zoneshifts[z][0] self.zoneshifts[z] = (xshift, yshift) return yshift
def geteastingshift(self, zonen, zonel): ''' If the lat, lon coordinates being converted are located in a different UTM zone than the canvas reference point, the UTM meters may need to be shifted. This picks a reference point in the same longitudinal band (UTM zone number) as the provided zone, to calculate the shift in meters for the x coordinate. ''' rzonen = int(self.refutm[0][0]) if zonen == rzonen: return None # same zone number, no x shift required z = (zonen, zonel) if z in self.zoneshifts and self.zoneshifts[z][0] is not None: return self.zoneshifts[z][0] # x shift already calculated, cached (rlat, rlon, ralt) = self.refgeo lon2 = rlon + 6*(zonen - rzonen) # ea. zone is 6deg band (e2, n2, zonen2, zonel2) = utm.from_latlon(rlat, lon2) # ignore northing # NOTE: great circle distance used here, not reference ellipsoid! xshift = utm.haversine(rlon, rlat, lon2, rlat) - e2 # cache the return value yshift = None if z in self.zoneshifts: yshift = self.zoneshifts[z][1] self.zoneshifts[z] = (xshift, yshift) return xshift