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

/shell/src/com/google/marvin/shell/StreetLocator.java

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