In this article we show how to embed a Google Map in a web page so that it will be mobile-friendly and work on all devices, including low-end devices without JavaScript support. To do this, we’ll use the Google Maps API for high-end devices that can handle JavaScript, and for low-end we make use of the simpler Google Static Maps API.
The Google Maps API generates interactive JavaScript maps, with embedded controls for zooming, panning, and is generally touch-friendly. The Static Maps service works via a simple URL request for a map tile for a specified location, and at a particular zoom level. There is no interaction directly possible with the map by the user (although it would possible to add buttons yourself for zooming, panning, and then requesting an appropriate tile for each button press).
Static Maps API for low-end devices
Let’s start with the easy one first. We use the Google Static maps API for this. This API is really simple to use, and amounts to building a URL to the Google Static Maps API, and, at a minimum, passing lat-lon and size parameters to it. Additional parameters, such as zoom, can also be included to customize the map further. Although it will work without an API key, Google recommends that you create a key so that you can track your application’s usage.
The map tiles below are generated simply with the following markup, centered on a well known Berlin landmark, with only the the zoom parameter changing:
1 |
<img src="https://maps.googleapis.com/maps/api/staticmap?center=52.516284,13.377678&zoom=12&size=200x200"> |
Optional parameters for Static Maps API
In addition to the latlon and size parameters, there are various optional parameters that you can use to customize the map, including
maptype
: Specifies the type of map to display. Values: roadmap, satellite, terrain, hybridscale
: Used to generate more detailed map tiles for devices with higher pixel density. Read more aboutscale
herezoom
: Zoom level for the map tile. Values between 0 and 19
Markers
Markers can be added be added to the static map URL using the markers
parameter to specify location, color, and label. Multiple markers can be added with the markers
parameter, spearated with a comma. The map tile below is generated using the following code:
1 2 3 |
<img src="https://maps.googleapis.com/maps/api/staticmap?center=52.516284,13.377678&zoom=12&size=200x200&maptype=roadmap &markers=color:blue|label:1|52.516284,13.377678&markers=color:yellow|label:2|52.518595,13.376198 &markers=color:red|label:3|52.514483,13.350013" /> |
Bonus: Street View static API
Should a business want to include a street view image of their business, or some other point of interest, they can use an almost identical URL, replacing staticmap
with streetview
and with just one new parameter:heading
to specify what direction to grab the image from.
1 |
<img src="https://maps.googleapis.com/maps/api/streetview?size=200x200&location=52.516405,13.376921&heading=100"> |
Google Maps API v2 for high-end phones
Using the Google Maps API, is just a little bit more complex than the static maps API, but is pretty easy to use all the same. As with the Static Maps API, this API also specifies that you should get a key to access the API, listing benefits such as usage tracking. In practice, it is not required, so it is up to you whether to obtain one or not. If your site is busy, you should probably get one, if for no other reason than to avoid having the service cut off unexpectedly.
First, we need to include the Google JavaScript API with
1 |
<script src="https://maps.googleapis.com/maps/api/js"></script> |
We also need an HTML div element that will hold the map:
1 2 |
<div id="map"> </div> |
Next, we generate the map by setting some map options, and passing these to a new google.maps.Map
object:
1 2 3 4 5 6 7 8 |
var map_options = { center: new google.maps.LatLng(52.516284,13.377678), zoom: 15, mapTypeId: google.maps.MapTypeId.ROADMAP } map_canvas = document.getElementById('map'); var map = new google.maps.Map(map_canvas, map_options); |
That’s pretty much all there is to it. The map below is generated using this code.
The most important options for this example are to specify location, zoom level, and scale.
Detecting high-end and low-end devices
Before we can decide which version of the map to use, we must detect if the user is on a low-end or a high-end device. To do this we’ll make use of the free version of DeviceAtlas. It’s a completely free web-service that you can hook into your app to figure out the class of device.
Set up cloud device detection
- Sign up for free account at deviceatlas.com
- Download the DA cloud API. In this example we’ll use the PHP version
- Grab your key from your licenses page, and drop it into to the
/Api/Client.php
file in the sample code you just downloaded - Test your implementation on a number of devices to make sure they are being detected correctly
The code you need to drop into your site looks like this. First, query the cloud service:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
require_once dirname(__FILE__).'./Api/Client.php'; $errors = null; // it is highly recommended to use the API in a try/catch block try { // get device properties for the current request $properties = DeviceAtlasCloudClient::getDeviceData(); // if errors happend within the cloud call/API if (isset($properties[DeviceAtlasCloudClient::KEY_ERROR])) { $errors = trim($properties[DeviceAtlasCloudClient::KEY_ERROR]); } } catch (Exception $ex) { // all errors must be taken care ok $errors = $ex->getMessage(); } |
Now that we have device detection set up, the two main tasks we need to determine if the device is high-end or low-end, so we can decide which version of the map to display.
Detecting high and low-end devices
The first thing we need to do is retrieve the set of properties of the device:
1 2 3 |
// Call static method and get back the device properties $results = DeviceAtlasCloudClient::getDeviceData(); $properties = $results[DeviceAtlasCloudClient::KEY_PROPERTIES]; |
For this example, to decide if the device is high-end or low-end, we’ll make use of the browserRenderingEngine
property. If its value is one of WebKit
, or Gecko
, or Trident
we’ll assume it’s in our high-end category, and we’ll deliver the high-end map. How exactly you define high-end will depend on your application. This is good enough for this example.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function isHighEnd() { //tablets, desktop browsers assumed highend if($properties['isBrowser']||$properties['isTablet']) { return true; } $engine = $properties['browserRenderingEngine']; $engine_list = array('WebKit', 'Blink', 'Gecko', 'Trident', 'UCWeb') if($engine in $engine_list) { return true; } return false; } |
Note also that DeviceAtlas recommends you cache results on your server, so that you can minimise the number of calls made to the external service, and so your application will get faster over time. The code to achieve this is included in the DeviceAtlas Cloud code samples.
Tying it all together
We combine all the previous code samples into one solution:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
<?php include './DeviceAtlasCloud/Api/Client.php'; // Call static method and get back the device properties $results = DeviceAtlasCloudClient::getDeviceData(); $properties = $results[DeviceAtlasCloudClient::KEY_PROPERTIES]; $is_high_end = isHighEnd($properties); if (isset($properties['mobileDevice']) && $properties['mobileDevice']) { $display_width = $properties['displayWidth']; } function isHighEnd($properties) { //tablets, desktop browsers assumed highend if($properties['primaryHardwareType']=='Desktop'||$properties['primaryHardwareType']=='Tablet') { return true; } $engine = $properties['browserRenderingEngine']; $engine_list = array('WebKit', 'Blink', 'Gecko', 'Trident', 'UCWeb'); if(in_array($engine, $engine_list)) { return true; } return false; } ?> <html> <?php // Use Google Maps API for high-end device if($is_high_end) { ?> <script src="https://maps.googleapis.com/maps/api/js"></script> <div id="map"></div> <script> function map_init() { var map_options = { center: new google.maps.LatLng(52.516284,13.377678), zoom: 15, mapTypeId: google.maps.MapTypeId.ROADMAP } map_canvas = document.getElementById('map'); var map = new google.maps.Map(map_canvas, map_options); } google.maps.event.addDomListener(window, 'load', map_init); </script> <?php } //Use static map else { ?> <div id="map"> <img width="100%" src="https://maps.googleapis.com/maps/api/staticmap?center=52.516284,13.377678&zoom=13&size=200x200" /> </div> <?php } ?> </html> |
Taking it further: geolocation
In this example we used a fixed latlon point to set the location of the Google map. Using DeviceAtlas to determine if the device was high-end or low-end, we could then decide which map type to deliver to the device, using either the Google Maps v2 API, or the Google Static Maps v2 API. In our examples, we used a fixed lat-lon position as the location for our maps. This is just the beginning! A logical next step is to use a phone’s GPS location data to set the map. Our HTML5 Geolocation API article demonstrates how you can do this, and how you can track a user on map in real-time.
Leave a Reply