We celebrated our last ‘Code the Road’ Europe stop in London where the team got an early start in our Code Lab building an Android app using the Google Maps APIs.



We celebrated our last ‘Code the Road’ Europe stop in London where the team got an early start in our Code Lab building an Android app using the Google Maps APIs.



Ed Boiling, Maps API sales engineer, led the Code Lab workshop where developers created an Android application using the Google Maps Android API and connected it to a Google Cloud Platform datastore. The Code Lab covered concepts including using Android Studio, creating a Google Maps activity, drawing data on the map, capturing the user's location, and adding location based rules to control the application logic. It also introduced the developers to Google Cloud Platform via the Cloud Endpoints integration in Android studio, allowing them to easily add and deploy a Google App Engine based API and datastore for their application to use.



This was not before trying out a Code the Road favorite—Pegman Skydiving. Using a camera, Maps APIs, and your arms the program can detect how you might look skydiving over a specific locale.



In the afternoon Kerstin Pittl, a lead engineer for Maps APIs from OniGroup, discussed how companies can use the “blue dot” on Google Maps in their applications and how partners can help them integrate it into their map.



Pittl was followed by Dan Hubert, the founder of Appyparking. Appyparking helps drivers across the United Kingdom understand parking regulations and find open parking spaces. The app color codes parking spots to show drivers where there’s free parking, where restrictions apply and where special types of spaces – such as electric-car charging and motorbike spots – are located.



We’re already planning our next roadtrip. We hope to see you at one of our future Code the Road stops!



Posted by Michael St. Germain, Associate Product Marketing Manager, Google Maps APIs


People around the world want to know how they can help the refugees and migrants caught up in the crisis in Europe, the Middle East and Northern Africa. As part of Code the Road Europe, we partnered with Ubilabs, a Google Maps for Work partner, to host a 24-hour hackathon dedicated to helping expand ...



People around the world want to know how they can help the refugees and migrants caught up in the crisis in Europe, the Middle East and Northern Africa. As part of Code the Road Europe, we partnered with Ubilabs, a Google Maps for Work partner, to host a 24-hour hackathon dedicated to helping expand RefugeeMaps.eu, Ubilabs’ open sourced platform to help the refugees in Hamburg and throughout Europe.



RefugeeMaps.eu highlights local points of interest that are relevant to refugees new to a particular area, including libraries, recreational facilities and other important landmarks. The goal is to take local knowledge from volunteers and make it easy for someone new to the area to orient themselves and find resources that will help them settle in quickly.


IMG_3502.jpg



We kicked-off the hackathon with a presentation from Barbara Kopf, a refugee activist and the manager of the institution ‘Freizeithaus Kirchdorf’. She provided context for what refugees need and how they can help. Then, we had Thomas Steiner, an engineer in the Google Hamburg office, and Martin Kleppe from Ubilabs talk about the technical aspects around the platform. To support the effort, Ed Boiling, Google Maps APIs Sales Engineer, presented 10 Google Maps APIs in 10 minutes, then it was time to start start coding.


IMG_3505.jpg



Six groups of developers formed and spent the rest of the night designing, coding, and working together to find ways to improve RefugeeMaps.eu with, of course, lots of coffee and snacks.


IMG_3518.jpg



After 24 hours, we all came together to review the improvements which included:




  • Improvement to the front end design and UX optimization based on language preferences, making it easier for refugees to navigate the platform based on their preference for Arabic, English or German.

  • A function that makes it easier for refugees to print out select, zoomed-in areas of the map. Not all refugees have cell phones, especially women and children, so one group decided it was important to make sure it was easy for someone to print out maps to make it truly offline.

  • Addition of new places. Currently, only local volunteers with access to a master spreadsheet can add locations; however, one group added a function that makes it easier for anyone to add in a location through the interface of the map. This then updates the master spreadsheet.

  • A native offline Android app. Offline is important for the refugees that might not have data plans, so one group created a native Android app that could be used offline.

  • No server solution. To make it easier to run the platform, developers made a solution that did not require a server-side.

  • A performance boost. Developers added back-end changes to allow for caching of resources for offline use.




Here is the improvement we made to the front end design:


front_end_design_update.png



