a1lin1's blog

Create a Geo File

In my previous MapQuest posts I've mostly been demonstrating how to use MapQuest to display the the various types of geo-formats (KML, GeoRSS, etc). Building on the examples of map event interaction from my previous posts, we can also build an interactive map interface where users can build their own geo-format files. Here's an example where users can interactively click on the map to create a polyline.


<html>
<head>
<title>Create a Geo File</title>
<script src="http://btilelog.access.mapquest.com/tilelog/transaction?
  transaction=script&key=YOUR-API-KEY&ipr=true&itk=true&v=5.2.0"
  type="text/javascript">&t;/script>
<script language="javascript">

MQInitDojo(initMap);
var myOverlayColl = new MQOverlayCollection();
var myShapePts = new MQLatLngCollection();
var myOL = new MQLineOverlay();
var allclicks  = new Array(0);
function showClick(event) {
    // log all clicks
    allclicks.push(event.ll.getLatitude(), 
      event.ll.getLongitude());
    // add clicks to polyline overlay
    myShapePts.add (new MQLatLng(event.ll.getLatitude(), 
     event.ll.getLongitude()));
    myOL.setShapePoints(myShapePts);
    myOverlayColl.add(myOL); 
    myMap.replaceOverlays(myOverlayColl); 
    // clear previous markers and add new start and end points
    myMap.removeAllPois()
    myMap.addPoi(new MQPoi(new MQLatLng(allclicks[0], allclicks[1])));
    if ( allclicks.length > 1 ) {
        myMap.addPoi(new MQPoi(new 
         MQLatLng(allclicks[allclicks.length-2],
         allclicks[allclicks.length-1])));
    }
}
function display() {
    alert (allclicks);
}
function initMap() {
   myMap = new MQTileMap(document.getElementById('mapDiv'),8,
    new MQLatLng(33.173676, -116.714889));
   myMap.addControl(new MQLargeZoomControl(myMap));
   MQEventManager.addListener(myMap,"click",showClick);
}
</script>
</head>
<body>
<div id="mapDiv" style="width:384px; height:384px; border:2px solid"></div>
<a href="#" onclick="display();">Display Coordinates</a>
</body>

</html>

As you can see, I'm simply using an 'alert' to display the captured latitudes and longitudes of the polyline that the user created. Obviously the next task is to transform that array of coordinates into your favorite geo-format. Here is a screenshot of the result:

More Overlay Events

Custom events are also a great way to 'clean up' the look of your maps. In most of my previous MapQuest posts, I've been only loading a single overlay or polyline at a time. Chances are, you'll encounter the need to load more than one at a time - but also don't want to clutter up the look of the map by having them all visible at the same time.

Here's an example where I've loaded two different polylines from different GeoRSS/GML files. Instead of having both automatically displayed on the map, I'm going to use a mousever event on a POI to display the polyline. Two do so, I create two POIs has a legend to each polyline. On a 'mouseover' event I load and display the appropriate file. On a 'mouseout' event the overlay is set to not be visible.

Custom Mouse Events to Data Overlays

In my previous MapQuest post I demonstrated to to add customized interactivity to maps via mouse control events. Here we'll add mouseover events to data overlays on the map.

