Пример #1
0
def check_valid_zone(zone_number, zone_letter):
    if not 1 <= zone_number <= 60:
        raise OutOfRangeError('zone number out of range (must be between 1 and 60)')

    if zone_letter:
        zone_letter = zone_letter.upper()

        if not 'C' <= zone_letter <= 'X' or zone_letter in ['I', 'O']:
            raise OutOfRangeError('zone letter out of range (must be between C and X)')
Пример #2
0
def from_latlon(latitude, longitude, force_zone_number=None):
    if not -80.0 <= latitude <= 84.0:
        raise OutOfRangeError(
            'latitude out of range (must be between 80 deg S and 84 deg N)')
    if not -180.0 <= longitude <= 180.0:
        raise OutOfRangeError(
            'longitude out of range (must be between 180 deg W and 180 deg E)')

    lat_rad = math.radians(latitude)
    lat_sin = math.sin(lat_rad)
    lat_cos = math.cos(lat_rad)

    lat_tan = lat_sin / lat_cos
    lat_tan2 = lat_tan * lat_tan
    lat_tan4 = lat_tan2 * lat_tan2

    if force_zone_number is None:
        zone_number = latlon_to_zone_number(latitude, longitude)
    else:
        zone_number = force_zone_number

    zone_letter = latitude_to_zone_letter(latitude)

    lon_rad = math.radians(longitude)
    central_lon = zone_number_to_central_longitude(zone_number)
    central_lon_rad = math.radians(central_lon)

    n = R / math.sqrt(1 - E * lat_sin**2)
    c = E_P2 * lat_cos**2

    a = lat_cos * (lon_rad - central_lon_rad)
    a2 = a * a
    a3 = a2 * a
    a4 = a3 * a
    a5 = a4 * a
    a6 = a5 * a

    m = R * (M1 * lat_rad - M2 * math.sin(2 * lat_rad) +
             M3 * math.sin(4 * lat_rad) - M4 * math.sin(6 * lat_rad))

    easting = K0 * n * (
        a + a3 / 6 * (1 - lat_tan2 + c) + a5 / 120 *
        (5 - 18 * lat_tan2 + lat_tan4 + 72 * c - 58 * E_P2)) + 500000

    northing = K0 * (m + n * lat_tan *
                     (a2 / 2 + a4 / 24 *
                      (5 - lat_tan2 + 9 * c + 4 * c**2) + a6 / 720 *
                      (61 - 58 * lat_tan2 + lat_tan4 + 600 * c - 330 * E_P2)))

    if latitude < 0:
        northing += 10000000

    return easting, northing, zone_number, zone_letter
Пример #3
0
def lon_lat_to_utm(lat, lon):
    ''' Function converts from any [Lat, Long] to [East, North, Grid]
    >>> lon_lat_to_utm(50.084522, -5.699057)
    ['30U 306918.367 5551517.614', 306918.367, 5551517.614]
    >>> lon_lat_to_utm('50 05.0713061 N', '005 41.9434092 W')
    ['30U 306918.379 5551517.588', 306918.379, 5551517.588]
    >>> lon_lat_to_utm(50.0845217683, -5.69905682)
    ['30U 306918.379 5551517.588', 306918.379, 5551517.588]
    
    '''
    # Convert from strings if required.
    if type(lat) == str:
        lat = deg_min_str_to_dec(lat)
    if type(lon) == str:
        long = deg_min_str_to_dec(lon)

    # Check if correct range
    if not -80.0 <= lat <= 84.0:
        raise OutOfRangeError(
            'latitude out of range (must be between 80 deg S and 84 deg N)')
    if not -180.0 <= lon <= 180.0:
        raise OutOfRangeError(
            'longditude out of range (must be between 180 deg W and 180 deg E)'
        )

    utm_pos = utm.from_latlon(lat, lon)
    #    print('my utm postition from the function: {} with Lat: {} and Long: {} as input'.format(utmPos, Lat, Long))
    # Google Earth does not accept this format. Translation for Google Earth:
    east = '%.3f' % (utm_pos[0])
    north = '%.3f' % (utm_pos[1])
    grid1 = str(utm_pos[2])
    grid2 = str(utm_pos[3])
    google_earth = (grid1 + grid2 + ' ' + east + ' ' + north)

    # returns Google Earth format and Easting and Northing as float
    return [google_earth, float(east), float(north)]