We were so impressed by all of the improvements that the developers made over the 24 hour period. While the hackathon is officially over, we also extend our invitation to collaborate on the project to external developers who could not attend the hackathon. You can find the code and all info on GitHub as well as a live demo instance of RefugeeMaps.eu online.



Posted by Hena Haines, Product Marketing Manager, Google Maps APIs


After a great trip to Tel Aviv, we were excited to be in Germany with our Code the Road bus. Our first stop was in Berlin, and then we were on to Hamburg for our 24-hour Hackathon.



After a great trip to Tel Aviv, we were excited to be in Germany with our Code the Road bus. Our first stop was in Berlin, and then we were on to Hamburg for our 24-hour Hackathon.



We hosted our first event in the Factory, Germany's largest startup campus. The Factory provides working spaces, communities and events for freelancers and startups to connect and empowers entrepreneurs and innovators in a beautiful space in Berlin.


IMG_4166.jpg



Before the event developers had a great time exploring the Code the Road bus and enjoying a coffee at our Location Cafe. They also had a chance to play multiple games including the Maps Skydiving game.


IMG_4161.jpg



Ed Boiling and Matt Toon kicked-off the event with a great Codelab focused on building an app that allows users to check into any mountain when going on a hike or visiting a new destination. Corien, a web developer and student, said, “It was great to learn more how to use Google Maps APIs on Android, a platform I don’t usually develop on as well as learn from the other developers at the event. It was great to see everyone working together and learning a thing or two about Google Maps APIs.”


IMG_4163.jpg



Then, we had Ed Parsons kick off our presentation by explaining how location technology is changing the way we interact with the world to create a more dynamic, emotive experience.



Next up, Oliver from Kia Motors spoke about how Kia is using Google Maps APIs in the Kia cee’d Surprise Drive digital marketing campaign. Martin Kleppe from Ubilabs followed up with the specific technical points on how this digital marketing campaign was developed with Distance Matrix API, Directions API and custom pins. He also gave our attendees some tips and tricks about how to get their maps looking snazzy with Image Tiles, clustering, Marker Images, Data Layer and more. He even share his presentation for our attendees to reference.


IMG_4273 (1).JPG



Finally, our technical lead from Sydney, Enoch, presented on a range of topics from keys to quotas to JavaScripts tips and tricks.



Shenouda, a developer from Egypt told us, “The presentations gave a great overview of the functionality of the technology and how to use the APIs to the best of their abilities.” He plans to take what he learned on styling and overlaying data on a map as well as using the Elevation API to incorporate into applications to give users a really interactive and exciting user experience.



We had a great time in Berlin. Next we were on to Hamburg and London!



Posted by Tobias Espig, Head of Global Field Marketing, Google Maps APIs


We had a fantastic start to our ‘Code the Road’ Europe tour at the Google Tel Aviv Campus. We were thrilled to have so many enthusiastic developers to help kick off our first event.



We had a fantastic start to our ‘Code the Road’ Europe tour at the Google Tel Aviv Campus. We were thrilled to have so many enthusiastic developers to help kick off our first event.



It was great to be in Tel Aviv to feel the excitement and energy of their thriving startup community and to see how these talented developers were using location and Google Maps APIs in their applications.



There we brought a Maps Dive gaming experience to the campus area as well as a full-size copy our Code the Road 1970s Volkswagen Tour bus. (The actual bus and the trailer were waiting for us in Berlin for our next stop on the 12th of November)


_DSC0252.JPG



For our first talk, Ed Parsons, Geospatial Technologist, Google Maps, gave a talk titled "Everything, everywhere: The evolving world of ambient location.” Next up was, Enoch Lau, Technical Lead, Javascript Maps API, who gave some tricks and tips to make Google Maps APIs run even smoother.


_DSC0198.JPG



We also welcomed Lidor Dvir, Head of Development from Gett who shared a talk titled "Using Google Maps API to build a multi-million user product". Lidor presented on how Gett uses multiple Google Maps APIs on multiple platforms to help both users and businesses get where they need to go and get the things they need. He described how the Google Maps Places API, Directions API and Roads APIs helps users easily find the places they need to go and the best way to get there. They also use heat maps, marker clustering, customize markers and animations to layer information on the map in beautiful visualizations.



