Skip to content

Commit

Permalink
Add support for getFromLocationName
Browse files Browse the repository at this point in the history
  • Loading branch information
mar-v-in committed Jan 30, 2015
1 parent 9e620c8 commit c9583d8
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 60 deletions.
48 changes: 24 additions & 24 deletions AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionName="1.0.0"
android:versionCode="1000"
package="org.microg.nlp.backend.nominatim">
android:versionName="1.1.0"
android:versionCode="1100"
package="org.microg.nlp.backend.nominatim">

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="19" />
<application
android:allowBackup="false"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
<service
android:name=".BackendService"
android:label="MapQuest Nominatim Backend">
<intent-filter>
<action android:name="org.microg.nlp.GEOCODER_BACKEND" />
</intent-filter>
</service>
</application>
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="21"/>
<application
android:allowBackup="false"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
<service
android:name=".BackendService"
android:label="Nominatim Backend">
<intent-filter>
<action android:name="org.microg.nlp.GEOCODER_BACKEND"/>
</intent-filter>
</service>
</application>
</manifest>
159 changes: 123 additions & 36 deletions src/org/microg/nlp/backend/nominatim/BackendService.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package org.microg.nlp.backend.nominatim;

import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Address;
import android.net.Uri;
import android.os.Build;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.microg.nlp.api.GeocoderBackendService;
Expand All @@ -18,13 +21,19 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;

public class BackendService extends GeocoderBackendService {
private static final String TAG = BackendService.class.getName();
private static final String TAG = "NominatimGeocoderBackend";
private static final String SERVICE_URL_MAPQUEST = "http://open.mapquestapi.com/nominatim/v1/";
private static final String SERVICE_URL_OSM = " http://nominatim.openstreetmap.org/";
private static final String REVERSE_GEOCODE_URL =
"%sreverse?format=json&accept-language=%s&lat=%f&lon=%f";
private static final String SEARCH_GEOCODE_URL =
"%ssearch?format=json&accept-language=%s&addressdetails=1&bounded=1&q=%s&limit=%d";
private static final String SEARCH_GEOCODE_WITH_BOX_URL =
"%ssearch?format=json&accept-language=%s&addressdetails=1&bounded=1&q=%s&limit=%d" +
"&viewbox=%f,%f,%f,%f";
private static final String WIRE_LATITUDE = "lat";
private static final String WIRE_LONGITUDE = "lon";
private static final String WIRE_ADDRESS = "address";
Expand All @@ -45,51 +54,20 @@ protected List<Address> getFromLocation(double latitude, double longitude, int m
String url = String.format(Locale.US, REVERSE_GEOCODE_URL, SERVICE_URL_MAPQUEST,
locale.split("_")[0], latitude, longitude);
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
setUserAgentOnConnection(connection);
connection.setDoInput(true);
InputStream inputStream = connection.getInputStream();
JSONObject result = new JSONObject(new String(readStreamToEnd(inputStream)));
JSONObject result = new JSONObject(new AsyncGetRequest(this,
url).asyncStart().retrieveString());
Address address = parseResponse(localeFromLocaleString(locale), result);
if (address != null) {
List<Address> addresses = new ArrayList<Address>();
List<Address> addresses = new ArrayList<>();
addresses.add(address);
return addresses;
}
} catch (IOException | JSONException e) {
} catch (Exception e) {
Log.w(TAG, e);
}
return null;
}

public static byte[] readStreamToEnd(InputStream is) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
if (is != null) {
byte[] buff = new byte[1024];
while (true) {
int nb = is.read(buff);
if (nb < 0) {
break;
}
bos.write(buff, 0, nb);
}
is.close();
}
return bos.toByteArray();
}

public void setUserAgentOnConnection(URLConnection connection) {
try {
connection.setRequestProperty("User-Agent",
String.format("UnifiedNlp/%s (Linux; Android %s)",
getPackageManager().getPackageInfo(getPackageName(), 0).versionName,
Build.VERSION.RELEASE));
} catch (PackageManager.NameNotFoundException e) {
connection.setRequestProperty("User-Agent",
String.format("UnifiedNlp (Linux; Android %s)", Build.VERSION.RELEASE));
}
}