Пример #4
0
def to_latlon(easting,
              northing,
              zone_number,
              zone_letter=None,
              northern=None,
              force_longitude=False,
              coords=None):
    """
    Convert UTM coordinates to latitude-longitude, courtesy of Tobias Bieniek, 2012 (with some
    minor edits).

    :arg easting: eastward-measured Cartesian geographic distance.
    :arg northing: northward-measured Cartesian geographic distance.
    :arg zone_number: UTM zone number (increasing eastward).
    :param zone_letter: UTM zone letter (increasing alphabetically northward).
    :param northern: specify northern or southern hemisphere.
    :param coords: coordinate field of mesh (used to check validity of coordinates).
    :return: latitude-longitude coordinate pair.
    """
    if not zone_letter and northern is None:
        raise ValueError('either zone_letter or northern needs to be set')

    elif zone_letter and northern is not None:
        raise ValueError('set either zone_letter or northern, but not both')

    if not force_longitude:
        if not 100000 <= easting < 1000000:
            raise OutOfRangeError(
                'easting {:f} out of range (must be between 100,000 m and 999,999 m)'
                .format(easting))

    msg = 'northing out of range (must be between 0 m and 10,000,000 m)'
    if isinstance(northing, ufl.indexed.Indexed):
        from firedrake import sin, cos, sqrt
        if coords is None:
            if os.environ.get('WARNINGS', '0') != '0':
                print_output("WARNING: Cannot check validity of coordinates.")
        else:
            minval, maxval = coords.dat.data[:, 1].min(
            ), coords.dat.data[:, 1].max()
            if not (0 <= minval and maxval <= 10000000):
                raise OutOfRangeError(msg)
    elif isinstance(northing, np.ndarray):
        from numpy import sin, cos, sqrt
        minval, maxval = northing.min(), northing.max()
        if not (0 <= minval and maxval <= 10000000):
            raise OutOfRangeError(msg)
    else:
        from math import sin, cos, sqrt
        if not 0 <= northing <= 10000000:
            raise OutOfRangeError(msg)
    if not 1 <= zone_number <= 60:
        raise OutOfRangeError(
            'zone number out of range (must be between 1 and 60)')

    if zone_letter:
        zone_letter = zone_letter.upper()

        if not 'C' <= zone_letter <= 'X' or zone_letter in ['I', 'O']:
            raise OutOfRangeError(
                'zone letter out of range (must be between C and X)')

        northern = zone_letter >= 'N'

    x = easting - 500000
    y = northing

    if not northern:
        y -= 10000000

    m = y / K0
    mu = m / R / M1

    p_rad = (mu + P2 * sin(2 * mu) + P3 * sin(4 * mu) + P4 * sin(6 * mu) +
             P5 * sin(8 * mu))

    p_sin = sin(p_rad)
    p_sin2 = p_sin * p_sin

    p_cos = cos(p_rad)

    p_tan = p_sin / p_cos
    p_tan2 = p_tan * p_tan
    p_tan4 = p_tan2 * p_tan2

    ep_sin = 1 - E * p_sin2
    ep_sin_sqrt = sqrt(1 - E * p_sin2)

    n = R / ep_sin_sqrt
    r = (1 - E) / ep_sin

    c = _E * p_cos**2
    c2 = c * c

    d = x / n / K0
    d2 = d * d
    d3 = d2 * d
    d4 = d3 * d
    d5 = d4 * d
    d6 = d5 * d

    latitude = (
        p_rad - p_tan / r * (d2 / 2 - d4 / 24 *
                             (5 + 3 * p_tan2 + 10 * c - 4 * c2 - 9 * E_P2)) +
        d6 / 720 *
        (61 + 90 * p_tan2 + 298 * c + 45 * p_tan4 - 252 * E_P2 - 3 * c2))

    longitude = (
        d - d3 / 6 * (1 + 2 * p_tan2 + c) + d5 / 120 *
        (5 - 2 * c + 28 * p_tan2 - 3 * c2 + 8 * E_P2 + 24 * p_tan4)) / p_cos

    return degrees(latitude), degrees(
        longitude) + zone_number_to_central_longitude(zone_number)
