Click here to Skip to main content
15,868,016 members
Articles / Web Development / HTML

Generate a Google Map

Rate me:
Please Sign up or sign in to vote.
4.79/5 (14 votes)
12 Nov 2013CPOL3 min read 41.7K   2.2K   41   9
How to generate a simple map image, using Google's Map API

Introduction

This article shows how to create a map image in your browser, showing a number of location markers that are taken from a list of addresses, using a few HTML lines and client side JavaScript. It also demonstrates a simple trick to add labels to the marker pins on that map. The locations are specified as human readable addresses, which are then converted to GPS coordinates using Google's Geocoder. As a bonus, a progress bar shows while doing the location lookups.

Background

It took me a few hours to get all information and put it together to a working demo. So I figured it would be a good idea to publish this working example to save you some time.

Using the Code

The example map is generated by a single HTML file, which has the HTML code and JavaScript combined. Let's go through the code block by block, from top to bottom of the file.

Image 1

Google API Declaration

The first part of the file contains the HTML header and Google API 'declarations' (please forgive me if I don't use the correct terminology):

HTML
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <title>Points of interest</title>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
        <script src="https://maps.googleapis.com/maps/api/js?v=3.11&sensor=false" 
                   type="text/javascript"></script>

List of Locations to Look Up

A a next step, the list of locations is defined as an Array of simple strings. Commas are used to separate the fields within a location string. The first field serves as the name, the rest is the address itself. Also note that the whole Java scripting is started when the document loading is ready():

JavaScript
<script type="text/javascript">
    $(document).ready(function() {
        // execute
        (function() {
            // Points of interest
            var locations = new Array();
            var i = 0;
            locations[i++] = "Rijksmuseum, Museumstraat 1, Amsterdam"
            locations[i++] = "Van Gogh Museum, Paulus Potterstraat 7, Amsterdam";
            locations[i++] = "Kroller-Muller Museum, Houtkampweg 6, Otterlo";
            locations[i++] = "Beeckestijn, Rijksweg 136, Velsen";
            var total_locations = i;
            i = 0;

The variable total_locations is introduced to calculate the progress (discussed later on).

Creating the Map

Now comes the interesting part. A variable options is created with a number of elements:

  • zoom: Sets the default zoom level of the map
  • center: Specifies the center of the map, using GPS coordinates (latitude, longitude)
  • mapTypeId: For this example, we use terrain
  • mapTypeControl: Set to 'true' so that controls are added to the map (zoom, navigate)

Then a new instance of the map is created with the options specified. The 'map_canvas' identifier comes from the HTML part. It is the identifier of a <div> element to hold the map image.

JavaScript
console.log('About to look up ' + total_locations + ' locations');
// map options
var options = {
    zoom: 8,
    center: new google.maps.LatLng(52.2313, 4.83565), // Amstelhoek, center of the world
    mapTypeId: google.maps.MapTypeId.TERRAIN,
    mapTypeControl: true
};

// init map
console.log('Initialise map...');
var map = new google.maps.Map(document.getElementById('map_canvas'), options);

Looking Up the Locations, Slowly...

When not using a Google API key, the number of Geolocation lookups per second is limited. If we perform too many queries, an error result code is returned by the Google Maps API server. So let's prevent that by limiting the number of location lookups to one per second. For this, the setInterval method is used:

JavaScript
// use the Google API to translate addresses to GPS coordinates
var geocoder = new google.maps.Geocoder();
if (geocoder) {
    console.log('Got a new instance of Google Geocoder object');
    // Call function 'createNextMarker' every second
    var myVar = window.setInterval(function(){createNextMarker()}, 1000);

When the 1000 millisecond interval expires, it calls createNextMarker in our JavaScript:

JavaScript
function createNextMarker() {
    if (i < locations.length) {
        var customer = locations[i];
        var parts = customer.split(",");
        var name = parts.splice(0,1);
        var address = parts.join(",");
        console.log('Looking up ' + name + ' at address ' + address);
        geocoder.geocode({ 'address': address }, makeCallback(name));
        i++;
        updateProgressBar(i / total_locations);
    } else {
        console.log('Ready looking up ' + i + ' addresses');
        window.clearInterval(myVar);
    }
}

Here, a little trick is performed. The geocoder.geocode method takes a callback as last argument. This will be called once the reply has been received from the server. That reply contains the GPS coordinates and address details, but not the original name from our list of locations. To have that name value available in the context of the callback, we use the trick as shown in the code fragment above. Note that makeCallback returns the function variable (geocodeCallBack) of the actual callback that will be called by geocoder.geocode. It will then parse the result (results[0]) and place the marker on the map.

JavaScript
function makeCallback(name) {
        var geocodeCallBack = function (results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                var longitude = results[0].geometry.location.lng();
                var latitude = results[0].geometry.location.lat();
                console.log('Received result: lat:' + latitude + ' long:' + longitude);
                var marker = new google.maps.Marker({
                    position: new google.maps.LatLng(latitude, longitude),
                    map: map,
                    title: name + ' : ' + results[0].formatted_address});
            } else {
                console.log('No results found: ' + status);
            }
        }
        return geocodeCallBack;
    }
} // endif geocoder

Progress Bar

Just for fun and to show some animation while looking up the geolocations, a progress bar is shown:

JavaScript
function updateProgressBar(percentage_factor) {
            var map_canvas = document.getElementById('map_canvas');
            var node = document.getElementById('progress_bar');
            var w = map_canvas.style.width.match(/\d+/);
            w = w * percentage_factor;
            node.style.width = parseInt(w) + 'px';
            if (percentage_factor == 1) {
                // jscript style properties are different to the CSS style properties
                node.style.backgroundColor = 'green';
            }
        }
    // Closing bits of jscript...
    })();
});
</script>

