Posted:


Some Android Wear apps are most useful when they are always available to the user, even at a glance. Now, with Google Play Services 8.1, the Google Maps Android API supports ambient mode, the API that provides always-on capabilities. In ambient mode, the map adjusts its style to provide a simplified, low-color rendering of the map. All markers, objects, and UI controls disappear, keeping the map on the screen while letting the user know that it is not currently ready to accept user input. An important advantage is the camera position and zoom level are retained, thus keeping the user’s context within the map.

The screenshot below show how maps appear in interactive mode and in ambient mode:

To implement ambient mode in your maps, follow these steps:

  1. Set your your targetSDKVersion to 22 or higher
  2. Add the following dependencies to build.gradle for your app to add the wearable support library.
  3. dependencies {
    compile 'com.google.android.support:wearable:1.2.0'
    provided 'com.google.android.wearable:wearable:1.0.0'
    }
    
  4. Add the wearable shared library entry into the wearable app manifest:
  5. <application>
    <uses-library android:name="com.google.android.wearable"
    android:required="false" />
    ...
    </application>
  6. Add the WAKE_LOCK permission to the handheld and wearable app manifest:
  7. <uses-permission android:name="android.permission.WAKE_LOCK" />
  8. Have your Activity extend WearableActivity. This will provide the overrides that notify your app when the wearable enters, exits and provides screen updates in ambient mode.
  9. In the onCreate() method of your activity, call the setAmbientEnabled() method. This tells the framework that the app should enter ambient mode rather than returning to the watch face.
  10. Set your map to support ambient mode. You can do this by setting the attribute map:ambientEnabled="true" in the activity's XML layout file, or programmatically by setting GoogleMapOptions.ambientEnabled(true). This informs the API to pre-load necessary map tiles for ambient mode.
  11. When the activity switches to ambient mode, the system calls the onEnterAmbient() method in your wearable activity. Override onEnterAmbient() and call MapFragment.onEnterAmbient() or MapView.onEnterAmbient(). The map changes to a non-interactive, low-color rendering of the map.
  12. When in ambient mode, your app can update the display every minute by overriding onUpdateAmbient(). If you need more frequent updates, check out this guide.
  13. When the activity leaves ambient mode, the system calls the onExitAmbient() method in your wearable activity. Override onExitAmbient() and call MapFragment.onExitAmbient() or MapView.onExitAmbient(). The map returns to the normal rendering and is now ready to accept user input.

With always-on maps on Android Wear, you can now show maps at a glance. For more information on these APIs check out the documentation and the sample code.

Posted:


Editor’s note: ‘Map Tips’ are designed to answer frequently asked questions about Google Maps APIs. For important tips on how to deploy Google’s mapping tools, read more from Ed Boiling, Google Maps Solution Architect at Google.

At Google, we understand that not everyone dreams in the same beautiful shades of orange and yellows of our Google Maps road network or the calm blues of Google Maps waterways. The reality is that our customers might want to make the water purple or their roads green. Sometimes you need a muted map with no labels to overlay your own data, or maybe you want the colors to match the branding of your website.

That’s why we offer Styled Maps. You can create the styles by hand and test your code to see how they look, or use our time saving visual tool — the Google Maps Style Wizard. The Google Maps Style Wizard allows you to select features and their elements, apply operations to those features, and save the styles to JSON, which you can copy and paste into your application.
Styled_map.png

With this simple JSON file, you can tailor that map to your needs—the color scheme of your website, a greyscale map to show details or to highlight a big event.

1. Select a type of feature to style in the Selectors panel. For any element type (e.g. roads, water) you can choose to style the shapes (select “Geometry”) or the text (Select “Labels”), or both. You can show a map of anywhere you wish as a preview.
Screen Shot 2015-09-07 at 11.56.33.png

2. To change the visibility, lightness or color, choose the combination of Stylers that match your needs. For example, to switch off all the map labels, select Feature type “All”, Element type “Labels” and check the box for the “Visibility” styler. Choose “Off” as the option for Visibility. To make all the water purple, select Feature type “water”, Element type “geometry” and select the “fill” option. Fill changes the solid color and stroke changes the line color. In the Stylers section choose the shade you want using the sliders or the hexadecimal value. For purple, either slide R to 204, G to 0 and B to 255 or enter #CC00FF in the text box.
Screen Shot 2015-09-07 at 11.58.19.png

