Package geodress.model.reader

Source Code of geodress.model.reader.GoogleMapsReader

/**
* GeoDress - A program for reverse geocoding
* Copyright (C) 2010  Stefan T.
*
* See COPYING for Details.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package geodress.model.reader;

import geodress.main.Logging;
import geodress.model.Address;
import geodress.model.Coordinate;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
* A location reader that gets the address from Google Maps.
*
* @author Stefan T.
* @see "http://code.google.com/intl/en/apis/maps/documentation/services.html"
*/
public class GoogleMapsReader implements LocationReader {
  /** Logger object */
  private Logger logger = null;
  /**
   * standard Google Maps API key for <a
   * href="http://geodress.sourceforge.net"
   * >http://geodress.sourceforge.net</a>
   */
  private final static String GOOGLE_MAPS_API_KEY = "ABQIAAAAz3DnkG-LcuBIXz2lfXNr_xRyL367N49j2iW21h-7GXG3qz_7-hRkguI3dEfa8B9XuirrjZ-ZD3Eg0Q";

  /**
   * Google maps API key, it is needed to use the Google Maps API
   *
   * @see "http://code.google.com/intl/en-US/apis/maps/faq.html#geocoder_limit"
   */
  private String googleMapsKey;
 
  /**
   * Country code top-level domain that specifies the region bias for the Google Maps request
   *
   * @see "http://code.google.com/intl/en/apis/maps/documentation/geocoding/index.html#RegionCodes"
   */
  private String googleRegion;

  /**
   * Initializes the reader and generates a random Google Maps key.
   */
  public GoogleMapsReader() {
    this(GOOGLE_MAPS_API_KEY);
  }

  /**
   * Initializes the reader with a special Google Maps key.
   *
   * @param googleMapsKey
   *            the Google Maps API key
   */
  public GoogleMapsReader(String googleMapsKey) {
    logger = Logging.getLogger(this.getClass().getName());
    setGoogleMapsKey(googleMapsKey);
    setGoogleRegion("us");
  }

  /**
   * @return the Google Maps key
   */
  public String getGoogleMapsKey() {
    return googleMapsKey;
  }

  /**
   * @param googleMapsKey
   *            the Google Maps key to set
   */
  public void setGoogleMapsKey(String googleMapsKey) {
    this.googleMapsKey = googleMapsKey;
  }

  /**
   * @return the region
   */
  public String getGoogleRegion() {
    return googleRegion;
  }

  /**
   * @param googleRegion a region to set
   */
  public void setGoogleRegion(String googleRegion) {
    this.googleRegion = googleRegion;
  }

  /**
   * @throws UnknownHostException
   * @see geodress.model.reader.LocationReader#getAddress(geodress.model.Coordinate)
   */
  @Override
  public Address getAddress(Coordinate coordinates)
      throws UnknownHostException {
    URI GoogleMapsXml = null;
    try {
      GoogleMapsXml = new URI(
          "http://maps.google.com/maps/geo?output=xml&q="
              + coordinates.getLatitude() + ","
              + coordinates.getLongitude() + "&key="
              + googleMapsKey + "&region="+googleRegion+"&output=xml");
    } catch (URISyntaxException urise) {
      logger.log(Level.WARNING, "URI for Google Maps address retrieval",
          urise);
    }

    try {
      return getAddress(GoogleMapsXml);
    } catch (SAXException saxe) {
      logger.log(Level.WARNING,
          "SAX error while reading Google Maps XML file", saxe);
    } catch (UnknownHostException uhe) {
      throw new UnknownHostException(
          "error while retrieving Google Maps XML file "
              + "(maybe no Internet connection)");
    } catch (IOException ioe) {
      logger.log(Level.WARNING,
          "error while reading Google Maps XML file", ioe);
    }
    return new Address();
  }

  /**
   * Gets the address by an XML file from the Google Maps APIs.
   *
   * @param xmlFile
   *            the URI of the XML file with the data
   * @return an Address object with the address
   * @throws IOException
   *             if an I/O error occurs
   * @throws SAXException
   *             if an SAX error occurs
   * @throws UnknownHostException
   *             if the Google Maps XML file could not be retrieved (maybe no
   *             Internet connection)
   */
  private Address getAddress(URI xmlFile) throws SAXException, IOException {
    logger.log(Level.FINEST, "get address by Google XML from "
        + xmlFile.toString());

    /* parse XML file */
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = null;
    try {
      builder = factory.newDocumentBuilder();
    } catch (ParserConfigurationException pce) {
      logger
          .log(
              Level.WARNING,
              "parser for Google Maps XML file could not be created",
              pce);
    }
    Document document = builder.parse(xmlFile.toString());

    int statusCode = Integer.valueOf(getNode(
        new LinkedList<String>(Arrays.asList("kml", "Response",
            "Status", "code")), document).getTextContent());
    logger.log(Level.FINEST, "status code of XML file: " + statusCode);

    Node address = getNode(new LinkedList<String>(Arrays.asList("kml",
        "Response", "Placemark", "address")), document);
    if (address != null) {
      logger.log(Level.FINEST, "address found: "
          + address.getTextContent());
      return new Address(address.getTextContent().trim(), String
          .valueOf(statusCode));
    } else {
      return new Address();
    }
  }

  /**
   * @see geodress.model.reader.LocationReader#toString()
   */
  @Override
  public String toString() {
    return "Google Maps API";
  }

  /**
   * Gets a special node in a XML document via DOM.
   *
   * @param path
   *            the path where the node is located, this is a list with the
   *            node (like a path)
   * @param node
   *            the root of the path
   * @return the wanted element
   */
  private Node getNode(LinkedList<String> path, Node node) {
    if (path.isEmpty()) {
      return node;
    } else {
      NodeList ndList = node.getChildNodes();
      for (int i = 0; i < ndList.getLength(); i++) {
        if (ndList.item(i).getNodeName() == path.getFirst()) {
          path.removeFirst();
          return getNode(path, ndList.item(i));
        }
      }
    }
    return null;
  }
}
TOP

Related Classes of geodress.model.reader.GoogleMapsReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.