Dienstag, 18. Juni 2013

GSAK-Macros: Buttons und Online Index

Voraussetzung: Der Einstieg in die GSAK Macro Welt

Einen Button für das Macro definieren


Abbildung 1: Wie heißt mein Button, welchen Text und Beschreibung soll er erhalten und wo ist das zugehörige Macro?
Damit wir den großen Batzen an Macrowissen aus dem Macro Einstiegstutorial besser verdauen können, wird es heute etwas übersichtlicher. Wir wollen lediglich bestehende Macros mit Buttons versehen und diese in er Speedbar (oberhalb der Cacheübersicht, da wo schon "Datei öffnen", "Drucken" usw definiert sind) anordnen.
Wir beginnen mit Macro->Button Configuration und wählen im ersten Feld einen noch unbelegten Button, z.B 7 - M7. Im nächsten Feld geben wir den zugehörigen Text ein. Dieser sollte nicht zu lange sein, damit er in die standardmäßig definierten 28 x 28 Pixel passt. (Alternativ kann man unten links die Breite raufsetzen, wenn der Button breiter werden soll). Für unseren "Init" Text reichen 28 Pixel aber aus. Button Description and Hint bezeichnet den Text der erscheint, wenn man mit der Maus über dem Button ein paar Sekunden verweilt und kann dazu genutzt werden eine genauere Beschreibung einzublenden.
Das wichtigste Feld ist der Macro file name in dem man den Pfad zum geschriebenen oder heruntergeladenen Macro (siehe unten) eintragen bzw. auswählen kann.
Ganz nützlich ist auch die Vorschau unten rechts im Abschnitt Toolbar sample wo ihr euch direkt ansehen könnt, ob der Text nicht zu lang für die Breite ist.

Abbildung 2: Um die Speedbar anzupassen, einfach den Button auswählen (eigene Buttons sind unter Macros) und per Drag&Drop auf die Speedbar ziehen.
Ist der Button erst einmal definiert, gilt es ihn noch auf die Speedbar zu ziehen. Dazu öffnen wir Macro->Add Button to Tool Bar wählen unter Macros (dort sind die 20 selbst definierbaren Buttons zu finden) unseren Init-Button aus und ziehen ihn per Drag'n'Drop auf unsere Speedbar an die gewünschte Stelle und ...
sind schon fertig. So einfach geht das.
Um einen Button wieder zu entfernen ziehen wir ihn einfach von der Speedbar aus nach unten, bis er außerhalb der Speedbar ist und quasi verschwindet. Maustaste loslassen und unser Button ist zwar nicht Geschichte, aber nicht mehr auf der Speedbar sichtbar.
So sammeln sich je nach Intensität und Funktionen mit denen man GSAK nutzt mehr und mehr Buttons / Macroshortcuts in der Speedbar an. Zum Glück ist dort ne Menge Platz.

Abbildung 3: Je intensiver man GSAK nutzt, desto größer wird die Button-Anzahl in der Speedbar.

Macro Online Index

Es muss aber nicht immer ein selbstgeschriebenes Macro sein. Geht man auf Macro->Run/Manage->Online Macro Index oder direkt auf http://gsak.net/board/MacroIndex.php so hat man Zugang zu einer riesigen Bibliothek an Macros für jeden Zweck. Gebt das passende Schlagwort (z.B Project81 für ein Macro, das euch die Caches raussucht, deren D/T Wertung euch noch für die Matrix fehlt) und klickt auf den blauen Macronamen.

Abbildung 4: Im Online Index existiert bereits eine Flut von fertigen Macros die viel nützliche Funktionen bereit stellen
Die darauf folgende Seite ist wie ein Forum aufgebaut und ihr könnt die (Weiter-)Entwicklung des Macros studieren. Zum Download des Macros geht ihr zum letzten Eintrag und ladet so die aktuellste Version des Macros hinunter. Bei der Frage, was der Browser mit dem Macro machen soll, wählt ihr "Öffnen mit GSAK" und anschließend Install the macro.
Wenn euch das Macro gefällt könnt ihr wieder nen Button definieren und ihn auf die Toolbar schieben. Oder das Macro in euren Programmablauf einbauen, so wie wir das mit dem MoveFound-Macro im Init-Macro vollzogen haben.

Montag, 17. Juni 2013

Minesweeper ist online !!!

Keine zwei Wochen mehr bis zum Event der Events. Heute schonmal der erste (kleine) Paukenschlag: Um FTF-Stress während des Events zu vermeiden und um Erfahrungen mit dem neuen Minesweeper-WherIGo im freien Feld zu erhalten, wurde heute die Minensuchversion fürs GPSr freigeschaltet.
Unter GC4B061 kann man ab sofort hoch oben auf der Festung Ehrenbreitstein Minen suchen, markieren, graben und hoffen dass man nicht in die Luft fliegt. Natürlich alles im Secure-Mode mit Reset-Funktion. Wir wollen ja nicht, dass jemand ernsthaft zu schaden kommt.
Das Cartrigde erhaltet ihr über das GC-Listing oder direkt von der Wherigo-Seite.
Also Cartrigde runterladen, Listing ausdrucken (enthält Anleitung), ab ins Auto und auf geht's. Ein jungfräuliches Logbuch wartet schon auf euch.

Einführung in die GSAK Macro Welt

Voraussetzung: Pocket Queries importieren
Nachdem die letzen Tutorials sich mit PQs und deren Nutzung in GSAK beschäftigten, geht es dieses Mal mehr um GSAK selbst.
Ich möchte heute auf eine ganz entscheidene Komponente aufmerksam machen, die Verwendung von Macros. Mit diesen steht euch ein mächtiges Tool zur Verfügung um die tägliche Arbeit mit dem Programm zu vereinfachen und zu automatisieren.
Wir wollen zum Einstieg in die Macrowelt ein solches schreiben, dass in unserer Datenbank nach gefundenden bzw. eigenen Caches sucht und diese in eine eigene Datenbank verschiebt, damit wir in unserer default Datenbank nur noch Caches halten, die wir suchen wollen.
Dazu legen wir zunächst zwei Datenbanken mit dem Namen foundDB und ownDB an, indem wir auf Database-->New klicken und den gewüschten Namen eintragen.