We spent the afternoon with a packed house for Codelab were we built a ‘Munro bagging’ Android app on Google Maps and Google Cloud Platform. We had a great time working with the developers helping them with the app.


_DSC0238.JPG



Tel Aviv was just the start of our journey. The next stop was Berlin!



Posted by Tobias Espig, Head of Global Field Marketing, Google Maps APIs





Today, we're announcing two new ways to help users enter places and addresses in your apps with less typing. Autocomplete functionality assists users by automatically completing the name and address of a place as they type. The autocomplete widget on ...




Today, we're announcing two new ways to help users enter places and addresses in your apps with less typing. Autocomplete functionality assists users by automatically completing the name and address of a place as they type. The autocomplete widget on iOS and Android makes it easier for you to add autocomplete functionality to your application with just a small amount of code. Also, we are adding autocomplete functionality to the place picker.



The new autocomplete widget UI comes in two different flavors: overlay and full screen.




Full screen autocomplete widget







Overlay autocomplete widget


On Android, you can add the autocomplete widget as a Fragment and add an event listener to retrieve the autocompleted place reference back in the application. Alternatively, you can invoke the autocomplete widget with an Intent.



Adding a Fragment In the XML layout file for your Activity:

<fragment
android:id="@+id/place_autocomplete_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:name="com.google.android.gms.location.places.ui.PlaceAutocompleteFragment"
/>



Adding an Event Listener in your Activity's onCreate() method:

// 
PlaceAutocompleteFragment fragment = (PlaceAutocompleteFragment)
getFragmentManager().findFragmentById(R.id.place_autocomplete_fragment);

fragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
@Override
public void onPlaceSelected(Place place) { // Handle the selected Place
}
@Override
public void onError(Status status) { // Handle the error
}



Creating an intent to invoke the autocomplete widget:

try {
Intent intent =
new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_FULLSCREEN)
.build(this);
startActivityForResult(intent, PLACE_AUTOCOMPLETE_REQUEST_CODE);
} catch (GooglePlayServicesRepairableException e) {
GooglePlayServicesUtil
.getErrorDialog(e.getConnectionStatusCode(), getActivity(), 0);
} catch (GooglePlayServicesNotAvailableException e) {
// Handle the exception
}



On iOS (Objective-C), you can implement autocomplete’s delegate to respond to a place selection:

@interface MyViewController () 
@end

@implementation ViewController
.
.
.
- (IBAction)onLaunchClicked:(id)sender {
// Present the Autocomplete view controller when the button is pressed.
GMSAutocompleteViewController *acController = [[GMSAutocompleteViewController alloc] init];
acController.delegate = self;
[self presentViewController:acController animated:YES completion:nil];
}

- (void)viewController:(GMSAutocompleteViewController *)viewController
didAutocompleteWithPlace:(GMSPlace *)place {
// The user has selected a place.
[self dismissViewControllerAnimated:YES completion:nil];
}

- (void)viewController:(GMSAutocompleteViewController *)viewController
didAutocompleteWithError:(NSError *)error {
[self dismissViewControllerAnimated:YES completion:nil];
}

// User pressed cancel button.
- (void)wasCancelled:(GMSAutocompleteViewController *)viewController {
[self dismissViewControllerAnimated:YES completion:nil];
}

@end



And in Swift:

import UIKit
import GoogleMaps

class MyViewController: UIViewController {

@IBAction func onLaunchClicked(sender: AnyObject) {
let acController = GMSAutocompleteViewController()
acController.delegate = self
self.presentViewController(acController, animated: true, completion: nil)
}
}

extension MyViewController: GMSAutocompleteViewControllerDelegate {

func viewController(viewController: GMSAutocompleteViewController!, didAutocompleteWithPlace place: GMSPlace!) {
// The user has selected a place.
self.dismissViewControllerAnimated(true, completion: nil)
}

func viewController(viewController: GMSAutocompleteViewController!, didAutocompleteWithError error: NSError!) {
self.dismissViewControllerAnimated(true, completion: nil)
}

func wasCancelled(viewController: GMSAutocompleteViewController!) {
self.dismissViewControllerAnimated(true, completion: nil)
}
}



