mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2025-10-27 08:49:27 +00:00
Check pyhamtools callinfo for lat/Lon of DXCC from static country info as a last resort. Closes #13
This commit is contained in:
@@ -2,6 +2,7 @@ import logging
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from pyhamtools import LookupLib, Callinfo
|
from pyhamtools import LookupLib, Callinfo
|
||||||
|
from pyhamtools.locator import latlong_to_locator
|
||||||
|
|
||||||
from core.config import config
|
from core.config import config
|
||||||
from core.constants import BANDS, UNKNOWN_BAND, CW_MODES, PHONE_MODES, DATA_MODES, ALL_MODES
|
from core.constants import BANDS, UNKNOWN_BAND, CW_MODES, PHONE_MODES, DATA_MODES, ALL_MODES
|
||||||
@@ -105,21 +106,34 @@ def infer_name_from_callsign(call):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
# Infer a latitude and longitude from a callsign (requires QRZ.com)
|
# Infer a latitude and longitude from a callsign (requires QRZ.com)
|
||||||
def infer_latlon_from_callsign(call):
|
def infer_latlon_from_callsign_qrz(call):
|
||||||
data = get_qrz_data_for_callsign(call)
|
data = get_qrz_data_for_callsign(call)
|
||||||
if data and "latitude" in data and "longitude" in data:
|
if data and "latitude" in data and "longitude" in data:
|
||||||
return [data["longitude"], data["longitude"]]
|
return [data["latitude"], data["longitude"]]
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Infer a grid locator from a callsign (requires QRZ.com)
|
# Infer a grid locator from a callsign (requires QRZ.com)
|
||||||
def infer_grid_from_callsign(call):
|
def infer_grid_from_callsign_qrz(call):
|
||||||
data = get_qrz_data_for_callsign(call)
|
data = get_qrz_data_for_callsign(call)
|
||||||
if data and "locator" in data:
|
if data and "locator" in data:
|
||||||
return data["locator"]
|
return data["locator"]
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
# Infer a latitude and longitude from a callsign (using DXCC, probably very inaccurate)
|
||||||
|
def infer_latlon_from_callsign_dxcc(call):
|
||||||
|
data = CALL_INFO_BASIC.get_lat_long(call)
|
||||||
|
if data and "latitude" in data and "longitude" in data:
|
||||||
|
return [data["latitude"], data["longitude"]]
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Infer a grid locator from a callsign (using DXCC, probably very inaccurate)
|
||||||
|
def infer_grid_from_callsign_dxcc(call):
|
||||||
|
latlon = infer_latlon_from_callsign_dxcc(call)
|
||||||
|
return latlong_to_locator(latlon[0], latlon[1], 8)
|
||||||
|
|
||||||
|
|
||||||
# Convert objects to serialisable things. Used by JSON serialiser as a default when it encounters unserializable things.
|
# Convert objects to serialisable things. Used by JSON serialiser as a default when it encounters unserializable things.
|
||||||
# Converts datetimes to ISO.
|
# Converts datetimes to ISO.
|
||||||
|
|||||||
27
data/spot.py
27
data/spot.py
@@ -8,7 +8,8 @@ from pyhamtools.locator import locator_to_latlong, latlong_to_locator
|
|||||||
from core.constants import DXCC_FLAGS
|
from core.constants import DXCC_FLAGS
|
||||||
from core.utils import infer_mode_family_from_mode, infer_band_from_freq, infer_continent_from_callsign, \
|
from core.utils import infer_mode_family_from_mode, infer_band_from_freq, infer_continent_from_callsign, \
|
||||||
infer_country_from_callsign, infer_cq_zone_from_callsign, infer_itu_zone_from_callsign, infer_dxcc_id_from_callsign, \
|
infer_country_from_callsign, infer_cq_zone_from_callsign, infer_itu_zone_from_callsign, infer_dxcc_id_from_callsign, \
|
||||||
infer_mode_from_comment, infer_name_from_callsign, infer_latlon_from_callsign, infer_grid_from_callsign
|
infer_mode_from_comment, infer_name_from_callsign, infer_latlon_from_callsign_dxcc, infer_grid_from_callsign_dxcc, \
|
||||||
|
infer_latlon_from_callsign_qrz, infer_grid_from_callsign_qrz
|
||||||
|
|
||||||
|
|
||||||
# Data class that defines a spot.
|
# Data class that defines a spot.
|
||||||
@@ -76,6 +77,10 @@ class Spot:
|
|||||||
# Latitude & longitude, in degrees. This could be from a geographical reference e.g. POTA, or from a QRZ lookup
|
# Latitude & longitude, in degrees. This could be from a geographical reference e.g. POTA, or from a QRZ lookup
|
||||||
latitude: float = None
|
latitude: float = None
|
||||||
longitude: float = None
|
longitude: float = None
|
||||||
|
# Location source. Indicates how accurate the location might be. Values: "SPOT", "QRZ, "DXCC", "NONE"
|
||||||
|
location_source: str = None
|
||||||
|
# Location good. Indicates that the software thinks the location data is good enough to plot on a map.
|
||||||
|
location_good: bool = None
|
||||||
# QRT state. Some APIs return spots marked as QRT. Otherwise we can check the comments.
|
# QRT state. Some APIs return spots marked as QRT. Otherwise we can check the comments.
|
||||||
qrt: bool = None
|
qrt: bool = None
|
||||||
# Where we got the spot from, e.g. "POTA", "Cluster"...
|
# Where we got the spot from, e.g. "POTA", "Cluster"...
|
||||||
@@ -129,6 +134,8 @@ class Spot:
|
|||||||
self.longitude = ll[1]
|
self.longitude = ll[1]
|
||||||
if self.latitude and self.longitude and not self.grid:
|
if self.latitude and self.longitude and not self.grid:
|
||||||
self.grid = latlong_to_locator(self.latitude, self.longitude, 8)
|
self.grid = latlong_to_locator(self.latitude, self.longitude, 8)
|
||||||
|
if self.latitude:
|
||||||
|
self.location_source = "SPOT"
|
||||||
|
|
||||||
# QRT comment detection
|
# QRT comment detection
|
||||||
if self.comment and not self.qrt:
|
if self.comment and not self.qrt:
|
||||||
@@ -140,12 +147,24 @@ class Spot:
|
|||||||
if self.dx_call and not self.dx_name:
|
if self.dx_call and not self.dx_name:
|
||||||
self.dx_name = infer_name_from_callsign(self.dx_call)
|
self.dx_name = infer_name_from_callsign(self.dx_call)
|
||||||
if self.dx_call and not self.latitude:
|
if self.dx_call and not self.latitude:
|
||||||
latlon = infer_latlon_from_callsign(self.dx_call)
|
latlon = infer_latlon_from_callsign_qrz(self.dx_call)
|
||||||
if latlon:
|
if latlon:
|
||||||
self.latitude = latlon[0]
|
self.latitude = latlon[0]
|
||||||
self.longitude = latlon[1]
|
self.longitude = latlon[1]
|
||||||
if self.dx_call and not self.grid:
|
self.grid = infer_grid_from_callsign_qrz(self.dx_call)
|
||||||
self.grid = infer_grid_from_callsign(self.dx_call)
|
self.location_source = "QRZ"
|
||||||
|
|
||||||
|
# Last resort for getting a position, use the DXCC entity.
|
||||||
|
if self.dx_call and not self.latitude:
|
||||||
|
latlon = infer_latlon_from_callsign_dxcc(self.dx_call)
|
||||||
|
self.latitude = latlon[0]
|
||||||
|
self.longitude = latlon[1]
|
||||||
|
self.grid = infer_grid_from_callsign_dxcc(self.dx_call)
|
||||||
|
self.location_source = "DXCC"
|
||||||
|
|
||||||
|
# Location is "good" if it is from a spot, or from QRZ if the callsign doesn't contain a slash, so the operator
|
||||||
|
# is likely at home.
|
||||||
|
self.location_good = self.location_source == "SPOT" or (self.location_source == "QRZ" and not "/" in self.dx_call)
|
||||||
|
|
||||||
# JSON serialise
|
# JSON serialise
|
||||||
def to_json(self):
|
def to_json(self):
|
||||||
|
|||||||
@@ -417,6 +417,19 @@ components:
|
|||||||
type: number
|
type: number
|
||||||
description: Latitude, in degrees. This could be from a geographical reference e.g. POTA, or from a QRZ lookup
|
description: Latitude, in degrees. This could be from a geographical reference e.g. POTA, or from a QRZ lookup
|
||||||
example: -1.2345
|
example: -1.2345
|
||||||
|
location_source:
|
||||||
|
type: string
|
||||||
|
description: Where we got the location (grid/latitude/longitude) from. If this was from the spot itself, it's likely quite accurate, but if we had to fall back to QRZ lookup, or even a location based on the DXCC itself, it will be a lot less accurate.
|
||||||
|
enum:
|
||||||
|
- SPOT
|
||||||
|
- QRZ
|
||||||
|
- DXCC
|
||||||
|
- NONE
|
||||||
|
example: SPOT
|
||||||
|
location_good:
|
||||||
|
type: boolean
|
||||||
|
description: Does the software think the location is good enough to put a marker on a map? This is true if the source is "SPOT", or alternatively if the source is "QRZ" and the callsign doesn't have a slash in it (i.e. operator likely at home).
|
||||||
|
example: true
|
||||||
qrt:
|
qrt:
|
||||||
type: boolean
|
type: boolean
|
||||||
description: QRT state. Some APIs return spots marked as QRT. Otherwise we can check the comments.
|
description: QRT state. Some APIs return spots marked as QRT. Otherwise we can check the comments.
|
||||||
|
|||||||
Reference in New Issue
Block a user