Пример #5
0
def from_latlon(latitude,
                longitude,
                force_zone_number=None,
                zone_info=False,
                coords=None):
    """
    Convert latitude-longitude coordinates to UTM, courtesy of Tobias Bieniek, 2012.

    :arg latitude: northward anglular position, origin at the Equator.
    :arg longitude: eastward angular position, with origin at the Greenwich Meridian.
    :param force_zone_number: force coordinates to fall within a particular UTM zone.
    :param zone_info: output zone letter and number.
    :param coords: coordinate field of mesh (used to check validity of coordinates).
    :return: UTM coordinate 4-tuple.
    """
    lat_msg = 'latitude out of range (must be between 80 deg S and 84 deg N)'
    lon_msg = 'longitude out of range (must be between 180 deg W and 180 deg E)'
    if isinstance(latitude, ufl.indexed.Indexed):
        from firedrake import sin, cos, sqrt
        if coords is None:
            if os.environ.get('WARNINGS', '0') != '0':
                print_output("WARNING: Cannot check validity of coordinates.")
        else:
            minval, maxval = coords.dat.data[:, 0].min(
            ), coords.dat.data[:, 0].max()
            if not (-80.0 <= minval and maxval <= 84.0):
                raise OutOfRangeError(lon_msg)
            minval, maxval = coords.dat.data[:, 1].min(
            ), coords.dat.data[:, 1].max()
            if not (-180.0 <= minval and maxval <= 180.0):
                raise OutOfRangeError(lat_msg)
    elif isinstance(latitude, np.ndarray):
        from numpy import sin, cos, sqrt
        minval, maxval = longitude.min(), longitude.max()
        if not (-180.0 <= minval and maxval <= 180.0):
            raise OutOfRangeError(lon_msg)
        minval, maxval = latitude.min(), latitude.max()
        if not (-80.0 <= minval and maxval <= 84.0):
            raise OutOfRangeError(lat_msg)
    else:
        from math import sin, cos, sqrt
        if not -180.0 <= longitude <= 180.0:
            raise OutOfRangeError(lon_msg)
        if not -80.0 <= latitude <= 84.0:
            raise OutOfRangeError(lat_msg)

    lat_rad = radians(latitude)
    lat_sin = sin(lat_rad)
    lat_cos = cos(lat_rad)

    lat_tan = lat_sin / lat_cos
    lat_tan2 = lat_tan * lat_tan
    lat_tan4 = lat_tan2 * lat_tan2

    if force_zone_number is None:
        zone_number = latlon_to_zone_number(latitude, longitude)
    else:
        zone_number = force_zone_number

    lon_rad = radians(longitude)
    central_lon_rad = radians(zone_number_to_central_longitude(zone_number))

    n = R / sqrt(1 - E * lat_sin**2)
    c = E_P2 * lat_cos**2

    a = lat_cos * (lon_rad - central_lon_rad)
    a2 = a * a
    a3 = a2 * a
    a4 = a3 * a
    a5 = a4 * a
    a6 = a5 * a

    m = R * (M1 * lat_rad - M2 * sin(2 * lat_rad) + M3 * sin(4 * lat_rad) -
             M4 * sin(6 * lat_rad))

    easting = K0 * n * (
        a + a3 / 6 * (1 - lat_tan2 + c) + a5 / 120 *
        (5 - 18 * lat_tan2 + lat_tan4 + 72 * c - 58 * E_P2)) + 500000

    northing = K0 * (m + n * lat_tan *
                     (a2 / 2 + a4 / 24 *
                      (5 - lat_tan2 + 9 * c + 4 * c**2) + a6 / 720 *
                      (61 - 58 * lat_tan2 + lat_tan4 + 600 * c - 330 * E_P2)))

    if isinstance(latitude, ufl.indexed.Indexed):
        if coords.dat.data[:, 1].min() < 0:
            northing += 10000000
    elif isinstance(latitude, np.ndarray):
        if latitude.min() < 0:
            northing += 10000000
    else:
        if latitude < 0:
            northing += 10000000

    if zone_info:
        return easting, northing, zone_number, latitude_to_zone_letter(
            latitude)
    else:
        return easting, northing