We have also added the autocomplete functionality to the place picker—a UI widget that helps users communicate their current location, such as a place, address or location on a map. This makes it even easier to pick a specific place by starting to type its name or address. If your app already uses the place picker it will automatically gain the autocomplete feature with no action required on your part.



To get started, check out the documentation and code samples. You can always send us any questions via Stack Overflow or the Google Maps API issue tracker if you have ideas for improvement.




Google My Business is helping businesses around the world connect with their customers when they search for them on Google. Today we’re introducing the Google My Business API to make it easier for large businesses and third parties to integrate with the Google My Business platform and publish updates to customers on Google Search & Maps. For example, you can now set your special hours for the holiday season and update them across all of your locations using the Google My Business API.
Google My Business is helping businesses around the world connect with their customers when they search for them on Google. Today we’re introducing the Google My Business API to make it easier for large businesses and third parties to integrate with the Google My Business platform and publish updates to customers on Google Search & Maps. For example, you can now set your special hours for the holiday season and update them across all of your locations using the Google My Business API.



Through the new Google My Business API, developers can:




  • Create business locations with information such as name, address, phone number, category, business hours, and more

  • Manage special hours

  • Mark a business location as permanently closed

  • Manage business photos

  • List, invite and remove managers on locations and business accounts

  • Read listing state to identify Google updated, duplicate and suspended locations

  • Search/Filter locations by name, category and label

  • Set the service area for a business either by specifying a point and radius or Place IDs




Here's a sample java function that creates a new location and sets special holiday hours:

public static Location createLocation(String accountName) throws Exception {
Location location = new Location();

// Street address
Address address = new Address();
List addressLines = Arrays.asList("740 Valencia Street");
address.setAddressLines(addressLines);
address.setLocality("San Francisco");
address.setAdministrativeArea("CA");
address.setCountry("US");
address.setPostalCode("94110");
location.setAddress(address);

// Business hours
BusinessHours businessHours = new BusinessHours();
List periods = new ArrayList<>();
List days = Arrays.asList("Monday", "Tuesday", "Wednesday", "Thursday", "Friday");
for (String day : days) {
TimePeriod period = new TimePeriod();
period.setOpenDay(day);
period.setOpenTime("11:00");
period.setCloseTime("20:00");
period.setCloseDay(day);
periods.add(period);
}
businessHours.setPeriods(periods);
location.setBusinessHours(businessHours);

// Special hours
Date christmasEve = new Date().setYear(2015).setMonth(12).setDay(24);
Date christmasDay = new Date().setYear(2015).setMonth(12).setDay(25);
List periods = new ArrayList<>();
periods.add(new SpecialHourPeriod()
.setStartDate(christmasEve)
.setOpenTime("11:00")
.setCloseTime("20:00")
.setEndDate(christmasEve));
periods.add(new SpecialHourPeriod()
.setStartDate(christmasDay)
.setIsClosed(true));
SpecialHours specialHours = new SpecialHours()
.setSpecialHourPeriods(periods);

location.setSpecialHours(specialHours);

location.setLocationName("Dandelion Chocolate");
location.setStoreCode("DC1");
location.setPrimaryPhone("415 349-0942");
location.setPrimaryCategory(new Category().setCategoryId("gcid:chocolate_shop"));
location.setWebsiteUrl("https://www.dandelionchocolate.com/");

// Create Location
CreateLocationRequest createLocationRequest = new CreateLocationRequest();
// RequestId is a unique id for each location created
createLocationRequest.setRequestId(“1a84939c-ab7d-4581-8930-ee35af6fefac”);
createLocationRequest.setLocation(location);
createLocationRequest.setLanguageCode("en-US");
Mybusiness.Accounts.Locations.Create createLocation =
mybusiness.accounts().locations().create(accountName, createLocationRequest);

Location createdLocation = createLocation.execute();

System.out.printf("Created Location:\n%s", createdLocation.toPrettyString());

return createdLocation;
}

When special hours are set in Google My Business, we will tell customers that they’re seeing holiday-specific opening hours on Google:





To learn more about the Google My Business API and to apply for access, visit our developer page.



Questions or feedback? Contact the API team on the Google My Business API Forum.



