/walkytalky/src/com/googlecode/eyesfree/walkytalky/ReverseGeocoder.java

http://eyes-free.googlecode.com/ · Java · 160 lines · 74 code · 13 blank · 73 comment · 4 complexity · 588097b14d6958e9c782b552c755736e MD5 · raw file

  1. /*
  2. * Copyright (C) 2008 Google Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.googlecode.eyesfree.walkytalky;
  17. import java.io.BufferedReader;
  18. import java.io.IOException;
  19. import java.io.InputStream;
  20. import java.io.InputStreamReader;
  21. import java.net.HttpURLConnection;
  22. import java.net.MalformedURLException;
  23. import java.net.URL;
  24. /**
  25. * This class implements methods to get street address from lat-lon using
  26. * reverse geocoding API through HTTP.
  27. *
  28. * @author chaitanyag@google.com (Chaitanya Gharpure)
  29. */
  30. public class ReverseGeocoder {
  31. /**
  32. * Interface for the callbacks to be used when a street is located
  33. */
  34. public interface OnAddressLocatedListener {
  35. public void onAddressLocated(Address address);
  36. }
  37. private OnAddressLocatedListener cb;
  38. private static final String ENCODING = "UTF-8";
  39. // URL for obtaining reverse geocoded location
  40. private static final String URL_GEO_STRING = "http://maps.google.com/maps/api/geocode/json?sensor=false&latlng=";
  41. public ReverseGeocoder(OnAddressLocatedListener callback) {
  42. cb = callback;
  43. }
  44. /**
  45. * Queries the map server and obtains the reverse geocoded address of the
  46. * specified location.
  47. *
  48. * @param lat The latitude in degrees
  49. * @param lon The longitude in degrees
  50. */
  51. public void getAddressAsync(double lat, double lon) {
  52. final double latitude = lat;
  53. final double longitude = lon;
  54. /**
  55. * Runnable for fetching the address asynchronously
  56. */
  57. class AddressThread implements Runnable {
  58. public void run() {
  59. cb.onAddressLocated(getAddress(latitude, longitude));
  60. }
  61. }
  62. (new Thread(new AddressThread())).start();
  63. }
  64. /**
  65. * Queries the map server and obtains the reverse geocoded address of the
  66. * specified location.
  67. *
  68. * @param lat The latitude in degrees
  69. * @param lon The longitude in degrees
  70. * @return Returns the reverse geocoded address
  71. */
  72. public Address getAddress(double lat, double lon) {
  73. try {
  74. String resp = getResult(makeGeoURL(lat, lon));
  75. return new Address(resp);
  76. } catch (MalformedURLException mue) {
  77. } catch (IOException e) {
  78. }
  79. return null;
  80. }
  81. /**
  82. * Sends a request to the specified URL and obtains the result from the
  83. * sever.
  84. *
  85. * @param url The URL to connect to
  86. * @return the server response
  87. * @throws IOException
  88. */
  89. private String getResult(URL url) throws IOException {
  90. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  91. conn.setDoInput(true);
  92. conn.setDoOutput(true);
  93. InputStream is = conn.getInputStream();
  94. String result = toString(is);
  95. return result;
  96. }
  97. /**
  98. * Prepares the URL to connect to the reverse geocoding server from the
  99. * specified location coordinates.
  100. *
  101. * @param lat latitude in degrees of the location to reverse geocode
  102. * @param lon longitude in degrees of the location to reverse geocode
  103. * @return URL The Geo URL created based on the given lat/lon
  104. * @throws MalformedURLException
  105. */
  106. private URL makeGeoURL(double lat, double lon) throws MalformedURLException {
  107. StringBuilder url = new StringBuilder();
  108. url.append(URL_GEO_STRING).append(lat).append(",").append(lon);
  109. return new URL(url.toString());
  110. }
  111. /**
  112. * Reads an InputStream and returns its contents as a String.
  113. *
  114. * @param inputStream The InputStream to read from.
  115. * @return The contents of the InputStream as a String.
  116. */
  117. private static String toString(InputStream inputStream) throws IOException {
  118. StringBuilder outputBuilder = new StringBuilder();
  119. String string;
  120. if (inputStream != null) {
  121. BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, ENCODING));
  122. while (null != (string = reader.readLine())) {
  123. outputBuilder.append(string).append('\n');
  124. }
  125. }
  126. return outputBuilder.toString();
  127. }
  128. /**
  129. * Replaces the short forms in the address by their longer forms, so that
  130. * TTS speaks the addresses properly
  131. *
  132. * @param addr The address from which to replace short forms
  133. * @return the modified address string
  134. */
  135. public static String extendShorts(String addr) {
  136. addr = addr.replace("St,", "Street");
  137. addr = addr.replace("St.", "Street");
  138. addr = addr.replace("Rd", "Road");
  139. addr = addr.replace("Fwy", "Freeway");
  140. addr = addr.replace("Pkwy", "Parkway");
  141. addr = addr.replace("Blvd", "Boulevard");
  142. addr = addr.replace("Expy", "Expressway");
  143. addr = addr.replace("Ave", "Avenue");
  144. addr = addr.replace("Dr", "Drive");
  145. return addr;
  146. }
  147. }