Beta lessons: Sydney to Hobart
Recently, the annual Sydney-to-Hobart race was on. As the boats make their way to Tasmania over multiple days, you can track them online on the website, and also through a Google Earth-compatible KML feed. We’ve added KML support to the Maparoni beta a little while ago, so this was a fun opportunity to test out that feature. As I did so, I noticed a few quirks which results in various improvements in the latest betas, which are now available in build 1361.
First up, with the data loaded and the ships appearing as pins, I wanted to show data for each ship, such as its course-over-ground and speed-over-ground, and distance-to-leader. In the KML file, these aren’t provided as individual fields but rather as an HTML table such as (much simplified):
<table> <tr><td>Status</td><td>Racing</td></tr> <tr><td>COG</td><td>226</td></tr> <tr><td>SOG</td><td>13.1</td></tr> <tr><td>DTL</td><td>75.8nm</td></tr> </table>
This is where Maparoni’s formula magic comes in handy, in particular one to extract individual values using a regular expression:
find(needle: String, haystack: String) -> String
With that you can extract, say, the DTL (distance-to-leader) by creating a new field of type “Formula” with the formula set to
find('<td>DTL</td><td>(.*)</td>', description). This didn’t work out-of-the-box as the raw data had a lot of random white space and line breaks and the regex was sensitive to that. I’ve tweaked this, to always prune all excessive whitespace when using the
Secondly, a little hurdle that I hit was matching the other fields, as, say,
<td>Status</td><td>(.*)</td> wouldn’t match “Racing” but instead everything from “Racing” to “75.8nm” as the regular expression matcher is greedy by default. Addressing this, didn’t require any chances to Maparoni but instead tweaking the formula to
<td>Status</td><td>(.*?)</td> as that question mark makes the match non-greedy. I’ve added that has a hint to the documentation of the formula on the website and in the app.
Next up, I wanted to show the country flag for each boat on the map and in the list. This wasn’t available in the data, but as only two boats were from somewhere else from Australia, I could hard-code this based on the name:
switch(name) .case("Black Jack", "🇲🇨") .case("SHK Scallywag", "🇭🇰") .default("🇦🇺")
Creating this formula worked already, but getting the name right was tedious as I had to remember the spelling or copy it. Ideally, after typing
switch(name) and then starting
.ca it should auto-complete the possible values, depending on the data in the collection. And even better, if it would then adjust that filter depending on a partial match, so that
.casca would match
.case("SHK Scallyway", ...) but not, say,
.case("Ichi Ban", ...). That took a little bit of work, but I’m happy to report that it now indeed works just like that.
Lastly, as I was editing the formulas, I noticed that the auto-completion suggestions were popping up when I didn’t expect them. This is generally a feature that ideally you don’t notice. It’s just there when you need it, it doesn’t get in your way, and you generally don’t think about it. As I was working on this, I really appreciated the time and effort that went into other editors that I use every day, such as Xcode or VS Code. I mirrored their behaviour and came up with this set of rules:
- At the start, there should be a list of suggestions, so that you don’t stare at an empty text field, wondering what to do.
- As you type, autocompletions should stay visible and adjust to what you type
- You should be able to toggle the autocompletion list on and off when pressing
Esc, and it should automatically re-appear after typing a
This is now exactly how it works on the Mac. There are still some cases where it pops-up unexpectedly and it’ll need a bit more fine-tuning, but generally I’m much happier with it now.
A notable exception of what was not ideal and which is not (yet) addressed, is that a KML file can have some contents that are fetched from another KML file2. For the regatta, there’s the static information of start, end, and shortest-line, and the dynamic locations of each of the boats. Maparoni currently expects a single data source for a collection, but these are essentially two distinct (but related) collections in one. Maparoni cannot yet import those from the single source KML file and instead you manually have to create multiple collections, one for the main KML and one for each KML source that it references. They can then be viewed together by command-clicking them on the Mac or using the “Select” option on iOS. To properly handle this, one option would be to create an explicit “meta collection” type where subscribing to such a KML URL would then result in a new meta collection in Maparoni, which then points at the main KML collection and each KML collection that it references.