Maps API or X marks the spot.

No, we're not making fun of Apple Maps, but we could if we wanted to. Let's just say I don't want to jump wink wink into the whole Apple Maps conundrum.

This article, in particular, is focused on describing my adventures with Apple Maps's older and more experienced brother, Google Maps.

Now, I'm sure you don't want to know how Google Maps came to be, I mean you can read that on Wiki, right? Lets get down to the nitty-gritty! Along my years as a developer I've had my fair share of experiences with the Google Maps API.

It all started on one summer morning. It was hot outside and the AC was running full steam. bing rang the email notification at the bottom of my screen. Oh look, a new project! As I read the short brief, I understood then and there that I would soon dive in the cumbersome world of the Maps API. And that was the beginning!

Tip: If you understand the Maps API from the very beginning, you won't have any trouble later on.

The basic principle of the Maps API is that you have a container and in that container, the map is loaded using JS. On top of that you can add an extra layer of interaction to the map, you can add markers.

The idea behind markers is that you can interact with them and point a user to a predefined location on the map. For example you have a website that promotes local businesses. But how can we achieve this, without staying too late and miss out beaut sleep? Well it's quite simple (It always is!). First of all we need to create a simple container, like the one below.

<div id="map-canvas"></div>

After we have this container, on our page, we can go ahead and start loading the Maps API. I should mention that for the sake of this example we are going to use jQuery to load some stuff, but don't worry there are other ways you can do this. In the head part of our page or in a different .js file we start initializing the map. We do this by using some basic JS.

<script type="text/javascript">
    var infowindow;
    var map;
    function initialize() {
        var mapOptions = {
            zoom: 13,
            minZoom: 13,
            center: new google.maps.LatLng(LATITUDE,LONGITUDE),
            panControl: false,
            zoomControl: true,
            zoomControlOptions: {
                style: google.maps.ZoomControlStyle.DEFAULT
            },
            mapTypeControl: false,
            scaleControl: false,
            streetViewControl: false,
            overviewMapControl: false,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            scrollwheel: false
        };
        jQuery.get("markers.php", function(data) {
            jQuery(data).find("marker").each(function() {
                var eachMarker = jQuery(this);
                var markerCoords = new google.maps.LatLng(
                    parseFloat(eachMarker.find("Latitude").text()),
                    parseFloat(eachMarker.find("Longitude").text())
                );
                var name = eachMarker.find("Name").text();
                var url = eachMarker.find("URL").text();
                var html = "<a href='" + url + "' title='" + name + "'>" + name + "</a>";
                var marker = addMarker(html, markerCoords);
            });
        });

        map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
    }

    function addMarker(html, markerCoords) {
        var marker = new google.maps.Marker({
            animation: google.maps.Animation.DROP,
            map: map,
            position: markerCoords
        });

        google.maps.event.addListener(marker, "click", function() {
            if (infowindow) infowindow.close();
            infowindow = new google.maps.InfoWindow({
                content: html,
                minHeight: 300
            });
            infowindow.open(map, marker);
        });
        return marker;
    }

    function loadScript() {
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=initialize';
        document.body.appendChild(script);
    }
    window.onload = loadScript;
</script>

Ok, but what does the code above mean? For starters, we need some basic variables to hold the map itself and the info box for each marker.

The first function initializes the map with the options we want. These options can have a great impact on the map itself. I should mention that the ones mentioned in the code are not all the ones available, those are just the ones I find the most useful.

One important thing to remember is that the center map option, that needs longitude and latitude, is required when initializing a map. Without it, the map would be all over the place and we don't want that, do we? The next bit of code is for loading the markers. We achieve this by using jQuery, an external php file that outputs some XML and another JS function that creates the marker and adds the info box to each one of the markers.

We're using jQuery's get function to achieve this, but as I said earlier, you can use what ever you'd like to load the markers, this is just a solution I use.

After all this is done, we generate the map object, using the already created container and applying the map options. Each marker is generated from an XML output, but to add it to the map we go through all of them and call the addMarker function to add the info box.

After that we add them to the map, using the coordinates available. Basically each marker is an object that we add to the main object, which is the map. Last but not least, we load the actual Maps API using some basic JS. You may have noticed that I skipped the loading markers step. Well that's because that is a whole different story.

For this particular example I'm going to use the version of the markers.php file that I use in WordPress. This means that I use basic WordPress functions and some things that you may blame me for using, but I don't care about that at the moment because this is not a production project.

Before we begin, I should mention that I use the Advanced Custom Fields plugin to add a location field to a post. The latest versions of this plugin come with a Google Maps field that you can generate and add as a field just like you would with other custom fields.

Ok, so the basic concept of this markers loading is that we query for posts and we get the name, coordinates and the url, after that jQuery can come in and get them. These are just some basic stuff you can get. You can grab all sorts of stuff from a post, you're imagination or requirements are the limit.

<?php
    header('Content-type: text/xml');
    $parse_uri = explode( 'wp-content', $_SERVER['SCRIPT_FILENAME'] );
    require_once ($parse_uri[0] . 'wp-load.php');

    echo '<?xml version="1.0" encoding="utf-8"?>';
        echo '<markers>';
            $query = new WP_Query(array(
                'post_type' => 'post',
                'posts_per_page' => '-1'
            ));
            while ($query->have_posts()) : $query->the_post();
                $location = get_field("location");
                if ($location['address'] != "") {
                    $marker = '';
                        $marker .= '' . get_the_title() . '';
                        $marker .= '' . trim($location['lat']) . '';
                        $marker .= '' . trim($location['lng']) . '';
                        $marker .= '' . get_permalink() . '';
                    $marker .= '';
                    echo $marker;
                }
            endwhile;
            wp_reset_query();
        echo '</markers>';
?>

Ignoring the second and the third row, we start generating our XML output. Using the basic WP_query function, available in WordPress, we query for posts and we get all of them, but you can play with this as you please.

If we have posts, we go through each one of them and start outputting.
The beauty of the ACF plugin is that it provides a simple function (The get_field function!) to get the field values for a post and with that data you can do what ever you want. In this case we have an array that contains the latitude, longitude and the address. All we need is the latitude and longitude. The basic get_the_title and get_permalink functions are also present.

We reset the query and close the XML. Now, jQuery can come in and grab each marker and add it to the map.

And there you have it, simple and easy Google Maps API integration with marker loading.

I hope this “short” tutorial was easy to understand. This was my version of Google Maps API integration for WordPress and if you have any suggestions / comments just tell me.

Until next time, code long and prosper!

Stefan