Locator Plus implementation guide

Overview

web iOS API

Google Maps Platform is available for web (JS, TS), Android, and iOS, and also offers web services APIs for getting information about places, directions, and distances. The samples in this guide are written for one platform, but documentation links are provided for implementation on other platforms.

Build it now!

Quick Builder in the Google Cloud Console lets you build a locator using an interactive UI that generates code for you.

Your users want to research products and services online, and find the best and most convenient location to visit, make an appointment, or pick up an order. They want to get to your location as quickly as possible. And you want to give them rich online experiences that increase visits to your physical locations, strengthen user satisfaction, and reduce support calls. You also want to measure the success of your locator to determine if your customers can find your location, and you want to understand where to make improvements.

Locator Plus—the guidance and customization tips we provide in this topic—is what we recommend as the optimal combination of Google Maps Platform APIs to build great locator user experiences. Following these practices, you can help users find your locations on a map, see detailed information they need to make decisions, and give them directions, whether they're driving, cycling, walking, or taking public transit.

The following diagram shows the core APIs involved in implementing Locator Plus. The diagram also shows a database of your own location data that you can combine with Place Details to give users the best, most complete set of information possible. (Click to enlarge.)

Left side of the diagram, a web browser displays a map with a Place Details popup.
              Right side of the diagram, a list of APIs that provide different functionality:
              Maps JavaScript API for location visualization and content, map styling, map
              markers, custom Street View, and displaying routes. Place Autocomplete for
              address completion and type-ahead functionality. Places and Geocoding APIs for
              address location. Distance Matrix API to rank locations by distance, time, and
              travel mode. Directions API to show a route based on travel time and travel mode.
              Middle of the diagram, a data store icon representing custom location data points
              up to a web server icon with a double-headed arrow indicating data read and write
              between web server and data store. Arrows between the web browser
              and APIs go through the web server as an intermediary.

Enabling APIs

To implement these practices, you must enable the following APIs in the Google Cloud Console: For more information about setup, see Getting started with Google Maps Platform.

Implementation sections

Following are the practices and customizations we'll cover in this topic.

  • The check mark icon is a core practice.
  • The star icon is an optional but recommended customization to enhance the solution.
Showing your locations on an interactive map Build a map that lets users see location details, move around, and zoom in and out.
Providing Place Details After users find your closest locations on a map, give them meaningful Place Details about the locations to help them make decisions.
Showing locations from a 45° view Give users a better visual of your location in satellite view from a 45-degree angle.
Identifying your user's location Add type-as-you-go functionality to improve the user experience on all platforms and improve address accuracy with minimum keystrokes.
Showing travel time and distance to nearest locations Calculate the travel distance and travel time for multiple origins and destinations, optionally specifying various forms of transport such as walking, driving, or cycling.
Helping users book appointments Let users book an appointment from the Place Details side panel.
Displaying local offers Show users clickable local offers in the Place Details side panel.
Providing navigation directions Get directions data from origin to destination using various forms of transport such as walking, driving, cycling, and public transit.
Customizing your map Create custom map markers to help your locations stand out, and style the map to match your brand colors. Display (or hide) specific points of interest (POI) on your map to help users better orient themselves, and control POI density to prevent map clutter.
Gaining usage insights with analytics Configure and use Google Analytics to gain insights about your locator strategy and implementation.
Sending directions to mobile In addition to showing directions on the locator, you can also send directions to a user's phone for navigation using Google Maps on the go.
Showing Street View to help users visualize locations Give users Street View imagery with 360-degree views to better orient them and help them find your locations faster.
Determining user location with Geolocation If you don't want to rely on in-device location services, use Geolocation to help identify user location.
Combining custom location data with Place Details Combine your own custom location details with Place Details to give users a rich set of data for making decisions.

Showing your locations on an interactive map

Using dynamic maps

This example uses: Maps JavaScript API Also available: Android | iOS

A locator is an important part of the user experience. Some sites, however, may lack even a simple map, requiring users to leave the site or the app to find a nearby location. This means a suboptimal experience for users who must navigate between pages in order to get the information they require. Instead, you can enhance this experience by embedding and customizing maps into your applications.

Adding a dynamic map to your page—that is, a map that users can move around, zoom in and out on, and get details about different locations and points of interest—can be done with a few lines of code.

First, you need to include the Maps JavaScript API in the page. This is done through linking the following script in your HTML page.

<script defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"></script>

The URL references the JavaScript initMap function that runs when the page loads. In the URL, you can also define the language or region of your map to make sure it’s formatted in the correct way for the specific country you are targeting. Setting a region also ensures that the behavior of apps used outside of the United States is biased towards the region you set. View the Google Maps Platform Coverage Details for a full list of supported languages and regions, and learn more about region parameter usage.

Next, you need an HTML div to place your map on the page. This is the place where the map will be displayed.

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

The next step is to set the basic functionality of your map. This is done in the initMap script function specified in the script URL. In this script, shown in the following example, you can set the initial location, the type of map, and which controls will be available on the map for your users. Notice that getElementById() references the "map" div ID above.

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 12,
    center: { lat: 51.485925, lng: -0.129500 },
    zoomControl: false
  });
}

