Alpine Ace - Ski App

Logo

Speichere diese Seite als Bookmark und verfolge unseren Projektstand!

View the Project on GitHub AlpineAceManagement/Alpine_Ace

Alpine Ace - Ski App

Willkommen auf der Projekt Website der Alpine Ace - Ski App.

Im Vertiefungsmodul 4230: GeoInformatik & Raumanalyse I des Bachelorstudiengangs Geomatik an der Fachhochschule Nordwestschweiz (FHNW) wurde im Rahmen einer Projektarbeit die Geodateninfrastruktur (GDI) Alpine Ace-Ski App entwickelt. Abgesehen von der Vorgabe räumlich-zeitlicher Inhalte hatten wir freie Themenwahl.

Diese Seite widmet sich der GDI Alpine Ace-Ski App. Wintersport ist in der Schweiz nicht nur ein Nationalsport, sondern auch ein bedeutender Wirtschaftszweig, der durch die Digitalisierung stark verändert wurde. Mittlerweile ist es möglich, Tickets im Voraus online zu buchen, Webcams an verschiedenen Standorten abzurufen und persönliche Statistiken über den Skitag zu erfassen. Allerdings erstellt jedes Skigebiet eigene Plattformen mit ähnlichen Funktionen, was dazu führt, dass man für jedes Skigebiet eine separate App herunterladen oder mehrere Webseiten als Lesezeichen speichern muss, um die wichtigsten Informationen zu erhalten. Dies kann die Anzahl der Apps und Lesezeichen auf dem Smartphone erheblich erhöhen.

Aus diesem Grund wurde die GDI Alpine Ace-Ski App entwickelt. Unser Ziel ist es, eine zentrale Plattform für verschiedene Skigebiete zu schaffen, die alle wichtigen Funktionen für den Wintersport bietet. Dazu gehören:

Erkunden Sie unsere Seite, um mehr über dieses spannende Projekt zu erfahren und zu entdecken, wie die Alpine Ace-Ski App Ihr Wintersporterlebnis revolutionieren kann.

Die Installationsanleitung befindet sich hier.

Inhaltsverzeichnis

Architektur

Eine vollständige Geodateninfrastruktur (GDI) umfasst das Backend, das Frontend sowie die verwendeten Bibliotheken und API-Schnittstellen. Das folgende Schema zeigt die entwickelte und genutzte GDI der Alpine Ace-Ski App.

Architektur Client-Server Struktur

Die App enthält dabei eine Server Client Umgebung:

Backend

Das Backend beinhaltet alle unsichtbaren Inhalte und Daten, die sich auf dem Server, in unserem Fall der Raspberry PI, befinden. Dazu gehören folgenden Punkte:

In der Datei network_config.js muss vor dem Start der App die aktuelle IP Adresse eingetragen werden. Die IP Adresse wird in die lokalen API’s, sowie WFS Abfragen eingetragen. So kann die React App von verschieden Geräten genutzt werden, solange dies im selben Netzwerk sind.

API

Um dem User die aktuellsten Informationen über das Skigebiet zur Verfügung stellen zu können, werden folgende APIs verwendet:

Architektur der APIs

Um einen reibungslosen Datenbezug zu gewährleisten, werden die entsprechenden Skripte über die Datei main.py gesteuert. Diese Datei läuft im Hintergrund und ruft die einzelnen Skripte in den festgelegten Zeitintervallen auf und führt sie aus.

GeoServer

Der GeoServer wird genutzt, um alle räumlichen Daten zu Verfügung zu stellen, die in der Datenbank gespeichert sind. Die Daten werden via WFS vom GeoServer angefordert. Um CORS auf dem GeoServer zu aktivieren, ist unter die Konfigurationsdatei unter docs\web.xml abgelegt. In dieser wird CORS aktiviert, um auch von anderen Geräten Daten WFS Anfragen zu tätigen.

Datenbank

In diesem Projekt werden neben Sachdaten auch räumliche Daten wie Pisten und Anlagen, die Geometrien besitzen, verwendet. Um sicherzustellen, dass die Datenbank diese geometrischen Daten effizient verarbeiten kann, haben wir uns für die Nutzung einer relationalen Datenbank mit der räumlichen Erweiterung PostGIS entschieden. Dadurch kann PostgreSQL räumliche Abfragen und Operationen durchführen, was für unser Projekt von entscheidender Bedeutung ist.

Datenbankverbindung

Während des Betriebes der Plattform müssen verschiedene Systeme Lese- oder Schreibzugriff haben. Für die Datenbankverbindung werden folgende Informationen verwendet:

Die Informationen werden an verschiedenen Orten im Programm Code verwendet. Dafür wurde für Python und Javascript jeweils eine Config-Datei erstellt, in welchem die Verbindungsinformationen angegeben sind:

Datenbankschema

Das Datenbankschema ist in folgende Gruppen eingeteilt:

Datenimport mit FME

Folgende Daten werden mit Hilfe von FME in den GeoServer importiert:

Node Server

Mit der Express-API greift die React App auf die Daten der Datenbank zu. Die Daten sind als API über den Port 5000 abrufbar.

Folgende Express-API’s sind vorhanden:

Fehler

Frontend

Das Frontend ist für das Auftreten unserer APP zuständig. Dabei baut unsere APP auf folgenden Technologien auf:

Der Vergleich zwischen Mock-Up und Endprodukt, die Erklärung zur Farbwahl und die einzelnen Funktionen werden in den nächsten Kapiteln beschrieben.

Mock-Up

Das Mock-Up der App ist in Form einer interaktiven PowerPoint hier verfügbar: Mock-Up

Dieses Mock-Up zeigt die ersten Ideen, wie die App aussehen sollte (Farbschema), aber auch die ersten Funktionen, die realisiert sein wollten. In den folgenden Grafiken werden die umgesetzten Features mit dem Mock-Up verglichen.

Mock-Up

App

Start

Karte

Wetter

Statistiken

Weg

Navi

Restaurant

Farbschema