I've loaded data to my map via a GeoRSS file using GML encoding. Unlike my previous GeoRSS/GML example, however, here I'm loading a data for a polyline overlay (For brevity, I've ommited the list of coordinates).

<feed xmlns="http://www.w3.org/2005/Atom"
      xmlns:georss="http://www.georss.org/georss"
      xmlns:gml="http://www.opengis.net/gml">

  <title>Sample GeoRSS ATOM feed</title>
  <entry>
    <title>Mesa Grande Road</title>
    <georss:where>
      <gml:LineString>

      <gml:posList> 
        [space delimited list of lat long coordinates]
      </gml:postList>
      </gml:LineString>
    </georss:where>
  </entry>
</feed>

With the feed, I simply read/parse the XML file and use the MapQuest API to create a polyline based on the coordinates - additionally we'll create default settings for the polyline (color, line width and opacity) which we will change depending if the mouse is over the polyline.

Custom Mouse Events

In my previous MapQuest posts I've been showing how to create custom maps by added data from various geographical sources. Another way to customize your maps is to add custom interactive control behaviors via mouse events. In my next couple posts, I'll show you how to add different mouse events to the maps and overlays.

In this post, we'll create basic map that will display the latitude and longitude coordinates of the center of the map canvas as well as the coordinates of mouse clicks on the canvas.

<html>
<head>

<title>Mouse Events</title>
<script src="http://btilelog.access.mapquest.com/tilelog/transaction?
	transaction=script&key=YOUR_API-KEY&ipr=true∓itk=true
	&v=5.2.0" type="text/javascript"></script>

<script language="javascript">

function showClick(event) {
  var foo = document.getElementById('click');
  foo.innerHTML = event.ll.getLatitude() + ', ' + event.ll.getLongitude();
}
function showCenter() {
    var foo2 = document.getElementById('center');
    foo2.innerHTML = this.getCenter().getLatitude() + ', ' +
       this.getCenter().getLongitude();
    // remove previous poi before marking center
    myMap.removeAllPois()
    myPoint = new MQPoi(new MQLatLng(this.getCenter().getLatitude(),  
       this.getCenter().getLongitude()));
    myMap.addPoi(myPoint);
}
function initMap() {
   myMap = new MQTileMap(document.getElementById('mapDiv'),8,
       new MQLatLng(33.173676, -116.714889));
   myMap.addControl(new MQLargeZoomControl(myMap));
   MQEventManager.addListener(myMap, "click", showClick);
   MQEventManager.addListener(myMap, "move", showCenter);
}
</script>

</head>
<body onload="initMap();">
<table>
<tr><td>Map Center: </td>>td><div id="center"></div></td></tr>
<tr><td>Mouse Click: </td>>td><div id="click"></div></td></tr>

</table>
<div id="mapDiv" style="width:384px; height:384px; border:2px solid"></div>
</body>
</html>

To add an event, you simply define a function that is attached to a mouse event using the MQEventManager() object. In this example there are two function, one to show the coordinates of the map center and one to show the coordinate of a click event. As you see, the click action require the use of a event object to be passed from the event manager. Also in showCenter() function, in addition to displaying the coordinates in the DIV tag, I'm also placing a POI at the center location (after clearing out the previous POIs).

Try an Interpreted Language

I hope everyone is having a great winter holiday. Another reason to celebrate - Perl turns 20 this month! I have to admit I've always been a big fan of 'scripting' languages. While some folks may have a certain amount of disdain towards interpreted languages, I've always found them to be a bit more flexible, efficient (in terms of coding - imagine, only one line of code for 'hello world'!) and a bit more elegant than their lower level counterparts. It's probably the same reason I prefer the command line over any GUI (I've never figured out how to pipe commands with a window manager).

Login Required?

If you've been following any developer blog these days, you've probably seen that there has been a lot of recent activity in online identity management. OpenID has just released specifications for version 2.0 and OAuth has released specifications for Core 1.0. While I think identity management is a great and necessary thing, I would hate for the Web to become a "login-only" environment.

A Firefox Toolbar Extension for Truveo

A few posts ago I showed how to add a simple plugin AOL Pictures search utility to the Firefox search bar. Firefox, of course, supports much more customization via what they call 'Extensions' - allowing developers to add new and custom functionality. Building an extension is fairly straight-forward, requiring some XML, Javascript and CSS. Specifically, Mozilla/Firefox Extensions are created via XUL (XML User Interface Language). I'll demonstrate by adding a toolbar dedicated for Truveo to my browser.

MapQuest Overlays via GML

In my previous MapQuest posts I've shown a couple of different ways to create POIs (point-of-interest) overlays on the maps. The MapQuest API, of course, is capable of various different types of overlays, including: lines (polylines), polygon, rectangle, ellipse and image. Like my previous post, I'll describe my overlay in an GeoRSS feed. For some variety, this time I'll use an ATOM feed, GML (Geography Markup Language) encoding and overlay a polygon. One of the advantages of GML is the ability to define a coordinate reference system. Other geography markup languages (such as KML - Keyhole Markup Language) often use a single pre-defined coordinate system.

Map your images with Mapquest

As most digital camera users know, there's actually quite a bit of information that goes along with each image. Known as the exchangeable image file format (Exif), this specification stores various bit of information (or meta data) along with the image, such as date/time and camera settings (e.g. shutter speed, ISO speed, focal length, etc).

While some of that information is rather dry, an often overlooked and very useful tag is 'GPSPosition'. This tag that allows you to store geographic parameters in your image. Now you'll never forget where you took that once-in-a-lifetime picture. In the Web 2.0 world, it means you can show folks on a map where you took that picture.

Search AOL Pictures with ATOM feeds

I found the fact that AOL Pictures offered an ATOM feed API was very interesting. I've pretty much always expected services to return something that needed further processing so I've tended to gravitate towards the JSON API. That thinking is probably a bit outdated...especially for web applications - since most, if not all browsers handle ATOM and XML these days. From an architectural perspective, feeds are really the epitome of REST, so I decided to take a look - here's an example of how we can create a simple global tag search for AOL pictures.

Here's a simple CGI program that takes a single parameter (you'll obvious want to add some error checking) and and returns an ATOM/XML feed. Note that I've used a different LWP module/library than my previous examples. If you're a fan of REST and PERL, then LWP is your best friend. Also as you might expect, the Content-type is changed as well.

Syndicate content