For a locator, you're usually interested in setting the initial location, the center point or bounds, and the zoom level (how much the map is zoomed into that location). Most other elements, such as tuning of controls, are optional as you determine the level of interaction with the map.

Getting place IDs

This example uses: Places API Also available: JavaScript

You may have a database of your locations with basic information like the name of that location, its address, and its phone number. To fetch the information that Google Maps Platform has about that place, including geographic coordinates and user-contributed information, find the place ID that corresponds to each of the locations in your database. You can make a free call to the Find Place endpoint in Places API Place Search and requesting only the field place_id. Here is an example of requesting the place ID for the Google London office:

https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input=google%20london&inputtype=textquery&fields=place_id&key=YOUR_API_KEY

You can store this place ID in your database alongside the rest of your location information and use it as an efficient way to request information about the place. Following are instructions for using the place ID to geocode, retrieve Place Details, and request directions to the place.

Geocoding your locations

This example uses: Geocoding API Also available: JavaScript

If your database of locations has street addresses but not geographic coordinates, use the Geocoding API to obtain the latitude and longitude of that address for the purposes of placing the marker on the map. You can geocode your addresses on the server side, store the latitudes and longitudes in your database, and refresh at least every 30 days.

Here is an example of using the Geocoding API to obtain the latitude and longitude of the place ID that was returned for the Google London office:

https://maps.googleapis.com/maps/api/geocode/json?place_id=ChIJVSZzVR8FdkgRTyQkxxLQmVU&key=YOUR_API_KEY

Adding locations to the map

The next step is to add your locations to the map. This is usually done by adding markers to the map, although there are a number of other options you can use such as data layers.

Once you have the latitude and longitude for your location, here is an example of adding a marker to the map:

var marker = new google.maps.Marker({
    position: { lat: 51.493073, lng: -0.146550 },
    label:"A",
    title:"Location Name"
});

// To add the marker to the map, call setMap();
marker.setMap(map);

With a few markers, you can see the location of a number of locations together.

If there are a large number of locations, you might consider using a marker clustering utility for JavaScript, Android, or iOS. Here's an example of marker clustering in the JavaScript store locator GitHub sample.

Providing Place Details

This example uses: Maps JavaScript API Also available: API | Android | iOS

You can share the Place Details users need to know before they visit one of your locations. With rich Place Details like contact information, hours of operation, user ratings, user photos, and temporary closure status, your users will know exactly what to expect when visiting your location. After making a call to the Places API, you can filter and render the response in an info window, a web sidebar, or in any other way you like.

To request Place Details, you will need the place ID of each of your locations. See Getting place IDs to retrieve the place ID of your location.

Expand to see videos for requesting Place Details:

Get opening hours

Check closures

Control costs

The following example uses the Places Library, Maps JavaScript API to retrieve Place Details and add them to an InfoWindow. This implementation uses the cost-saving strategy of triggering a Place Details request only when the user requests details by clicking on the marker instead of pre-emptively fetching details for all locations regardless of user interest.

     
  const marker = new google.maps.Marker({
    map,
    position: { lat: 51.493073, lng: -0.14655 },
  });
  const request = {
    placeId: "ChIJVSZzVR8FdkgRTyQkxxLQmVU",
    fields: ["name", "formatted_address", "rating", "website"],
  };
  const infowindow = new google.maps.InfoWindow();
  const service = new google.maps.places.PlacesService(map);

  google.maps.event.addListener(marker, "click", function () {
    service.getDetails(request, (place, status) => {
      if (status === google.maps.places.PlacesServiceStatus.OK && place) {
        infowindow.setContent(
          "<div><strong>" +
            place.name +
            "</strong><br>" +
            place.formatted_address +
            "<br>" +
            "Rating: " +
            place.rating +
            " stars<br>" +
            place.website +
            "</div>"
        );

        infowindow.open(map, this);
      }
    });
  });
  
  

Showing locations from a 45° view

This example uses: Maps JavaScript API Also available: Android | iOS

Giving users an aerial view of your location helps them get a clearer idea of what it looks like, which helps them find it more easily. When a user selects a single location to see more detail, you can zoom in on that location to display available satellite imagery from a 45° angle.

The following code sample sets the map to a high zoom level, a compatible map type, and a tilt angle that will display 45° imagery if available. Details about 45° imagery availability are explained in the documentation.

function seeDetail(location) {
  map.setCenter(location);
  map.setZoom(19);
  map.setMapTypeId(google.maps.MapTypeId.HYBRID);
  map.setTilt(45);
}

Resetting to the original map view

Users often want to switch back and forth between the detailed view of a single location and the summary view of several nearby locations. To facilitate this, add a listener to detect when the user leaves the detail view either in map interactions or in the list view. For example, listening for the zoom_changed event on the map object indicates that the user has either manually zoomed out from the detailed view or has called another function that has updated the zoom level. In this sample, zooming out resets the map to the original map type and tilt.