Für diese App wurde das Farbschema sorgfältig entwickelt, sodass es nicht nur funktional ist, sondern auch visuelle ansprechend und leicht verständlich für die Benutzer ist.

Die Hauptfarbe, #00112E, bildet das Fundament dieser App und verleiht ihr eine solide Basis.

Die Sekundärfarbe, #FF6155, wurde mit Bedacht gewählt, um wichtige Elemente wie Buttons und interaktive Funktionen hervorzuheben. Ihre lebendige Präsenz zieht die Aufmerksamkeit auf sich und führt die Benutzer intuitiv durch die App.

Für das Routing und die Elemente wurde #9EFF55 und #B655FF gewählt. Diese Farben wurden ausgewählt, da sie komplementär zu unserer Sekundärfarbe sind, was nicht nur visuell ansprechend ist, sondern auch einen starken Kontrast bietet, der die Benutzerführung erleichtert.

Die Darstellung von gefahrenen Strecken oder Routing-Strecken erfolgt in #FFA500. Diese kräftige Farbe hebt sich von den traditionellen Skipisten Farben ab und sorgt dafür, dass die Routen deutlich erkennbar sind, ohne mit den üblichen Farbkonventionen zu kollidieren.

Schliesslich wurde entschieden, die Skipisten auf der Karte mit den klassischen Farben Blau: #0077BA, Rot: #E40513 und Schwarz: #000000 darzustellen. Diese konventionelle Farben ermöglicht es den Benutzern, auf einen Blick zu erkennen, um welche Art von Piste es sich handelt, und trägt so zur Benutzerfreundlichkeit unserer App bei.

Funktionen

Kopfzeile

Die Kopfzeile ist in Menü und Untermenü gleich aufgebaut. Neben dem Logo in der Mitte, befindet sich links die Zurück-Pfeil und rechts das Zahnrad für die Einstellungen. Pfeil und Zahnrad sind aus der Symbol Bibliothek von MUI.

Funktion

Beim anklicken des Symbols wird mittels eines Links auf das entsprechende Menü navigiert. In der Datei App.jsx ist die Kopfzeilen über jeder Menü Komponente. Einzig die Menüs Restaurant und Statistiken, welche über Untermenüs verfügen, haben eine eigene abgeänderte Kopfziele. Dort zeigt der Link auf das vorherig Menü.

Hauptmenü

Das Hauptmenü ist der wichtigste Ort der Webseite. Aus diesem wird in die Untermenüs navigiert. Die Untermenüs sind in sechs Kacheln angeordnet. Die wichtigsten Informationen zum Skigebiet wie die Lawinensituation, offene Anlagen und Pisten sind wie in einem Dashboard direkt über den Kacheln angeordnet.

Bulletin Karte Lawinen

In dieser Karten wird die aktuelle Lawinengefahr pro Region dargestellt. Die Lawinengefahr ist dabei in fünf Stufen unterteilt. Genauer beschrieben sind diese im Abschnitt Symbol Lawinengefahr. Im Hintergrund ist die Winterlandeskarte der Swisstopo.

Bulletin Karte Grenzen

Die Kantons- und Landesgrenzen werden direkt als GeoPackage dem Datenspeicher hinzugefügt. Sie sind nicht in der Datenbank, weil sich die Daten nicht häufig ändern. Die Daten sind ausserdem nur für den Hintergrund gedacht um die Lesbarkeit der Karte zu erhöhen.

Funktion

Diagramme der aktuellen Pisten und Anlagen Informationen

Piktogramme der Bulletins

Karte

In der Karte finden sich verschiedene Funktionen wieder. Beim Start der Karte befindet sich der Kartenausschnitt zentrisch über der Position des Nutzers. Der Ausschnitt kann danach beliebig verschoben, vergrössert oder verkleinert werden. In der Karte sind folgende Informationen dargestellt:

Skigebiete

Die Daten der Skigebiete wurden von der Plattform OpenSnowMap bezogen. Die Platform OpenSnowMap bezieht täglich alle Pisten und Skigebiete weltweit von Open Street Map.

Die Daten wurden vor dem Import durch FME bereinigt. In einem QGIS Projekt wurden alle Flächen gelöscht, welche nicht innerhalb der Schweiz (Puffer + 10km) liegen. Die Flächen wurden anschliessend als Geopackage im Koordinatensystem EGSG:2056 gespeichert.

Die Flächen werden in der Workbench gefiltert auf Skigebiete (es gibt Pisten die als Flächen vorhanden sind in OSM). Das Attribut skigebiet_name und die ID skigebiet_id wird vergeben. Diese ID wird als Verknüpfung verwendet um die Zuordnung zum Skigebiet zu ermöglichen. Die Skigebiete werden anschliessend in der Tabelle skigebiet gespeichert. Die Skigebiete werden bis jetzt im Projekt nicht grafisch dargestellt. Sie dienen lediglich der Verknüpfung von andern Daten.

DHM25

Das DHM25 ist das digitale Höhenmodell der Swisstopo mit einer Auflösung von 25 Meter.

Die Datei dhm25_grid_raster.asc ist mit mehr als 844 MB zu gross für das GitHub repository. Deshalb gibt es unter DB_PG ein Download Python Datei ASCII_Hoehenmodell_download.py. Dies lädt das DHM25 automatisch herunter, entzippt dieses und speichert es im Ordner ASCII_Hoehenmodell. Das Höhenmodell wird nur im FME Prozess geoserver_Datenimport.fmw verwendet, für die Richtungsbestimmung der Analgen und Pisten. Deshalb werden diese nicht in die Datenbank importiert.

Pisten

Die Daten der Pisten wurden von der Platform OpenSnowMap bezogen. Die Platform OpenSnowMap bezieht täglich alle Pisten und Skigebiete weltweit von Open Street Map.

Die Daten wurden vor dem Import durch FME bereinigt. In einem QGIS Projekt wurden alle Linien gelöscht, welche nicht innerhalb der Schweiz (Puffer + 10km) liegen. Die Linien wurden anschliessend als Geopackage im Koordinatensystem EGSG:2056 gespeichert.