Пример #6
0
def to_latlon(easting,
              northing,
              zone_number,
              zone_letter=None,
              northern=None,
              strict=True):
    """This function converts UTM coordinates to Latitude and Longitude

        Parameters
        ----------
        easting: int or NumPy array
            Easting value of UTM coordinates

        northing: int or NumPy array
            Northing value of UTM coordinates

        zone_number: int
            Zone number is represented with global map numbers of a UTM zone
            numbers map. For more information see utmzones [1]_

        zone_letter: str
            Zone letter can be represented as string values.  UTM zone
            designators can be seen in [1]_

        northern: bool
            You can set True or False to set this parameter. Default is None

        strict: bool
            Raise an OutOfRangeError if outside of bounds

        Returns
        -------
        latitude: float or NumPy array
            Latitude between 80 deg S and 84 deg N, e.g. (-80.0 to 84.0)

        longitude: float or NumPy array
            Longitude between 180 deg W and 180 deg E, e.g. (-180.0 to 180.0).


       .. _[1]: http://www.jaworski.ca/utmzones.htm

    """
    if not zone_letter and northern is None:
        raise ValueError('either zone_letter or northern needs to be set')

    elif zone_letter and northern is not None:
        raise ValueError('set either zone_letter or northern, but not both')

    if strict:
        if not in_bounds(easting, 100000, 1000000, upper_strict=True):
            raise OutOfRangeError(
                'easting out of range (must be between 100,000 m and 999,999 m)'
            )
        if not in_bounds(northing, 0, 10000000):
            raise OutOfRangeError(
                'northing out of range (must be between 0 m and 10,000,000 m)')

    check_valid_zone(zone_number, zone_letter)

    if zone_letter:
        zone_letter = zone_letter.upper()
        northern = (zone_letter >= 'N')

    x = easting - 500000
    y = northing

    if not northern:
        y -= 10000000

    m = y / K0
    mu = m / (R * M1)

    p_rad = (mu + P2 * mathlib.sin(2 * mu) + P3 * mathlib.sin(4 * mu) +
             P4 * mathlib.sin(6 * mu) + P5 * mathlib.sin(8 * mu))

    p_sin = mathlib.sin(p_rad)
    p_sin2 = p_sin * p_sin

    p_cos = mathlib.cos(p_rad)

    p_tan = p_sin / p_cos
    p_tan2 = p_tan * p_tan
    p_tan4 = p_tan2 * p_tan2

    ep_sin = 1 - E * p_sin2
    ep_sin_sqrt = mathlib.sqrt(1 - E * p_sin2)

    n = R / ep_sin_sqrt
    r = (1 - E) / ep_sin

    c = E_P2 * p_cos**2
    c2 = c * c

    d = x / (n * K0)
    d2 = d * d
    d3 = d2 * d
    d4 = d3 * d
    d5 = d4 * d
    d6 = d5 * d

    latitude = (
        p_rad - (p_tan / r) * (d2 / 2 - d4 / 24 *
                               (5 + 3 * p_tan2 + 10 * c - 4 * c2 - 9 * E_P2)) +
        d6 / 720 *
        (61 + 90 * p_tan2 + 298 * c + 45 * p_tan4 - 252 * E_P2 - 3 * c2))

    longitude = (
        d - d3 / 6 * (1 + 2 * p_tan2 + c) + d5 / 120 *
        (5 - 2 * c + 28 * p_tan2 - 3 * c2 + 8 * E_P2 + 24 * p_tan4)) / p_cos

    longitude = mod_angle(
        longitude +
        mathlib.radians(zone_number_to_central_longitude(zone_number)))

    return (mathlib.degrees(latitude), mathlib.degrees(longitude))