3. Once you are happy with the styling of the feature type, click the Add button in the Map Style panel to save the style and create a new style to work on. Repeat Steps 2 to 5 to build up the set of styles for your map. Styles are applied in the order they are listed in the Map Style panel. To copy the style into your own Maps API map, click the Show JSON button to display the JSON object to pass to the style property of your MapOptions object. To generate an example map with this style using the Static Maps API, click the Static Map button.

4. Select a type of feature to style in the Selectors panel. For any element type (e.g. roads, water) you can choose to style the shapes (select “Geometry”) or the text (Select “Labels”), or both. You can show a map of anywhere you wish as a preview.
Screen Shot 2015-09-07 at 11.56.33.png

5. To change the visibility, lightness or color, choose the combination of Stylers that match your needs. For example, to switch off all the map labels, select Feature type “All”, Element type “Labels” and check the box for the “Visibility” styler. Choose “Off” as the option for Visibility. To make all the water purple, select Feature type “water”, Element type “geometry” and select the “fill” option. Fill changes the solid color and stroke changes the line color. In the Stylers section choose the shade you want using the sliders or the hexadecimal value. For purple, either slide R to 204, G to 0 and B to 255 or enter #CC00FF in the text box.
Screen Shot 2015-09-07 at 11.58.19.png

6. Once you are happy with the styling of the feature type, click the Add button in the Map Style panel to save the style and create a new style to work on. Repeat Steps 2 to 5 to build up the set of styles for your map. Styles are applied in the order they are listed in the Map Style panel. To copy the style into your own Maps API map, click the Show JSON button to display the JSON object to pass to the style property of your MapOptions object. To generate an example map with this style using the Static Maps API, click the Static Map button.

Here’s a complete example for a map with no labels and purple water.

[
  {
    "featureType": "water",
    "elementType": "geometry.fill",
    "stylers": [
      { "color": "#cc00ff" }
    ]
  },{
    "elementType": "labels",
    "stylers": [
      { "visibility": "off" }
    ]
  }
]

This style creates a muted grey scale map with just basic outlines that’s ideal for overlaying a data visualization using one of the many Maps API methods available.

[
  {
    "stylers": [
      { "visibility": "off" }
    ]
  },{
    "featureType": "landscape",
    "stylers": [
      { "visibility": "on" },
      { "color": "#e5e3df" }
    ]
  },{
    "featureType": "water",
    "elementType": "geometry",
    "stylers": [
      { "visibility": "on" },
      { "color": "#d4d4d4" }
    ]
  }
]
Screen Shot 2015-09-07 at 12.01.07.png

We hope you’re able to incorporate the Styled Maps capabilities into your website or application. Start customizing your maps today with the Google Maps Style Wizard. If you need some inspiration, visit our friends at snazzymaps.com to see a gallery of styled maps - you can start from any one of the hundreds of user uploaded Google Maps styles.

Posted:


Editor’s note: ‘Map Tips’ are designed to answer frequently asked questions about Google Maps APIs. Since web performance is so hot right now, we want to provide some useful information. For important tips on how to deploy Google’s mapping tools, read more from Mark McDonald, Google Developer Relations. Also, our friends over at Wikipedia have just done something similar!

Asynchronously loading JavaScript on your pages can give you huge performance wins. We have just updated all of our JavaScript Maps API samples and you can make these changes to your site, too. Read on to find out what we did and how it works, or skip straight to Unblocking scripts to see what you can start to update on your site today.

Loading JavaScript 101

There are plenty of great developer resources that describe browser rendering processes in detail, and you should read them all, but right now we’re interested in how <script> tags affect page load time. Here’s a quick refresher.
  1. As a browser loads its stream of HTML content representing the page to render, it builds DOM and CSSOM trees representing the page structure and style, respectively.
  2. JavaScript can change both the DOM and the CSSOM, for example through document.createElement() and myElement.style.backgroundColor.
  3. Ergo, when the browser hits a <script> tag, either in-line or externally hosted, it has to pause any further processing of the script and any further HTML rendering until the script has been fetched and any CSS declared prior has been fetched and processed. Take note—this is critical as it affects the speed at which the first round of content is displayed in the browser.