private static Locale localeFromLocaleString(String localeString) {
String[] split = localeString.split("_");
if (split.length == 1) {
Expand All @@ -106,6 +84,31 @@ private static Locale localeFromLocaleString(String localeString) {
protected List<Address> getFromLocationName(String locationName, int maxResults,
double lowerLeftLatitude, double lowerLeftLongitude, double upperRightLatitude,
double upperRightLongitude, String locale) {
String query = Uri.encode(locationName);
String url;
if (lowerLeftLatitude == 0 && lowerLeftLongitude == 0 && upperRightLatitude == 0 &&
upperRightLongitude == 0) {
url = String.format(Locale.US, SEARCH_GEOCODE_URL, SERVICE_URL_MAPQUEST,
locale.split("_")[0], query, maxResults);
} else {
url = String.format(Locale.US, SEARCH_GEOCODE_WITH_BOX_URL, SERVICE_URL_MAPQUEST,
locale.split("_")[0], query, maxResults, lowerLeftLongitude,
upperRightLatitude, upperRightLongitude, lowerLeftLatitude);
}
try {
JSONArray result = new JSONArray(new AsyncGetRequest(this,
url).asyncStart().retrieveString());
List<Address> addresses = new ArrayList<>();
for (int i = 0; i < result.length(); i++) {
Address address = parseResponse(localeFromLocaleString(locale),
result.getJSONObject(i));
if (address != null)
addresses.add(address);
}
if (!addresses.isEmpty()) return addresses;
} catch (Exception e) {
Log.w(TAG, e);
}
return null;
}

Expand Down Expand Up @@ -160,4 +163,88 @@ private Address parseResponse(Locale locale, JSONObject result) throws JSONExcep

return address;
}

private class AsyncGetRequest extends Thread {
public static final String USER_AGENT = "User-Agent";
public static final String USER_AGENT_TEMPLATE = "UnifiedNlp/%s (Linux; Android %s)";
private final AtomicBoolean done = new AtomicBoolean(false);
private final Context context;
private final String url;
private byte[] result;

private AsyncGetRequest(Context context, String url) {
this.context = context;
this.url = url;
}

@Override
public void run() {
synchronized (done) {
try {
Log.d(TAG, "Requesting " + url);
HttpURLConnection connection = (HttpURLConnection) new URL(url)
.openConnection();
setUserAgentOnConnection(connection);
connection.setDoInput(true);
InputStream inputStream = connection.getInputStream();
result = readStreamToEnd(inputStream);
} catch (Exception e) {
Log.w(TAG, e);
}
done.set(true);
done.notifyAll();
}
}

public AsyncGetRequest asyncStart() {
start();
return this;
}

public byte[] retrieveAllBytes() {
if (!done.get()) {
synchronized (done) {
while (!done.get()) {
try {
done.wait();
} catch (InterruptedException e) {
break;
}
}
}
}
return result;
}

public String retrieveString() {
return new String(retrieveAllBytes());
}

private void setUserAgentOnConnection(URLConnection connection) {
try {
connection.setRequestProperty(USER_AGENT, String.format(USER_AGENT_TEMPLATE,
context.getPackageManager().getPackageInfo(context.getPackageName(),
0).versionName, Build.VERSION.RELEASE));
} catch (PackageManager.NameNotFoundException e) {
connection.setRequestProperty(USER_AGENT, String.format(USER_AGENT_TEMPLATE, 0,
Build.VERSION.RELEASE));
}
}

private byte[] readStreamToEnd(InputStream is) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
if (is != null) {
byte[] buff = new byte[1024];
while (true) {
int nb = is.read(buff);
if (nb < 0) {
break;
}
bos.write(buff, 0, nb);
}
is.close();
}
return bos.toByteArray();
}
}
}

0 comments on commit c9583d8

Please sign in to comment.