A friend made a pitch to an creative agency about Augmented Reality. The pitch was well-received and the next step was to deploy a small sample to showcase the potential of the technology. The friend knew that Layar was a premiere AR platform and he also knew I had some Android experience so he called me.
Sure, I said, no problem I can build you a Layar. So, I got a developer key from Layar and jumped on the site to get started. In retrospect I should not have been surprised, but to deploy a layer on Layar you need a Web service to pump your "points of interest" data to Layar servers which in turn deliver it to the handset. I say in retrospect, because I expected to not only be able to define the layer container at dev.layar.com, but the points of interest as well. Of course. The concept is to take existing collections of point data and offer via AR. If you have a collection of hundreds, thousands or maybe millions of data points you're not going to be keying them into a Web form at Layar.
But, suppose you are starting from scratch and you only have a few points. Well, then you might want to enter them by hand and serve them up to Layar. There are services that allow you to do just that (buildAR and muzar.org to name two) and pre-built servers you can deploy and a whole host of developers who will do the job, but what's the fun in that. The fun is to build your own.
I chose App Engine because, well because it's there, because I been wanting to try it since they announced the Java environment and because for a light loads it's free.
This was my first experience with JDO. You have to adjust your thinking to keep your focus on you objects and resist the temptation to think about things like insert/select to make a copy of a "row". If you have trouble you can spend a little time in some JDO forums so the JDO police can sarcastically, flippantly and dismissively point out your old school thinking. Persisting a copy of an object seems like a perfectly legitimate thing to want to do and of course it is possible, the key for me being the key (set to null) and using the serializable DTO to move the data between the existing object and new one.
I built a simple GWT interface that allows you to login using your Google account, to enter POIs, save them, edit them and copy them. And once you've added some points of interest, there's a URL you can hit that will pump out the POIs in the appropriate JSON container for use with Layar.
It's built. It works. If you load Layar on your device and search "Idea City" you'll find a layer which is being served via this service. You have to be on 6th Street in Austin (30.271428, -97.752770) to see anything, but if you really want to see the POIs you can set your lat/lon in the settings menu of the Layar app. Better yet, here's a QR you can read.
Don't forget you put yourself on 6th and Wood in Austin either physically or virtually.
I say it's built, but there are more things to do. For one the geo-spatial query is not particularly efficient. In fact, it's positively brute force inefficient, but it works for small collections. After I steel myself, I'll head back into the JDO forums to see if I can figure out a query that will let me efficiently select on a radius from a fixed lat/lon similar to the SQL in this example (in the Create SQL statement to fetch the POI information section). There's also the matter of sanity checking on the Web form entries. Clearly URLs should look like URLs, lats and lons should probably be normalized and maybe I should even ask you if you're serious when you enter a point that's "far away" from other points in the layar just to be sure. The ultimate would be to add a service that would allow you to ingest an existing service into a UI, point and click the XML or JSON parts of the existing service output to build the crosswalk to the Layar JSON spec, maybe intersperse a few hand entered points and release the whole thing as a new Layar. Yeah. Right.
What is built now is called SnapLayar. If you want to try it, contact me via my profile and all add you to the list of authorized users. Maybe. After I get the sanity checking implemented.