Abbildung 1: Unser erster eigener Filter ist nicht zu kompliziert und beinhaltet als einzige Einschränkung uns selbst als Owner

Danach begeben wir uns an die Definition der Filter. Für unsere Funde stellt uns GSAK bereits einen Filter My Found Caches (GSAK Default) bereit, für unsere selbst gelegten Caches müssen wir allerdings ein klein bischen Arbeit investieren.
Nach einem Klick auf Search->Filter (alternativ Strg + F) erscheint das Fenster aus Abb.1. Da wir uns nicht auf bestimmte Cachearten oder andere Filterkritieren einschränken wollen müssen wir lediglich in der Zeile Placed by unseren Nickname eintragen und den Filter unter dem Namen My Own Caches abspeichern. (Auch hier ist der Name eigentlich Schall und Rauch, sollte aber im Hinterkopf behalten werden, da wir ihn später im Macro benötigen).
Mit einem Klick auf Save können wir die Speicheraktion einleiten.

Abbildung 2: Um die Verschiebung der Caches zu steuern legen wir eine Moveaktion an.
Die Filter sind vorbereitet, als nächstes geht es ums Verschieben. In GSAK muss man dafür im Move/Copy Dialog (erreichbar unter Database->Move/Copy Waypoints) angeben, wohin verschoben werden soll (je nach MoveAction foundDB bzw. ownDB), ob die Werte verschoben oder kopiert werden sollen und wie mit Werten umgegangen werden soll, die bereits in der Zieldatenbank vorhanden bzw. nicht vorhanden sind. Wir wollen aus der alten Datenbank verschieben, mit Einfügen bzw. Ersetzen in der neuen Datenbank. Den gesamten Dialog speichern wir als MoveAction Move to foundDB ab um es später im Macro verwenden zu können.
Damit unser Wissen auch lang hält, dürft ihr jetzt als Übung eine MoveAction definieren, die alle eigenen Caches in die passende Datenbank verschiebt. Die benötigte Datenbank sowie Filter haben wir weiter oben bereits vorbereitet.

Abbildung 3: In unserem ersten Macro verschieben wir alle Found in die foundDB und alle eigenen Cache nach ownDB
Die Vorbereitungen sind abgeschlossen, nun geht es endlich zum Macro an sich. Über Macro->Edit/Create gelangen wir zu einem Dialog wie in Abb. 3 zu sehen ist. (Genaugenommen bin ich über Macro->Run/Manage gegangen, da mein Macro bereits existierte. Da ihr es neu anlegen müsst, ist die Create Methode eure Wahl.
Die ersten Zeilen sind geprägt mit Infos über das Macro. Wer ist der Autor, wie heißt es und wichtig, falls ihr es im öffentlich Macro-GSAK-Verzeichnis einstellen wollt: Beschreibung und Version des Macros.
Alles was mit einem # beginnt ist Kommentarzeile und wird beim Abspielen des Macros nicht beachtet. So richtig los geht es erst in Zeile 8 mit der Anweisung FILTER.
Über das Attribute Name wählt ihr den vordefinierten Filter aus, der auf die akutell geöffnete Datenbank -sollte default sein-gesetzt werden soll.
Danach prüft das Macro ob es Caches gibt, für die diese Filterkriterien zutreffen. Auf deutsch: "Hab ich gerade gefundene Caches in meiner Datenbank".
Dies ist nach Zeile 10 definitiv nicht mehr so, denn hier wird mittels MOVECOPY mit den vordefinierten Einstellungen Move to foundDB alles verschoben, was der Filter hergibt.
Der Befehl ENDIF ist notwendig, falls ihr für die Caches aus dem Filter mehrere Kommandos ausführen wollt. Alles zwischen IF und ENDIF wird ausgeführt, wenn die Bedingung $_FilterCount > 0 zutrifft. $_FilterCount ist eine vordefinierte Variable von GSAK die beim Setzen eines Filters mit der Anzahl der Zeilen gefüllt wird, für die der Filter zutrifft. Um sicher zu stellen, dass ihr die weiteren Befehle nicht auf der foundDB sondern auf der Default Datenbank ausführt, setzt ihr die aktive Datenbank wieder auf Default. Es gab Versionen von GSAK, da wurde nach dem MOVECOPY die Zieldatenbank als aktive Datenbank gesetzt. Heute ist das nicht mehr so, aber sicher ist sicher und man sieht auch wie man eine Datenbank geziehlt auswählt.
Die letzten fünf Zeilen wiederholen eigenlich nur die ersten fünf, außer dass statt der gefundenen nun die eigenen gefiltert und verschoben werden.

Abbildung 4: Unser Init-Macro sollen die PQs herunterladen, gefunden und eigene Caches verschieben und abgelaufene Event entfernen.
Zum Abschluss des Tutorials erweitern wir das Aufgabengebiet unseres Macros auf alles was beim Start von GSAK durchgeführt werden soll:
  • Lade die aktuellen PQs
  • Verschiebe gefundene und eigene Caches
  • Entferne Event, die bereits stattgefunden haben
'Moment', wird sich der aufmerksame Leser von Pocket Queries importieren denken, 'bei der Definition der PQs haben doch die gefundenen sowie eigenen Caches ausgeschlossen'.
Dies ist soweit richig. In späteren Tutorials sehen wir, wie sich GSAK hervorragend zur Statistikgenerierung eignet. Dafür ist es aber notwendig alle gefundenen Caches in einer Datenbank zu pflegen. Aus diesem Grunde lasse ich alle paar Tage eine myFinds-PQ mitlaufen, die mir die gefundenen Caches im 50 km zuschickt. Details folgen in der versprochenen Fortsetzung.
Eigene Cache landen zwar immer noch recht selten in der Default Datenbanken (höchstens durch einmalige PQs die zwischendurch geniert werden bzw durch Einzelimport per GPX file-Button auf der GC-Seite) aber der Filter und die MoveAction diesbezüglich frisst kein bzw. nicht viel Brot und stört insofern nicht weiter. Sicher ist sicher, gell.

Nun aber zum Macro, als allererstes selektieren wir die Default-DB und führen mittels GcGetPg das Abrufen und Verarbeiten der PQs aus. Hier muss darauf geachtet werden das richtige Settings zu nehmen. Damit es zum letzten Tutorial passt, müsst ihr MyPQDLSettings statt PQDLMW nehmen.
Da wir das Verschieben der Funde a) als eigenes Macro belassen möchten (um diesen Schritt alleine ausführen zu können), b) aber die Anweisungen nicht wiederholen möchten (Codeduplikation ist für den Entwickler immer ein rotes Tuch) nutzen wir die Möglichkeit das jedes Macro Untermacros ausführen kann. Mit Macro unter der Angabe des Dateinahmens führen wir so in unserem Init-Macro einfach das MoveFounds Macro aus. Beide Datei müssen dafür im selben Macroverzeichnis sein, aber das schlägt euch GSAK beim Abspeichern schon korrekt vor.