Die Attribute sind für dieses Projekt so noch nicht nutzbar, da viele wichtige Informationen im Attribute other_tags sind. In der FME Workbench wird zuerst der Schwierigkeitsgrad extrahiert und im Attribut p_farbe festgehalten. Dasselbe passiert mit der Pistennummer p_nummer und Pistenname p_name. Multilines werden aufgesplittet in Linien. Für jede Linie wird eine ID erstellt, die piste_id. Die nicht mehr benötigten Attribute werden gelöscht. Für das Routing ist es später wichtig in welche Richtung die Piste verläuft. In einem benutzerdefinierten Transformer, dem Höhe_Start_und_Endpunkt_herausfinder, wird die Höhe des Starts und Endpunkts ermittelt. Die Höhe wird vom DHM25 abgegriffen. Ist die Höhe des Startpunktes tiefer als die des Endpunktes, wir die Orientierung der Piste umgedreht. Danach werden alle Pisten einem Skigebiet zugeordnet. Ist dies nicht möglich, wird diese Piste aussortiert. Bevor die Pisten gespeichert werden, wird das Attribut p_einweg vergeben. Dieses legt fest ab wann eine Piste als Einweg eingestuft (p_einweg = true) wird oder ob die Piste beidseitig befahrbar ist (p_einweg = false). Die Höhendifferenz wird als UserParameter angegeben vor dem Start des Prozesses. Der Standardwert ist 15m. Die Start- und Endpunkte werden in der Tabelle pisten_startpunkt, respektive pisten_endpunkt gespeichert und werden danach im Prozess Routing_geoserver.fmw. verwendet.

Anlagen

Die Daten der Anlagen sind aus dem TLM3D Datensatz der Swisstopo. In der Objektklasse Öffentlicher Verkehr, im Liniendatensatz tlm oev uebrige bahn befinden sich sämtliche Sesselbahnen, Gondelbahnen, Standseilbahnen und Bügellifte der Schweiz.

In der Workbench werden die anlage_id erstellt und das Attribut name in a_name umbenannt. Für das Routing ist es später wichtig, in welche Richtung die Anlage verläuft. In einem v Transformer, dem Höhe_Start_und_Endpunkt_herausfinder, wird die Höhe des Starts und Endpunkts ermittelt. Die Höhe wird vom DHM25 abgegriffen. Ist die Höhe des Startpunktes tiefer als die des Endpunktes, wir die Orientierung der Anlage umgedreht. Danach werden alle Anlagen einem Skigebiet zugeordnet. Wenn dies nicht möglich ist, wird diese Anlage aussortiert. Bevor die Anlagen gespeichert werden, wird das Attribut a_einweg vergeben. Dieses legt fest, ab wann eine Anlage als Einweg eingestuft (a_einweg = true) wird, oder ob die Anlage beidseitig befahrbar ist (a_einweg = false). Die Höhendifferenz wird als UserParameter angeben vor dem Start des Prozesses. Der Standartwert ist 15m. Die Start- und Endpunkte werden in der Tabelle anlagen_startpunkt, respektive anlagen_endpunkt gespeichert und werden danach im Prozess Routing_geoserver.fmw verwendet.

Parkplätze

Beim Datenimport in die Datenbank werden die Koordinaten von WGS84 in LV95 transformiert. Anschliessend wird jeder Parkplatz mit Hilfe des NeighborFinder dem nächsten Skigebiet zugewiesen.

ÖV-Haltestellen

Beim Datenimport in die Datenbank werden die Koordinaten von WGS84 in LV95 transformiert. Anschliessend wird jede Haltestelle mit Hilfe des NeighborFinder dem nächsten Skigebiet zugewiesen.

Funktion

Beim Öffnen werden zuerst alle WFS Daten bezogen, über die eigens erstellte Funkion createVectorSource aus der Datei kartenWFS.js. Mitgeliefert wird der Name des Layers der bezogen wird. In der Datei kartenLayerStyle.js sind alle Symbolisierungen von Vektordaten gespeichert. Die ist wie eine CSS-Datei. Die Symbolisierung muss nur in dieser Datei verändert werden und der Layer wird in allen Karten im Projekt angepasst. Die Winterlandeskarte wird über die Funktion SwisstopoLayer aus der Datei swisstopoLayer.js bezogen. In dieser sind auch die Quellenangaben. Diese sind in der Karte unten Links auf der Info Schaltfläche abrufbar, mit einem Link auf die Webseite der Swisstopo. Für das initialisieren der Karte wird der Ausschnitt und die Zoomstufe angeben. Mit der Open Layer Funktion controls wir bei Klicken auf die Schaltfläche E oben links, wird ein angegebener Bereich gezoomt. Wenn auf ein Layer geklickt wird, auf das Element gezoomt. Die Zoomstufe ist abhängig von der Grösse des Elements. In der Box unterhalb der Karte werden die Attribute vom selektieren Element angezeigt. Die Grösse der Box ist abhängig, wie viele Attribute vorhanden sind.

Wetter

Im Wetter-Menü findet man alle relevanten Informationen zu den Bedingungen im Skigebiet. Dazu gehören die Temperaturvorhersage für den aktuellen Tag, die aktuelle Temperatur, die Schneehöhe, das aktuelle Wetter, die Windgeschwindigkeit und die Windrichtung.

Konzept

Das Wetter-Menü ist in zwei Bereiche unterteilt: Im oberen Teil wird die Wettervorhersage präsentiert, während im unteren Teil die aktuelle Wettersituation dargestellt wird. Die Vorhersage wird in einem Diagramm visualisiert, wobei die Betriebszeiten der Skilifte grau hervorgehoben sind, um den Fokus auf die relevanten Zeiträume zu lenken. Der Bereich mit den aktuellen Informationen befindet sich im unteren Abschnitt der App. Windrichtung und Wetter werden dabei durch Symbole veranschaulicht.

Funktion

Wettervorhersage
Die täglichen Wettervorhersagen werden von einer lokalen API abgerufen:

Die abgerufenen Daten werden in die entsprechende Zustandsvariablen weatherChartData gespeichert. Die Daten werden dann in einem Liniendiagramm dargestellt. Das Diagramm wird mit Vega dargestellt.

Aktuelle Wetterdaten
Die aktuellen Wetterdaten werden von einer lokalen API abgerufen:

Die abgerufenen Daten werden dabei in den entsprechenden Zustandsvariablen snowData und weatherData gespeichert. Ebenfalls ist eine Fehlerbehandlung vorahnend, um Netzwerkfehler und fehlerhafte API-Antworten zu behandeln. Die Darstellung erfolgt über benutzerdefinierte Komponente, welche die jeweiligen Wetterinformation anzeigen, einschliesslich Temperatur, Wetterbedingungen, Windgeschwindigkeit und Windrichtung. Dabei erfolgt das aufrufen der Wetterinformationen über weatherData.md_temperatur, weatherData.md_wetter, weatherData.md_windrichtung, weatherData.md_windgeschwindigkeit. Wetter und Windrichtung verwenden Material-UI-Icons zur visuellen Darstellung.

Statistiken

Im Statistik-Menü finden Sie alle relevanten Informationen zu vergangenen Skitagen. Hier können Sie Vergleiche über die gesamte Saison hinweg anstellen, verschiedene Saisons miteinander vergleichen oder einzelne Tage im Detail auswerten.

Konzept

Das Menü Statistiken zeigt die Informationen zu den gefahrenen Pistenkilometern. Die Informationen stammen vom Live-Tracking. Das Menü ist aufgeteilt in verschiedene Tagesstatistiken und den Saisonverlauf. Für jeden Tag wird die zurückgelegte Distanz angezeigt, sowie Höhenmeter, Dauer des Wintersporttages und die Anzahl der benutzten Anlagen. Der Saisonverlauf zeigt die über die gesamte Saison zurückgelegte Distanz sowie weitere Informationen und den Tagesdurchschnitt. Für jeden Tag wird der zurückgelegte Weg in der Karte dargestellt. Dieser erscheint nach Anklicken der jeweiligen Tagesstatistiken. Unterhalb der Karte sind zwei Liniendiagramme, welche die Geschwindigkeit und die Höhenmeter in Abhängigkeit der Zeit abbilden. Zum einen kann der ganze Tag abgespielt werden in der Karte und im Diagramm, zum andern kann im Diagramm ein Zeitpunkt ausgewählt werden. Der Marker springt dann zur Position in der Karte zum entsprechenden Zeitpunkt. So kann der Wintersporttag analysiert werden.

Funktion

Statistiken

Statistiken Viewer

Beispiel: http://localhost:3000/StatistikenViewer?Skidaten_ID=6.

Balkendiagramm

Im Menü Navi wird der Start- und Zielpunkt auf der Karte an die gewünschte Position verschoben. Der kürzeste Weg zum Ziel wird danach in der Karte als Route hervorgehoben. Durch das Anklicken des Reset Button verschwinden die Marker und die Route von der Karte.

Alle Relevanten Dateien sind im Ordner Routing gespeichert.

Konzept

Die Navigation basiert auf den Daten der Pisten und Anlagen. Diese müssen zuerst aufbereitet werden und sind in separaten Tabellen angelegt. Das Routing wird serverseitig in der Datenbank berechnet. Dafür wird die Extension pgrouting verwendet.

Bei der Nutzung wird ein Startpunkt angegeben. In einem ersten Schritt wird in der Datenbank nach dem nächsten Startpunkt (Node) gesucht. Dasselbe passiert mit dem Zielpunkt. Über ein topologisches Netzwerk aus gerichteten Graphen (edges) wird dann die kürzeste Distanz mithilfe des Dijkstra Algorithmus errechnet.

Aufbereitung der Daten

Die Daten werden in der FME Workbench Routing_geoserver.fmw aufbereitet. Dabei wird eine Verbindungslinie zwischen den Anlagen und Pisten berechnet um ein durchgängiges topologisches Netzwerk zu erhalten. Grund für die Aufbereitung ist, dass beide Datensätze verschiedene Datengrundlagen haben. Die jeweiligen Start- oder Endpunkte schliessen dabei nicht aufeinander ab. In einem weiteren Schritt werden alle Linien die beidseitig sind, dupliziert. Beim Duplikat wir die Orientierung gedreht.

Für das Routing muss die Datenbank erweitert werden. Aus der Datei alpine_ace_routing_DB_erweitern.txt wird der SQL Code geladen der in der Datenbank mit einem SQLExecutor ausgeführt wird in der Datenbank. Es werden dabei zwei Tabellen erstellt. a_a_routing für das Routing der Pisten und a_a_anlage_routing für das Routing der Anlagen. Beide Tabellen sind nur für die Berechnung des Routings relevant und nachher inaktiv.

Zuerst werden die Koordinaten Start- und Endpunkte der Anlagen und Pisten extrahiert. Dann werden die Anlagen Endpunkte mit dem Pisten Startpunkt über den NeighborFinder gematcht . Genau gleich werden die Pisten Enden mit dem Anlagen Startpunkt über den NeighborFinder gematcht . Bei beiden Schritten ist die Anzahl der Matches nicht begrenzt und die Maximaldistanz kann über den UserParameter max_distanz_anlagen_end_pisten_start, respektive max_distanz_pisten_end_anlagen_starteingegeben werden. Der Standardwert ist 50 Meter. In einem zweiten Schritt werden die nicht gematchten Anlagen Endpunkte mit den Pisten Startpunkten gematcht. Dasselbe gilt für die nicht gematchten Pisten Startpunkte. Auch wieder mit dem NeighborFinder und nur einem Match mit einer Maximaldistanz von 120 Meter. Bei ersten Schritt mit der kürzeren Distanz werden nur die umliegenden Verbindungen hergestellt. Beim zweiten Schritt werden längere Verbindungen hergestellt, damit alle Anlagen oder Pisten in Netzwerk untereinander verbunden sind. Um zu verhindern, dass falsche Verbindungen entstehen ist nur ein Match zugelassen. Die Distanzen 50 Meter und 120 Meter sind Erfahrungswerte. Die Geometrien der Punkte werden anschliessend gelöscht. Mit den zuvor extrahierten Koordinaten wird anschliessend ein Punkt erstellt. Zwischen den jeweiligen Start und Endpunkten wird eine direkte Verbindungslinie berechnet. Die Orientierung der Line ist von oben nach unten. Die Pisten aus der Datenbank werden anschliessend mit den Verbindungslinien zusammengeführt. Alle Linien die das Attribut routing_einweg = true haben werden dupliziert und die Orientierung gedreht, damit in beide Richtungen eine Verbindung besteht. Die Verbindungen und Pisten werden in der Tabelle a_a_routing gespeichert. Dasselbe passiert mit den Anlagen welche beidseitig sind. Diese werden in der Tabelle a_a_anlage_routing gespeichert.