let originalMapTypeId = google.maps.MapTypeId.ROADMAP;
map.addListener("zoom_changed", () => {
  const newZoom = map.getZoom()!;

  if (newZoom < 19) {
    map.setTilt(0);
    map.setMapTypeId(originalMapTypeId);
  }
});

Identifying your user's location

This example uses: Maps JavaScript API Also available: Android | iOS

The next key component in any locator is identifying your user's starting location. By default, you can use mobile location services and web browser geolocation to request user permissions to set the origin as the user's current location. However, the user may deny those permissions or may want to set a different location as their starting point.

Today's users are accustomed to the autocomplete type-ahead functionality on the consumer version of Google Maps. This functionality can be integrated into any application using the Google Maps Platform Places libraries on mobile devices and the web. When a user types an address, autocomplete fills in the rest through the use of widgets. You can also provide your own autocomplete functionality using the Places libraries directly.

Adding the Place Autocomplete library to your site is just a matter of adding a couple of query parameters to the Maps JavaScript API script URL. In the following example, the addition is libraries=places.

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap" defer></script>

Next, add a text box to your page for user input.

<input id="autocomplete" placeholder="Enter starting
      address, city, or zip code" type="text"></input>

Finally, you need to initialize the Autocomplete service and link it to the named text box. Constraining the Place Autocomplete predictions to geocode types configures your input field to accept street addresses, neighborhoods, cities, and zip codes so users can input any level of specificity to describe their origin. Be sure to request the geometry field so that the response contains latitude and longitude of the user's origin. You'll use these map coordinates to recenter the map and indicate the relationship of your locations to the origin.

  // Create the autocomplete object, restricting the search predictions to
  // geographical location types.
  const autocomplete = new google.maps.places.Autocomplete(
    document.getElementById("autocomplete"),
    { types: ["geocode"],
      componentRestrictions: {'country': ['gb']},
      fields: ['place_id', 'geometry', 'formatted_address'] }
  );
  // When the user selects an address from the drop-down
  // zoom to the select location and add a marker.
  autocomplete.addListener("place_changed", addUserLocation);
}

In this example, once the user has selected the address, the addUserLocation() function is executed. This takes the geometry of the matched result, the user location, then moves the map to that location and adds a marker.

function addUserLocation() {
  // Get the place details from the autocomplete object.
  const place = autocomplete.getPlace();

  // Add a marker to the map.
  const marker = new google.maps.Marker({
          map: map
        });

  marker.setLabel("C");
  marker.setPosition(place.geometry.location);

  // Zoom the map to the marker.
  map.panTo(place.geometry.location);
  map.setZoom(12);
}

You can then see the relationship between the user and any particular locations, shown in the following image.

Expand this to see video walkthroughs of adding Place Autocomplete to your app:

Website

Android apps

iOS apps

Showing travel time and distance to nearest locations

This example uses: Distance Matrix API Also available: Distance Matrix Service, Maps JavaScript API

Once you have the location of the user, you can compare this to where your locations are. Doing this with the Distance Matrix Service, Maps JavaScript API helps your users select the location that is most convenient for them by driving time or road distance.

Showing locations near a user implies that you already have your locations populated. When using your own locations database, the key is to make sure the data is in a format that can be used in a map, such as GeoJSON, described in the Data Layer topic.

The standard way of organizing a list of locations is by sorting them by distance. Often this distance is calculated simply by using the straight line from a user to the location, but this can be misleading. The straight line might be over an impassable river or through busy roads at a time when another location might be more convenient. This is important when you have multiple locations within a few kilometers of each other.

The Distance Matrix Service works by taking a list of origin and destination locations and returning not only the travel distance but also time between them. In a user's case, the origin would be where they currently are, or their desired starting point, and the destinations would be that of the locations. Origins and destinations can be specified as coordinate pairs or as addresses; the latter will be matched when the service is called. You can use the Distance Matrix with a number of extra parameters to show results based on current or future driving times.

The following example calls the Distance Matrix Service, specifying the user's origin and the locations. This example shows the distance from the map center to three Google offices in London.

URL encoding quick reference: %2C = , (comma), %3A = : (colon), and %7C = | (pipe).

      https://maps.googleapis.com/maps/api/distancematrix/json?origins=51.493490%2C-0.097288
      &destinations=place_id%3AChIJVSZzVR8FdkgRTyQkxxLQmVU%7Cplace_id%3AChIJVSZzVR8FdkgR-HklrBMO0Hc%7Cplace_id%3AChIJ4abvVDwbdkgRDZVFR7A6Bcc
      &units=metric
      &mode=driving
      &key=YOUR_API_KEY

Here's a version you can copy and run:

      https://maps.googleapis.com/maps/api/distancematrix/json?key=YOUR_API_KEY&origins=51.493490%2C-0.097288&destinations=place_id%3AChIJVSZzVR8FdkgRTyQkxxLQmVU%7Cplace_id%3AChIJVSZzVR8FdkgR-HklrBMO0Hc%7Cplace_id%3AChIJ4abvVDwbdkgRDZVFR7A6Bcc&units=metric&mode=driving

The actual response from the service will be a list of matched addresses, distances and durations, similar to that shown in the following example:

Expand to see the sample response:

{
    "destination_addresses": [
        "123 Buckingham Palace Rd, Victoria, London SW1W 9SH, UK",
        "1-13 St Giles High St, West End, London WC2H 8AG, UK",
        "6 Pancras Square, Kings Cross, London N1C 4AG, UK"
    ],
    "origin_addresses": [
        "Unnamed Road, London, UK"
    ],
    "rows": [
        {
            "elements": [
                {
                    "distance": {
                        "text": "4.5 km",
                        "value": 4540
                    },
                    "duration": {
                        "text": "15 mins",
                        "value": 924
                    },
                    "status": "OK"
                },
                {
                    "distance": {
                        "text": "5.0 km",
                        "value": 5043
                    },
                    "duration": {
                        "text": "17 mins",
                        "value": 1044
                    },
                    "status": "OK"
                },
                {
                    "distance": {
                        "text": "6.9 km",
                        "value": 6919
                    },
                    "duration": {
                        "text": "23 mins",
                        "value": 1357
                    },
                    "status": "OK"
                }
            ]
        }
    ],
    "status": "OK"
}

The following image shows the origin (red marker C) and destinations on a map:

The image shows a city map with the user's location as a red marker
               and locations surrounding it as green markers.

The straight line distance and the route distance often differ, as illustrated in the following table.

Location Straight Distance Road in Traffic / Time
Location A 3.32 km 4.5 km / 15 minutes
Location B 3.20 km 5.0 km / 17 minutes
Location C 4.84 km 6.9 km / 23 minutes

Even though Location B is the closest by distance, the route and time to get there are longer since Location A is accessible by a highway.

Once you have made this request, you can process the match to order the responses by duration of driving time. You can find examples of such a function in the locator codelabs.

This example uses: Maps JavaScript API Directions Service Also available: Directions API web service for use on Android and iOS, either directly from the application or remotely through a server proxy

Showing users the directions from within your site or applications means that they don’t need to navigate away from your site, which means users won’t be distracted with other pages or see competitors on the map. You could even show the carbon emissions of the specific travel mode and show the impact of any particular journey.

The Directions Service also has functions that let you process the results and display them easily on a map.

Following is an example of displaying a directions panel. For more information on the sample, see Displaying Text Directions.

To learn more about these Maps features, read the Maps JavaScript API Documentation or take a look at the step-by-step codelabs to build a locator.

Helping users book appointments

When users view your location's Place Details in a side panel, you can offer the convenience of booking an appointment with a button click, illustrated in the following figure.

Google My Business is an ideal way to provide this functionality, but there are other options as well. This section describes both.

The following figure shows the technologies available for implementing appointment booking and offers (click to enlarge).

Using Google My Business to enable appointment booking

When you manage your online presence with Google My Business, the business locations you create are associated with Google Maps Platform place IDs to enable integrated mapping functionality with business data.

The Google My Business API lets you create actions, such as appointment booking, that you can retrieve and surface in your apps.