Nach dem Motto, das Beste kommt zum Schluss nutzen wir in den letzen Zeilen den MFilter. Mit diesem Tool kann man OnTheFly Filter definieren, die a) nicht gespeichert werden müssen und b) nicht die Cache-Ansicht verändern. Will heißen MFilter betrifft nur die Auswahl der Caches im Macro. Sobald das Macro endet wird der Wert verworfen, während FILTER die Auswahl der in GSAK angezeigten Caches manipuliert. Im Where Attribute von MFilter führen wir SQL-ähnlich eine Einschränkung auf den Cachetyp (Event, Z für Megaevent und CITO) sowie das Plazierungsdatum was bei Events dem Tag des Events entspricht. date('now') ist eine GSAK-, bzw. sqlite-interne Funktion um das Tagesdatum zu ermitteln.
Auch hier wird wieder kontrolliert, ob überhaupt abgelaufene Events vorhanden sind und gegebenenfalls mit macrodelete action=delscope (löscht alle selektierten Caches) und macrodelete action=commit (schreibt die zunächst lokale Änderung auf die sqlite-Datenbank durch) entfernt. Hier sieht man auch warum IF mit ENDIF abgeschossen werden muss, da zwei Zeilen von der Bedingung betroffen sind.
Dies soll für heute reichen. Beim nächsten Mal wird es etwas einfacher. Da kümmern wir uns um den Klicki-Bunti-Teil "Wie definiere ich für mein Macro nen hübschen Button?"

Freitag, 14. Juni 2013

Pocket Queries in GSAK importieren

Voraussetzung: Daily Pocket Queries erstellen
In den ersten beiden PQ Tutorials wurde erklärt wie man ne PQ bzw. eine Reihe von regelmäßigen PQs erstellt. Heute geht es darum wie GSAK mit diesen PQs seine lokale Datenbank aktuell hält.

Abbildung 1: GSAK kann Pocket Queries über die Geocaching.com api herunterladen und verarbeiten.
Der Download der PQs ist relativ einfach zu handeln. Ihr klickt einfach auf Geocaching.com access und anschließend auf Download PocketQueries. Im darauffolgenden Fenster (siehe Abb. 1) werden alle verfügbaren PQs angezeigt, die ihr einzeln auswählen könntet. Im unteren Teil könnt ihr festlegen, wo die PQs abgelegt werden sollen und dass sie nach dem Download verarbeitet werden. Typischerweise werden sie in die vordefinierte Datenbank default importiert.

Abbildung 2: Normalerweise möchte man jede PQ nur einmal herunterladen
Jetzt wäre es bei einem Daily-Update ja eher suboptimal jedes Mal zu prüfen welche PQ bereits geladen wurde und welche noch zu markieren ist. Deswegen fühlen wir uns als fortgeschrittener User und lassen die Maustaste beim Reiter Advanced interagieren.
Wenn unser Bildschirm Abb. 2 ähnelt, wählen wir Download all Pocket Queries not yet downloaded und speichern die Einstellung der Download Pocket Queries Funktion als MyPQDLSettings ab. Der Name darf frei gewählt werden, ihr solltet ihn euch aber gut merken, in späteren Tutorials werden wir den Download-Schritt mittels Macros weiter automatisieren.

Abbildung 3: Der Download läuft. Zeit um sich zurückzulehnen oder den nächsten Mysterie zu lösen
Danach heißt es für ein paar Sekunden / Minuten sich zurückzulehen und abzuwarten, denn nun beginnt GSAK die PQs herunterzuladen und anschließend mit den bereits bestehenden Caches in der Datenbank zu mergen. D.h. neue werden hinzugefügt, bestehende werden aktualisert, falls sie nicht von euch als gesperrt markiert wurden (RMT auf Cache -> Edit -> Checkbox lock auswählen.)
Je nach Internetgeschwindigkeit (oder gerade zuschlagener Telekom-Drossel) könnt ihr auch die nächste Cachetour planen oder WherIBlog durchstöbern.

Abbildung 4: Nach der Verarbeitung der PQs erfolgt eine ausführliche Zusammenfassung der Ereignisse
Ist der Download und die Verarbeitung beendet, erhaltet ihr eine Übersicht der geladenen Waypoints, der aktualiserten Cache, der gelöschten Caches und vieles mehr. Am interessantesten bei dieser Ansicht ist die Tabelle Waypoints in each file .
Hier könnt ihr schnell kontrollieren, ob in euren PQs noch Platz ist, oder ob die 1000er Marke erreicht sind. Wie man in Abb. 4 erkennen kann sieht es noch ganz entspannt aus, lediglich im Zeitraum von September 2010 bis August 2011 könnte es vorkommen, dass die am weitesten entfernten Caches nicht mehr erfasst werden, wenn in den nächsten zwei Tagen die Cacheraktivität steigt und damit die Anzahl der in den letzten 7 Tagen aktualiserten Caches aus diesem Zeitraum über die Millegrenze steigt.
Was sehr positiv zu bewerten ist, ist die Tatsache, dass in der w27er Query noch genügend Platz ist. Diese PQ wird nämlich jeden Tag wachsen, da wir ja erst Juni 2013 haben und die PQ alle zukünftigen Caches bis zum November erfassen wird. Sollte der Wert hier die 1000 erreichen, sollte man darüber nachdenken eine w28 einzuführen.

