Google Maps API Web Services

Google Maps API Web Services

This document discusses the Maps API Web Services, a collection of HTTP interfaces to Google services providing geographic data for your maps applications. This guide serves only to introduce the web services and host information common to all of the different services. Individual documentation for each service is located below:

The remainder of this guide discusses techniques for setting up web service requests and parsing the responses. For particular documentation for each service, however, you must consult the appropriate documentation.

Table of Contents

What is a Web Service?

The Google Maps API provides these web services as an interface for requesting Maps API data from external services and using them within your Maps applications. These services are designed to be used in conjunction with a map, as per the Maps API Terms of Service License Restrictions.

These web services use HTTP requests to specific URLs, passing URL parameters as arguments to the services. Generally, these services return data in the HTTP request as either JSON or XML for parsing and/or processing by your application.

A typical Web Service request is generally of the following form:

http://maps.googleapis.com/maps/api/service/output?parameters

where service indicates the particular service requested and output indicates the response format (usually json or xml).

Full documentation of each service is contained within the particular developer guides for those services. However, this guide serves to hold some common practices useful for setting up your web service requests and processing your web service responses.

SSL Access

You can also access the Maps API Web Services over HTTPS. To do so, change the protocol in your request URL to https as shown below:

https://maps.googleapis.com/maps/api/service/output?parameters

HTTPS is recommended for applications that include sensitive user data, such as a user's location, in requests.

Tracking Usage with the sensor Parameter

Use of the Google Maps API(s) now requires that you indicate whether your application is using a sensor (such as a GPS locator) to determine the user's location in any Maps API library or service requests. This is especially important for mobile devices. If your Google Maps API application uses any form of sensor to determine the location of the device accessing your application, you must declare this with a sensor parameter value of true.

Note that even if your application does not use a location sensor, you still must set the sensor parameter (in this case to false).

Building a Valid URL

You may think that a "valid" URL is self-evident, but that's not quite the case. A URL entered within an address bar in a browser, for example, may contain special characters (e.g. "上海+中國"); the browser needs to internally translate those characters into a different encoding before transmission. By the same token, any code that generates or accepts UTF-8 input might treat URLs with UTF-8 characters as "valid", but would also need to translate those characters before sending them out to a web server. This process is called URL-encoding.

We need to translate special characters because all URLs need to conform to the syntax specified by the W3 Uniform Resource Identifier specification. In effect, this means that URLs must contain only a special subset of ASCII characters: the familiar alphanumeric symbols, and some reserved characters for use as control characters within URLs. The table below summarizes these characters:

Summary of Valid URL Characters
SetcharactersURL usage
Alphanumeric a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 Text strings, scheme usage (http), port (8080), etc.
Unreserved - _ . ~ Text strings
Reserved ! * ' ( ) ; : @ & = + $ , / ? % # [ ] Control characters and/or Text Strings

When building a valid URL, you must ensure that it contains only those characters shown above. Conforming a URL to use this set of characters generally leads to two issues, one of omission and one of substitution:

  • Characters that you wish to handle exist outside of the above set. For example, characters in foreign languages such as 上海+中國 need to be encoded using the above characters. By popular convention, spaces (which are not allowed within URLs) are often represented using the plus '+' character as well.
  • Characters exist within the above set as reserved characters, but need to be used literally. For example, ? is used within URLs to indicate the beginning of the query string; if you wish to use the string "? and the Mysterions," you'd need to encode the '?' character.

All characters to be URL-encoded are encoded using a '%' character and a two-character hex value corresponding to their UTF-8 character. For example, 上海+中國 in UTF-8 would be URL-encoded as %E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B. The string ? and the Mysterians would be URL-encoded as %3F+and+the+Mysterians.

Some common characters that must be encoded are:

Unsafe character Encoded value
Space %20
" %22
< %3C
> %3E
# %23
% %25
| %7C

Converting a URL that you receive from user input is sometimes tricky. For example, a user may enter an address as "5th&Main St." Generally, you should construct your URL from its parts, treating any user input as literal characters.

Additionally, URLs are limited to 2048 characters for all web services. For most services, this character limit will seldom be approached. However, note that certain services have several parameters that may result in long URLs.

Processing Responses

As the exact format of individual responses with a web service request is not guaranteed (some elements may be missing or in multiple locations), you should never assume that the format returned for any given response will be the same for different queries. Instead, you should process the response and select appropriate values via expressions. This section discusses how to extract these values dynamically from web service responses.

The Google Web Services provide responses which are easy to understand, but not exactly user friendly. When performing a query, rather than display a set of data, you probably want to extract a few specific values. Generally, you will want to parse responses from the web service and extract only those values which interest you.