Пример #7
0
def from_latlon(latitude,
                longitude,
                force_zone_number=None,
                force_zone_letter=None):
    """This function converts Latitude and Longitude to UTM coordinate

        Parameters
        ----------
        latitude: float or NumPy array
            Latitude between 80 deg S and 84 deg N, e.g. (-80.0 to 84.0)

        longitude: float or NumPy array
            Longitude between 180 deg W and 180 deg E, e.g. (-180.0 to 180.0).

        force_zone_number: int
            Zone number is represented by global map numbers of an UTM zone
            numbers map. You may force conversion to be included within one
            UTM zone number.  For more information see utmzones [1]_

        force_zone_letter: str
            You may force conversion to be included within one UTM zone
            letter.  For more information see utmzones [1]_

        Returns
        -------
        easting: float or NumPy array
            Easting value of UTM coordinates

        northing: float or NumPy array
            Northing value of UTM coordinates

        zone_number: int
            Zone number is represented by global map numbers of a UTM zone
            numbers map. More information see utmzones [1]_

        zone_letter: str
            Zone letter is represented by a string value. UTM zone designators
            can be accessed in [1]_


       .. _[1]: http://www.jaworski.ca/utmzones.htm
    """
    if not in_bounds(latitude, -80, 84):
        raise OutOfRangeError(
            'latitude out of range (must be between 80 deg S and 84 deg N)')
    if not in_bounds(longitude, -180, 180):
        raise OutOfRangeError(
            'longitude out of range (must be between 180 deg W and 180 deg E)')
    if force_zone_number is not None:
        check_valid_zone(force_zone_number, force_zone_letter)

    lat_rad = mathlib.radians(latitude)
    lat_sin = mathlib.sin(lat_rad)
    lat_cos = mathlib.cos(lat_rad)

    lat_tan = lat_sin / lat_cos
    lat_tan2 = lat_tan * lat_tan
    lat_tan4 = lat_tan2 * lat_tan2

    if force_zone_number is None:
        zone_number = latlon_to_zone_number(latitude, longitude)
    else:
        zone_number = force_zone_number

    if force_zone_letter is None:
        zone_letter = latitude_to_zone_letter(latitude)
    else:
        zone_letter = force_zone_letter

    lon_rad = mathlib.radians(longitude)
    central_lon = zone_number_to_central_longitude(zone_number)
    central_lon_rad = mathlib.radians(central_lon)

    n = R / mathlib.sqrt(1 - E * lat_sin**2)
    c = E_P2 * lat_cos**2

    a = lat_cos * mod_angle(lon_rad - central_lon_rad)
    a2 = a * a
    a3 = a2 * a
    a4 = a3 * a
    a5 = a4 * a
    a6 = a5 * a

    m = R * (M1 * lat_rad - M2 * mathlib.sin(2 * lat_rad) +
             M3 * mathlib.sin(4 * lat_rad) - M4 * mathlib.sin(6 * lat_rad))

    easting = K0 * n * (
        a + a3 / 6 * (1 - lat_tan2 + c) + a5 / 120 *
        (5 - 18 * lat_tan2 + lat_tan4 + 72 * c - 58 * E_P2)) + 500000

    northing = K0 * (m + n * lat_tan *
                     (a2 / 2 + a4 / 24 *
                      (5 - lat_tan2 + 9 * c + 4 * c**2) + a6 / 720 *
                      (61 - 58 * lat_tan2 + lat_tan4 + 600 * c - 330 * E_P2)))

    if mixed_signs(latitude):
        raise ValueError("latitudes must all have the same sign")
    elif negative(latitude):
        northing += 10000000

    return easting, northing, zone_number, zone_letter
