Using NativeProcess in AIR 2 with GPSBabel

GPSBabel is one of the coolest projects on the Internet. It takes basically any geolocation format and quickly lets you convert it into any other format. And the world of geodata is a wild west of various formats so it makes it super easy to bring all of that together in a handy command line tool.

Because it has a command line tool I figured it would make a pretty good (and easy) demo for AIR 2′s NativeProcess APIs. And it does! In fact, I started work on an ActionScript 3 wrapper that (should) make it easy to call GPSBabel from an AIR application and make it do your bidding. It’s in really, really rough shape, but here’s the beginning of it.

Getting Started

The first thing you need to do to use the NativeProcess API is to alter your app-xml file. After the initialWindow tag are a bunch of commented lines that talk about supportedProfiles. The NativeProcess API only works in the extendedDesktop profile so you need to enable it with this line.

<supportedProfiles>extendedDesktop</supportedProfiles>

With that, you can start testing the NativeProcess API.

Calling GPSBabel

Using the NativeProcess API is pretty simple. You first create a NativeProcessStartupInfo object, which is where you point to the executable binary as well as pass in any arguments. Then you set up event listeners on the NativeProcess object, and finally you call the start() method and pass in your startup object.

To convert one file type from another, GPSBabel takes a series of command line arguments. This is the command to convert a GPX file into a KML file.

gpsbabel -i gpx -f /tmp/myroute.gpx -o kml -F /tmp/myroute.kml

So to replicate this with the NativeProcess API, first create the startup object and pass in those arguments. The -i is the format of the original file, -f points to the original file, -o is the format to convert to, and -F is the converted file. All of those are pushed to the arguments property of the startup object.

var npsi:NativeProcessStartupInfo = new NativeProcessStartupInfo();
// The location of GPSBabel (a file object)
npsi.executable = _gpsBabelLocation;
var args:Vector.<String> = new Vector.<String>;
args.push("-i");
args.push("gpx");
args.push("-f");
args.push("/tmp/myroute.gpx");
args.push("-o");
args.push("kml");
args.push("-F");
args.push("/tmp/myroute.kml");
npsi.arguments = args;

The next step is to add event listeners to the NativeProcess object. Most of the time, GPSBabel just sends standard messages in UTF, so handling responses is easy. In the case of a conversion, the only event listener that really matters is the error listener.

_process = new NativeProcess();
_process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA,onStandardErrorData);

Dealing with NativeProcess events was a little odd to me, but because GPSBabel just returns text, this is pretty easy. If it errors out, it dumps text to the screen. That text becomes part of the NativeProcess object. Depending on what the context is (if it’s an error, or just regular data output) it goes into a different variable. In this case, the event listener just reads the error data from the standardError property and traces it out

private function onStandardErrorData(event:ProgressEvent):void
{
trace(_process.standardError.readUTFBytes(_process.standardError.bytesAvailable));
}

The last thing to do is to go back up and start the process off by calling the start method and passing in the startup options that were created before.

_process.start(npStartupInfo);

And that’s it. I’ve got an example on GitHub as part of the GPSBabelOnAIR project. The mxml file in the examples folder uses the library, which has all of the NativeProcess code. The combination of those should provide a working basic example of using NativeProcess and GPSBabel.

No related posts.

  • http://omarfouad.net Omar Fouad

    Awesome example! Good job Ryan!

  • http://www.insinuate.org mark

    Great example, very informative. keep it coming

  • http://www.gpsbabel.org Robert Lipe

    Thanx for the kind words.

    GPSBabel tries to put all errors and warnings on stderr. Errors return a non-zero value from the process; you probably want to capture that return (I don’t do AIR) and splash the returned text to the user.

    Also, you don’t have to hard-code the list of options. You can query the executable to provide the known formats and options. Just call gpsbabel -%2 or %3 on startup and parse that tab-separated output to populate your menu structure. Then when new formats are added, your wrapper Just Works with them This is how GPSBabel’s own GUIs do it.

  • ryanstewart

    Thanks Robert, I was just thinking about parsing the return of formats/options and then parsing it this weekend. Was going to check to see if that’s how you guys do it and you saved me the work.

    The app is really phenomenal, thanks a ton for putting in the work!

    =Ryan
    ryan@adobe.com

  • http://www.freeetime.com شات مصرية
  • Hassan Derakhshandeh

    This works if youre building air app with Flash. gotoAndLearn has a tut on this. But how to use this with Dreamweaver? I build air apps with JS.