Thursday May 10, 2007

SmugMug + Project Blackbox Blog + Google Maps

It should be no secret by now that I'm the mysterious Project Blackbox blogger. I get lots of help from our marketing folks as it tours, as well as Dave and Paul the drivers. The Web 2.0 mashups are left to me. I'll be honest, I'm more of a middle-tier programmer and large application architect, so the mashups come with painful lessons these days. One of the reasons I took the job as Project Blackbox blogger was to "close the gap" between my architecture role and understanding the complexities of Web 2.0 programming. At the architecture tier, Web 2.0 is more or less obvious. The realities of what can and cannot be done and how long it takes to do it are extremely important to understand.

I just finished an update of the blog template to include two maps last night, and I am still tweaking the look to try to pack as much content as I can onto the page. In the spirit of open source and transparency, I figured I would post the current solution here so I could possibly help others as they do similar tasks.

With virtually all Web 2.0 mashups, you are going to use a whole pile of different technologies. Everyone has their own APIs and the Web 2.0 programming technologies are a dime a dozen, each with their own benefits and drawbacks.

My technology choice was also constrained by my vendor choice. I had determined that I was going to use SmugMug as my gallery provider and Google as my map provider. It turns out that Flickr! had some of the advanced APIs I needed but they don't have a first class geography tagging facility (I would have to use keywords). I am very happy with the personal level of support that the Smug crew gives so I am a big fan of theirs. I felt in the end getting responses and help from smug for the API additions of callback and geo information was far more likely then getting geo information inserted into the Flickr! site (I've had some bad customer support experiences with Yahoo...though I do get my own personal domains from Yahoo!).

The technology list that I ended up with is:
- Google Maps as the map provider
- SmugMug as the picture host, using the gallery RSS feed
- Rome RSS Parser for parsing the RSS
- Java with the NetBeans IDE in a standalone program to parse the SmugMug Feeds and converting to JavaScript.
- Curl for uploading the JavaScript to an intermediate site
- JSON for the JavaScript Object formatting
- JavaScript for the embedding into the blog

SmugMug APIs and Feeds
My original goal was to tie the blog directly to SmugMug through their APIs. Unfortunately, the APIs were geared toward either having applications built on the SmugMug infrastructure (you can build your own templates at SmugMug) or having control of the hosting infrastructure so you could use a proxy solution to resolve cross-domain security issues. The SmugMug crew is adding a callback mechanism to their JSON API to help me, but this wasn't ready in time for the blog.

Even with the callback mechanism, the geographical information that you can associate with a picture in your gallery is not available from the API, only from the RSS stream. This will also be resolved by the SmugMug crew in time, as you can see from this thread in the support forum.

In the end, each gallery has a robust RSS feed with the geographical information. I have two galleries with the feeds for the U.S. tour and the Europe tour coded into the RSS standalone parsing program. You will need the Rome RSS Parser and JDOM (a dependency of ROME) to compile it.

I upload the resulting JavaScripts from the conversion (that use JSON for the object format) to an intermediate web site using CURL. You may ask why I don't upload the JavaScript to the Sun blogs site. This is because there does not appear to be an FTP port open to insert it into my blog resources...and so I use an intermediate location.

Google Map APIs
The Google Map API is well studied. After importing the JavaScript that I converted and uploaded, I go through the array of pictures (one for the U.S. and one for Europe) and create "Markers" for each one. The RSS feed has the first item as the latest posted, so I open an HTML window for it.

JavaScript in the Blog Template
The scripts for the mashup all occur in the portion of the template. In the HTML body, right above the for loop for the weblog entries, I inserted the two div markers where the maps will be placed.

<div id="usmap" style="height: 250px;margin-left: 20px;margin-right: 20px;border-style: double;"></div>
<div id="eumap" style="height: 250px;margin-left: 20px;margin-right: 20px;border-style: double;"></div>

These were VERY difficult to get right. I started with two separate side by side maps, but the rendering was slow and inconsistent across browsers. I ended up with div's to place the maps above and below each other. This worked well.

The scripts took some time to get right. I actually edited and played with the maps on a sandbox web site from my hosting provider before I edited the templates. This gave me better formatting and quicker turnaround time. Here are the final JavaScripts for the Map and JavaScript import.

<script src="http://intermediatesite/eupictures.js"></script>
<script src="http://intermediatesite/uspictures.js"></script>

<script src=""
<script type="text/javascript">
function load() {
if (GBrowserIsCompatible()) {
var usmap = new GMap2(document.getElementById("usmap"));
usmap.addControl(new GSmallMapControl());
usmap.addControl(new GMapTypeControl());
usmap.setCenter(new GLatLng(39.096, -96.59), 3);

var eumap = new GMap2(document.getElementById("eumap"));
eumap.addControl(new GSmallMapControl());
eumap.addControl(new GMapTypeControl());
eumap.setCenter(new GLatLng(48.46, 8.88), 3);

function createMarker(point, text) {
var marker = new GMarker(point);
GEvent.addListener(marker, "click", function() {
return marker;

for (i=0 ; i var point = new GLatLng(uspictures[i].latitude, uspictures[i].longitude);
var text = "<a href=\\"" + uspictures[i].link + "\\">";
var text = text + "<img src=\\"";
var text = text + uspictures[i].thumbnail +"\\" width=\\"150\\" height=\\"101\\" />";
var text = text + "</a>";
var text = text + "<br/><small>" + uspictures[i].title + "";
var marker = createMarker(point, text);
if(i==0) {marker.openInfoWindowHtml(text);}

for (j=0 ; j var point = new GLatLng(eupictures[j].latitude, eupictures[j].longitude);
var text = "<a href=\\"" + eupictures[j].link + "\\">";
var text = text + "<img src=\\"";
var text = text + eupictures[j].thumbnail +"\\" width=\\"150\\" height=\\"101\\" />";
var text = text + "</a>";
var text = text + "<br/> var marker = createMarker(point, text);
if(j==0) {marker.openInfoWindowHtml(text);}


And that is about it!

Some Extra Commentary
So, this took WAY longer than it should have, thus my desire to do a blog entry in case other folks try to do the same thing. The reasons that it took a while are:
- The cross-domain security issues and workarounds are a pain and assume you own infrastructure for the most part (except the new JSON callback solution which I'm very excited about). The amount of material (some links above) I had to digest and learn about was astounding, I had to be duplicating effort of someone else but there doesn't seem to be a single location for this information, it is literally cutting edge. In the end, these solutions didn't work. Pure client solutions for AJAX / Web 2.0 Mashups are very hard to come by. Even the new JSON Callback mechanisms raise my eyebrows around security. The community around mashups is also relatively naive around pure client applications. Hats off to Google Maps for getting it and to SmugMug for being responsive.
- What language to use? COME ON PEOPLE, these Web Tier languages are a dime a dozen now. I understand each has benefits and drawbacks but the long term support of this tier is going to be terrible. There WILL BE consolidation in this tier to reel in the learning curve and focus developers (in tools, in companies, etc...). What will be the standing survivor? I have to look into the JavaOne announcements in this tier...sorry, I'm a Java survivor and I love the language. It is powerful with tons of libraries and I don't have to download and compile source code whenever I want an update to the language.
- Browser compatibility is close, but getting the div's to work right was a complete pain.
- Coding tools are primitive in this tier. I spent a lot of time with the Error console in Firefox to get this right, and lots of uploading and downloading of .html files. Also, lots of pure head scratching.





« February 2017