PageRenderTime 22ms CodeModel.GetById 10ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/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
 17package com.googlecode.eyesfree.walkytalky;
 18
 19import java.io.BufferedReader;
 20import java.io.IOException;
 21import java.io.InputStream;
 22import java.io.InputStreamReader;
 23import java.net.HttpURLConnection;
 24import java.net.MalformedURLException;
 25import java.net.URL;
 26
 27/**
 28 * This class implements methods to get street address from lat-lon using
 29 * reverse geocoding API through HTTP.
 30 * 
 31 * @author chaitanyag@google.com (Chaitanya Gharpure)
 32 */
 33public class ReverseGeocoder {
 34    /**
 35     * Interface for the callbacks to be used when a street is located
 36     */
 37    public interface OnAddressLocatedListener {
 38        public void onAddressLocated(Address address);
 39    }
 40
 41    private OnAddressLocatedListener cb;
 42
 43    private static final String ENCODING = "UTF-8";
 44
 45    // URL for obtaining reverse geocoded location
 46    private static final String URL_GEO_STRING = "http://maps.google.com/maps/api/geocode/json?sensor=false&latlng=";
 47
 48    public ReverseGeocoder(OnAddressLocatedListener callback) {
 49        cb = callback;
 50    }
 51
 52    /**
 53     * Queries the map server and obtains the reverse geocoded address of the
 54     * specified location.
 55     * 
 56     * @param lat The latitude in degrees
 57     * @param lon The longitude in degrees
 58     */
 59    public void getAddressAsync(double lat, double lon) {
 60        final double latitude = lat;
 61        final double longitude = lon;
 62        /**
 63         * Runnable for fetching the address asynchronously
 64         */
 65        class AddressThread implements Runnable {
 66            public void run() {
 67                cb.onAddressLocated(getAddress(latitude, longitude));
 68            }
 69        }
 70        (new Thread(new AddressThread())).start();
 71    }
 72
 73    /**
 74     * Queries the map server and obtains the reverse geocoded address of the
 75     * specified location.
 76     * 
 77     * @param lat The latitude in degrees
 78     * @param lon The longitude in degrees
 79     * @return Returns the reverse geocoded address
 80     */
 81    public Address getAddress(double lat, double lon) {
 82        try {
 83            String resp = getResult(makeGeoURL(lat, lon));
 84            return new Address(resp);
 85        } catch (MalformedURLException mue) {
 86        } catch (IOException e) {
 87        }
 88        return null;
 89    }
 90
 91    /**
 92     * Sends a request to the specified URL and obtains the result from the
 93     * sever.
 94     * 
 95     * @param url The URL to connect to
 96     * @return the server response
 97     * @throws IOException
 98     */
 99    private String getResult(URL url) throws IOException {
100        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
101        conn.setDoInput(true);
102        conn.setDoOutput(true);
103        InputStream is = conn.getInputStream();
104        String result = toString(is);
105        return result;
106    }
107
108    /**
109     * Prepares the URL to connect to the reverse geocoding server from the
110     * specified location coordinates.
111     * 
112     * @param lat latitude in degrees of the location to reverse geocode
113     * @param lon longitude in degrees of the location to reverse geocode
114     * @return URL The Geo URL created based on the given lat/lon
115     * @throws MalformedURLException
116     */
117    private URL makeGeoURL(double lat, double lon) throws MalformedURLException {
118        StringBuilder url = new StringBuilder();
119        url.append(URL_GEO_STRING).append(lat).append(",").append(lon);
120        return new URL(url.toString());
121    }
122
123    /**
124     * Reads an InputStream and returns its contents as a String.
125     * 
126     * @param inputStream The InputStream to read from.
127     * @return The contents of the InputStream as a String.
128     */
129    private static String toString(InputStream inputStream) throws IOException {
130        StringBuilder outputBuilder = new StringBuilder();
131        String string;
132        if (inputStream != null) {
133            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, ENCODING));
134            while (null != (string = reader.readLine())) {
135                outputBuilder.append(string).append('\n');
136            }
137        }
138        return outputBuilder.toString();
139    }
140
141    /**
142     * Replaces the short forms in the address by their longer forms, so that
143     * TTS speaks the addresses properly
144     * 
145     * @param addr The address from which to replace short forms
146     * @return the modified address string
147     */
148    public static String extendShorts(String addr) {
149        addr = addr.replace("St,", "Street");
150        addr = addr.replace("St.", "Street");
151        addr = addr.replace("Rd", "Road");
152        addr = addr.replace("Fwy", "Freeway");
153        addr = addr.replace("Pkwy", "Parkway");
154        addr = addr.replace("Blvd", "Boulevard");
155        addr = addr.replace("Expy", "Expressway");
156        addr = addr.replace("Ave", "Avenue");
157        addr = addr.replace("Dr", "Drive");
158        return addr;
159    }
160}