diff --git a/core/sig_lookup_helper.py b/core/sig_lookup_helper.py index b977ce3..c3984c8 100644 --- a/core/sig_lookup_helper.py +++ b/core/sig_lookup_helper.py @@ -29,6 +29,7 @@ def get_sig_ref_info(sig, ref_id): # If the SIG is HEMA, we have no current lookup for this so just skip the lookup here. if sig.upper() == "HEMA": + sig_ref.type = "Summit" return sig_ref ### PROGRAMMATIC DATA GENERATION INSTEAD OF LOOKUPS ### @@ -37,6 +38,7 @@ def get_sig_ref_info(sig, ref_id): # calculate all the information we are going to get directly. if sig.upper() == "TILES": # Tiles on the Air just uses Maidenhead 6-digit squares, so ID, Name and Grid are all the same + sig_ref.type = "Grid" if not sig_ref.name: sig_ref.name = sig_ref.id if not sig_ref.grid: @@ -48,6 +50,7 @@ def get_sig_ref_info(sig, ref_id): return sig_ref elif sig.upper() == "WAB" or sig.upper() == "WAI": + sig_ref.type = "Grid" ll = wab_wai_square_to_lat_lon(ref_id) if ll: sig_ref.name = ref_id @@ -61,6 +64,7 @@ def get_sig_ref_info(sig, ref_id): elif sig.upper() == "BOTA": # For BOTA all we can ever generate is the URL, there is no data file or lookup for lat/longs + sig_ref.type = "Beach" if not sig_ref.name: sig_ref.name = sig_ref.id sig_ref.url = "https://www.beachesontheair.com/beaches/" + sig_ref.name.lower().replace(" ", "-") diff --git a/data/sig_ref.py b/data/sig_ref.py index 1d2b32c..949f580 100644 --- a/data/sig_ref.py +++ b/data/sig_ref.py @@ -12,13 +12,17 @@ class SIGRef: sig: str # Name of the reference, e.g. "Null Country Park", if known. name: str | None = None + # Type of the reference, e.g. "Park", if known. + type: str | None = None # URL to look up more information about the reference, if known. url: str | None = None - # Latitude of the reference, if known. + # Latitude of the reference, in degrees, if known. latitude: float | None = None - # Longitude of the reference, if known. + # Longitude of the reference, in degrees, if known. longitude: float | None = None - # Maidenhead grid reference of the reference, if known. + # Altitude of the reference, in metres, if known. + altitude: float | None = None + # Maidenhead grid ref of the reference, if known. grid: str | None = None # Activation score. SOTA only activation_score: int | None = None diff --git a/providers/sigrefdata/arlhs.py b/providers/sigrefdata/arlhs.py index 9960a44..871932b 100644 --- a/providers/sigrefdata/arlhs.py +++ b/providers/sigrefdata/arlhs.py @@ -21,6 +21,7 @@ class ARLHS(FileDownloadSIGRefDataProvider): if "ARLHS" in row and row["ARLHS"] != "": ref_id = row["ARLHS"] new_data.append(SIGRef(sig=self.SIG, id=ref_id, name=row["Name"] if "Name" in row else None, + type="Lighthouse", url="https://www.cqgma.org/zinfo.php?ref=" + ref_id, latitude=float(row["Latitude"]) if "Latitude" in row and row[ "Latitude"] != "" else None, diff --git a/providers/sigrefdata/dme.py b/providers/sigrefdata/dme.py index 96c9f94..a175dc0 100644 --- a/providers/sigrefdata/dme.py +++ b/providers/sigrefdata/dme.py @@ -27,6 +27,7 @@ class DME(LocalFileSIGRefDataProvider): "LONGITUD_ETRS89_REGCAN95") else None ref = SIGRef(sig=self.SIG, id=ref_id, + type="Town", name=row["NOMBRE_ACTUAL"] + ", " + row["PROVINCIA"], latitude=latitude, longitude=longitude) diff --git a/providers/sigrefdata/gma.py b/providers/sigrefdata/gma.py index 01da1cc..8bd3067 100644 --- a/providers/sigrefdata/gma.py +++ b/providers/sigrefdata/gma.py @@ -20,11 +20,14 @@ class GMA(FileDownloadSIGRefDataProvider): for row in csv.DictReader(http_response.content.decode("utf-8-sig").splitlines()[1:]): ref_id = row["Reference"] new_data.append(SIGRef(sig=self.SIG, id=ref_id, name=row["Name"] if "Name" in row else None, + type="Summit", url="https://www.cqgma.org/zinfo.php?ref=" + ref_id, latitude=float(row["Latitude"]) if "Latitude" in row and row[ "Latitude"] != "" else None, longitude=float(row["Longitude"]) if "Longitude" in row and row[ "Longitude"] != "" else None, + altitude=float(row["Height (m)"].replace("m", "")) if "Height (m)" in row and row[ + "Height (m)"] != "" else None, grid=row["Maidenhead Locator"])) # Bail out if a stop has been requested, i.e. the program is shutting down - no need to parse the rest of diff --git a/providers/sigrefdata/illw.py b/providers/sigrefdata/illw.py index 04d0219..a5fef30 100644 --- a/providers/sigrefdata/illw.py +++ b/providers/sigrefdata/illw.py @@ -21,6 +21,7 @@ class ILLW(FileDownloadSIGRefDataProvider): if "ILLW" in row and row["ILLW"] != "": ref_id = row["ILLW"] new_data.append(SIGRef(sig=self.SIG, id=ref_id, name=row["Name"] if "Name" in row else None, + type="Lighthouse", url="https://www.cqgma.org/zinfo.php?ref=" + ref_id, latitude=float(row["Latitude"]) if "Latitude" in row and row[ "Latitude"] != "" else None, diff --git a/providers/sigrefdata/iota.py b/providers/sigrefdata/iota.py index f3d78da..eeef47e 100644 --- a/providers/sigrefdata/iota.py +++ b/providers/sigrefdata/iota.py @@ -32,7 +32,7 @@ class IOTA(FileDownloadSIGRefDataProvider): logging.debug(f"Error converting lat/lon to locator for an IOTA reference %f %f", latitude, longitude) new_data.append(SIGRef(sig=self.SIG, id=ref_id, name=ref["name"], - grid=grid, latitude=latitude, longitude=longitude)) + type="Island", grid=grid, latitude=latitude, longitude=longitude)) # Bail out if a stop has been requested, i.e. the program is shutting down - no need to parse the rest # of the data in this case diff --git a/providers/sigrefdata/llota.py b/providers/sigrefdata/llota.py index b5ad1e9..d0a4865 100644 --- a/providers/sigrefdata/llota.py +++ b/providers/sigrefdata/llota.py @@ -26,6 +26,7 @@ class LLOTA(FileDownloadSIGRefDataProvider): ll = locator_to_latlong(grid) new_data.append(SIGRef(sig=self.SIG, id=ref_id, name=str(ref["name"]), + type="Lake", url="https://llota.app/list/ref/" + ref_id, grid=grid, latitude=ll[0], diff --git a/providers/sigrefdata/mota.py b/providers/sigrefdata/mota.py index b0db137..1b0d6d8 100644 --- a/providers/sigrefdata/mota.py +++ b/providers/sigrefdata/mota.py @@ -20,6 +20,7 @@ class MOTA(FileDownloadSIGRefDataProvider): for row in csv.DictReader(http_response.content.decode("utf-8-sig").splitlines()[1:]): ref_id = row["Reference"] new_data.append(SIGRef(sig=self.SIG, id=ref_id, name=row["Name"] if "Name" in row else None, + type="Mill", url="https://www.cqgma.org/zinfo.php?ref=" + ref_id, latitude=float(row["Latitude"]) if "Latitude" in row and row[ "Latitude"] != "" else None, diff --git a/providers/sigrefdata/pnp_kml_sig_ref_data_provider.py b/providers/sigrefdata/pnp_kml_sig_ref_data_provider.py index 0c4e4fe..3ef7130 100644 --- a/providers/sigrefdata/pnp_kml_sig_ref_data_provider.py +++ b/providers/sigrefdata/pnp_kml_sig_ref_data_provider.py @@ -36,6 +36,7 @@ class ParksNPeaksKMLSIGRefDataProvider(FileDownloadSIGRefDataProvider): longitude, latitude = placemark.geometry.x, placemark.geometry.y ref = SIGRef(sig=self.sig_name, id=ref_id, name=placemark.name, + type="Park", url="https://parksnpeaks.org/getPark.php?actPark=" + ref_id, latitude=latitude, longitude=longitude) diff --git a/providers/sigrefdata/pota.py b/providers/sigrefdata/pota.py index c57e6ca..7991e5b 100644 --- a/providers/sigrefdata/pota.py +++ b/providers/sigrefdata/pota.py @@ -20,6 +20,7 @@ class POTA(FileDownloadSIGRefDataProvider): for row in csv.DictReader(http_response.content.decode("utf-8-sig").splitlines()): ref_id = row["reference"] new_data.append(SIGRef(sig=self.SIG, id=ref_id, name=row["name"] if "name" in row else None, + type="Park", url="https://pota.app/#/park/" + ref_id, grid=row["grid"] if "grid" in row else None, latitude=float(row["latitude"]) if "latitude" in row and row[ diff --git a/providers/sigrefdata/siota.py b/providers/sigrefdata/siota.py index add41d1..8a2cf1f 100644 --- a/providers/sigrefdata/siota.py +++ b/providers/sigrefdata/siota.py @@ -20,6 +20,7 @@ class SIOTA(FileDownloadSIGRefDataProvider): for row in csv.DictReader(http_response.content.decode("utf-8-sig").splitlines()): ref_id = row["SILO_CODE"] new_data.append(SIGRef(sig=self.SIG, id=ref_id, name=row["NAME"] if "NAME" in row else None, + type="Silo", grid=row["LOCATOR"] if "LOCATOR" in row else None, latitude=float(row["LAT"]) if "LAT" in row else None, longitude=float(row["LNG"]) if "LNG" in row else None)) diff --git a/providers/sigrefdata/sota.py b/providers/sigrefdata/sota.py index 0853a19..ea40a0b 100644 --- a/providers/sigrefdata/sota.py +++ b/providers/sigrefdata/sota.py @@ -23,10 +23,13 @@ class SOTA(FileDownloadSIGRefDataProvider): ref_id = row["SummitCode"] latitude = float(row["Latitude"]) if "Latitude" in row and row["Latitude"] != "" else None longitude = float(row["Longitude"]) if "Longitude" in row and row["Longitude"] != "" else None + altitude = float(row["AltM"]) if "AltM" in row and row["AltM"] != "" else None ref = SIGRef(sig=self.SIG, id=ref_id, name=row["SummitName"] if "SummitName" in row else None, + type="Summit", url="https://www.sotadata.org.uk/en/summit/" + ref_id, latitude=latitude, longitude=longitude, + altitude=altitude, activation_score=int(row["Points"]) if "Points" in row else None) if latitude and longitude: ref.grid = latlong_to_locator(latitude, longitude, 6) diff --git a/providers/sigrefdata/toilets.py b/providers/sigrefdata/toilets.py index 0a03510..dc35139 100644 --- a/providers/sigrefdata/toilets.py +++ b/providers/sigrefdata/toilets.py @@ -19,8 +19,8 @@ class Toilets(LocalFileSIGRefDataProvider): csv_data = _f.read() dr = csv.DictReader(csv_data.splitlines()) for row in dr: - new_data.append(SIGRef(sig=self.SIG, id=row["ref"], name=row["ref"], latitude=float(row["lat"]), - longitude=float(row["lon"]))) + new_data.append(SIGRef(sig=self.SIG, id=row["ref"], name=row["ref"], type="Toilet", + latitude=float(row["lat"]), longitude=float(row["lon"]))) # Bail out if a stop has been requested, i.e. the program is shutting down - no need to parse the rest # of the data in this case diff --git a/providers/sigrefdata/towers.py b/providers/sigrefdata/towers.py index c968d72..5b309c3 100644 --- a/providers/sigrefdata/towers.py +++ b/providers/sigrefdata/towers.py @@ -20,6 +20,7 @@ class Towers(FileDownloadSIGRefDataProvider): for row in csv.DictReader(http_response.content.decode("utf-8-sig").splitlines(), delimiter=";"): ref_id = row["Ref"] new_data.append(SIGRef(sig=self.SIG, id=ref_id, name=row["Nazev"] if "Nazev" in row else None, + type="Tower", url="https://wwtota.com/seznam/karta_rozhledny.php?ref=" + ref_id, grid=row["Lokator"] if "Lokator" in row and row["Lokator"] != "" else None, latitude=float(row["Lat"]) if "Lat" in row and row["Lat"] != "" else None, diff --git a/providers/sigrefdata/wca.py b/providers/sigrefdata/wca.py index 339b360..97e1cd3 100644 --- a/providers/sigrefdata/wca.py +++ b/providers/sigrefdata/wca.py @@ -37,6 +37,7 @@ class WCA(FileDownloadSIGRefDataProvider): logging.debug(f"Encountered dodgy formatting in WCA CSV, skipping location data for %s", ref_id) new_data.append(SIGRef(sig=self.SIG, id=ref_id, name=row["CLEAN NAME"] if "CLEAN NAME" in row else None, + type="Castle", url="https://www.cqgma.org/zinfo.php?ref=" + ref_id, latitude=latitude, longitude=longitude, diff --git a/providers/sigrefdata/wota.py b/providers/sigrefdata/wota.py index dba4459..092ae47 100644 --- a/providers/sigrefdata/wota.py +++ b/providers/sigrefdata/wota.py @@ -26,9 +26,11 @@ class WOTA(FileDownloadSIGRefDataProvider): url = "https://www.wota.org.uk/MM_LDO-" + str(number + 214) new_data.append(SIGRef(sig=self.SIG, id=ref_id, name=feature["properties"]["title"], url=url, + type="Summit", grid=feature["properties"]["qthLocator"], latitude=feature["geometry"]["coordinates"][1], - longitude=feature["geometry"]["coordinates"][0])) + longitude=feature["geometry"]["coordinates"][0], + altitude=feature["properties"]["height"])) # Bail out if a stop has been requested, i.e. the program is shutting down - no need to parse the rest of # the data in this case diff --git a/providers/sigrefdata/wwbota.py b/providers/sigrefdata/wwbota.py index 6e0535d..1cdf828 100644 --- a/providers/sigrefdata/wwbota.py +++ b/providers/sigrefdata/wwbota.py @@ -20,6 +20,7 @@ class WWBOTA(FileDownloadSIGRefDataProvider): for row in csv.DictReader(http_response.content.decode("utf-8-sig").splitlines()): ref_id = row["Reference"] new_data.append(SIGRef(sig=self.SIG, id=ref_id, name=row["Name"] if "Name" in row else None, + type="Bunker", url="https://bunkerwiki.org/?s=" + ref_id if ref_id.startswith("B/G") else None, grid=row["Locator"] if "Locator" in row and row["Locator"] != "" else None, latitude=float(row["Lat"]) if "Lat" in row and row["Lat"] != "" else None, diff --git a/providers/sigrefdata/wwff.py b/providers/sigrefdata/wwff.py index 7f02ed1..fc5c840 100644 --- a/providers/sigrefdata/wwff.py +++ b/providers/sigrefdata/wwff.py @@ -20,6 +20,7 @@ class WWFF(FileDownloadSIGRefDataProvider): for row in csv.DictReader(http_response.content.decode("utf-8-sig").splitlines()): ref_id = row["reference"] new_data.append(SIGRef(sig=self.SIG, id=ref_id, name=row["name"] if "name" in row else None, + type="Park", url="https://wwff.co/directory/?showRef=" + ref_id, grid=row["iaruLocator"] if "iaruLocator" in row and row[ "iaruLocator"] != "-" else None, diff --git a/providers/sigrefdata/zlota.py b/providers/sigrefdata/zlota.py index f0cb1be..0e8c085 100644 --- a/providers/sigrefdata/zlota.py +++ b/providers/sigrefdata/zlota.py @@ -26,11 +26,20 @@ class ZLOTA(FileDownloadSIGRefDataProvider): longitude = ref["longitude"] new_ref = SIGRef(sig=self.SIG, id=ref_id, name=ref["name"], + type=ref["asset_type"].title, url="https://ontheair.nz/assets/" + ref_id.replace("/", "_"), latitude=latitude, longitude=longitude) + + # Check lat/lon validity and update grid accordingly if latitude and longitude: - ref.new_ref = latlong_to_locator(latitude, longitude, 6) + try: + new_ref.grid = latlong_to_locator(latitude, longitude, 6) + except ValueError: + # Junk lat/lon, remove from the spot + new_ref.latitude = None + new_ref.longitude = None + new_data.append(new_ref) # Bail out if a stop has been requested, i.e. the program is shutting down - no need to parse the rest diff --git a/static/apidocs/openapi.yml b/static/apidocs/openapi.yml index 6c452bf..a7dffdf 100644 --- a/static/apidocs/openapi.yml +++ b/static/apidocs/openapi.yml @@ -26,6 +26,7 @@ info: * GET `/options` now returns `spot_submit_providers`, a map of SIG names to the names of providers that support upstream spot submission for that SIG. (This allows clients to present the user with options of where a new spot can be sent to.) * Added `sig_ref_data_providers`, `static_data_providers` and `callsign_data_providers` to `/status` response * Added `callsign_data_providers` and `spot_providers_enabled_by_default` to `/options` response + * SIG Refs now have `type` and `altitude` parameters #### Upgrading a client from v1 to v2 API endpoints @@ -996,6 +997,10 @@ components: type: string description: SIG reference name example: Null Country Park + type: + type: string + description: SIG reference type + example: Park url: type: string description: SIG reference URL, which the user can look up for more information @@ -1012,6 +1017,10 @@ components: type: number description: Longitude of the reference, in degrees, if known. example: -1.2345 + altitude: + type: number + description: Altitude of the reference, in metres, if known. + example: 1234.5 activation_score: type: integer description: Activation score. SOTA only diff --git a/templates/add_spot.html b/templates/add_spot.html index 3771e26..60ea3cf 100644 --- a/templates/add_spot.html +++ b/templates/add_spot.html @@ -76,7 +76,7 @@ - + diff --git a/templates/alerts.html b/templates/alerts.html index cc3c16f..e2f7f16 100644 --- a/templates/alerts.html +++ b/templates/alerts.html @@ -82,7 +82,7 @@ - + diff --git a/templates/bands.html b/templates/bands.html index f8a2cf4..71721d9 100644 --- a/templates/bands.html +++ b/templates/bands.html @@ -79,8 +79,8 @@ - - + + diff --git a/templates/base.html b/templates/base.html index 51b32a5..9433b6f 100644 --- a/templates/base.html +++ b/templates/base.html @@ -1,6 +1,6 @@ {% extends "skeleton.html" %} {% block head_extra %} - + @@ -10,10 +10,10 @@ - - - - + + + + {% end %} {% block body %}