Mittwoch, 12. Juni 2013

Pocket Queries für's tägliche Update

Voraussetzung: Der Einstieg in die Pocket Queries

Im Einsteigertutorial wurde beschrieben wie man eine einmalige PQ für Caches rund um einen Ort definiert.
Jetzt geht es darum mit GSAK eine möglichst aktuelle lokale Datenbank zu pflegen um sich eine eigenen Cacheauswahl aufs GPSr zu laden.

Geocaching.com API und tägliche PQ als erste Ansätze

Wozu der Aufwand mit PQs wird sich so manch einer denken, ich hab doch die Geocaching.com API und kann mir die Caches von GSAK aus direkt laden. Das stimmt, aber bei nem Limit von 6000 Caches pro Monat kommt man da auch nicht weit.

Abbildung 1: Die Daily-PQ soll jeden Montag, Mittwoch und Freitag laufen.
Der nächste Ansatz ist, sich jeden Tag eine PQ mit den Caches rund um seine Home-Location schicken zu lassen. Eigentlich keine schlechte Idee, es sei denn, man schaut mal, wie weit man damit kommt. Die meisten werden den 10 km Radius nicht überschreiten. D.h. wenn ich nicht im Nachbarort sondern einen Ort weiter unterwegs sein möchte, ist meine lokale Datenbank schon außerhalb ihrer Reichweite.

Was kann ich tun, um meinen Radius zu vergrößern


Daher stelle ich hier drei Optimierungsmöglichkeiten vor, um unseren Radius auszudehnen. Ich komme so auf eine lokale Datenbank, die Caches bis zu 50 Kilometer entfernt erfasst. Das sind meistens zw. 60 und 80 km Fahrstrecke und sollte als Home-Zone ausreichen. Alles darüber hinaus ist besser mit Spezial-PQs wie im Einsteiger-Tutorial beschrieben zu lösen.

Abbildung 2: Es reicht vollkommen aus, wenn ich nur die Änderungen der letzten 7 Tage mitbekomme.
Als erste Optimierung lasse ich mir nur die noch nicht gefundenen, nicht die eigenen und nur die Caches raussuchen, die in den letzten 7 Tagen ein Update (neuer Logeintrag, Listing oder Koors geändert) erfahren haben. Ausgehend von einer einmalig initialisierten Datenbank reicht es ja nur die Änderungen mitzubekommen.
Um den Initialzustand zu erhalten kann ich auf die 6000 Caches aus der API setzen oder mir ne Woche lang jeden Tag 5 PQ zuschicken, die alle aktiven Caches enthalten.
Außerdem werden die meisten Caches in den Sommermonaten mind. einmal im Monat angegangen, sodass ich recht schnell ne ziemlich komplette Datenbank haben. Was nicht dabei ist, ist meistens so schwierig, dass es eher unwahrscheinlich ist, dass ich einen solchen Cache spontan angehe.

Abbildung 3: Neben Home Location und Reduzierung des Radius kann man gut über das Datum der Cacheauslegung mehrere PQs trennen.
Aber auch das ist noch viel zu viel, da im Sommer die meisten Caches innerhalb der letzten 7 Tagen angegangen werden.
Als zweite Optimierung müssen wir eine Möglichkeit finden, nicht eine sondern 4 PQs pro Tag zu erhalten (1 PQ sollte man sich immer für Notfälle oder Spontansuchen übrig halten). Da stellt sich die Frage, wie kann man die Caches voneinander trennen, also in Gruppen bzw. Packete aufteilen. Die Entfernung von zu Hause ist keine Möglichkeit, da immer die nähesten genommen werden. Eine PQ mit Tradies, eine mit Multis u.s.w. ist zwar nen Ansatz aber kein guter, da es mehr als 4 Cachetypen gibt und der Radius für die Tradis wesentlich kleiner ist als für Multis oder gar WherIGos.
Was sich dagegen hervorragend anbietet, ist die Unterscheidung nach Plazierungsdatum, also wann wurde der Cache gelegt. Vereinfach gesagt, eine PQ für die ganz alten Dosen bis 2009, eine für 2010 und 2011, eine für 2012 und die vierte für das aktuelle Jahr. Dabei werdet ihr feststellen, dass für die aktuellen Monate immer schwieriger wird, die 1000er Marke nicht zu knacken, besonders da jeden Tag der Zeitraum größer wird. Dafür verschinden aber immer mehr Dosen aus den "alten Zeiten", da ihr sie entweder gefunden habt oder sie archiviert werden, da Versteck "verbrannt" ist, Naturschützer und Behörden aufmerksam geworden sind oder die Owner nicht mehr die Zeit für die Dosenpflege aufbringen wollen. Es lohnt sich also ab und zu zu konrollieren wie viele Caches im Schnitt durch ein PQ erfasst werden und die Zeiträume zu verschieben. Dann heißt es 2000-2010, 2011-Juni2012, Juli2012-Feb2013, März2013-Dez2013.