Ilya Grigorik has written on this topic in detail, so check out his article on asynchronously loading JavaScript to find out more.

Unblocking scripts

The first change we made to our samples was to add the async and defer attributes to the script tag:

<script src="https://maps.googleapis.com/maps/api/js" async defer></script>

The async attribute instructs the browser to fetch the script asynchronously, then execute the script as soon as it is retrieved, removing both the block on DOM construction and the wait for CSSOM construction.

The defer attribute is an older, more supported attribute that instructs the browser to execute the script when the DOM is ready. We’ve included it because the async attribute is not supported in all browsers (specifically, older versions of Internet Explorer). In older browsers (as far back as Internet Explorer 5.5), defer still speeds up the page load, so it’s worth including even though it’s ignored in newer browsers when async is present.

The WHATWG spec explains the behavior:

There are three possible modes that can be selected using these attributes. If the async attribute is present, then the script will be executed as soon as it is available, but without blocking further parsing of the page. If the async attribute is not present but the defer attribute is present, then the script is executed when the page has finished parsing. If neither attribute is present, then the script is fetched and executed immediately, before the user agent continues parsing the page.

The second change we made to our samples was to move the map initialization code from the window’s onLoad event to use a callback. So this code:
<script src="https://maps.googleapis.com/maps/api/js"></script>
...
<script>
function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: -34.397, lng: 150.644},
    zoom: 8
  });
}
google.maps.event.addDomListener(window, 'load', initMap);
</script>

Now looks like:
<script>
function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: -34.397, lng: 150.644},
    zoom: 8
  });
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?callback=initMap" 
async defer></script>

This change allows the Maps API code (which now executes as soon as it has been fetched) to run the map initialization code as soon as it can. We’ve also moved the <script> tag after the custom code, to avoid a race condition where the Maps API code could load before initMap is declared.

When implementing this, you should also ensure that any DOM objects you need (particularly the map) are going to be available when your code is called, which could be before DOMContentLoaded fires. For simple inline scripts, you can guarantee this by putting the script after the element in the page.

The numbers

Here are the before & after screenshots of the waterfall from Chrome DevTools. The first image shows the old technique, without async/defer or any callbacks. In addition to the code above, the test code logs window.performance.now() at the end of initMap, which is used to calculate the point at which you can start making map customizations.

Before:
DOMContentLoaded is triggered at ~600ms (658ms in the screenshot below) and map customizations can begin around 700 - 1000ms.
sync.png

After:
DOMContentLoaded is triggered at 35ms and map customizations can begin at around 300 - 500ms.
async.png

I can use this everywhere, right?

Alas, no. As the script tags are no longer synchronously loading in a predictable order, any code using the google.maps namespace needs to run within the callback or sometime afterwards.

To work around this constraint, you can either fall back to loading the API synchronously or mix in your code with the parent class once it’s available. If you choose to load it synchronously, you can still move the <script> tag to the end of the <body> section so your page renders quickly.

There are 2 particular cases you should look out for:
  • Subclassing anything in the Google Maps JavaScript API (for example, custom overlays). You must ensure your classes are defined after the callback has been executed.
  • LatLngs defined outside of the map initialization function. Most functions now accept LatLngLiterals, so you can simply pass { lat: 33, lng: 151 }.

Updating your own code

This optimization applies beyond just the Maps APIs and you should check your own sites too. After you’ve updated your Maps APIs code, look for externally loaded scripts and determine if your code needs to be executed at the point at which it has been defined. If not, add a callback mechanism and the async/defer attributes.

While you’re there, many popular JavaScript libraries support (in fact, encourage) use of the async attribute. You can find out which ones using the PageSpeed tool.

We hope you can squeeze even a few extra milliseconds of performance out of your page loads. Remember that performance is a feature!

Posted:


