summaryrefslogtreecommitdiffstats
path: root/src/com/android/dialer/lookup/openstreetmap/OpenStreetMapForwardLookup.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/dialer/lookup/openstreetmap/OpenStreetMapForwardLookup.java')
-rw-r--r--src/com/android/dialer/lookup/openstreetmap/OpenStreetMapForwardLookup.java190
1 files changed, 190 insertions, 0 deletions
diff --git a/src/com/android/dialer/lookup/openstreetmap/OpenStreetMapForwardLookup.java b/src/com/android/dialer/lookup/openstreetmap/OpenStreetMapForwardLookup.java
new file mode 100644
index 000000000..5bd5e723f
--- /dev/null
+++ b/src/com/android/dialer/lookup/openstreetmap/OpenStreetMapForwardLookup.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2014 The OmniROM Project
+ * Copyright (C) 2014 Xiao-Long Chen <chillermillerlong@hotmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Partially based on OmniROM's implementation
+
+package com.android.dialer.lookup.openstreetmap;
+
+import android.content.Context;
+import android.location.Location;
+import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
+import android.provider.ContactsContract.CommonDataKinds.Website;
+import android.util.Log;
+
+import com.android.dialer.calllog.ContactInfo;
+import com.android.dialer.lookup.ContactBuilder;
+import com.android.dialer.lookup.ForwardLookup;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.util.EntityUtils;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Locale;
+
+public class OpenStreetMapForwardLookup extends ForwardLookup {
+ private static final String TAG =
+ OpenStreetMapForwardLookup.class.getSimpleName();
+
+ /** Search within radius (meters) */
+ private static final int RADIUS = 30000;
+
+ /** Query URL */
+ private static final String LOOKUP_URL =
+ "http://overpass-api.de/api/interpreter";
+
+ private static final String LOOKUP_QUERY =
+ "[out:json];node[name~\"%s\"][phone](around:%d,%f,%f);out body;";
+
+ private static final String RESULT_ELEMENTS = "elements";
+ private static final String RESULT_TAGS = "tags";
+ private static final String TAG_NAME = "name";
+ private static final String TAG_PHONE = "phone";
+ private static final String TAG_HOUSENUMBER = "addr:housenumber";
+ private static final String TAG_STREET = "addr:street";
+ private static final String TAG_CITY = "addr:city";
+ private static final String TAG_POSTCODE = "addr:postcode";
+ private static final String TAG_WEBSITE = "website";
+
+ public OpenStreetMapForwardLookup(Context context) {
+ }
+
+ @Override
+ public ContactInfo[] lookup(Context context,
+ String filter, Location lastLocation) {
+
+ // The OSM API doesn't support case-insentive searches, but does
+ // support regular expressions.
+ String regex = "";
+ for (int i = 0; i < filter.length(); i++) {
+ char c = filter.charAt(i);
+ regex += "[" + Character.toUpperCase(c)
+ + Character.toLowerCase(c) + "]";
+ }
+
+ String request = String.format(Locale.ENGLISH, LOOKUP_QUERY, regex,
+ RADIUS, lastLocation.getLatitude(), lastLocation.getLongitude());
+
+ try {
+ String httpResponse = httpPostRequest(request);
+
+ JSONObject results = new JSONObject(httpResponse);
+
+ return getEntries(results);
+ } catch (IOException e) {
+ Log.e(TAG, "Failed to execute query", e);
+ } catch (JSONException e) {
+ Log.e(TAG, "JSON error", e);
+ }
+
+ return null;
+ }
+
+ private ContactInfo[] getEntries(JSONObject results)
+ throws JSONException {
+ ArrayList<ContactInfo> details =
+ new ArrayList<ContactInfo>();
+
+ JSONArray elements = results.getJSONArray(RESULT_ELEMENTS);
+
+ for (int i = 0; i < elements.length(); i++) {
+ try {
+ JSONObject element = elements.getJSONObject(i);
+ JSONObject tags = element.getJSONObject(RESULT_TAGS);
+
+ String displayName = tags.getString(TAG_NAME);
+ String phoneNumber = tags.getString(TAG_PHONE);
+
+ // Take the first number if there are multiple
+ if (phoneNumber.contains(";")) {
+ phoneNumber = phoneNumber.split(";")[0];
+ phoneNumber = phoneNumber.trim();
+ }
+
+ // The address is split
+ String addressHouseNumber =
+ tags.optString(TAG_HOUSENUMBER, null);
+ String addressStreet = tags.optString(TAG_STREET, null);
+ String addressCity = tags.optString(TAG_CITY, null);
+ String addressPostCode = tags.optString(TAG_POSTCODE, null);
+
+ String address = String.format(
+ "%s %s, %s %s",
+ addressHouseNumber != null ? addressHouseNumber : "",
+ addressStreet != null ? addressStreet : "",
+ addressCity != null ? addressCity : "",
+ addressPostCode != null ? addressPostCode : "");
+
+ address = address.trim().replaceAll("\\s+", " ");
+
+ if (address.length() == 0) {
+ address = null;
+ }
+
+ String website = tags.optString(TAG_WEBSITE, null);
+
+ ContactBuilder builder = new ContactBuilder(
+ ContactBuilder.FORWARD_LOOKUP, null, phoneNumber);
+
+ builder.setName(ContactBuilder.Name.createDisplayName(displayName));
+ builder.addPhoneNumber(ContactBuilder.PhoneNumber.createMainNumber(phoneNumber));
+
+ ContactBuilder.Address a = new ContactBuilder.Address();
+ a.formattedAddress = address;
+ a.city = addressCity;
+ a.street = addressStreet;
+ a.postCode = addressPostCode;
+ a.type = StructuredPostal.TYPE_WORK;
+ builder.addAddress(a);
+
+ ContactBuilder.WebsiteUrl w = new ContactBuilder.WebsiteUrl();
+ w.url = website;
+ w.type = Website.TYPE_HOMEPAGE;
+ builder.addWebsite(w);
+
+ builder.setPhotoUri(ContactBuilder.PHOTO_URI_BUSINESS);
+
+ details.add(builder.build());
+ } catch (JSONException e) {
+ Log.e(TAG, "Skipping the suggestions at index " + i, e);
+ }
+ }
+
+ if (details.size() > 0) {
+ return details.toArray(new ContactInfo[details.size()]);
+ } else {
+ return null;
+ }
+ }
+
+ private String httpPostRequest(String query) throws IOException {
+ HttpClient client = new DefaultHttpClient();
+ HttpPost post = new HttpPost(LOOKUP_URL);
+
+ post.setEntity(new StringEntity(query));
+
+ return EntityUtils.toString(client.execute(post).getEntity());
+ }
+}