Abbildung 4: Da in den letzten 2 Jahren die Cacheanzahl explodiert ist, muss der Zeitraum umso kleiner gewählt werden, je näher er am Tagesdatum liegt. Auch reichen 4 PQs nicht mehr aus. Deswegen alle zwei Tage jeweils 4 ergibt 8 PQs.
Je nach Radius den ihr abdecken wollt, reichen aber auch 4 PQs nicht mehr aus. Ich bin deswegen zur Tradeoff gelangt, dass es reicht jeden zweiten Tag eine aktuelle Datenbank zu besitzen. Wie in Abb. 4 erkennbar ist, wird Montags, Mittwoch und Freitags die Caches Begin bis 01. Juni 2011 erfasst und Dienstags, Donnerstags und Samstags alle Caches ab 02. Juni 2011 bis heute.
Eine Codierung der Suchzeiten im PQNamen hilft ungemein, die Zeitfenster zu koordinieren. In der ersten Runde hab ich noch ein PQ frei. Sobald w27_021212-011113 die 1000er Marke regelmäßig knackt wird w24... zu w14... (d.h. Montags ausgeführt) und eine neue PQ w28_020713-010114erstellt. Wenn dann Ende des Jahres auch die achte PQ gefüllt ist, geht der Tanz von vorne los. Da muss ich entweder einen dritten Tag einführen (also mit 2 Tage alten Cachedaten leben) oder den Radius reduzieren. Der entspricht bei mir z.Zt 50 km, was verdammt viel ist, da die Fahrstrecke im Schnitt das 1,4 bis 1,5 fache der Luftlinie, also gut 70 km entspricht.
 Oder ich schreib weniger Tutorials und "bereinige" die PQ-Zone von den alten Caches .

Damit endet der zweite Teil der PQ-Einführung. Wir haben dieses Mal gelernt, wie man PQs so definieren und teilen kann, dass sie sich dazu eigenen eine lokale Datenbank wie z.B GSAK mit regelmäßigen Updates zu versorgen. Im nächsten Teil geht es darum, wie man die erzeugten PQs in GSAK importiert und was man damit machne kann.

Dienstag, 11. Juni 2013

Der Einstieg in die Pocket Queries

Ausnahmsweise geht es mal nicht um Wherigos sondern dieses Mal um Pocket Queries und (in den nächsten Tagen folgend) um GSAK und die Nutzung von Pocket Queries in GSAK. Vorneweg sei gesagt, dass das Feature der Pocket Queries (nachfolgend PQs genannt) nur den Premium Members zur Verfügung steht. Aber wer sich ein bischen mehr mit Geocaching beschäftig (und schonmal weiß das es nicht "Kätsching" heißt), der kommt schnell an den Punkt an dem er bereit ist 30 € im Jahr für sein Hobby zu zahlen. Da ich kein Freund von schlechten Übersetzungen bin, habe ich die Spracheinstellung meines GC-Profil auf englisch gelassen (ja, es gab mal eine Zeit, da war Geokätisch nicht Trendsportart Nr 1 und die Webseite wurde nur auf englisch betrieben). Es sollte aber keine allzu große Transferleistung sein, das Szenario mit deutscher Spracheinstellung nachzuspielen.

Was ist ein PQ?

Eine Pocket Query ist das Ergebnis einer Suchanfrage, mit der wir von geocaching.com die Daten mehrere Caches auf einmal erhalten. Technisch gesehen handelt es sich um eine GPX-Datei, was wiederum ein Datenformat zur Speicherung von Geodaten (GPS-Daten) auf Basis des XML-Standart ist. Wir erhalten die PQ, verpackt in einem zip Container als eMail, können sie vom geocaching.com Server herunterladen oder über die Geocaching.com API in Programme wie GSAK importieren.

Was mache ich mit einer PQ?

Es gibt zwei bedeutende Anwendungsscenarien für PQs:
  • Entpacken und als GPX aufs GPSr laden (z.B beim Garmin Oregon in \Garmin\GPX)
  • In GSAK importieren und somit eine lokale Datenbank aufbauen aus der heraus man Cache nach bestimmten Kriterien auswählen und aufs GPSr exportieren kann
Da es sich hier um ein erweitertes GSAK Turorial handelt, bevorzuge ich natürlich die zweite Variante. Ziel ist es einen möglichst aktuellen Zustand der potentiellen Cachegegenden zu haben um auf die Schnelle die 1000 Caches dabei zu haben, die man evtl. beim Wochenendausflug angehen möchte.

Wie erstelle ich eine PQ?


Abbildung 1: Wie heißt meine PQ, wann soll sie generiert werden und welche Cachetypen sind erlaubt?
Als Einstieg hab ich mir folgendes einfaches Scenario überlegt: Ich möchte gerne 1000 Caches rund um Freiburg haben. Es sollen Caches sein, die ich aktuell suchen kann, also weder inaktive noch Dosen, die von mir sind oder die ich bereits besucht habe.
Dazu gehen wir auf die PQ-Übersicht http://www.geocaching.com/pocket/default.aspx und wählen dort "Create a new Query". Anschließend kommen wir zur Konfigurationsübersicht wie in Abb. 1 zu sehen. Neben einem möglichst sprechenden Namen geben wir ein, dass wir die PQ einmal generieren, sie aber für spätere erneute Verwendung behalten und dem zu Folge nicht löschen möchten.
Außerdem setzen wir das Maximallimit von 500 auf 1000 Caches rauf und schließen keinen Cachetyp aus. ( Man könnte hier auch nur Tradies und Multis auswählen, aber solche Spielereien sind jedem selbst überlassen.)

Abbildung 2: Auch Cachegröße, gefundene, eigene und deaktiverte Dosen oder Dosen die mir zu schwer oder zu hoch im Baum sind lassen sich herausfiltern
Ebenso wie bei den Cachetypen wollen wir keine Cachegrößen ausschließen. Es wäre aber auch möglich nur nach den ganz großen Large Dose zu suchen.
Wo wir allerdings einschränkend aktiv werden ist die nächste Passage. So haben wir weder an bereits gefundenen noch an eigenen Caches Interesse. Auch deaktivierte Caches lassen wir links liegen.
Und was ist mit archivierten Caches? Die werden nie in PQs mitgeliefert. Für unseren Fall ganz praktisch. In späteren Tutorial werden wir aber sehen, dass das auch so seine Tücken hat.
Weitere Einschränkungen nehmen wir jetzt noch nicht vor. Im nächsten Tutorial wird die Sache hier aber schon ganz anders aussehen.
Auch bei Schwierigkeit und Terrain lassen wir die Auswahl offen. Freunde der Klettercaches könnten natürlich hier mit >= 5 oder vllt besser noch >= 4,5 die Auswahl verfeinern.
Nur noch angedeutet könnten wir in der Within Box ganze Länder bzw. Regionen / Bundesländer herausfiltern. Aber Vorsicht, mehr als 1000 Dosen gibt eine PQ nie heraus. Die Auswahl dürfte so in den wenigsten Fällen vollständig sein, wenn es nicht gerade Lichtenstein oder Vatikan sein soll.

