3 Commits

Author SHA1 Message Date
Ian Renton
21a3ae70b5 Add support for DME. Closes #114. 2026-06-23 06:38:41 +01:00
Ian Renton
d4d43a43c8 DME geodata CSV #114 2026-06-21 22:39:36 +01:00
Ian Renton
f28bcc2464 Allow standard parentheses for DX cluster "de_grid<prop_mode>dx_grid" structures 2026-06-21 22:18:20 +01:00
13 changed files with 8171 additions and 22 deletions

View File

@@ -32,6 +32,7 @@ SIGS = [
SIG(name="Tiles", description="Tiles on the Air", ref_regex=r"[A-Za-z]{2}[0-9]{2}[A-Za-z]{2}"), SIG(name="Tiles", description="Tiles on the Air", ref_regex=r"[A-Za-z]{2}[0-9]{2}[A-Za-z]{2}"),
SIG(name="WAB", description="Worked All Britain", ref_regex=r"[A-Z]{1,2}[0-9]{2}"), SIG(name="WAB", description="Worked All Britain", ref_regex=r"[A-Z]{1,2}[0-9]{2}"),
SIG(name="WAI", description="Worked All Ireland", ref_regex=r"[A-Z][0-9]{2}"), SIG(name="WAI", description="Worked All Ireland", ref_regex=r"[A-Z][0-9]{2}"),
SIG(name="DME", description="Diplomas de Municipios Españoles", ref_regex=r"\d{4,5}"),
SIG(name="TOTA", description="Toilets on the Air", ref_regex=r"T\-[0-9]{2}") SIG(name="TOTA", description="Toilets on the Air", ref_regex=r"T\-[0-9]{2}")
] ]

View File

@@ -7,6 +7,9 @@ from core.cache_utils import SEMI_STATIC_URL_DATA_CACHE
from core.constants import SIGS, HTTP_HEADERS from core.constants import SIGS, HTTP_HEADERS
from core.geo_utils import wab_wai_square_to_lat_lon from core.geo_utils import wab_wai_square_to_lat_lon
with open("datafiles/dme-geodata.csv", encoding="utf-8") as _f:
_DME_INDEX = {row["dme"]: row for row in csv.DictReader(_f)}
def get_ref_regex_for_sig(sig): def get_ref_regex_for_sig(sig):
"""Utility function to get the regex string for a SIG reference for a named SIG. If no match is found, None will be returned.""" """Utility function to get the regex string for a SIG reference for a named SIG. If no match is found, None will be returned."""
@@ -188,6 +191,17 @@ def populate_sig_ref_info(sig_ref):
sig_ref.longitude = ll[1] sig_ref.longitude = ll[1]
except: except:
logging.debug("Invalid lat/lon received for reference") logging.debug("Invalid lat/lon received for reference")
elif sig.upper() == "DME":
row = _DME_INDEX.get(ref_id)
if row:
sig_ref.name = row["municipio"] + ", " + row["provincia"]
sig_ref.latitude = float(row["lat"]) if row.get("lat") else None
sig_ref.longitude = float(row["lon"]) if row.get("lon") else None
if sig_ref.latitude and sig_ref.longitude:
try:
sig_ref.grid = latlong_to_locator(sig_ref.latitude, sig_ref.longitude, 6)
except Exception:
logging.debug("Invalid lat/lon received for reference")
except Exception: except Exception:
logging.warning("Failed to look up sig_ref info for " + sig + " ref " + ref_id, exc_info=True) logging.warning("Failed to look up sig_ref info for " + sig + " ref " + ref_id, exc_info=True)
return sig_ref return sig_ref

View File