The parsing scheme you use depends on whether you are returning output in XML or JSON. JSON responses, being already in the form of Javascript objects, may be processed within Javascript itself on the client; XML responses should be processed using an XML processor and an XML query language to address elements within the XML format. We use XPath in the following examples, as it is commonly supported in XML processing libraries.

Processing XML with XPath

XML is a relatively mature structured information format used for data interchange. Although it is not as lightweight as JSON, XML does provide more language support and more robust tools. Code for processing XML in Java, for example, is built into the javax.xml packages.

When processing XML responses, you should use an appropriate query language for selecting nodes within the XML document, rather than assume the elements reside at absolute positions within the XML markup. XPath is a language syntax for uniquely describing nodes and elements within an XML document. XPath expressions allow you to identify specific content within the XML response document.

XPath Expressions

Some familiarity with XPath goes a long way towards developing a robust parsing scheme. This section will focus on how elements within an XML document are addressed with XPath, allowing you to address multiple elements and construct complex queries.

XPath uses expressions to select elements within an XML document, using a syntax similar to that used for directory paths. These expressions identify elements within an XML document tree, which is a hierarchical tree similar to that of a DOM. Generally, XPath expressions are greedy, indicating that they will match all nodes which match the supplied criteria.

We'll use the following abstract XML to illustrate our examples:

<WebServiceResponse> 
 <status>OK</status> 
 <result> 
  <type>sample</type> 
  <name>Sample XML</formatted_address> 
  <location> 
   <lat>37.4217550</lat> 
   <lng>-122.0846330</lng> 
  </location> 
 </result>
 <result>
  <message>The secret message</message>
 </result> 
</WebServiceResponse> 

Node Selection in Expressions

XPath selections select nodes. The root node encompasses the entire document. You select this node using the special expression "/". Note that the root node is not the top-level node of your XML document; actually, it resides one level above this top-level element and includes it.

Element nodes represent the various elements within the XML document tree. A <WebServiceResponse> element, for example, represents the top-level element returned in our sample service above. You select individual nodes either via absolute or relative paths, indicated by the presence or absence of a leading "/" character.

  • Absolute path: the "/WebServiceResponse/result" expression selects all <result> nodes that are children of the <WebServiceResponse> node. (Note that both of these elements descend from the root node "/".)

  • Relative path from the current context: the expression "result" would match any <result> elements within the current context. Generally, you shouldn't have to worry about context, as you're usually processing web service results via a single expression.

Either of these expressions may be augmented through addition of a wildcard path, indicated with a double-slash ("//"). This wildcard indicates that zero or more elements may match in the intervening path. The XPath expression "//formatted_address," for example, will match all nodes of that name in the current document. The expression //viewport//lat would match all <lat> elements that can trace <viewport> as a parent.

By default, XPath expressions match all elements. You can restrict the expression to match a certain element by providing a predicate, which is enclosed in square brackets ([]). The XPath expression "/GeocodeResponse/result[2] always returns the second result, for example.

XPath ExpressionType of ExpressionSelection
"/"Root node
<WebServiceResponse> 
 <status>OK</status> 
 <result> 
  <type>sample</type> 
  <name>Sample XML</formatted_address> 
  <location> 
   <lat>37.4217550</lat> 
   <lng>-122.0846330</lng> 
  </location> 
 </result>
 <result>
  <message>The secret message</message>
 </result> 
</WebServiceResponse> 
"/WebServiceResponse/result"Absolute Path
<result> 
 <type>sample</type> 
 <name>Sample XML</formatted_address> 
 <location> 
  <lat>37.4217550</lat> 
  <lng>-122.0846330</lng> 
 </location> 
</result>
<result>
 <message>The secret message</message>
</result>
"/WebServiceResponse//location"Path with Wildcard
<location> 
 <lat>37.4217550</lat> 
 <lng>-122.0846330</lng> 
</location> 
"/WebServiceResponse/result[2]/message"Path with Predicate
<message>The secret message</message>
"/WebServiceResponse/result[1]/*"All direct children of the first result
 <type>sample</type> 
 <name>Sample XML</formatted_address> 
 <location> 
  <lat>37.4217550</lat> 
  <lng>-122.0846330</lng> 
 </location> 
"/WebServiceResponse/result[type/text()='sample']/name"The name of a result whose type text is "sample."
Sample XML 

It is important to note that when selecting elements, you select nodes, not just the text within those objects. Generally, you will want to iterate over all matched nodes and extract the text. You may also match text nodes directly; see Text Nodes below.

Note that XPath supports attribute nodes as well; however, all Google Maps web services serve elements without attributes, so matching of attributes is not necessary.