Abbildung 3: Ganz wichtig ist der Mittelpunkt unserer Suche
Wo wir wieder aktiv werden, ist der From Origin Part der Konfiguration. Hier gibt es neben der Homezone (vorausgesetzt ihr habt eure Home Location ordentlich gepflegt) auch die Möglichkeit rund um eine gemessene Koordinate zu suchen. Da wir unser Schwarzwald-Urlaub-Quartier in Freiburg beziehen möchten, wählen wir die Koors dieser Stadt. Man kann auch nen GC-Code eines Caches angeben, dann werden dessen Koors als Mittelpunkt der Suche herangezogen.
Beim Radius hab ich die Suche auf dem Maximum von 100 Milen gelassen. Diese Obergrenze macht aber nur Sinn, wenn ich wesentlich kleinere Werte eintrage. 1000 Caches findet man heute oft im 20-30 km Radius. Aber 100 ist OK, wir wollen uns ja eigentlich gar nicht auf den Radius einschränken und bei der Suche werden die ersten 1000 Dosen, gemessen vom Mittelpunkt herangezogen.
Wann die Dose gelegt wurde ist uns (diese Mal genauso egal wie die Attribute die sie hat. Eltern mit kinderwagenkompatiblen Kindern können hier aber genauso einschränkend aktiv werden wie Taucher die nur Unterwassendosen suchen möchten. Da der Schwachpunkt bei der Filterung nach Attributen jedoch die Pflege eben dieser durch den Cacheowner darstellt, ist auch hier Vorsicht bei der Einschränkung geboten.

Abbildung 4: Die generierte Pocket Query würde uns per eMail zugeschickt, wenn da nicht die Einschränkung auf die 500 Caches wäre.
Den Abschluss der Konfigurationsmöglichkeiten bildet der eMail-Versand. Hier kann man der gewünschte eMail-Empfänger eingetragen werden, die Komprimierung ins Zip Format sollte man immer aktiv schalten um den Datentraffic nicht unnötig zu erhöhen. Der Name der PQ als FileName des Zips ist auch ne praktische Sache.
Einen Hacken hat die eMail-Verschickerei allerdings. Sie funktioniert nur bei PQs bis 500 Caches. Sind mehr in der PQ enthalten, so muss man die Datei händisch downloaden. Dies ist auch über die Hauptseite unter dem Reiter Pocket Queries Ready For Download möglich. Gilt auch für bereits per eMail verschickte PQs.

In diesem Tutorial haben wir gelernt wie man eine einfache PQ mit zu suchenden Caches rund um einen Ort erstellen. In der nächsten Ausgabe schauen wir, wie wir GSAK mit DailyUpdates versorgen können.

Freitag, 7. Juni 2013

Minesweeper beim Project-Eck kurz vor der Veröffentlichung

Es sind noch gut drei Wochen bis es endlich los geht und Project-Eck seine Tore öffnet. Unter anderem wird auch der neue Minesweeper-Wherigo verfügbar sein. Die Finaldose ist bereits versteckt und es laufen die letzten Beta-Tests.

Abbildung 1: So in etwas wird es aussehen, wenn du vor der Entscheidung deines Lebens stehst: Risikiere ich zu graben oder versuche ich es lieber nebenan?
Das Spiel orientiert sich dabei an der Windows-Version, die wir schon seit vielen Jahren kennen: Laufe über das Spielfeld und entscheide für jedes Minenfeld, ob du graben möchtest oder doch lieber das Feld als Mine markierst.

Abbildung 2: Puh, nochmals Glück gehabt, oder war es gut kalkuliert?. Nach dem Graben auf einem Feld weiß man ob die Rechnung aufgegangen ist oder ob man sich verrechnet hat
Hat man sich zum Graben durchgerungen, dauert es nicht lange bis man über Erfolg oder Desaster informiert wird. Hab ich richtig gerechnet? Wenn ja, dann wirst du mit weiteren Informationen belohnt, die dir hoffentlich helfen werden weitere Minen auszumachen. Manchmal hilft auch einfach nur raten.

Abbildung 3: Die Rechnung geht aber nicht immer auf. Aber keine Angst. Wenn du ne Mine erwischt hast beginnt das Spiel von vorne und es heißt wieder: "Neues Spiel, neues Glück"
Strapaziere deine Glück aber nicht zu sehr. Beim ersten Fehlgriff war es das mit deiner Baggerkarriere und du fliegst samt deinem Grubengrabgerät in die Luft. Aber im Gegensatz zur Realität geht es klimplich aus und du kannst sofort wieder von vorne starten. Obwohl: So wenig ist es schon schade, dass man dem WIG-Player keine Vibrationskommandos mitgeben kann, ähnlich nem Gamepad-Kontroller.

Abbildung 4: Ganz so viele Minen wird es nicht geben, aber ein Kinderspiel ist es trotzdem nicht.
Es sind nicht mehr viele Male die ihr noch schlafen müsst ehe das Christkind kommt, äh ich meine bis zum Event der Events. Bis dahin könnt ihr ja am PC fleißig üben, um vor Ort beim Graben gewappnet zu sein.

Donnerstag, 6. Juni 2013

Wherigo ohne Zonen

Voraussetzung: "Der Einstieg in lua“
Im heutigen Tutorial geht es darum einen Wherigo ohne Zonen zu programmieren. Dies kann hilfreich sein, wenn die benötigte WIG-Lösung viele Zonen bräuchte bzw. die Zonen nicht sichtbar sein sollen.
Die kann bei einem schachbrettartigen Spielfeld sinnvoll sein, z.B ein Memory-Spiel oder dem beim Projekt-Eck verfügbaren Minesweeper-Spiel. Ansonsten hätte wir selbst bei einem 4x4 Memory 16 aktive Felder. Mit dem Oregon undenkbar.

Ermittlung der aktuellen "Zone"


Abbildung 1: Bei der Ermittlung wo der Spieler gerade steht wird über alle Felder iteriert
Das Zauberwort heißt hier (mal wieder) Player.ObjectLocation. Damit kann festgestellt werden, wo sich der Spieler gerade befindet. Danach wird "lediglich" über alle vorher definierten Felder (z.B das Feld A2 auf unserem Schachbrett, Definition folgt weiter unten im Tutorial) iteriert und geprüft, ob der Abstand zum Feld einen definierten Mindestabstand distance entspricht. Dieses Attribut haben wir global festgelegt, z.B distance = 5 (Meter).

Abbildung 2: Die Klasse Field enthält alle benötigten Werte: Name, Index und vorallem die Location
Ein Feld wird dabei durch die Klasse Field definiert. Sie enthält neben Namen und Index(sinnvoll für Verwendung von Arrays) die Eigenschaft Location, die aus der GPS-Koordinate des Mittelpunktes besteht. Freunde des OnProximity Event (siehe Zone als Kreis) kennen diese Logik bereits. Der Radius der virtuellen Zone wird durch die obige Variable distance definiert.
Sobald das erste Feld diese Bedingung erfüllt (distance sollte passend zum Abstand zwischen den Feldern so gewählt sein, dass immer nur 1 Feld nahe genug ist), speichern wir es als activeField und führen die Aktionen aus, die wir normalerweise im onEnter oder onProximity definieren. Im Listing wird dazu die Methode handleField aufgerufen, die dann die gewünschten Anweisungen enthält.
Außerdem wird die Variable foundField auf true gesetzt und der Schleifendurchlauf mit break abgebrochen, denn schließlich haben wir unser aktives Feld ja gefunden. Wenn alle Felder durchlaufen sind, aber kein Feld gefunden wurde, so befindet sich der Spieler außerhalb des Spielfeldes (zur Sicherheit nochmals mit Spielfeld:Contains(Player) abgsichert, könnte auch weggelassen werden) so wird das activeField auf fieldOutside(definiert als Feld mit Namen "outside" und Index -1) gesetzt und eine MessageBox ausgegeben, dass man sich doch gefälligst wieder zurück zum Spielfeld begeben sollte. Diesen Teil habe ich in einer Methode out ausgelagert.
Spielfeld habe ich als wirkliche Zone definitert, damit der Spieler sich über den gewohnten Navigationpfeil leiten lassen kann um das Spiel zu beginnen / wieder aufzunehmen. Ganz ohne Zonen geht es also nicht, wenn man die Usabiltiy nicht außer Acht lassen möchte.

Nebenläufige Programmierung und ihre Tücken

Was aber sollen die Vergleich von activeField in Zeile 47 und 54?
Um das zu verstehen muss man wissen, dass die Methode calcActiveField regelmäßig angestoßen werden muss, da sich der Spieler dreisterweise bewegen möchte. Ein Timer mit Interval 1-5 Sekunden (je größer die Felder desto seltener, nicht zu oft, damit das Oregon mitkommt) bietet sich hier an.
Wenn wir die obigen Vergleiche nicht einbauen, wird die handleField Routine alle 5 Sekunden ausgeführt, was bei nem stattfindenen Dialog sehr unangenehm ist und dazu führt, dass der Spieler die gestellte Aufgabe womöglich nie durchführen kann. Also lieber handleField nur einmal ausführen und dann erst wieder wenn der Spieler das Feld wechselt. Das gleiche gilt für den Fall, dass er sich außerhalb des Spielfeldes verlaufen hat. Auch da reicht es wenn die MessageBox nur einmal angezeigt wird.
Bei sehr großer Anzahl von Felder kann es zu der Situation kommen, dass der aktuelle Schleifendurchlauf noch läuft, während der Timer schon wieder das Signal gibt den nächsten Durchlauf zu starten. Um Fehler oder Wechselwirkungen bei dieser Art der parallelen Abläufe zu verhindern bildet die boolean Variable runningActiveFieldCalculation, als Mutex-Variable eingesetzt, einen Schutz gegen gleichzeitiges Ausführen mehrerer Schleifendurchläufe. Vereinfacht gesagt: So lange ein Iterier-über-alle-Felder-Durchlauf läuft besitzt die Variable den Wert true und weist damit weitere Versuche ab. (! Ich rede bewußt von Abweisen, nicht von Blockieren). Erst wenn der kritische Programmteil abgarbeitet ist wird er mit runningActiveFieldCalculation = false wieder freigegeben.

Wann endet das Spiel?

Die ersten drei Zeilen steuern die Beendigung des Spieles. So soll die Methode endGame() aufgerufen werden, wenn das Spiel als beendet markiert wurde, die notwendige Benachrichtigung an der Spieler ("Gewonnen, gehe zum Final bei N 50° ....") noch nicht vollzogen ist. Die beiden boolean Variablen werden irgendwo in handleField gesetzt, z.B wenn alle Memory-Paare aufgedeckt sind. Zeile 32-35 sind aber nicht zwingend notwendig für die Implementierung des Wherigos ohne Zonen.
Am Ende des Listing beginnt die Implementierung von handleField. Besonders bei Schachbrett-Spielfeldern ist es für den Spieler sehr hilfreich gesagt zu bekommen, wo er sich befindet.
Bei der weiteren Abarbeitung des Feld bitte nicht vergessen ob die Siegbedingung (s.o.) erfüllt ist und das Spiel beendet werden kann.

Spielfeld definieren

Ich hoffe ihr habt noch ein wenig Saft im Aufmerksamkeitstank, denn jetzt wird es richtig knifflig.
Was haben wir?
Wir haben zwei Koordinaten für die Eckpunkte unseres Spielfeldes (ObenLinks und UntenRechts)
Was wollen wir berechnen?
Ein schachbrettartiges Spielfeld mit rows Zeilen und columns Spalten, z.B 3 x 5 Felder. Siehe Abb. 5 als Beispiel
Wie machen wir das
Vereinfacht gesagt ermitteln wir Breite und Höhe des Spielfeldes, teilen diese durch die Anzal der Spalten bzw. Zeilen und iterieren über alle Felder (bei 3 x 5 => 15 Felder) und setzen den Mittelpunkt des Feldes. Zum Schluss setzen wir noch die Ecken ObenLinks, ObenRechts, UntenLinks und UntenRechts als Points der wirklichen Zone Spielfeld und schalten es aktiv und sichtbar.

Abbildung 3: Ausgehend von den Ecken ObenLinks sowie UntenRechts wird das Spielfeld ermittelt

Nun im Detail von oben nach unten, beginnend mit den Zeilen 452 und 453. Dort werden die beiden gegenüberliegenden Eckpunkte unserer Rechteckes definiert. Mit Wherigo.VectorToPoint ermitteln wird den Abstand d sowie den Winkelb zwischen den beiden Punkten. Dies ist ähnlich dem Peilen von einer Koordianten zur anderen mittels Entfernung und Winkel. Ein Winkel b von 135° bedeutet, dass man von firstLoc schräg nach rechts unten gehen muss um zu lastLoc zu gelangen.
Die Variable dist hält den Abstand in Meter fest. Zeile 456 ermittelt den Anteil der Distanz in X-Richtung (also auf der genordeten Karte nach rechts). Wie wir an math.sqrt erkennen, kommt hier der Pythagoras-Klassiker a² + b² = c² zum Einsatz. Wer die Berechnung von distX verstanden hat, wird auch mit distY sowie degX und degY zurechtkommen. Die Modulo-Rechnung mit 360 soll verhindern, dass unser Peilwinkel größer als 360° wird.
Wer es genau wissen möchte, dem kann folgende Debug Zeile helfen:
print("b " .. b .. " dist " .. dist .. " distX ".. distX .. " distY " .. distY .." degX " .. degX .. " degY " .. degY)
In der Kurzversion wird zwischen 456 und 459 die Höhe und Breite sowie der Peilwinkel ermittelt um ein Rechteck aufzuziehen, dessen Verhältnis Höhe / Breite dem Verhältnis Zeilen / Spalten entspricht. Abb. 4 und 5 zeigen zwei Beispiele wie das resultierende Spielfeld aussehen kann. ObenLinks und UntenRechts sind auf beiden Abbildungen gleich, nämlich N 50.3691166666667 E 7.6164 bzw. N 50.3680333333333 E 7.61715.

Abbildung 4: Das Spielfeld mit 5 Zeilen und 3 Spalten ist höher als breit ...

Abbildung 5: während 3 Zeilen und 5 Spalten eher breit als hoch ist

Danach wird die Ecke ObenLinks aka firstLoc als Start der Zeile gesetzt. Dies entspricht in unserem Schachbrett A1. (Bitte entschuldigt den Unterschied zum realen Schachbrett, ich habe gerade erst gesehen, dass dort Zeile 1 die unterste Zeile ist. Bei mir ist es die oberste).
Ist der Rest der Division durch die Anzahl der Spalten 1 (tritt in unserem 3 x 5 Beispiel Abb. 5 bei 1, 6 und 11 auf) so wandert unsere Position nach unten, da wir eine neue Zeile starten. "Nach unten" ist aber nicht genau senkrecht (das wären 180°), sondern abhängig vom Peilwinkel den das Rechteck haben soll (im Beispiel SüdSüdWest bzw. 191,43°). Zur Erinnerung Wherigo.TranslatePoint berechnet den Punkt der von firstLoc aus distY Meter in Richtung degY geht. Vektorrechnung für Anfänger.
math.floor macht übrigens nichts anderes als das Ergenis des Bruches abzurunden, damit 0, 1 bzw. 2 herauskommt. (In der ersten Zeile müssen wir noch nicht nach unten verschieben)

Wenn wir nicht gerade das erste Element einer Zeile antreffen, so müssen wir vom Zeilenanfang nach rechts gehen. Genauer genommen in Richtung degX (OstSüdOst oder 101.43°, merkwürdigerweise genau 90° weniger als degY ). Auch hier gehen wir abhängig von der Spalte in der wir uns befinden 1/4, 2/4, 3/4, 4/4 nach rechts um unsere Position neu zu berechnen.

Zum Abschluss noch etwas entspanntes, um das Tutorial sanft ausklingen zu lassen. Um unsere Zone Spielfeld zu erzeugen setzen wir die Ecken ObenLinks, ObenRechts, UntenRechts und UntenLinks als Points, machen sie sichtbar und aktiv.
Die ganz aufmerksamen unter euch werden jetzt zurecht sagen: Moment, das Spielfeld ist kleiner als die Fläche die von den Feldern abgedeckt wird, denn die Eckpunkte von Spielfeld sind die Mittelpunkte der Eckkreise. Dies ist korrekt, aber Spielfeld dient lediglich dazu den Spieler zurück zur Spielfläche zu führen, wenn der diese früher erreicht als vom GPSr angezeigt so ist dies nicht wirklich schlimm, sollte aber bei der Messung der beiden Ecken ObenLinks und UntenRechts beachtet werden.
Vielen Dank an dieser Stelle an bodenseepingu, der mir seinen Quellcode von Geomemory zur Verfügung stellte und so die nötigen Denkanstöße gab ein Feld mit zwei gegenüberliegenden Eckpunkten aufzuziehen.