Posted by Aditya Tendulkar, Product Manager, Google My Business


Today we are launching the Google Maps SDK for iOS 1.11, which includes bitcode support, new events and some features previously available only in the Android SDK.



Bitcode is an intermediate representation of your app that is uploaded to the Apple Store. With this abstraction, Apple can optimize for specific target devices at provisioning time.
Today we are launching the Google Maps SDK for iOS 1.11, which includes bitcode support, new events and some features previously available only in the Android SDK.



Bitcode is an intermediate representation of your app that is uploaded to the Apple Store. With this abstraction, Apple can optimize for specific target devices at provisioning time.



The Google Maps SDK for iOS 1.11 also introduces two new events: didLongPressInfoWindowOfMarker and didCloseInfoWindowOfMarker. The long press event takes advantage of iOS long-touch as another way for users to interact with Maps SDK for iOS enabled apps. The close event is particularly useful if you wish to programmatically zoom back out on the map after the user has looked at the detail associated with a particular marker.



We have also added start and finish rendering events to the GMSMapViewDelegate and GMSPanoramaViewDelegate protocols. The start rendering events are triggered when tiles have just been requested or labels have just started rendering. The finish events are triggered on rendering completion for tiles and StreetView panoramas, respectively.



Finish events can be used in conjunction with an activity indicator to accurately represent when a map has finished rendering. The sample code below shows how to include this functionality. (We’ve also included SVProgressHUD in the sample below to improve the user experience, but it is not required)



import UIKit
import GoogleMaps

class MapRenderingViewController: UIViewController {
@IBOutlet var mapView: GMSMapView!

override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
}

// MARK: - GMSMapViewDelegate

func mapViewDidStartTileRendering(mapView: GMSMapView!) {
SVProgressHUD.showWithStatus("Loading tiles")
}

func mapViewDidFinishTileRendering(mapView: GMSMapView!) {
SVProgressHUD.dismiss()
}
}

Lastly, the Google Maps SDK for iOS 1.11 offers new features & bugfixes we think you'll find useful, including:




  • Setting ground overlay opacity with an alpha value

  • Polygon hole support

  • Increased camera tilt range at high zoom

  • Additional Places autocomplete functionality




Take a look at our release notes and update to Google Maps SDK for iOS 1.11 today.



Posted by Megan Boundey, Product Manager, Google Maps Mobile APIs

Planning journeys ahead of time has always been difficult, since traffic conditions vary greatly over time. Developers have used live traffic data from the Google Maps APIs for years to help drivers with this problem, but up to now, this has been available only for journeys starting very close to now, and limited to Google Maps for Work customers only.
Planning journeys ahead of time has always been difficult, since traffic conditions vary greatly over time. Developers have used live traffic data from the Google Maps APIs for years to help drivers with this problem, but up to now, this has been available only for journeys starting very close to now, and limited to Google Maps for Work customers only.



Today we’re extending traffic predictions in the Google Maps APIs indefinitely into the future - a feature we call predictive travel times. This will let developers plan journeys hours, days or even weeks in advance, using Google’s model of what the traffic conditions will be like on that day. We’re also making all traffic features in Directions API and Distance Matrix API available under our Standard Plan (2500 requests/day for free, with pay-as-you-go pricing for extra requests), and increasing the waypoint limit in Directions API for these developers from 8 to 23 waypoints. (Traffic features and higher waypoint limits in the JavaScript Maps API are available to Google Maps for Work customers for now.)



Using these new traffic features is super simple—just add the departure_time parameter to Directions API or Distance Matrix API queries, and the results will contain the travel time estimate given the predicted traffic conditions at that time. The route returned may also change depending on traffic conditions, which lets developers recommend the fastest route to their users. For example, the image below shows the fastest route from San Francisco International Airport to the Google campus in Mountain View late at night when there’s no traffic (blue), and during peak hour when an accident on Highway 101 has slowed traffic to a crawl (red).


Screen Shot 2015-11-10 at 8.26.11 PM.png