HTML Code

HTML
</head>
    <body>
    <div style="border: 1px solid black; width:1024px; height:3px;">
        <div id="progress_bar" style="height:3px; width:0px; background-color:red;"/>
    </div>
    <!-- if you change this id, then also update code of progress bar above -->
        <div id="map_canvas" style="width: 1024px; height:600px;"></div>
    </body>
</html>

Browser Security

When first loading the HTML code, the security settings of your browser may prevent display of the map. Internet Explorer shows a pop-up bar at the bottom of the page. Firefox and Chrome show a shield icon in the address bar. Click it with the mouse and choose the option to disable security for this page.

Points of Interest

The thing that I have learned from the examples that are already published on the net, is the trick of passing a variable value to a callback. The rest of the code is actually pretty straight forward and already available on the net, but not combined into a working example as shown here.

History

  • 12th November, 2013: Initial version
  • 13th November, 2013: Fixed small typo and added security note

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) LSO - Lieshout Software Ontwikkeling
Netherlands Netherlands
Fred is an experienced software engineer with in-depth knowledge of software design, coding and testing. He is interested in the analysis, requirements and design phases in particular, but still enjoys ‘getting his hands dirty’ with software programming. Favorite programming languages are C, C++, C# and Java.

LinkedIn: profile

Comments and Discussions

 
Questionlove it Pin
Word Code24-Apr-17 0:05
Word Code24-Apr-17 0:05 
GeneralCongrats Pin
Member 1163950424-Apr-15 4:55
Member 1163950424-Apr-15 4:55 
QuestionQuestions about info window and using inside another <div> Pin
Gary Henning25-Aug-14 13:51
Gary Henning25-Aug-14 13:51 
AnswerRe: Questions about info window and using inside another <div> Pin
Fred van Lieshout25-Aug-14 20:32
Fred van Lieshout25-Aug-14 20:32 
GeneralRe: Questions about info window and using inside another <div> Pin
Gary Henning11-Sep-14 7:20
Gary Henning11-Sep-14 7:20 
GeneralRe: Questions about info window and using inside another <div> Pin
Fred van Lieshout11-Sep-14 19:46
Fred van Lieshout11-Sep-14 19:46 
GeneralMy vote of 5 Pin
Gun Gun Febrianza13-Nov-13 5:20
Gun Gun Febrianza13-Nov-13 5:20 
Questioni love this article :) Pin
Gun Gun Febrianza13-Nov-13 5:19
Gun Gun Febrianza13-Nov-13 5:19 
AnswerRe: i love this article :) Pin
Fred van Lieshout13-Nov-13 19:45
Fred van Lieshout13-Nov-13 19:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.