Пример #8
0
def to_latlon(easting, northing, zone_number, zone_letter=None, northern=None):
    if not zone_letter and northern is None:
        raise ValueError('either zone_letter or northern needs to be set')

    elif zone_letter and northern is not None:
        raise ValueError('set either zone_letter or northern, but not both')

    if not 100000 <= easting < 1000000:
        raise OutOfRangeError('easting out of range (must be between 100.000 m and 999.999 m)')
    if not 0 <= northing <= 10000000:
        raise OutOfRangeError('northing out of range (must be between 0 m and 10.000.000 m)')
    if not 1 <= zone_number <= 60:
        raise OutOfRangeError('zone number out of range (must be between 1 and 60)')

    if zone_letter:
        zone_letter = zone_letter.upper()

        if not 'C' <= zone_letter <= 'X' or zone_letter in ['I', 'O']:
            raise OutOfRangeError('zone letter out of range (must be between C and X)')

        northern = (zone_letter >= 'N')

    x = easting - 500000
    y = northing

    if not northern:
        y -= 10000000

    m = y / K0
    mu = m / (R * M1)

    p_rad = (mu +
             P2 * math.sin(2 * mu) +
             P3 * math.sin(4 * mu) +
             P4 * math.sin(6 * mu) +
             P5 * math.sin(8 * mu))

    p_sin = math.sin(p_rad)
    p_sin2 = p_sin * p_sin

    p_cos = math.cos(p_rad)

    p_tan = p_sin / p_cos
    p_tan2 = p_tan * p_tan
    p_tan4 = p_tan2 * p_tan2

    ep_sin = 1 - E * p_sin2
    ep_sin_sqrt = math.sqrt(1 - E * p_sin2)

    n = R / ep_sin_sqrt
    r = (1 - E) / ep_sin

    c = _E * p_cos ** 2
    c2 = c * c

    d = x / (n * K0)
    d2 = d * d
    d3 = d2 * d
    d4 = d3 * d
    d5 = d4 * d
    d6 = d5 * d

    latitude = (p_rad - (p_tan / r) *
                (d2 / 2 -
                 d4 / 24 * (5 + 3 * p_tan2 + 10 * c - 4 * c2 - 9 * E_P2)) +
                d6 / 720 * (61 + 90 * p_tan2 + 298 * c + 45 * p_tan4 - 252 * E_P2 - 3 * c2))

    longitude = (d -
                 d3 / 6 * (1 + 2 * p_tan2 + c) +
                 d5 / 120 * (5 - 2 * c + 28 * p_tan2 - 3 * c2 + 8 * E_P2 + 24 * p_tan4)) / p_cos

    return (math.degrees(latitude),
            math.degrees(longitude) + zone_number_to_central_longitude(zone_number))
Пример #9
0
def to_latlon(easting,
              northing,
              zone_number,
              zone_letter=None,
              northern=None,
              strict=True):
    """This function convert an UTM coordinate into Latitude and Longitude

        Parameters
        ----------
        easting: int
            Easting value of UTM coordinate

        northing: int
            Northing value of UTM coordinate

        zone number: int
            Zone Number is represented with global map numbers of an UTM Zone
            Numbers Map. More information see utmzones [1]_

        zone_letter: str
            Zone Letter can be represented as string values. Where UTM Zone
            Designators can be accessed in [1]_

        northern: bool
            You can set True or False to set this parameter. Default is None


       .. _[1]: http://www.jaworski.ca/utmzones.htm

    """
    if not zone_letter and northern is None:
        raise ValueError('either zone_letter or northern needs to be set')

    elif zone_letter and northern is not None:
        raise ValueError('set either zone_letter or northern, but not both')

    if strict:
        if not 100000 <= easting < 1000000:
            raise OutOfRangeError(
                'easting out of range (must be between 100.000 m and 999.999 m)'
            )
        if not 0 <= northing <= 10000000:
            raise OutOfRangeError(
                'northing out of range (must be between 0 m and 10.000.000 m)')
    if not 1 <= zone_number <= 60:
        raise OutOfRangeError(
            'zone number out of range (must be between 1 and 60)')

    if zone_letter:
        zone_letter = zone_letter.upper()

        if not 'C' <= zone_letter <= 'X' or zone_letter in ['I', 'O']:
            raise OutOfRangeError(
                'zone letter out of range (must be between C and X)')

        northern = (zone_letter >= 'N')

    x = easting - 500000
    y = northing

    if not northern:
        y -= 10000000

    m = y / K0
    mu = m / (R * M1)

    p_rad = (mu + P2 * math.sin(2 * mu) + P3 * math.sin(4 * mu) +
             P4 * math.sin(6 * mu) + P5 * math.sin(8 * mu))

    p_sin = math.sin(p_rad)
    p_sin2 = p_sin * p_sin

    p_cos = math.cos(p_rad)

    p_tan = p_sin / p_cos
    p_tan2 = p_tan * p_tan
    p_tan4 = p_tan2 * p_tan2

    ep_sin = 1 - E * p_sin2
    ep_sin_sqrt = math.sqrt(1 - E * p_sin2)

    n = R / ep_sin_sqrt
    r = (1 - E) / ep_sin

    c = _E * p_cos**2
    c2 = c * c

    d = x / (n * K0)
    d2 = d * d
    d3 = d2 * d
    d4 = d3 * d
    d5 = d4 * d
    d6 = d5 * d

    latitude = (
        p_rad - (p_tan / r) * (d2 / 2 - d4 / 24 *
                               (5 + 3 * p_tan2 + 10 * c - 4 * c2 - 9 * E_P2)) +
        d6 / 720 *
        (61 + 90 * p_tan2 + 298 * c + 45 * p_tan4 - 252 * E_P2 - 3 * c2))

    longitude = (
        d - d3 / 6 * (1 + 2 * p_tan2 + c) + d5 / 120 *
        (5 - 2 * c + 28 * p_tan2 - 3 * c2 + 8 * E_P2 + 24 * p_tan4)) / p_cos

    return (math.degrees(latitude), math.degrees(longitude) +
            zone_number_to_central_longitude(zone_number))