Editor's Note: Gone are the days when users were impressed with a marker on a map. The Maps Zen blog post series covers integrations of Google Maps APIs to help your apps provide great maps user experiences. What’s a zen pattern? Simply put, a design pattern that results in harmonious user experiences.



Maps are awesome because they show us where to go. But how are your users getting to their chosen destination? The Directions API web service provides step-by-step directions from point A to B and can get your user where they’re going. Being a web service, it is protected by an API key and thus it should not consumed in the mobile app - proxy it via your server as shown here.

The Directions API can give you walking, cycling and driving directions as expected. But it also gives great public transport directions. When guiding users to a destination, it’s best to show them the path on a map.

Polylines are a great way to show a path but rather than have them simply appear on the map, it’s nicer to animate them in place. In the image below, the intended path grows providing a clear distinction about the direction of travel.

So now we’re showing users where to go and how to get there. But once they’re at their destination, our app’s work is not done. In Shibuya, a city in Tokyo, Japan, there are many tall buildings whose shops visible from the road. It can be really hard to tell which one of those is the destination. In effect, users can be left feeling lost after they get to their destination. Thankfully, there’s a Maps API for that!

Street View is a great way to visualize the user’s destination, or any address really. Adding Street View adds a real-world visual element to your app and provides meaningful context for users. Users will generally expect that they can interact with a Street View since they’re likely to pan and scan around the location so be sure to leave not to disable interactivity with the StreetViewPanorama.

You can add a StreetViewPanorama into your app by including it in your XML layouts, like so.
<fragment
    android:id="@+id/streetview"
    android:name=
        "com.google.android.gms.maps.StreetViewPanoramaFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

You can provide a location for the StreetViewPanorama using the following Java code.
streetViewPanorama.setPosition(targetLatLng);
StreetViewPanoramaCamera camera =
    new StreetViewPanoramaCamera(zoom, tilt, bearing);
mStreetViewPanorama.animateTo(camera, duration);

With guided directions and the addition of Street View in your apps, users are given a visual representation of their destination. They’re no longer lost on the way there and they’re not lost when they get there.

Posted:
Controls are UI elements that allow your users to interact with a map. Whether they are moving Pegman to see Street View or switching between map and satellite modes, people use the controls to explore and get the information they need from a map.

The Google Maps JavaScript API has a range of options that let developers customize controls by changing their visibility, positioning, styling and behavior. Control options give developers a lot of flexibility to change the way controls work on their maps.

Today, we are rolling out an update to the Google Maps JavaScript API default controls. The updated controls have a more modern look and feel and are more consistent with other Google Maps products, including the Google Maps Embed API and the Google Maps website. Most features of the new control style have already been available to signed-in maps, but today we are excited to make the new control style available by default to all maps, not just those with signed-in mode enabled.

This API update changes the position, color and size of many of the controls, as well as the functionality of a few controls. For example, the zoom control feature is now on the bottom right instead of the top left, with only “+” and “-” buttons instead of a slider. In addition, some controls and control options are no longer available in v3.22 of the API (the current experimental version). The Google logo has also been updated to the new version.

Old
New
Screen Shot 2015-08-25 at 7.33.31 AM.png

You can temporarily switch back to the old control style in API versions 3.22 (current experimental version) and 3.23 (experimental version from November 2015). In versions 3.22 and 3.23, the old control style can be obtained setting a single parameter, google.maps.controlStyle = 'azteca', before you initialize the map. This parameter will be available until August 2016, giving you ample time to make any required updates to your application. In version 3.24 (experimental version from February 2016), this parameter will be removed. If you are using custom controls or UI elements that overlap the map, we recommend that you test your application with the new controls style and make any updates well before August 2016. The new logo is the only change that affects all API versions and cannot be removed.

For full details of how individual controls will be affected, as well as how to revert to the old controls style, please refer to our developer documentation. You can also visit the Maps API versioning guide for details of how Maps API versions work, how to check which API version you are using, and other best practices for developers.

Posted by Elena Kelareva, Product Manager, Google Maps APIs

Posted:


Editor's Note: Gone are the days when users were impressed with a marker on a map. The Maps Zen blog post series covers integrations of Google Maps APIs to help your apps provide great maps user experiences. What’s a zen pattern? Simply put, a design pattern that results in harmonious user experiences.