Since traffic conditions far in the future could vary greatly, developers can set an optional traffic_model parameter to choose whether they’d prefer to get an optimistic, pessimistic or best_guess estimate of the travel time. For example, one of our customers, Redfin, plan to use the Google Maps APIs to predict how long it will take to drive between homes, so they will use the pessimistic traffic model to ensure there’s enough travel time taking traffic into account. On the other hand, a developer building thermostat app wants their user’s house to be warm by the time they get home from work, so they would use the optimistic travel time estimate to calculate when their user is likely to get home, and when their thermostat needs to turn on.



The default traffic model, best_guess, returns the most likely travel time given everything that’s known about the traffic conditions—both the historical model for the queried time and day of the week, and the actual live traffic conditions right now. This can be used in apps that give drivers an indication of what their travel time will most likely be.



To learn more about the traffic features in the Google Maps APIs, please take a look at our video, check out the documentation for the Directions API, the Distance Matrix API and the JavaScript Maps API Directions and Distance Matrix services, or download the updated client libraries for Java or Python.



Posted by Elena Kelareva, Product Manager, Google Maps APIs




After an exciting road trip across the U.S. this summer, we decided to bring Code the Road to Europe to highlight what developers have made possible with the Google Maps APIs. We’ll be driving our customized 1979 Volkswagen T2 Bus with 50 Horsepower, 78Tkm on a four stop trip across Europe where along the way we’ll meet with developers, customer and partners.




After an exciting road trip across the U.S. this summer, we decided to bring Code the Road to Europe to highlight what developers have made possible with the Google Maps APIs. We’ll be driving our customized 1979 Volkswagen T2 Bus with 50 Horsepower, 78Tkm on a four stop trip across Europe where along the way we’ll meet with developers, customer and partners.



Code the Road Europe kicks-off in Tel Aviv on November 10. From there we’ll be heading across Europe—stopping in Berlin, Hamburg and London.



We will also be hosting three developer meetups: Tel Aviv on November 10, Berlin on November 12 and London on November 25. The meetups will highlight how developers can use the Google Maps APIs in their apps and websites and include sessions with Google Engineers and customers. We’re expecting these meet-ups to fill-up quickly, so register today to reserve a seat at a location near you.



We’ll be hosting a 24-hour hackathon in Hamburg beginning the afternoon of November 18. Ubilabs and the Google Maps APIs team will be bringing developers, product managers and students together to develop innovative solutions to lend a hand in the Syrian Refugee Crisis.



We will be sharing on-the-road updates and photos on the site throughout the trip. We hope to see you on the road!



Posted by Tobias Espig, EMEA Marketing, Google Maps APIs





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 Corey Bradford, Google Maps Solution Architect at Google. ...




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 Corey Bradford, Google Maps Solution Architect at Google.



Many location-based sites and applications can accurately tell users how far they are from nearby points of interest. However, they often provide only straight-line distance (ie as the crow flies), which isn’t always a true representation of proximity. Alternatively, these applications can be improved by the Distance Matrix service available in the Google Maps Javascript API and the Distance Matrix Web Service, which provides accurate travel distances and times, and for premium customer can even factor in current traffic conditions.



Store locators and rideshare/taxi applications are common applications that can benefit from using the Distance Matrix service. In both use cases, a user is trying to determine their relative distance from either a store or taxi.



Store locators

Suppose a customer has provided their location, “1903 Toro Canyon Rd, Austin, TX 78746.” (Point C on the map) Using straight-line distances, your application found your three nearest stores, as shown on this map:


dm_map1.png

“As the crow flies,” store #1 (shown in the image below as "B") is clearly nearest to the customer location, “C.” However, there’s a river between these locations. Unless the customer intends to use watercraft for part of their travel, they’ll need to travel via the nearest bridge or tunnel. The Directions Service provides the suggested route, confirming the need to travel much farther than the straight-line distance:


dm_map2.png



Since we know that the straight-line distance doesn’t accurately reflect the proximity of the stores in this case, let’s make a call to the Distance Matrix Service to determine actual driving distances and times. Here are the results returned:












Store #


Straight-Line Distance (mi)


Driving Distance (mi)


Driving Time (min)


Driving Time with Current Traffic (min)


1


1.4


5.4


15


20


2


2.7


4.4


9


15


3


2.5


4.7


11


11