Manuelle Änderungen des Routings

Mit Hilfe des QGIS Projektes Alpine_ace_Routing.qgz können Änderungen in den Routing Tabellen vorgenommen werden. Beim Start des Projekts muss der Benutzername und das Passwort der Datenbank eingetragen werden.

Die Änderungen müssen in der Datengrundlage Routing vorgenommen werden . Es dürfen nur die Tabellen a_a_routing und a_a_anlage_routing angepasst werden. Der Pfeil zeigt jeweils die Orientierung der Verbindungslinien an. Nach vollbrachter Änderung muss die Berechnung des Routings in pgAdmin 4 erfolgen.

Falls die Fehlermeldung: Konnte Änderungen am Layer a_a_routing nicht festschreiben Fehler: FEHLER: Ein Objekt nicht hinzugefügt. erscheint, liegt dies meist an der Vergabe der id in der Tabelle. Behoben kann dieses Problem werden, wenn unter: Eigenschaften --> Attributformular --> Verfügbare Element --> Fields --> id --> Vorgaben den Ausdruck maximum( "id" ) + 1 eingefügt wird. Dieser erhöht den aktuell höchsten Wert der id um 1 und setzt diesen ins Attributformular automatisch ein. Zusätzlich die Checkbox bei Vorgabewert bei Aktualisierung anwenden setzen.

Berechnen des Routings

Im pgAdmin 4 wird anschliessend das Routing berechnet, der Code dafür liegt in der Datei alpine_ace_routing.txt. Zuerst werden für die Anlagen und die Pisten separat die Knoten berechnet mit dem Befehl pgr_nodeNetwork. Daraus resultieren die beiden Tabellen a_a_routing_noded und a_a_anlage_routing_noded Dies geschieht getrennt, da überall, wo sich zwei Linien schneiden, ein Knoten erstellt wird. Da die Anlagen über den Pisten sind dürfen zwischen diesen Linien keine Punkte erstellt werden. In die beiden Tabellen werden die Attribute der Ursprungsdaten kopiert. Die Knoten der Anlagen werden in Tabelle a_a_routing_noded kopiert. Darin wird das Routing gerechnet mit dem Befehl pgr_createTopology.

Ursprünglich war geplant, die Funktion Einweg Routing über die reverse_cost zu steuern. Deshalb wurden Kosten in Abhängigkeit der Distanz vergeben. Wenn eine Strecke einseitig ist, wurde zu den reverse_cost eine Million addiert. Für beidseitige Strecken sind die Kosten in beide Richtungen gleich. Dies findet aber im jetzigen Routing keine Anwendung, da beidseitige Strecken doppelt in beide Richtungen im Datensatz vorhanden sind.

SQL views Routing

Für das Routing werden zwei SQL views benötigt.

SQL view a_a_nearest_vertex:

SELECT
    v.id,
    v.the_geom
FROM
    a_a_routing_noded_vertices_pgr AS v,
    a_a_routing_noded AS e
WHERE
    v.id = (
        SELECT
            id
        FROM
            a_a_routing_noded_vertices_pgr
        ORDER BY
            the_geom <-> ST_SetSRID(ST_MakePoint(%x%, %y%), 2056)
        LIMIT 1
    )
    AND (e.source = v.id OR e.target = v.id)
GROUP BY
    v.id, v.the_geom

Diese SQL view bekommt als Parameter das Koordinatenpaar %x% und %y% mit dem Wertebereich ^[\d\.\+]+$ Dieser lässt Positive Gleitkommazahlen zu. Es sucht in der Tabelle a_a_routing_noded den nächsten Knoten. Ausgeben wird die Geometrie des Knotens und die id. Beispiel: http://localhost:8080/geoserver/wfs?service=WFS&version=1.0.0&request=getFeature&typeName=Alpine_Ace:a_a_nearest_vertex&viewparams=x:2648338;y:1137974;&outputformat=application/json

SQL view a_a_shortest_path_test:

SELECT
    min(r.seq) AS seq,
    e.old_id AS id,
    e.p_farbe,
    sum(e.distance) AS distance,
    ST_Collect(e.the_geom) AS geom,
    sum(e.cost) AS cost,  -- Adding the 'cost' column
    sum(e.rcost) AS rcost  -- Adding the 'rcost' column
FROM
    pgr_dijkstra(
        'SELECT id,source,target,distance AS cost, rcost FROM a_a_routing_noded', %source%, %target%, false
    ) AS r,
    a_a_routing_noded AS e
WHERE
    r.edge = e.id
GROUP BY
    e.old_id, e.p_farbe

Diese SQL view bekommt als Parameter die Knoten ID des Startpunktes %source% und des Zielpunktes %target% mit dem Wertebereich \d+, der nur positive Integer zulässt. Mit Hilfe des Dijkstra Algorithmus wird die kürzeste Distanz zwischen den beiden Punkten im Topologie Netzwerk berechnet. Ausgegeben werde die einzelnen die Geometrien der Strecken, seq (Sequenznummer für die Reihenfolge), p_farbe und die distance. Beispiel: http://localhost:8080/geoserver/wfs?service=WFS&version=1.0.0&request=GetFeature&typeName=Alpine_Ace:a_a_shortest_path&viewparams=source:3862;target:2114;&outputformat=application/json

