Geocoder.java revision 34901409a404c8c66914c5a8ad0f29b1bcde0e78
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of 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,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.location;
18
19import android.content.Context;
20import android.location.Address;
21import android.os.RemoteException;
22import android.os.IBinder;
23import android.os.ServiceManager;
24import android.util.Log;
25
26import java.io.IOException;
27import java.util.Locale;
28import java.util.ArrayList;
29import java.util.List;
30
31/**
32 * A class for handling geocoding and reverse geocoding.  Geocoding is
33 * the process of transforming a street address or other description
34 * of a location into a (latitude, longitude) coordinate.  Reverse
35 * geocoding is the process of transforming a (latitude, longitude)
36 * coordinate into a (partial) address.  The amount of detail in a
37 * reverse geocoded location description may vary, for example one
38 * might contain the full street address of the closest building, while
39 * another might contain only a city name and postal code.
40 *
41 * The Geocoder class requires a backend service that is not included in
42 * the core android framework.  The Geocoder query methods will return an
43 * empty list if there no backend service in the platform.
44 */
45public final class Geocoder {
46    private static final String TAG = "Geocoder";
47
48    private GeocoderParams mParams;
49    private ILocationManager mService;
50
51    /**
52     * Constructs a Geocoder whose responses will be localized for the
53     * given Locale.
54     *
55     * @param context the Context of the calling Activity
56     * @param locale the desired Locale for the query results
57     *
58     * @throws NullPointerException if Locale is null
59     */
60    public Geocoder(Context context, Locale locale) {
61        if (locale == null) {
62            throw new NullPointerException("locale == null");
63        }
64        mParams = new GeocoderParams(context, locale);
65        IBinder b = ServiceManager.getService(Context.LOCATION_SERVICE);
66        mService = ILocationManager.Stub.asInterface(b);
67    }
68
69    /**
70     * Constructs a Geocoder whose responses will be localized for the
71     * default system Locale.
72     *
73     * @param context the Context of the calling Activity
74     */
75    public Geocoder(Context context) {
76        this(context, Locale.getDefault());
77    }
78
79    /**
80     * Returns an array of Addresses that are known to describe the
81     * area immediately surrounding the given latitude and longitude.
82     * The returned addresses will be localized for the locale
83     * provided to this class's constructor.
84     *
85     * <p> The returned values may be obtained by means of a network lookup.
86     * The results are a best guess and are not guaranteed to be meaningful or
87     * correct. It may be useful to call this method from a thread separate from your
88     * primary UI thread.
89     *
90     * @param latitude the latitude a point for the search
91     * @param longitude the longitude a point for the search
92     * @param maxResults max number of addresses to return. Smaller numbers (1 to 5) are recommended
93     *
94     * @return a list of Address objects. Returns null or empty list if no matches were
95     * found or there is no backend service available.
96     *
97     * @throws IllegalArgumentException if latitude is
98     * less than -90 or greater than 90
99     * @throws IllegalArgumentException if longitude is
100     * less than -180 or greater than 180
101     * @throws IOException if the network is unavailable or any other
102     * I/O problem occurs
103     */
104    public List<Address> getFromLocation(double latitude, double longitude, int maxResults)
105        throws IOException {
106        if (latitude < -90.0 || latitude > 90.0) {
107            throw new IllegalArgumentException("latitude == " + latitude);
108        }
109        if (longitude < -180.0 || longitude > 180.0) {
110            throw new IllegalArgumentException("longitude == " + longitude);
111        }
112        try {
113            List<Address> results = new ArrayList<Address>();
114            String ex =  mService.getFromLocation(latitude, longitude, maxResults,
115                mParams, results);
116            if (ex != null) {
117                throw new IOException(ex);
118            } else {
119                return results;
120            }
121        } catch (RemoteException e) {
122            Log.e(TAG, "getFromLocation: got RemoteException", e);
123            return null;
124        }
125    }
126
127    /**
128     * Returns an array of Addresses that are known to describe the
129     * named location, which may be a place name such as "Dalvik,
130     * Iceland", an address such as "1600 Amphitheatre Parkway,
131     * Mountain View, CA", an airport code such as "SFO", etc..  The
132     * returned addresses will be localized for the locale provided to
133     * this class's constructor.
134     *
135     * <p> The query will block and returned values will be obtained by means of a network lookup.
136     * The results are a best guess and are not guaranteed to be meaningful or
137     * correct. It may be useful to call this method from a thread separate from your
138     * primary UI thread.
139     *
140     * @param locationName a user-supplied description of a location
141     * @param maxResults max number of results to return. Smaller numbers (1 to 5) are recommended
142     *
143     * @return a list of Address objects. Returns null or empty list if no matches were
144     * found or there is no backend service available.
145     *
146     * @throws IllegalArgumentException if locationName is null
147     * @throws IOException if the network is unavailable or any other
148     * I/O problem occurs
149     */
150    public List<Address> getFromLocationName(String locationName, int maxResults) throws IOException {
151        if (locationName == null) {
152            throw new IllegalArgumentException("locationName == null");
153        }
154        try {
155            List<Address> results = new ArrayList<Address>();
156            String ex = mService.getFromLocationName(locationName,
157                0, 0, 0, 0, maxResults, mParams, results);
158            if (ex != null) {
159                throw new IOException(ex);
160            } else {
161                return results;
162            }
163        } catch (RemoteException e) {
164            Log.e(TAG, "getFromLocationName: got RemoteException", e);
165            return null;
166        }
167    }
168
169    /**
170     * Returns an array of Addresses that are known to describe the
171     * named location, which may be a place name such as "Dalvik,
172     * Iceland", an address such as "1600 Amphitheatre Parkway,
173     * Mountain View, CA", an airport code such as "SFO", etc..  The
174     * returned addresses will be localized for the locale provided to
175     * this class's constructor.
176     *
177     * <p> You may specify a bounding box for the search results by including
178     * the Latitude and Longitude of the Lower Left point and Upper Right
179     * point of the box.
180     *
181     * <p> The query will block and returned values will be obtained by means of a network lookup.
182     * The results are a best guess and are not guaranteed to be meaningful or
183     * correct. It may be useful to call this method from a thread separate from your
184     * primary UI thread.
185     *
186     * @param locationName a user-supplied description of a location
187     * @param maxResults max number of addresses to return. Smaller numbers (1 to 5) are recommended
188     * @param lowerLeftLatitude the latitude of the lower left corner of the bounding box
189     * @param lowerLeftLongitude the longitude of the lower left corner of the bounding box
190     * @param upperRightLatitude the latitude of the upper right corner of the bounding box
191     * @param upperRightLongitude the longitude of the upper right corner of the bounding box
192     *
193     * @return a list of Address objects. Returns null or empty list if no matches were
194     * found or there is no backend service available.
195     *
196     * @throws IllegalArgumentException if locationName is null
197     * @throws IllegalArgumentException if any latitude is
198     * less than -90 or greater than 90
199     * @throws IllegalArgumentException if any longitude is
200     * less than -180 or greater than 180
201     * @throws IOException if the network is unavailable or any other
202     * I/O problem occurs
203     */
204    public List<Address> getFromLocationName(String locationName, int maxResults,
205        double lowerLeftLatitude, double lowerLeftLongitude,
206        double upperRightLatitude, double upperRightLongitude) throws IOException {
207        if (locationName == null) {
208            throw new IllegalArgumentException("locationName == null");
209        }
210        if (lowerLeftLatitude < -90.0 || lowerLeftLatitude > 90.0) {
211            throw new IllegalArgumentException("lowerLeftLatitude == "
212                + lowerLeftLatitude);
213        }
214        if (lowerLeftLongitude < -180.0 || lowerLeftLongitude > 180.0) {
215            throw new IllegalArgumentException("lowerLeftLongitude == "
216                + lowerLeftLongitude);
217        }
218        if (upperRightLatitude < -90.0 || upperRightLatitude > 90.0) {
219            throw new IllegalArgumentException("upperRightLatitude == "
220                + upperRightLatitude);
221        }
222        if (upperRightLongitude < -180.0 || upperRightLongitude > 180.0) {
223            throw new IllegalArgumentException("upperRightLongitude == "
224                + upperRightLongitude);
225        }
226        try {
227            ArrayList<Address> result = new ArrayList<Address>();
228            String ex =  mService.getFromLocationName(locationName,
229                lowerLeftLatitude, lowerLeftLongitude, upperRightLatitude, upperRightLongitude,
230                maxResults, mParams, result);
231            if (ex != null) {
232                throw new IOException(ex);
233            } else {
234                return result;
235            }
236        } catch (RemoteException e) {
237            Log.e(TAG, "getFromLocationName: got RemoteException", e);
238            return null;
239        }
240    }
241}
242