@@ -263,7 +263,7 @@ class Spot:
# If so, add that to the sig_refs list for this spot. # If so, add that to the sig_refs list for this spot.
ref_regex = get_ref_regex_for_sig(found_sig) ref_regex = get_ref_regex_for_sig(found_sig)
if ref_regex: if ref_regex:
ref_matches = re.finditer(r"(^|\W)" + found_sig + r"($|\W)(" + ref_regex + r")($|\W)", self.comment, ref_matches = re.finditer(r"(^|\W)" + found_sig + r"([ -])(" + ref_regex + r")($|\W)", self.comment,
re.IGNORECASE) re.IGNORECASE)
for ref_match in ref_matches: for ref_match in ref_matches:
self._append_sig_ref_if_missing(SIGRef(id=ref_match.group(3).upper(), sig=found_sig)) self._append_sig_ref_if_missing(SIGRef(id=ref_match.group(3).upper(), sig=found_sig))
@@ -290,23 +290,23 @@ class Spot:
if self.sig_refs and len(self.sig_refs) > 0 and not self.sig: if self.sig_refs and len(self.sig_refs) > 0 and not self.sig:
self.sig = self.sig_refs[0].sig self.sig = self.sig_refs[0].sig
# Parse "de_grid<prop_mode>dx_grid" structures from the comment, e.g. "JN61ES<ES>JM56XT" or "JO02GQ<>KN17LG". # Parse "de_grid<prop_mode>dx_grid" structures from the comment, e.g. "JN61ES(ES)JM56XT" or "JO02GQ<>KN17LG".
# These are common on cluster spots and can provide grid references in preference to e.g. QRZ lookup, as well as # These are common on cluster spots and can provide grid references in preference to e.g. QRZ lookup, as well as
# being the only source we have for propagation mode. # being the only source we have for propagation mode. Brace for nightmare regex from hell.
if self.comment: if self.comment:
grid_mode_grid_match = re.search( grid_mode_grid_match = re.search(
r'\b([A-Ra-r]{2}\d{2}(?:[A-Xa-x]{2}(?:\d{2})?)?)<([^>]*)>([A-Ra-r]{2}\d{2}(?:[A-Xa-x]{2}(?:\d{2})?)?)\b', r'\b([A-Ra-r]{2}\d{2}(?:[A-Xa-x]{2}(?:\d{2})?)?)(?:<([^>]*)>|\(([^)]*)\))([A-Ra-r]{2}\d{2}(?:[A-Xa-x]{2}(?:\d{2})?)?)\b',
self.comment) self.comment)
if grid_mode_grid_match: if grid_mode_grid_match:
# regex matches, so extract grids: # regex matches, so extract grids:
if not self.de_grid: if not self.de_grid:
self.de_grid = grid_mode_grid_match.group(1).upper() self.de_grid = grid_mode_grid_match.group(1).upper()
if not self.dx_grid: if not self.dx_grid:
self.dx_grid = grid_mode_grid_match.group(3).upper() self.dx_grid = grid_mode_grid_match.group(4).upper()
self.dx_location_source = "SPOT" self.dx_location_source = "SPOT"
# And extract propagation mode: # And extract propagation mode (group 2 for <...>, group 3 for (...)):
mode_tag = grid_mode_grid_match.group(2).upper() mode_tag = (grid_mode_grid_match.group(2) or grid_mode_grid_match.group(3) or "").upper()
if mode_tag and not self.propagation_mode: if mode_tag and not self.propagation_mode:
if mode_tag in PROPAGATION_MODES: if mode_tag in PROPAGATION_MODES:
self.propagation_mode = PROPAGATION_MODES[mode_tag] self.propagation_mode = PROPAGATION_MODES[mode_tag]

8133
datafiles/dme-geodata.csv Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -76,7 +76,7 @@
</div> </div>
<script src="/js/add-spot.js?v=1782076050"></script> <script src="/js/add-spot.js?v=1782076701"></script>
<script>$(document).ready(function () { <script>$(document).ready(function () {
$("#nav-link-add-spot").addClass("active"); $("#nav-link-add-spot").addClass("active");
}); <!-- highlight active page in nav --></script> }); <!-- highlight active page in nav --></script>

View File

@@ -75,7 +75,7 @@
</div> </div>
<script src="/js/alerts.js?v=1782076050"></script> <script src="/js/alerts.js?v=1782076701"></script>
<script>$(document).ready(function () { <script>$(document).ready(function () {
$("#nav-link-alerts").addClass("active"); $("#nav-link-alerts").addClass("active");
}); <!-- highlight active page in nav --></script> }); <!-- highlight active page in nav --></script>

View File

@@ -77,8 +77,8 @@
<script> <script>
let spotProvidersEnabledByDefault = {% raw json_encode(web_ui_options["spot-providers-enabled-by-default"]) %}; let spotProvidersEnabledByDefault = {% raw json_encode(web_ui_options["spot-providers-enabled-by-default"]) %};
</script> </script>
<script src="/js/spotsbandsandmap.js?v=1782076050"></script> <script src="/js/spotsbandsandmap.js?v=1782076701"></script>
<script src="/js/bands.js?v=1782076050"></script> <script src="/js/bands.js?v=1782076701"></script>
<script>$(document).ready(function () { <script>$(document).ready(function () {
$("#nav-link-bands").addClass("active"); $("#nav-link-bands").addClass("active");
}); <!-- highlight active page in nav --></script> }); <!-- highlight active page in nav --></script>

View File

