Data, Maps, Usability, and Performance

Leaflet Map Markers with API Caching

Last updated on August 20, 2013 in Development

caching API calls with PHP

LeafLet Map showing Flickr and Panoraimo Photos with Caching

I was looking at my OpenLayers Flickr And Panoraimo Demo today and I realized that plotting anything on a map with data that comes from an external API should leverage the server. The most important reason for this is caching but there are other benefits. You don’t have to deal with any cross-domain policy or hope for JSONP support since the communication with the API will be server-side. Also, it’s not secure to have API keys in your JavaScript as they can easily be taken, especially with search engines like NerdyData. So, it’s good practice to have these keys on the server. Today, I am going to explore some caching options in PHP and show how to create a nice Leaflet Map with markers generated by API calls that are cached on the server.

Caching can be complex but our use case here is quite simple. Plotting photos on a map requires either an individual geo coordinate or more ideally, the bounds of the map or 4 geo coordinates. This is really all we need to send to the server, which will initiate the API calls based on that geo location data and send the information back to the client. If you are not caching, every page refresh or a new user that lands on the same area of the map will trigger the same API request multiple times.

So, all we really need is to store the API requests to a file, write a conditional to check if the request was made previously (by just checking if a file exists), and serve the request from the file instead of making an API request. It could be as easy as this or this or we could just leverage an already created API Cache class. My choice is for this super simple PHP cache function and here is my implementation for caching both Flickr and Panoraimo API calls:

I think it is pretty self explanatory. Now, let’s consider the client side. We define a leaflet map with cloudmate layer and constrain zoom to 9 so that we don’t send huge bounds to Flickr and Panoraimo servers. Since Leaflet has a Geo Location function, I used that to center the map on the page to the user’s location. If there is any error, we handle that in our onLocationError function that just sets the map view to some arbitrary geo coordinate.

Since the GeoLocation function is asynchronous, I had trouble retrieving the center geo location of the map from the “map load” event. So, I made a viewreset event and retrieved the center of the map at this starting point. I am doing this because, in addition to server-side caching, I want to limit the amount of Ajax requests on the client side. I am going to do this with distance, similar to my SongKick API example with Modest Maps. So, we track the first center point when the map loads and then, on a dragend event (when someone moves the map), we compare the new center location to the previous point. I have used the point.distanceTo function to measure the distance between the two points and I am only sending requests to the server if the drag/pan was more than some arbitrary distance.

Initially, if someone drags the map by a good amount, I send them to my start function which first, removes any markers that have already been placed on the map, and second, gets the bounds of the map and makes an Ajax request to the api-cache.php script above. Both Flickr and Panoraimo take the same geo coords, so we don’t need to consider any extra parameters, but the response will need to be parsed differently. We could do the parsing server side but some level of parsing will always be required to place the markers on the map, so I decided to let the server handle caching while the client does the parsing.

Again, I get into some asynchronous JavaScript here so I decided to wrap the JSON from the API requests around a function and eval that function on the client side. Eval might be evil but even Douglas Crockford said that eval is ok for parsing JSON. I later noticed that Flickr and Panoraimo both support JSONP, so instead of wrapping the JSON response in a function, I just let the API servers do that for me by defining the callback in the JSONP request. So, the server sends both API responses back to the client, and when they get eval’ed, each one goes to the appropriate parsing function. These functions parse the API JSON response and send the markers to the final function that plots the Flickr and Panoraimo photos on the map.

I have used a different icon for Flickr vs Panoraimo and the photos pop up in a little Leaflet tooltip. Check out the LeafLet with Photo Markers and API caching demo.

External:

PHP Caching Twitter
Caching API Responses

Tags: , ,

Facebook Twitter Hacker News Reddit More...