When users view Place Details for one of your locations in a side panel, you can provide a link for them to make an appointment. This section describes how.

  1. Create a Google My Business placeActionLink for the location of type APPOINTMENT, ONLINE_APPOINTMENT, or DINING_RESERVATION. The placeActionLink will be the object you use for the appointment link in the side panel. (If you've already created the appointment action link you want, skip to the next step.) Here is an example response from a successful placeActionLinks.create POST operation:

    {
        "name": "locations/15899957830169237700/placeActionLinks/9c984be778a7ebbc",
        "providerType": "MERCHANT",
        "isEditable": true,
        "uri": "https://example.com/reservation-uri",
        "placeActionType": "DINING_RESERVATION",
        "createTime": "2021-05-01T01:17:41.609161Z",
        "updateTime": "2021-05-01T01:17:41.609161Z"
    }
    
  2. Find the Google My Business location associated with the Google Maps Platform place ID.

    When users view Place Details, they're viewing the details for a Google Maps Platform place ID. The place ID is associated with a Google My Business location ID, so you need to find the location ID based on the map place ID to retrieve and display the appointment-booking link you created. Make the following Google My Business API calls:

    1. List your project's accounts.
    2. List all the locations within an account.
    3. In the account locations, the LocationKey contains the Google Maps Platform place ID, which you can compare to the place ID for the location being viewed.
  3. With the location ID, you can get the action link you want. To retrieve an existing appointment placeActionLink, list existing placeActionLinks for the location, and filter for placeActionType to find the appointment link you want to use (APPOINTMENT, ONLINE_APPOINTMENT, or DINING_RESERVATION).

    The following example shows an APPOINTMENT placeActionLink in the response from the LIST call.

     {
       "placeActionLinks": [
           {
               "name": "locations/15899957830169237700/placeActionLinks/9c984be778a7ebbc",
               "providerType": "MERCHANT",
               "isEditable": true,
               "uri": "https://example.com/",
               "placeActionType": "APPOINTMENT",
               "createTime": "2021-05-01T01:17:41.609161Z",
               "updateTime": "2021-05-01T01:17:41.609161Z"
           }
       ]
     }
  4. Create and populate a <div> in the side panel with relevant data from the placeActionLink object, especially the URI for the appointment booking link.

Alternatives for adding appointment links

If you don't use Google My Business, check your appointment booking platform for documentation on embedding a booking widget into a website or app. Another option is using Google Cloud, such as Cloud Spanner for inventory management (video).

Displaying local offers

In the Place Details side panel for a location, you can show local offers for users to click. The Google My Business API lets you create and retrieve "posts" (such as local offers) that are associated with your locations. The following figure shows an example of a local offer in a Place Details side panel.

(The architectural diagram in the previous section shows available technologies for adding offers to your locator.)

Because local offers are associated with locations, you'll need to find the Google My Business location ID that's associated with the Google Maps Platform place ID for the location users are viewing. When you have the Google My Business location ID, you can retrieve the relevant offer as a localPost to display in your Place Details side panel. Here are the steps:

  1. With the Google My Business API, create any offer posts you want to display, of type OFFER.
  2. Find the Google My Business location / location ID associated with the place ID on the map.

    When users view Place Details, they're viewing the details for a Google Maps Platform place ID. The place ID is associated with a Google My Business location ID, so you need to find the location ID based on the map place ID to retrieve and display the local offer link for your location. Make the following Google My Business API calls:

    1. With the Google My Business API, list your project's accounts.
    2. List all the locations within an account.
    3. In the account locations, the LocationKey contains the maps place ID, which you can compare to the place ID for the location being viewed.

    The following is an example request for a location's details in the Google My Business API:

    https://mybusiness.googleapis.com/v4/accounts/111098884960588804666/locations/15899957830169237700

    The response contains a locationKey field which is the place ID you can use with Google Maps Platform requests.

    Expand to see the sample response.

          {
        "name": "accounts/111098884960588804666/locations/15899957830169237700",
        "locationName": "Sushi Sushi",
        "primaryPhone": "+49 2222 22222",
        "primaryCategory": {
            "displayName": "Restaurant",
            "categoryId": "gcid:restaurant",
        },
        "regularHours": {
            "periods": [
                {
                    "openDay": "MONDAY",
                    "openTime": "09:00",
                    "closeDay": "MONDAY",
                    "closeTime": "09:10"
                },
                {
                    "openDay": "TUESDAY",
                    "openTime": "11:30",
                    "closeDay": "TUESDAY",
                    "closeTime": "24:00"
                }
            ]
        },
        "locationKey": {
            "placeId": "ChIJs4wtL04X2jERbc8qHd_wZzk",
            "requestId": "2c72cbcb-ea2e-4d66-b684-0ef5f090300c"
        },
        "latlng": {
            "latitude": 1.3670033,
            "longitude": 103.8556385
        },
        "openInfo": {
            "status": "OPEN",
            "canReopen": true
        },
        "locationState": {
            "isGoogleUpdated": true,
            "canUpdate": true,
            "canDelete": true,
            "isVerified": true,
            "isPublished": true,
            "canHaveFoodMenus": true
        },
        "attributes": [
            {
                "attributeId": "has_delivery",
                "valueType": "BOOL",
                "values": [
                    false
                ]
            },
            {
                "attributeId": "requires_masks_customers",
                "valueType": "BOOL",
                "values": [
                    true
                ]
            },
            {
                "attributeId": "url_order_ahead",
                "valueType": "URL",
                "urlValues": [
                    {
                        "url": "https://example.com/"
                    },
                ]
            },
            {
                "attributeId": "pay_credit_card_types_accepted",
                "valueType": "REPEATED_ENUM",
                "repeatedEnumValue": {
                    "setValues": [
                        "visa"
                    ],
                    "unsetValues": [
                        "american_express"
                    ]
                }
            }
        ],
        "address": {
            "regionCode": "SG",
            "languageCode": "en-US",
            "postalCode": "560445",
            "addressLines": [
                "445 Ang Mo Kio Ave 10"
            ]
        },
        "profile": {
            "description": "Example restaurant"
        }
    }
          
  3. Now that you have the location ID, you can get the offer you want. To retrieve an existing offer Post, list existing localPosts for the location, and filter for topicType of OFFER to find the offer content you want to use.

    Here is an example request to list the active Local Posts for a location:

    https://mybusiness.googleapis.com/v4/accounts/111098884960588804666/locations/15899957830169237700/localPosts

    The following example shows an OFFER localPost in the response.

    Expand to see the sample response.

    {
        "localPosts": [
            {
                "name": "accounts/111098884960588804666/locations/15899957830169237700/localPosts/2524928563578730680",
                "languageCode": "en",
                "summary": "Buy One Get One Free on all order-ahead bento boxes today!",
                "state": "LIVE",
                "event": {
                    "title": "Bento BOGO",
                    "schedule": {
                        "startDate": {
                            "year": 2020,
                            "month": 1,
                            "day": 20
                        },
                        "startTime": {},
                        "endDate": {
                            "year": 2021,
                            "month": 1,
                            "day": 21
                        },
                        "endTime": {}
                    }
                },
                "updateTime": "2020-09-11T10:56:22.594Z",
                "createTime": "2020-09-11T10:56:22.594Z",
                "searchUrl": "https://local.google.com/place?id=4156539623820808045&use=posts&lpsid=2524928563578730680",
                "media": [
                    {
                        "name": "accounts/111098884960588804666/locations/15899957830169237700/media/localPosts/AF1QipOBQCIf40SbF_PPJxb_zvfCHmaTbv9Zw02PoYPS",
                        "mediaFormat": "PHOTO",
                        "googleUrl": "https://lh3.googleusercontent.com/p/AF1QipOBQCIf40SbF_PPJxb_zvfCHmaTbv9Zw02PoYPS"
                    }
                ],
                "topicType": "OFFER",
                "offer": {
                    "couponCode": "BOGO-JET-CODE",
                    "redeemOnlineUrl": "https://www.example.com/redeem",
                    "termsConditions": "Offer only valid for order-ahead orders placed online."
                }
            },
        ],
    }
            
  4. Create and populate a <div> in the side panel with relevant data from the localPost object.

Customizing your map

You can change your map's appearance and details in a number of ways. For example, you can:

  • Create your own custom markers to replace the default map pins.
  • Change the colors of map features to reflect your brand.
  • Control which points of interest you display (attractions, food, lodging, and so on) and at what density, letting you focus user attention on your locations while highlighting the landmarks that help users get to the nearest location.

Creating custom map markers

You can customize your markers by changing the default color (possibly showing whether a location is currently open) or replacing the marker with a custom image, such as the logo of your brand. Info windows, or pop-up windows, can provide additional information to users, such as opening hours, phone number, or even photos. You can also create custom markers that are raster, vector, draggable, and even animated.

Following is a sample map that uses custom markers. (See the source code in the Maps JavaScript API custom markers topic.)

For detailed information, see the markers documentation for JavaScript (web), Android, and iOS.

Styling your map

Google Maps Platform lets you style your map in ways that help users find the closest location, get there as quickly as possible, and help you reinforce your brand. For example, you can change map colors to match your branding, and you can reduce distractions on the map by controlling the points of interest that are visible to users. Google Maps Platform also provides a number of map starter templates, some of which are optimized for different industries, such as travel, logistics, real estate, and retail.

You can create or modify map styles in the Google Cloud Console Map Styles page in your project.

Expand to see animations of map style creation and styling in the Cloud Console:

Industry map styles

This animation shows predefined industry-specific map styles you can use. These styles provide an optimal starting point for each type of industry. For example, the Retail map style reduces points of interest on the map, letting users focus on your locations, as well as the landmarks to help them get to the closest location as quickly and confidently as possible.

On the Map Style page, the mouse clicks Create New Map Style. On the
              New Map Style page, the mouse clicks the radio button next to each of the
              following industry optimized styles: Travel, Logistics, Real Estate, and
              Retail. As each button is clicked, the map style description and graphical
              preview changes.

Points of interest control

This animation sets the marker color for points of interest and increases the POI density on the map style. The higher the density, the more POI markers appear on the map.

On the Map Style page, the mouse clicks Create New Map Style. On the
                New Map Style page, under Create Your Own Style, the Google Map radio button
                is selected. The mouse clicks the Atlas radio button for the Atlas style,
                then clicks Open in Style Editor. In the Style Editor, the mouse clicks
                the Points of Interest feature, then clicks the Icon element, setting the
                color to red. The mouse then selects the POI Density checkbox and slides
                the density control to the right for maximum density. More and more red
                markers appear on the map preview as density increases. The mouse then moves
                to the Save button.

Each map style has its own ID. After you publish a style in the Cloud Console, you reference that map ID in your code—which means you can update a map style in real time without refactoring your app. The new look will automatically appear in the existing application and be used across platforms. The following examples show how to add a map ID to a web page using the Maps JavaScript API.

By including one or more map_ids in the script URL, the Maps JavaScript API automatically makes those styles available for faster map rendering when you call those styles in your code.

<script
 src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&map_ids=MAP_IDs&callback=initMap">
</script>

The following code displays a styled map on the web page. (Not shown is an HTML <div id="map"></div> element where the map will appear on the page.)

map = new google.maps.Map(document.getElementById('map'), {
  center: {lat: 51.485925, lng: -0.129500},
  zoom: 12,
  mapId: '1234abcd5678efgh'
});

Learn more about incorporating Cloud-based maps styling in JavaScript (web), Android, and iOS.

Gaining usage insights with analytics

Using analytics, you can gain valuable insights about how users are interacting with your locator. This section provides guidance on configuring and monitoring Google Analytics and Google My Business analytics to track the data you're most interested in.

Given the power and flexibility of Google Analytics, we won't attempt to provide comprehensive setup and usage information. Instead, we'll point you to key documentation for further reading and instructions while highlighting the key analytics considerations for your locator app.

Setting up Google Analytics

If you're already using Google Analytics with your app, you can skip this section.

Following is an example of a “Global Tag” you'd paste on your site to enable Google Analytics.

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/
gtag/js?id=G-XR5B5D4NW0"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-XR5B5D4NW0');
</script>

Whether you're using Google Tag Manager or adding Google Analytics directly to your site, the key is to understand how to use your Google Analytics implementation to do the following:

Using custom events

Following is an example of defining a custom event in your locator:

gtag('event', 'location', {
  'method': 'address'
});

It's important to name your event and method clearly enough that you can understand events in reporting. Trigger them for the specific interactions you want to measure, such as when a user selects and address from the Autocomplete drop-down list, shown in the following figure.

You can send the following tracking call to Google Analytics that uses the event and method you defined. (We'll show each query parameter on a separate line for ease of reading.)

https://www.google-analytics.com/g/collect?v=2
&tid=G-XR5B5D4NW0
>m=2oe550
&_p=64678170
&sr=1920x1200
&ul=fr
&cid=489856786.1598861364
&_s=2
&dl=http%3A%2F%2.storelocator.html
&dt=Store%20Locator
&sid=1620827159
&sct=1
&seg=1
&en=location
&_et=6032
&ep.method=address

The following figure shows how that Google Analtics call appears in the browser's Inspect view, on the Network tab. (Click to enlarge).

You can verify that your custom event tags are properly being captured by viewing the "Real-time" view in Google Analytics. For example, the "location" event set up previously for Place Autocomplete appears in Google Analytics as shown in the following figures.

 

Alternatively, you could monitor real-time events using the DebugView, as shown in the following figure. Note that you have to wait 24 hours before accessing a full Events report in the Engagement > Events section of Google Analytics.

You can also develop and measure strategies to drive more foot traffic to your physical locations from your locator app. For example, Google Analytics has a Store Visits in Analytics offering that links physical store visits analytics (measured by Google Ads) to your locator analytics. You can also develop your own app-to-location strategies, such as online offers redeemable at your physical locations.

Google My Business metrics

In addition to tracking the events, metrics, and dimensions you're interested in with Google Analytics, Google My Business also has its own metrics. For example, if you add appointment booking and local offer links to your locator, you can get metrics on those views and clicks.

The following sample request to the Google My Business API asks for multiple types of metrics. For tracking offer clicks, the LOCAL_POST_VIEWS_SEARCH and LOCAL_POST_ACTIONS_CALL_TO_ACTION metrics would be the most relevant.

Expand to see the sample request.

POST https://mybusiness.googleapis.com/v4/accounts/111098884960528804666/locations:reportInsights
Body:
{
 "locationNames": [
   "accounts/111098884960528804666/locations/15899957830169237700"
 ],
 "basicRequest": {
         "metricRequests": [
            {
              "metric": "QUERIES_DIRECT"
            },
            {
              "metric": "QUERIES_INDIRECT"
            },
            {
              "metric": "VIEWS_MAPS"
            },
            {
              "metric": "VIEWS_SEARCH"
            },
            {
                "metric": "ACTIONS_DRIVING_DIRECTIONS"
            },
            {
                "metric": "LOCAL_POST_VIEWS_SEARCH"
            },
            {
                "metric": "LOCAL_POST_ACTIONS_CALL_TO_ACTION"
            }
         ],
         "timeRange": {
              "startTime": "2021-01-01T01:01:23.045123456Z",
              "endTime": "2021-04-30T23:59:59.045123456Z"
         }
   }
}

Expand to see the sample response.

{
   "locationMetrics": [
       {
           "locationName": "accounts/111098884960528804666/locations/15899957830169237700",
           "timeZone": "Asia/Singapore",
           "metricValues": [
               {
                   "metric": "QUERIES_DIRECT",
                   "totalValue": {
                       "metricOption": "AGGREGATED_TOTAL",
                       "timeDimension": {
                           "timeRange": {
                               "startTime": "2021-01-01T01:01:23.045123456Z",
                               "endTime": "2021-04-30T23:59:59.045123456Z"
                           }
                       },
                       "value": "82"
                   }
               },
               {
                   "metric": "QUERIES_INDIRECT",
                   "totalValue": {
                       "metricOption": "AGGREGATED_TOTAL",
                       "timeDimension": {
                           "timeRange": {
                               "startTime": "2021-01-01T01:01:23.045123456Z",
                               "endTime": "2021-04-30T23:59:59.045123456Z"
                           }
                       },
                       "value": "1493"
                   }
               },
               {
                   "metric": "VIEWS_MAPS",
                   "totalValue": {
                       "metricOption": "AGGREGATED_TOTAL",
                       "timeDimension": {
                           "timeRange": {
                               "startTime": "2021-01-01T01:01:23.045123456Z",
                               "endTime": "2021-04-30T23:59:59.045123456Z"
                           }
                       },
                       "value": "1571"
                   }
               },
               {
                   "metric": "VIEWS_SEARCH",
                   "totalValue": {
                       "metricOption": "AGGREGATED_TOTAL",
                       "timeDimension": {
                           "timeRange": {
                               "startTime": "2021-01-01T01:01:23.045123456Z",
                               "endTime": "2021-04-30T23:59:59.045123456Z"
                           }
                       },
                       "value": "631"
                   }
               },
               {
                   "metric": "ACTIONS_DRIVING_DIRECTIONS",
                   "totalValue": {
                       "metricOption": "AGGREGATED_TOTAL",
                       "timeDimension": {
                           "timeRange": {
                               "startTime": "2021-01-01T01:01:23.045123456Z",
                               "endTime": "2021-04-30T23:59:59.045123456Z"
                           }
                       },
                       "value": "3"
                   }
               },
               {
                   "metric": "LOCAL_POST_ACTIONS_CALL_TO_ACTION",
                   "totalValue": {
                       "metricOption": "AGGREGATED_TOTAL",
                       "timeDimension": {
                           "timeRange": {
                               "startTime": "2021-01-01T01:01:23.045123456Z",
                               "endTime": "2021-04-30T23:59:59.045123456Z"
                           }
                       },
                       "value": "42"
                   }
               },
               {
                   "metric": "LOCAL_POST_VIEWS_SEARCH",
                   "totalValue": {
                       "metricOption": "AGGREGATED_TOTAL",
                       "timeDimension": {
                           "timeRange": {
                               "startTime": "2021-01-01T01:01:23.045123456Z",
                               "endTime": "2021-04-30T23:59:59.045123456Z"
                           }
                       },
                       "value": "11"
                   }
               }
           ]
       }
   ]
}

The response contains the metrics, most notably:

  • 1571 views of the location on Google Maps
  • 631 location views on Google Search.
  • 3 requests for Driving Directions to the location.
  • 42 LOCAL_POST_ACTIONS_CALL_TO_ACTION offer clicks.
  • 11 views of Local Posts on Google Search.

Another metrics option involves using Reserve with Google to create action links. When users click action links created in Reserve with Google, you can log those actions to Google Analytics, which lets you track conversions in Google Analytics. See the conversion tracking documentation for more information.

Regardless of the metrics strategy you use, measurement is more than seeing how you're doing against your KPIs. The numbers also help you understand the impact these locator improvements have on your business. Additionally, you can compare the metrics from Google Analytics on your locator with the Google My Business metrics. For instance, by comparing these metrics, you can see how many customers are getting directions from your locator and Google Maps to then visit your physical locations.


Enhancing Locator Plus

Depending on your business' or users' needs, you can further enhance the user’s experience.

Sending directions to mobile

To make it even easier for users to reach a location, you can text or email them a directions link. When they click it, the Google Maps app will launch on their phone if it is installed, or maps.google.com will load in their device's web browser. Both of these experiences provide the user with the option to use turn-by-turn navigation, including voice guidance, to reach the destination.

Use Maps URLs to compose a directions URL like the following, with the URL-encoded place name as the destination parameter and place ID as the destination_place_id parameter. There is no cost to compose or use Maps URLs, so you don't need to include an API key in the URL.

      https://www.google.com/maps/dir/?api=1&destination=Google%20London&destination_place_id=ChIJVSZzVR8FdkgRTyQkxxLQmVU

You can optionally provide an origin query parameter using the same address format as the destination. But by omitting it, the directions start from the user's current location, which may be different from where they were using your Locator Plus app. Maps URLs provide additional query parameter options, such as travelmode and dir_action=navigate to launch the directions with navigation turned on.

This clickable link, which extends the example URL above, sets the origin as a London football stadium and uses travelmode=transit to provide public transit directions to the destination.

To send a text or email containing this URL, we currently recommend using a third-party application such as twilio. If you're using App Engine, you can use third-party companies to send SMS messages or email. For more information, see Sending Messages with Third-Party Services.

Showing Street View to help users visualize locations

For many locations in the world, Street View can be used to display the outside of a location, offering users a visual of the location before they arrive. You can provide Street View in either an interactive (web) or static (API) form, depending on whether you want your users to "look around" the area in 360 degrees. Street Viewis also available for Android and iOS.

Determining user location with Geolocation

In most cases, you can pinpoint user location using the location services built into their devices or browsers. We provide an example of using a brower's HTML5 Geolocation feature to display the geographic location of a user or device on a Google map, and there's documentation on requesting permissions and obtaining location in Android and iOS. However, there may be situations where you want an alternative location finder; for example, if device location services are disabled or you have concerns about device location being spoofed.

The Geolocation API is a server-side API that returns a location and accuracy radius based on information about cell towers and Wi-Fi nodes that the client can detect. You can use Geolocation as a backup mechanism for determining user location, or you can use it to cross-check the location reported by the device.

Combining custom location data with Place Details

In the previous Providing Place Details section, we covered using Place Details to give users a rich level of information about your locations, such as opening hours, photos, and reviews.

It's helpful to understand the cost of different data fields in Place Details, which are categorized as Basic, Contact, and Atmosphere Data. To manage your costs, one strategy is to combine the information you already have about your locations with the fresh information (usually Basic and Contact Data) from Google Maps such as temporary closure, holiday hours, and user ratings, photos, and reviews. If you already have the contact information for your locations, you won't need to request those fields from Place Details and can constrain your request to fetch only Basic or Atmosphere Data fields depending on what you want to display.

You may have your own place data to supplement or use instead of Place Details. The codelab for the full-stack locator provides an example of using GeoJSON with a database to store and retrieve your own location details.