Markers are much more useful than identifying points on a map. Markers can also be used as a way to visually convey information about a place. If a user is searching for a well rated restaurant, they’d fire up your app to find that there’s a bunch of restaurants in their vicinity. But it’s not easy to tell which ones are actually worth visiting. To see the ratings for each place, they’d end up having to tap each one first.

Here’s an how marker selection and marker animations can be a great way to show this information. In this example, markers that lack colour rate poorly and the vibrant colorful markers are the highly rated ones. There’s also animated steam on some markers also helping to highlight the best rated restaurants!

To achieve the steam animation, the marker icon is being changed by calling the setIcon() method periodically. A delay of 32ms roughly corresponds to 30 marker icon updates a second — animating the icon at 30 frames per second.
mAnimHandler.post(new Runnable() {
@Override
public void run() {
marker.setIcon(mSteamFrames.nextFrame());
// Next frame in 32 ms
mAnimHandler.postDelayed(this, 32);
}
});

To desaturate the marker icons, a ColorMatrixColorFilter from the Android framework being used. First, setup the color filter based on the restaurant rating scale via a ColorMatrix. In this case, any restaurant that has a 3 star rating will be presented as having an entirely grayscale icon. Restaurants with a 4.5 star or higher rating will be presented in full color. The restaurant scale is set it to a Paint object and the filter is applied to the marker image using a canvas.
ColorMatrix desatMatrix = new ColorMatrix();
desatMatrix.setSaturation(restaurantRating);

ColorFilter paintColorFilter = new
ColorMatrixColorFilter(desatMatrix);
Paint paint = new Paint();

paint.setColorFilter(paintColorFilter);

Canvas canvas = new Canvas(newImage);
canvas.drawBitmap(oldImage, 0, 0, paint);

Markers are great for showing points on a map but sometimes you can end up with too many. In this case, we have too well rated many restaurants around us - sure, it’s a nice problem to have but it’s not helping the user choose a restaurant. In such situations, you need to display many markers but still keep the view comprehensible. We’re going to look at two ways to overcome these issues.

The first is through the use of marker clustering. As the zoom levels of the map change, markers are aggregated making for a much more digestible view. Now as the map zooms out, markers will combine, showing how many restaurants are in the surrounding areas.

This visual effect may seem like a lot of work, but it is not. The Android Maps Util library provides a four-step implementation of marker clustering:

1. Add the library to your gradle config.
compile 'com.google.maps.android:android-maps-utils:0.3+'
2. Implement ClusterItem interface in your main data class.
public interface ClusterItem {
LatLng getPosition();
}
3. Instantiate the cluster manager and register it for a couple of map listeners.
mClusterManager = new ClusterManager<>(this, mMap);
mMap.setOnCameraChangeListener(mClusterManager);
mMap.setOnMarkerClickListener(mClusterManager);
4. Replace your marker management code with calls to the cluster manager - the cluster manager will manage adding and removing the markers for you.
mClusterManager.addItem(clusterItem);
5. You can optionally customise the effect further by providing custom aggregate markers (showing images instead of a count for example).

Let’s look at the second method to show marker aggregation - it looks really cool! Here, the count of markers are replaced with a heat map showing the concentration of these markers.

Achieving this effect is also just four simple steps using the Android Maps Utils library, thanks to its heatmaps.

1. Add the library to your gradle config.
compile 'com.google.maps.android:android-maps-utils:0.3+'
2. Instantiate a HeatMapTileProvider and pass it your LatLngs.
mHeatmapTileProvider = new HeatmapTileProvider.Builder()
.data(mLatLngCollection)
.build();
3. Use it to create a map overlay.
mTileOverlay = mMap.addTileOverlay(
new TileOverlayOptions().tileProvider(mHeatmapTileProvider));
4. You can optionally customize this further by specifying the gradient and the radius of the heatmap.

It’s worth keeping in mind that information overload is a common problem with mobile apps. Location apps, in particular suffer from poor user experiences when dealing lots of places. The Android Maps Utils library offers beautiful visualizations enabling you to build amazing maps.