Пример #10
0
def from_latlon(latitude, longitude, force_zone_number=None):
    """This function convert Latitude and Longitude to UTM coordinate

        Parameters
        ----------
        latitude: float
            Latitude between 80 deg S and 84 deg N, e.g. (-80.0 to 84.0)

        longitude: float
            Longitude between 180 deg W and 180 deg E, e.g. (-180.0 to 180.0).

        force_zone number: int
            Zone Number is represented with global map numbers of an UTM Zone
            Numbers Map. You may force conversion including one UTM Zone Number.
            More information see utmzones [1]_

       .. _[1]: http://www.jaworski.ca/utmzones.htm
    """
    if not -80.0 <= latitude <= 84.0:
        raise OutOfRangeError(
            'latitude out of range (must be between 80 deg S and 84 deg N)')
    if not -180.0 <= longitude <= 180.0:
        raise OutOfRangeError(
            'longitude out of range (must be between 180 deg W and 180 deg E)')

    lat_rad = math.radians(latitude)
    lat_sin = math.sin(lat_rad)
    lat_cos = math.cos(lat_rad)

    lat_tan = lat_sin / lat_cos
    lat_tan2 = lat_tan * lat_tan
    lat_tan4 = lat_tan2 * lat_tan2

    if force_zone_number is None:
        zone_number = latlon_to_zone_number(latitude, longitude)
    else:
        zone_number = force_zone_number

    zone_letter = latitude_to_zone_letter(latitude)

    lon_rad = math.radians(longitude)
    central_lon = zone_number_to_central_longitude(zone_number)
    central_lon_rad = math.radians(central_lon)

    n = R / math.sqrt(1 - E * lat_sin**2)
    c = E_P2 * lat_cos**2

    a = lat_cos * (lon_rad - central_lon_rad)
    a2 = a * a
    a3 = a2 * a
    a4 = a3 * a
    a5 = a4 * a
    a6 = a5 * a

    m = R * (M1 * lat_rad - M2 * math.sin(2 * lat_rad) +
             M3 * math.sin(4 * lat_rad) - M4 * math.sin(6 * lat_rad))

    easting = K0 * n * (
        a + a3 / 6 * (1 - lat_tan2 + c) + a5 / 120 *
        (5 - 18 * lat_tan2 + lat_tan4 + 72 * c - 58 * E_P2)) + 500000

    northing = K0 * (m + n * lat_tan *
                     (a2 / 2 + a4 / 24 *
                      (5 - lat_tan2 + 9 * c + 4 * c**2) + a6 / 720 *
                      (61 - 58 * lat_tan2 + lat_tan4 + 600 * c - 330 * E_P2)))

    if latitude < 0:
        northing += 10000000

    return easting, northing, zone_number, zone_letter
Пример #11
0
def check_valid_zone_number(zone_number):
    if not 1 <= zone_number <= 60:
        raise OutOfRangeError(
            'zone number out of range (must be between 1 and 60)')
Пример #12
0
def check_valid_zone_letter(zone_letter):
    zone_letter = zone_letter.upper()
    if not 'C' <= zone_letter <= 'X' or zone_letter in ['I', 'O']:
        raise OutOfRangeError(
            'zone letter out of range (must be between C and X)')