kopia lustrzana https://github.com/bmo/py-wsjtx
81 wiersze
3.0 KiB
Python
81 wiersze
3.0 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
class GPSException(Exception):
|
|
def __init__(self,*args):
|
|
Exception.__init__(*args)
|
|
|
|
# From K6WRU via stackexchange : see https://ham.stackexchange.com/questions/221/how-can-one-convert-from-lat-long-to-grid-square/244#244
|
|
# Convert latitude and longitude to Maidenhead grid locators.
|
|
#
|
|
# Arguments are in signed decimal latitude and longitude. For example,
|
|
# the location of my QTH Palo Alto, CA is: 37.429167, -122.138056 or
|
|
# in degrees, minutes, and seconds: 37° 24' 49" N 122° 6' 26" W
|
|
class LatLongToGridSquare(object):
|
|
upper = 'ABCDEFGHIJKLMNOPQRSTUVWX'
|
|
lower = 'abcdefghijklmnopqrstuvwx'
|
|
|
|
@classmethod
|
|
def to_grid(cls,dec_lat, dec_lon):
|
|
|
|
if not (-180<=dec_lon<180):
|
|
raise GPSException('longitude must be -180<=lon<180, given %f\n'%dec_lon)
|
|
if not (-90<=dec_lat<90):
|
|
raise GPSException('latitude must be -90<=lat<90, given %f\n'%dec_lat)
|
|
|
|
adj_lat = dec_lat + 90.0
|
|
adj_lon = dec_lon + 180.0
|
|
|
|
grid_lat_sq = LatLongToGridSquare.upper[int(adj_lat/10)]
|
|
grid_lon_sq = LatLongToGridSquare.upper[int(adj_lon/20)]
|
|
|
|
grid_lat_field = str(int(adj_lat%10))
|
|
grid_lon_field = str(int((adj_lon/2)%10))
|
|
|
|
adj_lat_remainder = (adj_lat - int(adj_lat)) * 60
|
|
adj_lon_remainder = ((adj_lon) - int(adj_lon/2)*2) * 60
|
|
|
|
grid_lat_subsq = LatLongToGridSquare.lower[int(adj_lat_remainder/2.5)]
|
|
grid_lon_subsq = LatLongToGridSquare.lower[int(adj_lon_remainder/5)]
|
|
|
|
return grid_lon_sq + grid_lat_sq + grid_lon_field + grid_lat_field + grid_lon_subsq + grid_lat_subsq
|
|
|
|
# GPS sentences are encoded
|
|
@classmethod
|
|
def convert_to_degrees(cls, gps_value, direction):
|
|
if direction not in ['N','S','E','W']:
|
|
raise GPSException("Invalid direction specifier for lat/long: {}".format(direction))
|
|
|
|
dir_mult = 1
|
|
if direction in ['S','W']:
|
|
dir_mult = -1
|
|
|
|
if len(gps_value) < 3:
|
|
raise GPSException("Invalid Value for lat/long: {}".format(gps_value))
|
|
|
|
dot_posn = gps_value.index('.')
|
|
|
|
if dot_posn < 0:
|
|
raise GPSException("Invalid Format for lat/long: {}".format(gps_value))
|
|
|
|
degrees = gps_value[0:dot_posn-2]
|
|
mins = gps_value[dot_posn-2:]
|
|
|
|
f_degrees = dir_mult * (float(degrees) + (float(mins) / 60.0))
|
|
return f_degrees
|
|
|
|
@classmethod
|
|
def GPGLL_to_grid(cls, GPSLLText):
|
|
# example: $GPGLL,4740.99254,N,12212.31179,W,223311.00,A,A*70\r\n
|
|
try:
|
|
components = GPSLLText.split(",")
|
|
if components[0]=='$GPGLL':
|
|
del components[0]
|
|
if components[5] != 'A':
|
|
raise GPSException("Not a valid GPS fix")
|
|
lat = LatLongToGridSquare.convert_to_degrees(components[0], components[1])
|
|
long = LatLongToGridSquare.convert_to_degrees(components[2], components [3])
|
|
grid = LatLongToGridSquare.to_grid(lat, long)
|
|
except GPSException:
|
|
grid = ""
|
|
return grid
|