This past weekend I wrote an app for my local town: it displays a route, and schedule information, for the town's
jitney. (In local terms, a jitney is a township-sponsored shuttle service for resident commuters to and from the train station.) You can see it at
http://myjitney.appspot.com.
I'd like to discuss the short development history of this web application.
The Original Plan
The original plan was to write a public, custom
Google Map to be shared with the other residents using
My Maps, a tool that allows users to create customized maps.
The problem with My Maps is that each marker had be placed individually, and that's tedious: at least to me. What I needed was a programmatic way to feed a set of addresses, determine each address' coordinates (you know, latitude, longitude) and place markers in a custom map.
For that I wanted the
Google Maps API in Javascript, and if I had to use the Javascript API for determining coordinates, I might as well use it to build the map from scratch.
The Prototype
The prototype was written in pure Javascript, using the Google Maps API. It was really basic; routes were stored in JSON (natch), and the whole app lived inside a Google Maps widget.
To get started with the API I found an excellent
Google Maps API Tutorial written by
Mike Williams. The relevant entries were the entries on
Markers and info windows,
Polylines from XML and
Geocoding Multiple Addresses.
In fact, I hacked a version of the geocoding example by adding all the jitney stop addresses, and from that I got the coordinates of most of the map markers. For those addresses that the API couldn't parse, I used a tedious trial and error process.

The prototype took five hours to write: one hour to parse and codify the data, one hour for figuring out how to get reasonable coordinates for each address, and three hours to get my head around Javascript. For me, writing Javascript is like this: trial, error, trial, error,
google, trial, trial, error, trial, error,
google, but by the end, I got a map that showed all the jitney stops and their paths.
Two issues with writing the app in Javascript were my basic lack of comfort with Javascript, and also, the app didn't render on my Android phone. I dreaded debugging a web app on an Android phone.
The Rewrite
So I needed to rewrite the app, and by need, I mean want. 24 hours earlier I could have just manually built a damn custom map with My Maps, but now I was committed to code and more code. For the rewrite, I chose
GWT. The Google Web Toolkit is a terrific piece of technology; you can write web applications using Java in
Eclipse, my preferred IDE, and with a
debugger. Since Google provides a
GWT implementation of the Google Maps API, it was reasonable to port the existing prototype to GWT. The
Google Plugin for Eclipse, a fabulous tool that combined GWT,
AppEngine, and Eclipse, made it dead simple to deploy the app to to
appspot.com which meant a permanent home to the app, along with a back-end infrastructure in case there was ever a need for servlets or a back-end data store.

(This is a great time to point out that I think that GWT is magic, and the GWT team are a bunch of magicians.)
It took four hours to write a feature-equivalent version of the application using GWT. Most of that time was spent familiarizing myself with the various APIs and getting reacquainted with GWT.
I didn't want to go through the effort of learning how to work with the AppEngine database, so the rewrite still shipped the route data as java source turned into javascript. One of the great benefits of this turned out to be that the map loaded super-quick. So I moved the CSS to the HTML
<style> tag, removing yet another server request.
Thanks to GWT the app ran perfectly fine on Android. But more important, thanks to GWT I could write code in a more familiar style, and easily manipulate the DOM outside the web page's map object.
So I did.
Spit and Polish
I spent two more days adding features and polish: a pretty display of the schedule. A list of the routes so each could be viewed independent of the others. A visual indicator of when a jitney will next stop at a certain route.
One of the features was to replace the straight lines from stop to stop with paths along the street. The township had a map that laid out the supposed bus paths, so the trick was finding the coordinates where the paths turn. That turned out to be surprisingly easy with this small piece of Java:
map.addMapClickHandler(new MapClickHandler()
@Override
public void onClick(MapClickEvent event) {
System.out.println(event.getLatLng());
}
});
Then it was just a matter of running the web application and clicking each spot along the path, feeding the console output back to the web application as intermediate points.
Besides adding features, I spent a ton of time dealing with things like positioning and formatting. I spent 30 minutes building a general purpose route building API. I spent 15 minutes on a general purpose algorithm for calculating the center of a group of points. 30 minutes went into making a widget that looks like, but isn't quite, an anchor tag. I spent endless time playing with different types of GWT panels, setting widths, heights and spans. I played with CSS. I failed at CSS, and then I played with it some more. It seems I have the same development cycle for CSS that I do with Javascript: trial, error, trial, error,
google.
Done.
By Sunday night the app was done, and so was I. But it's still not done. Even with such a small one-off project, there so many features that could be added. For instance, while the app runs on Android (and reportedly the iPhone) it's not really built for small phones. The individual links are too small to be useful.
But also, I'd like to use Street View to show each stop. Unfortunately, while a
Street View API exists in the Javascript API, there's no equivalent in the GWT API. I probably spent about two hours before I recognized that it would involve another painful, endless cycle of trial, error, trial, error,
google. Too bad.
Done?
Damn. While writing this post, someone provided feedback, requesting a feature that made too much sense not to implement. So instead of cleaning up this post I'm reading about geocoding again. I love writing software.