Exemplo n.º 1
0
 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)
Exemplo n.º 2
0
 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)
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
    def getxyz(self, lat, lon, alt):
        """
        Given latitude, longitude, and altitude location data, convert them
        to (x, y, z) Cartesian coordinates based on the configured
        reference point and scale. Lat/lon is converted to UTM meter
        coordinates, UTM zones are accounted for, and the scale turns
        meters to pixels.

        :param lat: latitude
        :param lon: longitude
        :param alt: altitude
        :return: converted x, y, z coordinates
        :rtype: tuple
        """
        # convert lat/lon to UTM coordinates in meters
        e, n, zonen, zonel = utm.from_latlon(lat, lon)
        _rlat, _rlon, ralt = self.refgeo
        xshift = self.geteastingshift(zonen, zonel)
        if xshift is None:
            xm = e - self.refutm[1]
        else:
            xm = e + xshift
        yshift = self.getnorthingshift(zonen, zonel)
        if yshift is None:
            ym = n - self.refutm[2]
        else:
            ym = n + yshift
        zm = alt - ralt

        # shift (x,y,z) over to reference point (x,y,z)
        x = self.m2px(xm) + self.refxyz[0]
        y = -(self.m2px(ym) + self.refxyz[1])
        z = self.m2px(zm) + self.refxyz[2]
        return x, y, z
Exemplo n.º 5
0
 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
Exemplo n.º 6
0
 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
Exemplo n.º 7
0
 def getxyz(self, lat, lon, alt):
     ''' Given latitude, longitude, and altitude location data, convert them
         to (x, y, z) Cartesian coordinates based on the configured
         reference point and scale. Lat/lon is converted to UTM meter
         coordinates, UTM zones are accounted for, and the scale turns
         meters to pixels.
     '''
     # convert lat/lon to UTM coordinates in meters
     (e, n, zonen, zonel) = utm.from_latlon(lat, lon)
     (rlat, rlon, ralt) = self.refgeo
     xshift = self.geteastingshift(zonen, zonel)
     if xshift is None:
         xm = e - self.refutm[1]
     else:
         xm = e + xshift
     yshift = self.getnorthingshift(zonen, zonel)
     if yshift is None:
         ym = n - self.refutm[2]
     else:
         ym = n + yshift
     zm = alt - ralt
     
     # shift (x,y,z) over to reference point (x,y,z)
     x = self.m2px(xm) + self.refxyz[0]
     y = -(self.m2px(ym) + self.refxyz[1])
     z = self.m2px(zm) + self.refxyz[2]
     return (x, y, z)
Exemplo n.º 8
0
    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
Exemplo n.º 9
0
    def getxyz(self, lat, lon, alt):
        ''' Given latitude, longitude, and altitude location data, convert them
            to (x, y, z) Cartesian coordinates based on the configured
            reference point and scale. Lat/lon is converted to UTM meter
            coordinates, UTM zones are accounted for, and the scale turns
            meters to pixels.
        '''
        # convert lat/lon to UTM coordinates in meters
        (e, n, zonen, zonel) = utm.from_latlon(lat, lon)
        (rlat, rlon, ralt) = self.refgeo
        xshift = self.geteastingshift(zonen, zonel)
        if xshift is None:
            xm = e - self.refutm[1]
        else:
            xm = e + xshift
        yshift = self.getnorthingshift(zonen, zonel)
        if yshift is None:
            ym = n - self.refutm[2]
        else:
            ym = n + yshift
        zm = alt - ralt

        # shift (x,y,z) over to reference point (x,y,z)
        x = self.m2px(xm) + self.refxyz[0]
        y = -(self.m2px(ym) + self.refxyz[1])
        z = self.m2px(zm) + self.refxyz[2]
        #return (x, y, z)
        #Note: For some reason the coordinate conversion seems to be off
        #for the y axix by an amount that depends on the refgeo. No idea why.
        return (x, y + 3, z)
Exemplo n.º 10
0
 def setrefgeo(self, lat, lon, alt):
     ''' Record the geographical reference point decimal (lat, lon, alt)
         and convert and store its UTM equivalent for later use.
     '''
     self.refgeo = (lat, lon, alt)
     # easting, northing, zone
     (e, n, zonen, zonel) = utm.from_latlon(lat, lon)
     self.refutm = ( (zonen, zonel), e, n, alt)
Exemplo n.º 11
0
 def setrefgeo(self, lat, lon, alt):
     ''' Record the geographical reference point decimal (lat, lon, alt)
         and convert and store its UTM equivalent for later use.
     '''
     self.refgeo = (lat, lon, alt)
     # easting, northing, zone
     (e, n, zonen, zonel) = utm.from_latlon(lat, lon)
     self.refutm = ((zonen, zonel), e, n, alt)
Exemplo n.º 12
0
    def setrefgeo(self, lat, lon, alt):
        """
        Record the geographical reference point decimal (lat, lon, alt)
        and convert and store its UTM equivalent for later use.

        :param lat: latitude
        :param lon: longitude
        :param alt: altitude
        :return: nothing
        """
        self.refgeo = (lat, lon, alt)
        # easting, northing, zone
        e, n, zonen, zonel = utm.from_latlon(lat, lon)
        self.refutm = ((zonen, zonel), e, n, alt)
Exemplo n.º 13
0
    def setrefgeo(self, lat, lon, alt):
        """
        Record the geographical reference point decimal (lat, lon, alt)
        and convert and store its UTM equivalent for later use.

        :param lat: latitude
        :param lon: longitude
        :param alt: altitude
        :return: nothing
        """
        self.refgeo = (lat, lon, alt)
        # easting, northing, zone
        e, n, zonen, zonel = utm.from_latlon(lat, lon)
        self.refutm = ((zonen, zonel), e, n, alt)