Dijkstra ist ein Algorithmus mit welchem der kürzeste Weg zwischen Start und Ziel, in einem Netzwerk berechnet werden kann. Dies ist mit Einbezug von von Kosten möglich, in diesem Fall dem Abstand zwischen den Konten (Distanz). Der Dijkstra Algorithmus kann auch die Heuristik miteinbeziehen. Diese ist eine Schätzung, welche eine Annäherung zur optimalen Lösung ist.(geoinformation.net o.J) Diese muss aber nicht korrekt sein. Die Annäherung kann zum Beispiel die Luftlinie zwischen Start und Endpunkt sein. Der Dijkstra Algorithmus mit Heuristik wird als A\* bezeichnet. Mit der Schätzung ist der Algorithmus meist schneller, da dieser einen Anhaltspunkt hat in welche Richtung die Suche los gehen soll.(Sun/Ding/Jiang 2017)

Wieso wird nicht der A\* Algorithmus verwendet? Die Luftlinienschätzung funktioniert bei den Anlagen weniger gut, da diese dem Gelände hinauf verlaufen. Dabei nicht immer in die Richtung des Zielpunktes zeigen. Der Geschwindigkeitsgewinn ist bei grossen Netzwerken mit mehren hundert Knoten signifikant. Da aber die längste Strecke in der Lenzerheide von der Bergstation Piz Scalottas zur Brüggerhorn Black Diamond Piste nur 87 Teilstücke umfasst, ist dies nicht sehr lange. Dies bedeutet, der Zeitgewinn bei diesem einfachen Netzwerk ist nicht gross. Um aber dies Umfassend zu klären müssten beide Algorithmen an den Daten getestet und verglichen werden.

Funktion

Durch anklicken der Schaltfläche START oder ZIEL wird der Start, respektive Ziel Marker in den Mittelpunkt des Kartenausschnittes gesetzt. Sobald der Start oder Ziel Marker erstellt ist, wird die Schaltfläche für das erstellen deaktiviert. Den Start und Ziel Marker mittels des Attribut markerType unterschieden. Das Icon bezieht der Marker aus der Ordner Karte_Symbole vom online Github Repository, da dies per lokalen Ordner nicht funktioniert. Mit der Position des Markers wird über die Funktion fetchNearestVertex mit der SQL View a_a_nearest_vertex die nächste Node_ID gesucht. Diese wird dann als nodeSource beim Start Marker und als nodeTarget beim Ziel Marker gesetzt. Wenn die Marker verschoben werden, wir die Funktion fetchNearestVertex wieder aufgerufen und die Node_ID aktualisiert. Wenn die nodeSource oder nodeTarget den Wert ändern wird die Funktion handleLoadRoute gestartet. Diese löscht als erstes die alte Route und lädt die neue Route mit der SQL View a_a_shortest_path in der die Parameter nodeSource und nodeTarget verwendet werden. Der Stil für den Layer kommt aus der Datei kartenLayerStyle.js, dem CSS für die Layer Symbolisierung.

Mit der Funktion resetMarkerUndRoute wird durch anklicken von der Schaltfläche RESET gestartet. Dabei werden die Marker und den Routen Layer gelöscht. Die Schaltflächen START und Ziel werden wieder aktiviert (verwendbar).

In der Karte sind die Layer Pisten und Anlagen mit der Winterlandeskarte im Hintergrund. Der Import der WFS und WMS Daten, die Symbolisierung, die Quellenangaben der Hintergrundkarte und das Zoomen auf einen vorgeben Bereich über die Schaltfläche E ist gleich wie in der Karte der Mit der Funktion setZIndex wird die Darstellungsreihenfolge gesetzt. Dabei ist 1 zu unterst und 5 zuoberst:

  1. Winterlandeskarte
  2. Pisten
  3. Anlagen
  4. Route
  5. Marker

Restaurant

Die Restaurants des Skigebietes werden in Kacheln angeordnet. In diesen Kacheln ist jeweils ein Bild des Restaurants und darunter der Name. Nach dem Anklicken einer Kachel wird das gewählte Restaurant in der Karte dargestellt. Unterhalb der Karte werden die Informationen zu Öffnungszeiten und Kontaktinformationen wie Telefonnummer oder Webseite angezeigt.

Beim Datenimport in die Datenbank werden die Koordinaten von WGS84 in LV95 transformiert. Anschliessend wird jedes Restaurant mithilfe des NeighborFinder dem nächsten Skigebiet zugewiesen.

Funktion

Vom Hauptmenü aus kann auf die Schaltfläche Restaurants navigiert werden. Dort befinden sich die Bilder der Restaurants und unterhalb der dazugehörige Name. Beim Anklicken des Bildes oder Textes öffnet sich die Karte und es wird auf die Position des Restaurants gezoomt. Unterhalb der Karte werden die Informationen angezeigt.

Upcoming Features

Folgende Features werden in der AlpineAce V2.0 eingebaut. Die Datenbank ist dafür bereits ausgelegt, was die Implementierung der Features vereinfachen sollte.

Upcoming features in AlpineACE V2.0

Aktueller Standort

In der Karte wird die aktuelle Position des Gerätes angezeigt mit einem Marker. Dies erleichter das Nutzen der Karte und die Navifunktion.

Karten Legende

In der Karte werden alle Symbole erklärt. Zusätzlich lassen sich die verschiedenen Layers beliebig ein und ausblenden.

Karte mit Legende

Karten Zoom

In der Karte kann das Zoomen zur Piste oder Anlage verbessert werden. Es wird momentan nur ein Teil der Linie dargestellt. Dies könnte behoben werden beim Import im geoserver_Datenimport.fmw. Pisten und Anlagen könnten mit dem Transformer Aggregator nach dem Attribut Namen als eine Geometry zusammengesetzt werden. Im Frontend ist die Funktionalität nach der Ausdehnung der Geometrie bereits vorhanden.

Aktuelle Dashboard Daten