@@ -1,6 +1,6 @@
{% extends "skeleton.html" %} {% extends "skeleton.html" %}
{% block head_extra %} {% block head_extra %}
<link rel="stylesheet" href="/css/style.css?v=1782076050" type="text/css"> <link rel="stylesheet" href="/css/style.css?v=1782076701" type="text/css">
<link href="/vendor/css/bootstrap-5.3.8.min.css" rel="stylesheet"> <link href="/vendor/css/bootstrap-5.3.8.min.css" rel="stylesheet">
<link href="/vendor/css/fontawesome-6.7.2.min.css" rel="stylesheet"> <link href="/vendor/css/fontawesome-6.7.2.min.css" rel="stylesheet">
<link href="/vendor/css/solid-6.7.2.min.css" rel="stylesheet"> <link href="/vendor/css/solid-6.7.2.min.css" rel="stylesheet">
@@ -10,10 +10,10 @@
<script src="/vendor/js/bootstrap-5.3.8.bundle.min.js"></script> <script src="/vendor/js/bootstrap-5.3.8.bundle.min.js"></script>
<script src="/vendor/js/tinycolor2-1.6.0.min.js"></script> <script src="/vendor/js/tinycolor2-1.6.0.min.js"></script>
<script src="/js/utils.js?v=1782076050"></script> <script src="/js/utils.js?v=1782076701"></script>
<script src="/js/ui-ham.js?v=1782076050"></script> <script src="/js/ui-ham.js?v=1782076701"></script>
<script src="/js/geo.js?v=1782076050"></script> <script src="/js/geo.js?v=1782076701"></script>
<script src="/js/common.js?v=1782076050"></script> <script src="/js/common.js?v=1782076701"></script>
{% end %} {% end %}
{% block body %} {% block body %}
<div class="container"> <div class="container">

View File

@@ -284,7 +284,7 @@
</div> </div>
<script src="/vendor/js/chart-4.4.9.umd.min.js"></script> <script src="/vendor/js/chart-4.4.9.umd.min.js"></script>
<script src="/js/conditions.js?v=1782076050"></script> <script src="/js/conditions.js?v=1782076701"></script>
<script>$(document).ready(function () { <script>$(document).ready(function () {
$("#nav-link-conditions").addClass("active"); $("#nav-link-conditions").addClass("active");
}); <!-- highlight active page in nav --></script> }); <!-- highlight active page in nav --></script>

View File

@@ -95,8 +95,8 @@
<script> <script>
let spotProvidersEnabledByDefault = {% raw json_encode(web_ui_options["spot-providers-enabled-by-default"]) %}; let spotProvidersEnabledByDefault = {% raw json_encode(web_ui_options["spot-providers-enabled-by-default"]) %};
</script> </script>
<script src="/js/spotsbandsandmap.js?v=1782076049"></script> <script src="/js/spotsbandsandmap.js?v=1782076701"></script>
<script src="/js/map.js?v=1782076049"></script> <script src="/js/map.js?v=1782076701"></script>
<script>$(document).ready(function () { <script>$(document).ready(function () {
$("#nav-link-map").addClass("active"); $("#nav-link-map").addClass("active");
}); <!-- highlight active page in nav --></script> }); <!-- highlight active page in nav --></script>

View File

@@ -116,8 +116,8 @@
<script> <script>
let spotProvidersEnabledByDefault = {% raw json_encode(web_ui_options["spot-providers-enabled-by-default"]) %}; let spotProvidersEnabledByDefault = {% raw json_encode(web_ui_options["spot-providers-enabled-by-default"]) %};
</script> </script>
<script src="/js/spotsbandsandmap.js?v=1782076049"></script> <script src="/js/spotsbandsandmap.js?v=1782076701"></script>
<script src="/js/spots.js?v=1782076049"></script> <script src="/js/spots.js?v=1782076701"></script>
<script>$(document).ready(function () { <script>$(document).ready(function () {
$("#nav-link-spots").addClass("active"); $("#nav-link-spots").addClass("active");
}); <!-- highlight active page in nav --></script> }); <!-- highlight active page in nav --></script>

View File

@@ -59,7 +59,7 @@
</div> </div>
</div> </div>
<script src="/js/status.js?v=1782076050"></script> <script src="/js/status.js?v=1782076701"></script>
<script> <script>
$(document).ready(function () { $(document).ready(function () {
$("#nav-link-status").addClass("active"); $("#nav-link-status").addClass("active");

View File

@@ -335,6 +335,7 @@ const SIG_ICONS = {
"WWTOTA": "fa-tower-observation", "WWTOTA": "fa-tower-observation",
"WAB": "fa-table-cells-large", "WAB": "fa-table-cells-large",
"WAI": "fa-table-cells-large", "WAI": "fa-table-cells-large",
"DME": "fa-building",
"Tiles": "fa-square", "Tiles": "fa-square",
"TOTA": "fa-toilet" "TOTA": "fa-toilet"
} }