diff --git a/core/models/caves.py b/core/models/caves.py index 4827095..3079ed1 100644 --- a/core/models/caves.py +++ b/core/models/caves.py @@ -158,9 +158,11 @@ class Cave(TroggleModel): for e in CaveAndEntrance.objects.filter(cave=self): if e.entrance.best_station() and e.entrance.best_station() != "": #print(self, e, e.entrance.best_station()) - if e.entrance.best_station_object().x: - # print(f"{self} {e.entrance.best_station_object()} {e.entrance.best_station_object().x}") + try: + x = e.entrance.best_station_object().x no_data = False + except: + pass return no_data def singleentrance(self): diff --git a/core/models/survex.py b/core/models/survex.py index 68bae05..6e2a06f 100644 --- a/core/models/survex.py +++ b/core/models/survex.py @@ -58,6 +58,7 @@ class SurvexStation(models.Model): x = models.FloatField(blank=True, null=True) y = models.FloatField(blank=True, null=True) z = models.FloatField(blank=True, null=True) + entrance = models.ForeignKey("Entrance", blank=True, null=True, on_delete=models.SET_NULL) class Meta: ordering = ("id",) diff --git a/core/views/statistics.py b/core/views/statistics.py index 2927bd3..c1a0ca8 100644 --- a/core/views/statistics.py +++ b/core/views/statistics.py @@ -1,4 +1,5 @@ from collections import OrderedDict +from math import sqrt from pathlib import Path from django.shortcuts import render @@ -276,15 +277,10 @@ def dataissues(request): def eastings(request): """report each Northing/Easting pair wherever recorded""" - ents = [] - entrances = Entrance.objects.all() - for e in entrances: - if e.easting or e.northing: - ents.append(e) - if e.lat_wgs84 or e.long_wgs84: - ents.append(e) - - for e in ents: + ents = set() + gpsents = set() + + def add_stations(e): try: ts = e.tag_station if ts: @@ -306,10 +302,39 @@ def eastings(request): e.tag_es = None e.tag_os = None # print(f"exception for {e}") - - stations = SurvexStation.objects.all() + + entrances = Entrance.objects.all() + for e in entrances: + if e.easting or e.northing: + ents.add(e) + add_stations(e) + e.northing = float(e.northing) + e.easting = float(e.easting) + + if e.northing < 5200000: + e.bmn = True + # e.northing = e.northing + 5200000 + e.northing = e.northing + 5198919.918 + + #e.easting = e.easting - 36000 + 486000 + e.easting = e.easting + 374854.63 # linear hack + + try: + e.diffx = e.easting - e.best_station_object().x + e.diffy = e.northing - e.best_station_object().y + e.error = sqrt(e.diffx**2 + e.diffy**2) + except: + pass + + for e in entrances: + if e.lat_wgs84 or e.long_wgs84: + gpsents.add(e) + add_stations(e) + + + stations = SurvexStation.objects.all() # NB these are NOT all the stations in troggle_import_root.pos - return render(request, "eastings.html", {"ents": ents, "stations": stations}) + return render(request, "eastings.html", {"ents": ents, "gpsents": gpsents, "stations": stations}) def aliases(request, year): diff --git a/parsers/locations.py b/parsers/locations.py index 8a5da4f..acf41b9 100644 --- a/parsers/locations.py +++ b/parsers/locations.py @@ -34,7 +34,7 @@ class MapLocations(object): We don't need these map locations any more ?! They would only be used in addition to entrances going onto a map display""" - p = [ + fp = [ ("laser.0_7", "BNase", "Reference", "Bräuning Nase laser point"), ("226-96", "BZkn", "Reference", "Bräuning Zinken trig point"), ("vd1", "VD1", "Reference", "VD1 survey point"), @@ -48,13 +48,15 @@ class MapLocations(object): ("laser.0_5", "LSR5", "Reference", "Laser Point 0/5"), ("225-96", "BAlm", "Reference", "Bräuning Alm trig point"), ] # 12 fixed points + + p = [] def points(self): prior = len(self.p) for ent in Entrance.objects.all(): for st, ent_type in {ent.exact_station: "exact", ent.other_station: "other", ent.tag_station: "tag"}.items(): if st != "": - self.p.append((st, str(ent), ent.needs_surface_work(), str(ent))) + self.p.append((st, str(ent), ent.needs_surface_work(), ent)) store_data_issues() found = len(self.p) - prior message = f" - {found} Entrance tags found - not yet validated against survex .pos file." @@ -70,9 +72,10 @@ def validate_entrance_stations(ent=None): """ bads = 0 good = 0 + url="/caves" # fallback def tag_lower_case(station): - + nonlocal url so = SurvexStation.objects.filter(name=station.lower()) if so.count() == 1: message = f"X - Entrance {ent} station '{station}' should be '{station.lower()}'" @@ -104,29 +107,31 @@ def validate_entrance_stations(ent=None): continue try: so = SurvexStation.objects.filter(name=st) - if so.count() == 1: - good +=1 - # print(f"OK - Entrance {ent} '{ent_type}' station '{st}'") - continue - if so.count() != 0: - message =f"{so.count()} found for Entrance {ent} '{ent_type}' station '{st}' {so}" - else: - message = f" ! - Entrance {ent} has invalid '{ent_type}' station '{st}'" - if st == ent.best_station(): - message = message + " - AND THIS IS THE 'BEST' ONE" - else: - message = message + " - not the 'best'" - stash_data_issue(parser="positions", message=message, url=url) - print(message) - bads +=1 - tag_lower_case(st) - continue except: message = f" ! - Entrance {ent} has invalid '{ent_type}' station '{st}'. EXCEPTION." stash_data_issue(parser="positions", message=message, url=url) print(message) bads +=1 continue + + if so.count() == 1: + good +=1 + # print(f"OK - Entrance {ent} '{ent_type}' station '{st}'") + continue + if so.count() != 0: + message =f"{so.count()} found for Entrance {ent} '{ent_type}' station '{st}' {so}" + else: + message = f" ! - Entrance {ent} has invalid '{ent_type}' station '{st}'" + if st == ent.best_station(): + message = message + " - AND THIS IS THE 'BEST' ONE" + else: + message = message + " - not the 'best'" + stash_data_issue(parser="positions", message=message, url=url) + print(message) + bads +=1 + tag_lower_case(st) + continue + if ent: return validate_ent(ent) @@ -255,8 +260,10 @@ def LoadPositions(): mappoints = {} for pt in MapLocations().points(): - svxid, number, point_type, label = pt - mappoints[svxid] = True + svxid, number, point_type, ent = pt + #((st, str(ent), ent.needs_surface_work(), ent)) + + mappoints[svxid] = ent if svxid =="1": print(f"BOGUS {pt}") # this is now checked for when importing the entrance tags in parsers/caves.py @@ -294,6 +301,7 @@ def LoadPositions(): ss.x = float(x) ss.y = float(y) ss.z = float(z) + ss.entrance = mappoints[sid] ss.save() found += 1 except: diff --git a/templates/cave.html b/templates/cave.html index bd1519f..00b2a5f 100644 --- a/templates/cave.html +++ b/templates/cave.html @@ -175,7 +175,7 @@
Explorers
{{ ent.entrance.explorers|safe }}
{% endif %} {% if ent.entrance.northing %} -
Location
UTM33 Northing: {{ ent.entrance.northing|safe }}, Easting: {{ ent.entrance.easting|safe }}, {{ ent.entrance.alt|safe }}m
+
Location
Northing: {{ ent.entrance.northing|safe }}, Easting: {{ ent.entrance.easting|safe }} (UTM or BMN, depending...), {{ ent.entrance.alt|safe }}m
{% endif %} {% if ent.entrance.lat_wgs84 %}
Location
WGS84 Lat.: {{ ent.entrance.lat_wgs84|floatformat:7 }} N, Long.:{{ ent.entrance.long_wgs84|floatformat:7 }} E
diff --git a/templates/eastings.html b/templates/eastings.html index 646cba4..2bb57ed 100644 --- a/templates/eastings.html +++ b/templates/eastings.html @@ -27,15 +27,25 @@ Coordinate systems in Austria are explained in:

The Lat. Long. coordinates are manually entered using a phone or a hand-held GPS device at (or near) the entrance.

For the Cave column, if there is an official cave name, then it is shown. Otherwise whatever other name we can find for it is shown in italics. -For the Entrance column, if the entrance has a name (e.g. Grüner Eingang in Schwarzmooskogeleishöhle) then it is shown. - Otherwise it says "Anon:" followed by whatever other name we can find for it, usually the entrance id slug, in italics. + - - + +

OK now for the nasty bit. Many of the older caves did not have easting & northing in UTM 33T at all, but (probably) in BMN and converting between BMN into UTM requires ellipsoids and bessel functions.. or we can just take a linear approximation, which is what I have done here:
+e.northingUTM = e.northingBMN + 5198919.918
+e.eastingUTM = e.easting + 374854.63
+Such converted eastings and northings are in italics in the table below. As you can see, some were wildly out. +

These magic numbers simply come from assuming that both BMN and UTM are in metres, and linear over our area, and then taking the avergage of the offsets for 5 locations, the 5 cave entrances at the bottom of this page: +Olaf's Coordinates. +

This horrible approximation is accruate to ~8m in the northing and ~30m in the easting. +

CaveEntrancebest Eastingbest NorthingGPS LatGPS Longtagtag exacttag otherslug
BMN + + + + {% for ent in ents %} - - - - - - - - + + + + + + + + + {% endfor %}
CaveEntrance slugEastingNorthingbest tag eastingbest tag northingΔ xΔ yDistance (m)
@@ -47,28 +57,24 @@ th, td { {{c|safe}} {% endif %}
{% endfor %}
- {% if ent.name %} - {{ent.name|safe}} - {% else %} - Anon: {{ent|safe}} - {% endif %} - {{ent.easting|floatformat:2}}{{ent.northing|floatformat:2}}{{ent.lat_wgs84|floatformat:6}}{{ent.long_wgs84|floatformat:6}}{{ent.tag_station}}{{ent.exact_station}}{{ent.other_station}} {{ent.slug}}{{ent.easting|floatformat:2}}{{ent.northing|floatformat:2}}{{ent.best_station_object.x|floatformat:2}}{{ent.best_station_object.y|floatformat:2}}{{ent.diffx|floatformat:0}}{{ent.diffy|floatformat:0}}{{ent.error|floatformat:0}}
-

and now with the locations of the survey stations. All as UTM eatings, norhtings: + +

and now the GPS equivalents: - -{% for ent in ents %} + +{% for ent in gpsents %} + + @@ -104,8 +112,9 @@ the assemblage of survex files, including fixed point files, and is probably 'co GPS and coordinate systems
Basic Coordinate Systems. +

This next table is of all the survex stations in troggle: i.e. only those survey stations which have been identified with an Entrance by manually editing the Entrance data.

Cavebest Latbest Longtagtag Lattag Longtag exactexact Latexact Longtag otherother Latother Long
CaveGPS LatGPS Longbest Latbest Longtagtag Lattag Longtag exactexact Latexact Longtag otherother Latother Long
{% for c in ent.cavelist %} @@ -80,6 +86,8 @@ th, td { {% endif %}
{% endfor %}
{{ent.lat_wgs84|floatformat:6}}{{ent.long_wgs84|floatformat:6}} {{ent.lat|floatformat:6}} {{ent.long|floatformat:6}} {{ent.tag_station}}
- + {% for s in stations %} @@ -113,7 +122,7 @@ the assemblage of survex files, including fixed point files, and is probably 'co - + {% empty %}
Survex Stationxylat.long.
Survex Stationxylat.long.Used on ent
{{s.name|safe}} {{s.y|floatformat:2}} {{s.lat|floatformat:6}} {{s.long|floatformat:6}} {{s.entrance|safe}}
NO STATION DATA - This is due to survex (cavern) failing on the entire dataset.