In Version 2.0 werden die Daten im Dashboard direkt von den Webseiten der Bergbahnen bezogen, um stets die aktuellsten Informationen bereitstellen zu können. Die Daten werden dann alle 15 min aktualisiert, somit ist eine hohe Aktualität gewährleistet. Eine weitere Möglichkeit wäre Webscraping von der Webseite Bergfex. Auf dieser sind sämtlich Anlage und Pisten Informationen von Skigebieten der Schweiz vorhanden. Das Webscraping müsst so nur für einer Webseite programmiert werden und nciht für jedes Skigebiet neu.

Status Pisten und Analgen

Das Attribut Status ist bei den Pisten und Analgen momentan leer. Wenn die Daten von Bergbahnen automatisch bezogen werden, könnten geschlossene Pisten und Analgen zusätzlich in der Karte differenziert symbolisiert werden. Auch das Routing könnte so angepasst werden, damit nur Routen angezeigt werden über offene Pisten und Anlagen. Das Datenbankschema wäre bereit für dieses Feature. Es existiert das Attribut Status auch in den Routing Tabellen. Wäre diese offen, ist das Attribut Status true und wenn geschlossen false.

Mehrere Skigebiete

Damit das Skierlebnis sich nicht nur auf ein Skigebiet beschränkt, wird es möglich sein, mehrere Skigebiete auszuwählen. Dabei muss beim Starten der Web-App das gewünschte Skigebiet gewählt werden und anschliessend werden die Informationen des ausgewählten Skigebiets dargestellt. Es wird möglich sein, Favoriten festzulegen, damit nicht immer gesucht werden muss.

Auswahl des Skigebietes

Bewertungen

Mit einem Bewertungsmenü sollen die Nutzer sowohl Restaurants als auch die Pisten bewerten können. Somit lassen sich Daten über die Nutzererfahrung und das Qualitätsempfinden sammeln. Das Bewertungsmenü wird dabei nach einem Restaurant Besuch automatisch geöffnet. Es kann aber auch manuell über das Hauptmenü geöffnet werden.

Bewertung Restaurant

Einstellungen

In den Einstellungen kann die Webapp an die Bedürfnisse des Nutzers angepasst werden. Wenn die Einstellungen verändert werden, muss dies mit dem Knopf speichern bestätigt werden. Folgende Einstellungen werden möglich sein:

Einstellungen des Profiles

Benutzerkonto

Um Ihr Skierlebnis weiter zu verbessern, wird es bald möglich sein, ein Benutzerkonto anzulegen. Mit einem Konto kann man seine Statistiken sicher speichern und die Daten sind nicht mehr an ein einzelnes Gerät gebunden. So wird das individuelle Nutzungserlebnis optimal unterstützt.

Live Tracking

Um den Vergleich von Skitagen zu vereinfachen, wird ein Live-Tracking in die App integriert. Dadurch ist das Aufzeichnen nicht mehr von einem zusätzlichen Gerät wie einer GPS-Uhr abhängig. Die Tracking-Funktion kann einfach durch ein Wischen eines Buttons von links nach rechts aktiviert werden.

Rückmeldung Lawinen

