Advanced WordPress Google Maps Made Simple

Maps showing your office location are all well and good but with the right WordPress plugin and a little bit of tweaking, your WordPress-embedded Google Maps can be a whole lot more engaging for your visitors.

In this tutorial, we’ll create custom post types from a CSV datafile, create a plugin to dynamically generate a KML and then overlay that file on a Google Map: a technique you could use for any geocoded post type.

So, roll up those cartography sleeves and let’s get mapping!

Google Maps, KML overlays and custom post types all come together for massively engaging maps
Google Maps, KML overlays and custom post types all come together for massively engaging maps

What Are You Going To Learn?

This tutorial was inspired by a comment on my recent post about the Google Maps plugin from @josh_armstrong:

I want to build a location finder. We have 2 radio programs that is aired on many stations (hundreds) around the US and Canada. Can I build a map and have a way to display them all — but ideally I would be able to import them in via a spreadsheet.

There were a couple of comments as well about plotting geocoded posts and the technique we’ll go through will work equally well but we are going to focus on the above request as it involves a number of interesting techniques:

  1. Importing CSV data into WordPress as custom post types
  2. Dynamically generating a KML-formatted file
  3. Using a KML overlay to display placemarkers

This tutorial will create a Google Map version of this map of local radio stations operated by the Australian public broadcaster, the ABC.

Each station (represented here as a place marker) will be a custom post type that we will generate from a CSV file. To put the placemarkers on the map, we’ll dynamically generate a KML file that will be “overlayed”.

What you should keep in mind is that this is really just working with posts that are geocoded – that is, they have a latitude and longitude assigned to them in custom fields. For this example we are using radio stations but the post could be a business from a business directory, an event location, a restaurant on a review site, a real estate listing, a job vacancy or anything else that you can dream up.

Using these techniques and the plugins described, you can display any geocoded post and easily control the style and formatting of the balloon, all without needing to delve into javascript.

What Is KML And Why Is It So Useful?

Here’s the official definition of KML:

KML is a file format used to display geographic data in an Earth browser such as Google Earth, Google Maps, and Google Maps for mobile.

KML uses the XML format to define such items as placemarks or “pins”. Where KML becomes really useful, though, is that you can define all manner of additional attributes and a style which means that you can completely control the styling and content of the balloons that appear when you click on a placemarker, all without resorting to Javascript.

Powerful stuff, indeed.

Shortcuts With Existing KML Files

Although we are going to dynamically build our own KML file from posts in WordPress (so hopefully you’ll be inspired to tailor it for your own situation), if the data you want is already available in KML format then there is a very quick and easy shortcut to generating the map.

The WPMU DEV Google Maps plugin supports KML overlays, so if you have the plugin installed go to Settings > Google Maps, click on Add-ons and activate both KML Overlay and KML Uploader.

If you upload a KML file you will be able to select the file when creating a map, or you can just specify the URL of an existing file. We’ll do the latter with the ABC stations KML file:

  1. Create a new WordPress page and give it the title of ABC Local Radio Stations
  2. Click on the maps icon and Create new map in the pop-up dialog
  3. Give the map a name and click on Map options
  4. Scroll to the bottom of the Map options dialog and in the KML file URL textbox enter: http://www.abc.net.au/local/data/public/stations/abc-local-radio.kml
  5. Click OK. The map should update automatically and you should see something like this:
Add map dialog from Google Maps plugin showing a map of australia with pins for each local ABC radio station
Using KML overlays means no fiddling with javascript for placemarkers and their balloons
  1. Click on Save changes to this map and then Insert this map
  2. Publish and view the page and you’ll see the map (you might want to specify new a new width and height appropriate for your theme).

Clearly, if you can get your hands on an existing KML file and it has exactly the data and the look and feel that you want, then the KML support in the Google Maps plugin makes creating maps like this an absolute breeze.

But what if a KML file isn’t available, what can you do then?

You can, of course, generate a KML file outside of WordPress and repeat what we’ve done above. Alternatively, you can use WordPress itself to hold the data and dynamically generate the KML for any post that is geocoded: regular posts, business directories, members, classified ads or radio stations.

And that’s what we are going to do now. We are going to take the geocoded data for the ABC local radio stations, conveniently also available as a CSV file, import it into WordPress as custom post types and then dynamically generate a KML file for our map.

Converting CSV Data To Custom Post Types

Getting the CSV data into WordPress is actually surprisingly easy.

Although we don’t have to, we are going to use a custom post type just to keep things nice and clean, so the first thing to do is to create it. I used CustomPress (naturally) but there are any number of plugins out there that will help you. Or, if you are feeling adventurous, you can always roll-your-own using generatewp.com.

The post type should have the name station (and preferably the labels Stations and Station). If you want to play with filtering using tags and categories, make sure you have these enabled.

Once you have your custom post type, install the WP Ultimate CSV Importer plugin (my newest favorite WordPress plugin). This is a fantastic plugin that makes importing CSV ridiculously easy.