Text Selection in Expressions

Text within an XML document is specified in XPath expressions via a text node operator. This operator "text()" indicates extraction of text from the indicated node. For example, the XPath expression "//formatted_address/text()" will return all text within <formatted_address> elements.

XPath ExpressionType of ExpressionSelection
"//text()"All text nodes (including whitespace)

sample
Sample XML

37.4217550
-122.0846330
The secret message
"/WebServiceRequest/result[2]/message/text()" Text Selection
The secret message
"/WebServiceRequest/result[type/text() = 'sample']/name/text()" Context Sensitive Selection.
Sample XML

Alternatively, you may evaluate an expression and return a set of nodes and then iterate over that "node set," extracting the text from each node. We use this approach in the example below.

For more information on XPath, consult the XPath W3C Specification.

Evaluating XPath in Java

Java has wide support for parsing XML and using XPath expressions within the javax.xml.xpath.* package. For that reason, the sample code in this section uses Java to illustrate how to handle XML and parse data from XML service responses.

To use XPath in your Java code, you will first need to instantiate an instance of an XPathFactory and call newXPath() on that factory to create an XPath object. This object can then process passed XML and XPath expressions using the evaluate() method.

When evaluating XPath expressions, make sure that you iterate over any possible "node sets" which may be returned. Because these results are returned as DOM nodes in Java code, you should capture such multiple values within a NodeList object and iterate over that object to extract any text or values from those nodes.

The following code illustrates how to create an XPath object, assign it XML and an XPath expression, and evaluate the expression to print out the relevant content.

import org.xml.sax.InputSource;
import org.w3c.dom.*;
import javax.xml.xpath.*;
import java.io.*;

public class SimpleParser {

  public static void main(String[] args) throws IOException {
 
	XPathFactory factory = XPathFactory.newInstance();

    XPath xpath = factory.newXPath();

    try {
      System.out.print("Web Service Parser 1.0\n");

      // In practice, you'd retrieve your XML via an HTTP request.
      // Here we simply access an existing file.
      File xmlFile = new File("XML_FILE");

      // The xpath evaluator requires the XML be in the format of an InputSource
	  InputSource inputXml = new InputSource(new FileInputStream(xmlFile));

      // Because the evaluator may return multiple entries, we specify that the expression
      // return a NODESET and place the result in a NodeList.
      NodeList nodes = (NodeList) xpath.evaluate("XPATH_EXPRESSION", inputXml, XPathConstants.NODESET);

      // We can then iterate over the NodeList and extract the content via getTextContent().
      // NOTE: this will only return text for element nodes at the returned context.
      for (int i = 0, n = nodes.getLength(); i < n; i++) {
        String nodeString = nodes.item(i).getTextContent();
        System.out.print(nodeString);
        System.out.print("\n");
      }
    } catch (XPathExpressionException ex) {
	  System.out.print("XPath Error");
    } catch (FileNotFoundException ex) {
      System.out.print("File Error");
    }
  }
}

Download the code from gmaps-samples

Processing JSON with Javascript

JSON (Javascript Object Notation) has an obvious advantage over XML in that the response is lightweight. Parsing such a result is trivial in JavaScript as the format is already a valid Javascript object. For example, to extract the value of the 'formatted_address' keys within a JSON result object, simply access them using the following code:

for (i = 0; i < myJSONResult.results.length; i++) {
  myAddress[i] = myJSONResult.results[i].formatted_address;
}

Note that because JSON may contain multiple values, it's wisest to iterate over the length of the results array if you want to capture all possible values. In practice, you may wish to only return the first result (results[0]), however.

Parsing JSON in other languages is only moderately more difficult. The following Python example initiates a Geocoding web service request and displays all resulting formatted_address values to the user within an array:

import simplejson, urllib

GEOCODE_BASE_URL = 'http://maps.googleapis.com/maps/api/geocode/json'

def geocode(address,sensor, **geo_args):
    geo_args.update({
        'address': address,
        'sensor': sensor  
    })

    url = GEOCODE_BASE_URL + '?' + urllib.urlencode(geo_args)
    result = simplejson.load(urllib.urlopen(url))

    print simplejson.dumps([s['formatted_address'] for s in result['results']], indent=2)

if __name__ == '__main__':
    geocode(address="San+Francisco",sensor="false")

Output: [ "San Francisco, CA, USA" ]

Download the code from gmaps-samples

Authentification requise

Vous devez être connecté à Google+ pour effectuer cette opération.

Connexion en cours…

Le site Google pour les développeurs a besoin de votre autorisation pour effectuer cette opération.