Rückmeldungen aus dem Gelände sind unerlässlich für ein zuverlässiges Lawinenbulletin. Um die Rückmeldung zu gewährleisten, wird ein Button mit einer Verlinkung zum Rückmeldetool (https://pro.slf.ch/reply/public/#/) des Instituts für Schnee und Lawinenforschung gemacht. Damit kann ein Beitrag zu einem qualitativ hochwertigen Lawinenbulletin geleistet werden.

Reflektion

Das Projekt war sehr umfassend mit verschieden Herausforderungen über alle Projektphasen hinaus.

Gelerntes in diesem Projekt

Besprechungen mit Whiteboard : Die regelmässigen Besprechungen im Team haben sich als äusserts wertvoll erwiesen, um das weitere Vorgehen zu planen, Probleme zu lösen und neue Ideen zu entwickeln. Durch die kontinuierliche Nutzung eines Whiteboards konnten wir unsere Gedanken und Pläne effektiv visualisieren. Diese Visualisierungen ermöglichten es uns, verschiedene Ansätze schnell auszuprobieren und zu bewerten. Das Whiteboard hat sich dabei als unverzichtbares Planungstool etabliert und wesentlich zur Effizienz unserer Meetings beigetragen.

API Datenbezug : Bezug von Daten mittels API-Adressen und Speicherung in ein RDBS.

Geoserver : Aufsetzen und Betreiben des GeoServer auf den Betriebssystem Windows und Raspberry Pi OS.

SQL Views : Mit SQL Views auf dem GeoServer können nur gewünschte Objekte per WFS bezogen werden. Die Parameter werden dabei per URL übergeben. Es konnten verschiedenste SQL Views mit unterschiedlichen Parameter, Wertebereiche und Funktionen kreiert werden.

React App Mobile Version : Entwickeln einer React Webseite spezifisch auf mobile Endgeräte. Die Komponenten passen sich dabei automatisch der Grösse des Bildschirms an.

CORS : Was Cross-Origin Ressource Sharing ist und wie dies in der Express-API und im GeoServer gehandhabt wird, damit schlussendlich Daten auch auf Drittgeräten angezeigt werden.

Open Layer : Mit der Open Layer Bibliothek konnten unterschiedliche Funktionen genutzt werden.

Routing : Mithilfe der Erweiterung pgrouting konnten Routing Netzwerke über mehrere Ebenen berechnet werden. Dabei wurde vertieftes Verständnis für das automatische Erstellen von Knoten, Netzwerk Topologien (gerichtet/ungerichtet, gewichtet/ungewichtet) und Routing Algorithmen (Dijkstra, A\*) erworben.

Vega Diagramme : Die Nutzung von Vega und Vega-Lite hat sich als äusserst effektiv erwiesen, um Daten anschaulich im Zusammenhang mit Javascript darzustellen. Diese beiden Tools bieten eine flexible und leistungsfähige Möglichkeit zur Datenvisualisierung, die uns geholfen hat, komplexe Datensätze verständlich und übersichtlich zu präsentieren.

Git Hub README : Im README wurde eine Installationsanleitung für das Projekt erstellt und getestet. Es sind die ersten Erfahrungen, um ein README zu schreiben. Bisher wurde dieses nur gelesen. Dies ist ein spannender Perspektivenwechsel..

Git Hub Page : Erstellen einer Web-Dokumentation auf GitHub mit Markdown-Dateien.

Probleme

CORS : Den Zugriff auf andere Webressourcen in der React App wurde zuerst nicht definiert. So wurde Teile der Webseite nicht geladen.

Routing : Zuerst wurden die Konten für die Pisten und Anlagen gemeinsam erstellt. Dies hatte zur Folge, dass die Navigationsroute beim Kreuzen die Anlage genutzt und/oder verlassen hat. Das konnte gelöst werden, indem die Konten getrennt berechnet wurden. Dies brachte zusätzliche Komplexität mit den Attributen der Routen Tabellen und der manuellen Bearbeitung.

GIT Hub merge conflict : Mehrmals während der Bearbeitung des Projekts entstanden Konflikte, da an der gleichen Stelle im Code gearbeitet wurde. Dies konnte mit verbesserter Kommunikation gelöst werden. Die Verbindungsinformationen waren der häufigste Grund für ein Konflikt. Dies konnte mit einer separaten Config-Datei gelöst werden, welche in der gitignore-Datei eingetragen ist.

GIT Hub Limit : Das DHM25 mit einer Grösse von mehr als 100Mb können nicht hochgeladen werden. Wird dies versucht, entsteht ein Fehler und blockiert das ganze GitHub-Repository. Gelöst wurde dies mit einem Eintrag in der gitignore-Datei. Der Bezug vom DHM25 wurde mittels automatischen Download Skript gelöst. Dieses führt die den Download aus, entzippt dieses und legt es im korrekten Verzeichnis ab.

Namenskonventionen : Teilweisse änderten sich die Namen von Funktionen im Laufe des Projekts. Dabei mussten Dateinamen und Konstante über alle Skripts angepasst werden. Mit bessere Absprache untereinander und einer guten Umbenennungsfunktion konnte dem Problem entgegengesetzt werden. Die Mischung zwischen den Sprachen Deutsch Englisch besteht aber weiterhin.

Vega : Es traten Probleme mit der Darstellung von Daten der Datenbank, welche über eine Express-API bezogen werden, mit Vega auf. Daher sind alle verwendeten Diagramme momentan noch Hard gecoded.

Vorgehen nächstes Projekt

Probleme Unterteilen : Probleme in kleinstmögliche Form reduzieren und sich Hilfe in Foren suchen oder Chat-GPT konsultieren. Nutzer von Foren helfen nur, wenn der Code kurz und dieser gut beschreiben ist (teilweise wird der Fehler beim Dokumentieren bereits gefunden).

Funktionen : Mehr Funktionen schreiben, um Redundanzen möglichst klein zu halten. Faustregeln: Wird der gleiche Code mehr als drei Mal verwendet im Projekt gehört dieser in eine Funktion.

Verbindungsinformationen Datenbank : Wenn möglich alle Verbindungsinformationen für alle gleich (DB Name, Passwort, Host und Port) während der Entwicklung und diese in separaten Config-Dateien speichern.

Sprache und Namenskonventionen festlegen : Vor dem Projekt Start sollte die Sprache (Code und Dokumentation) festgelegt werden. Für den Code sollte ausschliesslich Englisch genutzt werden. Schreibfehler können mit einem Rechtschreiben-Plug-in verhindert werden.

Quellenverzeichnis

Folgend sind alle Quellen für diese Arbeit in mehreren Kategorien unterteilt und aufgelistet.s

Literatur

geoinformation.net (o.J.). Lernmodul 7: Geo-Algorithmen und -Datenstrukturen - Dijkstra-Erweiterungen. URL: http://www.geoinformation.net/lernmodule/folien/Lernmodul_07/druck/lm7_le2.pdf [Zugriffsdatum: 28. Mai 2024].

SUN, Yan-Jiang/DING, Xiang-Qian/JIANG, Lei-Na (2017). Heuristic Pathfinding Algorithm Based on Dijkstra. In. Qingdao, Shandong, China. DOI: 10.2991/eeeis-17.2017.59.

Datenquellen

Namen der Datenquelle

Link

Wetterdaten

https://open-meteo.com/

Lawinensituation

https://aws.slf.ch/api/bulletin/caaml

Schneehöhe

https://measurement-api.slf.ch/

Haltestellen

https://www.google.com/maps

Anlagen

https://www.swisstopo.admin.ch/de/landschaftsmodell-swisstlm3d

Pisten

data.opensnowmap.org.

DHM25

https://www.swisstopo.admin.ch/de/hoehenmodell-dhm25

Libraries

Python

Namen der Library

Link zur Dokumentation

openmeteo-requests

https://pypi.org/project/openmeteo-requests/

psycopg2

https://www.psycopg.org/docs/

requests

https://pypi.org/project/requests/

requests-cache

https://pypi.org/project/requests-cache/

retry-requests

https://pypi.org/project/retry-requests/

pyproj

https://pyproj4.github.io/pyproj/stable/

pandas

https://pandas.pydata.org/

shutil

https://docs.python.org/3/library/shutil.html

JavaScript

Namen der Library

Link zur Dokumentation

React

https://react.dev/

MUI

https://mui.com/

npm

https://www.npmjs.com/

Vega

https://vega.github.io/vega/

Express

https://expressjs.com/de/api.html

Verwendete Hilfsmittel

Namen des Hilfsmittel

Anwendungsfall

Link zur Webseite

Duden

Synonym Suche

https://www.duden.de/

German - Code Spell Checker

Rechtschreibprüfung in der Dokumentation

https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker-german

deepl

Rechtschreibprüfung in der Dokumentation

https://www.deepl.com/de/translator

ChatGPT

Code Beispiele, Code Fehlersuche

https://chatgpt.com/

Contribution

Zurück nach oben