Once installed, click on WP Ultimate CSV Importer in the Admin menu. We just have to switch on Custom Post support first, so go to Settings in the plugin’s top menu and check Custom Post at the bottom of the list and click save.

We need, of course, data to upload, and very conveniently our list of ABC local stations is available in CSV format also. Download and save this file somewhere convenient.

We have our data and our custom post type – let’s import.

1. Click on CUSTOMPOST in the WP Ultimate CSV Importer menu

2. Select the CSV file you just downloaded either by clicking on Browse or dragging and dropping the file. When the file has uploaded, click on Next.

3. In the Import Data Configuration pane, select the post type (station) and select Publish as the value for Import with post status.

Import configuration options pane for the WP Ultimate CSV Importer plugin
This plugin makes importing CSV data ridiculously easy

You’ll see that each of the CSV columns is listed along with a drop-down for mapping to a post field and a sample value. Map the following:

  • Station to post_title
  • Town to post_content

Everything else can be mapped to Add Custom Field which will create a new custom field for you with the name in the text box. You can change this but there is no need to.

You don’t have to map every column but you must map the following:

  • Latitude
  • Longitude

It will also be useful if you also map (to Add Custom Field):

  • Street-number
  • Street-suburb
  • Twitter
  • Facebook
  • Website-URL

4. Click Next when you’ve finished mapping.

5. Don’t worry about the detect duplicate checkboxes (these are useful for multiple imports of the same data) but you do need to enter a value in How much comparisons per Server-Request?. This effectively batches the import and the maximum you can add for the free version is 5, so enter 5 and click on Import Now.

You’ll see some details scrolling through the LOGS: window and without too much delay the import will complete.

Clicking on Stations in your Admin Menu should now display a list of station posts. So, now our data is there, we can move onto building a KML file.

Dynamically Building A KML File

The idea behind dynamically building a KML file is that we can then specify that URL in the Map options file rather than having to specify an already created, static KML file. Of course, you can also just pop the URL into a browser and save the output if you want to load the file up as a static KML file.

The point is that the KML file is going to be generated from our WordPress posts. I’ve chosen the simplest path I could to achieve this but also hopefully built in some flexibility to make it useful for you.

All we really do is just hook into the template_include filter and check to see if a KML request is being made.

If it is then the function looks to see if a template has been specified in the URL and if it has then it will check to see if the template file exists. If the template doesn’t exist or if none has been specified then the default template is used.

[gist file=”kml_export.php”]11278396[/gist]

Using this approach allows us to create multiple KML templates and then specify which we want to use in the URL.

As you’ve probably guessed, all the hard work is done by the template file itself. Here’s the template file for the station KML file:

[gist file=”kml-default.php”]11278396[/gist]

Again, nothing too scary here.

The template uses WP_Query to retrieve the appropriate posts and builds a KML file (held in an array) by iterating through the returned posts and creating a Placemark element for each.

The template uses the QUERY_STRING as the input for the creation of the WP_Query object to allow some flexibility in specifying the posts that are to be retrieved (you can specify categories and tags for example). An extra parameter of posts_per_page=-1 is added to the arguments to override WP_Query‘s default behavior of returning posts in pages and ensure that all posts are returned.

You’ll notice that the styling and formatting is specified at the top of the KML document and then simply referenced by each Placemark. The formatting references child elements of the Placemark, allowing the complete customization of the balloon content.

The critical element, of course, is Point and its child coordinates. The content of coordinates is longitude, latitude and altitude (we always set this to 0).

Here’s a sample KML file for our data:

[gist file=”sample.kml”]11278396[/gist]

Download and install the KML Exporter plugin and you test its output with the following URL:

http://[your wordpress domain]/?kml=yes&post_type=station

If this URL outputs the KML file then head back to the page you created earlier, click on the map icon, edit the map and in Map options change the KML URL to the one above.

Click OK and then Save changes to this map. View the page and you shouldn’t see any difference!

Playing and Extending For Even More Awesome Maps

In this tutorial we’ve covered quite a lot of ground.

We’ve converted CSV encoded data to custom post types, used those posts to generate a KML file which we’ve then used as an overlay on a Google Map.

Of course, the solution here is pretty simplistic and is designed to work with the radio station data, but hopefully it’s given you a taste for what’s possible when you move beyond a static KML file. Even in this example, it would be possible to improve on the original KML file by perhaps allowing reviews on the station posts and including them in the KML file. Or even taking the mashup further and including the details of the program currently being broadcast.

There are also plenty of areas where the technique can be improved generally including:

  • Caching the KML output and building in triggers for rebuilding (either CRON-based or event-based)
  • Consolidating the style in a single file for easier management (rather than hard-coding in the template)
  • Extending the ability to tailor the post selection through the query string
  • Creating templates for common types of data (perhaps those created by popular plugins)

Maybe you’ll take up the challenge, write your own templates, and do something awesome with this simple plugin, KML and the Google Maps plugin?