Posted:


Editor’s note: Today’s guest blogger is Kristan Hamill, CEO of the proximity-based marketing company Kocomojo. Read how Kocomojo uses Google Maps APIs to help businesses build customer loyalty.

Access to real-time location data has opened up new ways to interact with and better understand customers and customer behavior. With the Kocomojo web dashboard and mobile SDK, marketers can create campaigns inside their own applications or third-party apps based on real-time customer locations and behavior. Since geo-targeting is becoming one of the most powerful ways businesses can connect with customers, we partnered with Google Maps Premier Partner Dito to build our Kocomojo proximity-based marketing platform, KocoConnectTM using Google Maps APIs.

Beacons (Bluetooth low energy devices ) broadcast their location to nearby portable electronic devices, allowing smartphones, tablets and other devices to perform actions when in close proximity to beacons. This gives marketers the ability to promote at close proximity in the range of three to fifty feet with accuracy up to three feet. You can read more about beacons on the Google Developers website.

When we combine geofences with beacon technology, marketers can create sophisticated geo-targeted and hyper-local boundaries that trigger campaigns on the mobile phone. These campaigns can direct customer foot traffic and help businesses interact with customers who are near or on premises. And the KocoConnect platform is beacon agnostic, working with iBeacon, Eddystone, and proprietary beacon protocols so that marketers using it have options when selecting beacon hardware.
Kocomojo screenshot map.png

The Google Maps JavaScript API allows us to insert maps into our Web dashboard, so clients can instantly visualize their data and make informed decisions. With the Kocomojo analytics tools, marketers can measure engagement rates, user preference on A / B tests, and promotion performance over time or within any particular boundary, making adjustments to campaign strategy as needed. People intuitively know how to use Google Maps, so they can quickly focus on the work that needs to be done rather than spend time learning a new interface.

The Google Maps Geocoding API and the Google Maps Drawing Layer let our clients draw a boundary around their stores to define the area in which they want to make offers to nearby customers. The same approach can be applied to building campaigns in remote areas, giving clients the flexibility to send targeted messaging to select neighborhoods and demographics.

When their customers are inside those boundaries, they’ll receive an offer or message on their phones. The boundary can be as small as a quarter mile or as wide as ten miles. The offers don’t have to be just for special sales — companies can also use them to build brand loyalty, for example, offering rewards for visiting a store a certain number of times or promoting an exclusive event.

When building proximity marketing campaigns in iOS and Android, we use the Google Maps Geocoding API Web Service. For iOS, we use the Google Maps SDK for iOS, and Android uses the Google Maps Android API.
Kokomojo_2.png

With the Google Maps APIs, we’re just starting to scratch the surface of what proximity-based marketing will eventually do. But even today, the results are phenomenal. Proximity-based marketing delivers a 60 percent engagement rate, which means that people respond to 60 percent of offers sent to them. That’s extraordinarily high. While that number may drop over time — new technologies often have the highest engagement rates when they’re first introduced — it’s clear that marketing that incorporates user’s location is here to stay, with benefits for both consumers and businesses.

Posted:


The Google Maps Web Service APIs offer a powerful toolkit for the real world - including geocoding, directions, elevation for any point on earth, and snapping GPS crumbs to the road network.

Today we’re introducing a simple and flexible option for developers to instantly and easily scale with these Web Service APIs, by opening them up to pay-as-you-go purchasing via the Google Developers Console. In this new purchasing structure, the Google Maps Geocoding, Directions, Distance Matrix, Roads, Geolocation, Elevation, and Time Zone APIs remain free of charge for the first 2,500 requests per day, and developers may now simply pay $0.50 USD per 1,000 additional requests up to 100,000 requests per API per day. Developers requiring over 100,000 requests per day should contact us to purchase a premium licence.

To get started, head over to our updated Google Maps APIs developer site to check out the APIs, get a key, and provide your billing details to enable the higher limits.

Lastly, alongside this change we’ve updated our Google Maps/Earth APIs Terms of Service to include a section on payment terms as well as some clarifications to the deprecation policy, turn-by-turn navigation restrictions and derivative data sets.

Enjoy!