Concerts Map with SongKick API and ModestMaps
It’s time for another JavaScript mapping library and data visualization demo so today I wanted to take a look at ModestMaps with some real-time data. I was just looking for concerts around my area and stumbled on SongKick so this demo will use the SongKick API for concerts data. ModestMaps comes from the makers of MapBox and it looks really simple and clean with GitHub hosted API docs and examples you can easily download. The idea is to load a simple map, process the end users geolocation and position the map to that location, initiate a call to SongKick API for concerts in that location, and show the results in an overlayed panel, while allowing the end user to plot each concert on the map. Lets get started.
Final Demo: Find Concerts per Geo Location on a Map
Simple Map Example with ModestMaps
Even though I love the way ModestMaps examples are presented, with a zip to download, the first example did not show the map but threw a JavaScript error instead: Refused to execute script from ‘https://raw.github.com/stamen/modestmaps-js/master/modestmaps.min.js’ because its MIME type (‘text/plain’) is not executable, and strict MIME type checking is enabled. This is not a good start, but it has to do with GitHub serving content with a ‘X-Content-Type-Options: nosniff’ header more explained here and here. When I downloaded the actual ModestMaps JavaScript file, everything worked. Here is the Basic ModestMaps Example.
User GeoLocation with ModestMaps
I have written about HTML5 Geolocation before, so I setup a simple JavaScript function that grabs the end users location, translates it into latitude and longitude and updates the map accordingly. Here is the ModestMaps GeoLocation Demo. There isn’t much change in the code but Geo Location is an asynchronous call and that will be important in the upcoming examples.
ModestMaps with Map Drawn Callback
Let’s say you want to let the end user know where the map has been moved to as a result of the geo location call or any interaction with the map. ModestMaps has neat drawn callback that you can utilize to update all kinds of elements with map interaction. The problem is that moving the map or zooming in and out triggers too many drawn events and you want to throttle or delay your update functions until for a little bit. You only really care about the last drawn event so placing some sort of a JavaScript pause is necessary, especially if your update functions are processing a lot of information.
How do you delay JavaScript execution? I like the underscore throttle function, and there are different versions but I implemented this one. Now, every time the map is moved, zoomed, and/or redrawn, I only have one function call because I delay or wait for 50 milliseconds. Here is the demo of ModestMaps with Map Drawn Callback and Throttling Events.
ModestMaps with Map Marker
In the demo above, I updated the latitude and longitude information in an overlayed element on the map but lets place these coordinates into a map marker. I did not see a good markers example for ModestMaps but the popup example is easy enough to follow. The basic concept is that you translate geo locations to x and y locations on the page and then just drop in html markup with normal JavaScript events. It sounds like a bit of custom coding, and a marker function would be nice, but it’s really not bad at all and I love the full control. The locationPoint() function converts a lat, lon geo location to an x, y pixel point on the map so I use that function and feed it the center geo location. Here is the demo of a Simple Geo Marker on a Modest Map.
Calculating Geo Distance with ModestMaps
Before we dig into SongKick API calls, I wanted to figure out how to limit these calls in general. Requests for concerts do not have to occur with every map interaction (drag and zooming) so I wanted to setup some sort of distance threshold before I would process new Ajax requests to SongKick. So, I created a global variable previousCenter and used the ModestMaps MM.Location.distance function to measure the distance between two geographical points. This will allow me to define a custom distance variable and check if the user has dragged the map far enough from a previous location to initiate some extra calls. Here is the ModestMaps Distance Demo.
Using SongKick API with ModestMaps
You need to grab an API from SongKick first but afterwords, the API documentation is pretty straightforward. The location search method returns a lot of cities around the latitude and longitude geo position. Ideally, you would search for a city name instead of a geo position but that would require an extra step of reverse geocoding. I decided to look at all the metro ids returned and use the one that occurs most often. Another approach would be to just query each one until you get some results. I think the proper approach also depends on the zoom level of the map but for this demo, I wrote a JavaScript function that detects the most duplicate or frequent element in array and later, I will use that metro id to query for concerts.
I added jQuery to handle the JSONP requests to SongKick and I am limiting the zoom with ModestMaps map.setZoomRange() function because we don’t want to move the map too far away in distance with each drag. In the reprocess function, I am only requesting another call to SongKick if the total distance panned from one center point to another center point is larger than 40,000 meters. I also put an if statement there so we don’t process a distance change in the initial relocation call (as that just locates the end user on the map). Everything seemed to work but I noticed that even though the zoom is limited, redraw is still called when you keep trying to zoom out. So, that if statement also checks to see if the previous and current geo location is the same, in which case we skip the distance processing.
Here is the demo of ModestMaps with SongKick API. Try interacting with the map and when you move more than 40,000 meters from the previous center location, the JavaScript will initiate another location request to SongKick.
Concerts per Geo Location with SongKick API and ModestMaps
We are still missing the biggest part of the demo, the actual concerts and festivals getting listed on the page. So, I added some CSS to the panel element and added anther request to SongKick API for upcoming events according to the most frequent metro id from the selected map location. When I create the listing, I added a “Map It” element with a click event that plots any event on the list as a marker on the map. I used HTML 5 data- attributes to store latitude and longitude values and I reposition the map to that geo location when the element is clicked.
As a result of repositioning the map, I have to wait for the redrawn function to complete before I can accurately place the marker on the map. So, marker placement lives in the reprocess function and I use a flag to identify this action. All of this asynchronous functionality results in a lot of information living in the global namespace which is not ideal, and this could be improved or written differently. But, it works for a demo and here is the final example, a map build with ModestMaps that lets you explore concerts by location provided by SongKick API.
External:
Other Documentation for ModestMaps
HyperText Plugin for ModestMaps
Easey – Simple Maps Animation Library
Parallax demo with ModestMaps