Now we have some useful information for the customer. First, we can see that, although store #2 is the farthest in a straight line, it’s actually the shortest driving distance. In addition, in normal traffic conditions, it’s also the shortest driving time. However, if we consider current traffic conditions, we see that store #2 will take longer to reach than store #3. The following maps, which use the Directions Service along with the traffic layer, illustrate these results:


dm_map3.png



In this case, the customer may choose to visit store #3 (shown in the image below as "B") if they are leaving now or store # 2 if they plan to travel later, after traffic clears.


dm_map4.png



Rideshare and taxis

Now let’s consider another example: users looking to hire a car service or dispatchers who need to direct the nearest taxi to a customer. As the following maps shows, the user can see the actual current drive times, provided by the Distance Matrix API, of each driver to their location, regardless of straight-line distance.


Taxi mobile map.png



What's Under The Hood

Now that we’re taken a look at how driving distances, duration, and duration in traffic information can benefit your customers, you might be wondering “How can I implement this as a developer?” Below are code snippets from the store locator example that provide the technical details of how to build these features using the Distance Matrix service.



For simplicity, we’ve pre-defined the customer and store locations:

var customerLocation = '1903 Toro Canyon Rd, Austin, TX 78746';

var store1 = '3808 W. 35th, Austin, TX 78703';
var store2 = '4933 Plaza on the Lake, Austin, TX 78746';
var store3 = '6500 Bee Cave Rd, Austin, TX 78746';

Using this location information, we make a call to the Distance Matrix service:

function calculateDistances() {
// Create a new Distance Matrix Service object
var service = new google.maps.DistanceMatrixService();

// Set the options such as the pre-defined origin
// and destinations, as well as specifying to use
// duration in traffic

service.getDistanceMatrix({
origins: [customerLocation],
destinations: [store1, store2, store3],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.IMPERIAL,
avoidHighways: false,
avoidTolls: false,
durationInTraffic: true
}, callback);
}

function callback(response, status) {
if (status != google.maps.DistanceMatrixStatus.OK) {
console.log('DistanceMatrix Error: ', status);
} else {
// Get the arrays of origins and destinations
var origins = response.originAddresses;
var destinations = response.destinationAddresses;

for (var i = 0; i < origins.length; i++) {
// For each of the origins, get the results of the
// distance and duration of the destinations
var results = response.rows[i].elements;
for (var j = 0; j < results.length; j++) {
// Store the results for later sorting
storeResults.push([destinations[j],
results[j].duration_in_traffic.value,
results[j].distance.value]);
}
}
// Sort the results by duration in traffic
storeResults.sort(function(a, b) {
return a[1] - b[1];
});
}
}

The call returns the following data, which includes the critical information of driving distances, duration, and duration in traffic:


destination_addresses" : [
"3808 West 35th Street, Austin, TX 78703, USA",
"4933 Plaza on the Lake, Austin, TX 78746, USA",
"6500 Bee Cave Road, Austin, TX 78746, USA"
],
"origin_addresses" : [ "1903 Toro Canyon Road, Austin, TX 78746, USA" ],
"rows" : [
{
"elements" : [
{
"distance" : {
"text" : "5.4 mi",
"value" : 8631
},
"duration" : {
"text" : "15 mins",
"value" : 917
},
"duration_in_traffic" : {
"text" : "20 mins",
"value" : 1188
},
"status" : "OK"
},
{
"distance" : {
"text" : "4.4 mi",
"value" : 7157
},
"duration" : {
"text" : "9 mins",
"value" : 569
},
"duration_in_traffic" : {
"text" : "15 mins",
"value" : 911
},
"status" : "OK"
},
{
"distance" : {
"text" : "4.7 mi",
"value" : 7490
},
"duration" : {
"text" : "11 mins",
"value" : 635
},
"duration_in_traffic" : {
"text" : "11 mins",
"value" : 635
},
"status" : "OK"
}
]
}

With this data, customers can sort the store results according to their preferences and make better decisions about which store to visit.



We hope you’re able to take advantage of some of these features in your website or application. For more details on implementing the Google Maps Javascript API Distance Matrix service, visit our developer documentation and review our available code samples. You can also find out more about the Distance Matrix API, part of our Google Maps Web Services APIs.





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 ...




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.





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. ...




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.





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! ...




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!