Mark Gilbert's Blog

Science and technology, served light and fluffy.

Balloon Mapper

Our receiving station for the Stratoballoon project consisted of three major pieces of software:

I’ve gone into great depth about how the first two are configured on my technical blog (“Stratoballoon Radio Details”).  Today, I want to talk about the third one, BalloonMapper.  Here is the basic interface:

10

We would copy a dataline out of dl-fldigi and past it into the “Data Line” box (#1).  We could then hit Enter, or manually click the “Find Position” button in the upper right corner.  This would extract the altitude, and the lat/long from the data string.  It would convert the former into feet and display that in the “Altitude” box (#2).  It would also create the Google Maps URL that would show the lat/long as a pin on the map.

What did the data strings look like?  A picture-perfect data string that came off the radio would look like this:

KD8VZA-KD8VZA-KD8VZA,120057.00,234.11,4214.7460,8533.3750,*4FF4

This is a comma-delimited string, and is made up of the following:

  • My callsign, repeated 3 times
  • A timestamp, in hhmmss.xx format (where the decimal places are ignored)
  • The altitude, in meters
  • The latitude (format explained below)
  • The longitude (format explained below)
  • A termination string, made up of an asterisk, followed by four alphanumeric characters

In most cases the callsigns came out a bit garbled, so it would look more like this:

a8czZA-KD8VZA-KD8VZA,120057.00,234.11,4214.7460,8533.3750,*4FF4

The first part of the string got chewed up because it took us a second to tune dl-fldigi to lock onto the signal.  That’s the main reason I start the string with three copies – I wanted to give Katherine or I (whoever was working the radio) a second or two to get ahold of the signal.

Extracting the altitude was very straightforward.  Simply grab the 3rd piece of data in the string, multiple it by 3.28 to convert it from meters to feet, and display it in the box.

        public static String GetAltitude(String DataLine)
        {
            String[] DataLineComponents;
            String RawAltitude;

            DataLine = (DataLine ?? "").Trim();
            if (String.IsNullOrEmpty(DataLine)) { return ""; }

            DataLineComponents = DataLine.Split(',');

            RawAltitude = DataLineComponents[2];

            return String.Format("{0} ft", (double.Parse(RawAltitude) * 3.28).ToString("0"));
        }

The lat/long was a bit tricker.  First, I had to get them into a format that Google Maps would understand.  You can browse directly to a specific lat/long point on Google Maps like so:

https://www.google.com/maps/place/42°17’44.76″N+85°43’22.50″W

The lat/long values, however, always come off the radio in the 4-dot-4 pattern.  Here is how they broke down:

4214.7460 = 42° 14.7460′

8533.3750 = 85° 33.3750′

So, I would need to split the degrees from the rest of the string, then convert the fractional arc-minutes into arc-seconds, before I could drop it into Google Maps:

        public static String GetUrl(String DataLine)
        {
            String[] DataLineComponents;
            String RawLat, RawLong, FormattedLat, FormattedLong;

            DataLine = (DataLine ?? "").Trim();
            if (String.IsNullOrEmpty(DataLine)) { return ""; }

            DataLineComponents = DataLine.Split(',');

            RawLat = DataLineComponents[3];
            RawLong = DataLineComponents[4];

            FormattedLat = String.Format("{0}°{1}'{2}\"", RawLat.Substring(0, 2),
                                                          RawLat.Substring(2, 2),
                                                          (double.Parse(RawLat.Substring(4)) * 60).ToString("00.00"));
            FormattedLong = String.Format("{0}°{1}'{2}\"", RawLong.Substring(0, 2),
                                                           RawLong.Substring(2, 2),
                                                           (double.Parse(RawLong.Substring(4)) * 60).ToString("00.00"));

            return String.Format("https://www.google.com/maps/place/{0}N+{1}W", FormattedLat, FormattedLong);
        }

So, now I had my URL.  I needed a way to embed a browser into BalloonMapper, which was a Windows desktop app.  I looked at a few options, but eventually settled on Gecko Effects: https://bitbucket.org/geckofx/geckofx-29.0/downloads.

I created a Gecko.GeckoWebBrowser object on my form called “GoogleMaps”.  To browse to a URL, I simply called the .Navigate() method on the GoogleMaps object, and passed it the URL that I generated above:

                this.GoogleMaps.Navigate(GetUrl(this.DataLineBox.Text));

 

Using it was easy.  Getting the control installed and working was a little more difficult, and I had a few false starts.  In the end, here is what worked:

  • I downloaded Gecko Effects 29.0 (see link above).
  • Gecko requires another application called “xulrunner”, which I obtained from here: http://ftp.mozilla.org/pub/mozilla.org/xulrunner/releases/29.0.1/runtimes/ .
  • I found that I needed to match the version of xulrunner to the version of Gecko, otherwise I got a “Specified cast is not valid” error.
  • I also found that the program has to be installed to a folder called “xulrunner” – all lowercase – or it wouldn’t work.

This made finding the capsule’s current location extremely easy:

20

For full source code and binaries, please visit http://TinyURL.com/MarkGilbertSource, and look for the BalloonMapper.zip archive.

Advertisements

October 10, 2014 - Posted by | Science, Stratoballoon, Visual Studio/.NET

1 Comment

  1. […] are configured on my technical blog (“Stratoballoon Radio Details”).  Please check out “Balloon Mapper.” on my technical blog for a detailed write-up of the third […]

    Pingback by Balloon Mapper | Mark Of Quality | October 10, 2014


Sorry, the comment form is closed at this time.

%d bloggers like this: