Skip to content

Commit 8f6164f

Browse files
committed
Use OSM Nominatim, properly format addresses
1 parent 42b332a commit 8f6164f

File tree

4 files changed

+113
-66
lines changed

4 files changed

+113
-66
lines changed

build.gradle

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2015 µg Project Team
2+
* Copyright 2014-2017 microG Project Team
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,26 +16,50 @@
1616

1717
buildscript {
1818
repositories {
19-
mavenCentral()
19+
jcenter()
2020
}
2121
dependencies {
22-
classpath 'com.android.tools.build:gradle:1.1.3'
22+
classpath 'com.android.tools.build:gradle:2.2.3'
2323
}
2424
}
2525

2626
apply plugin: 'com.android.application'
2727

28+
String getMyVersionName() {
29+
def stdout = new ByteArrayOutputStream()
30+
if (rootProject.file("gradlew").exists())
31+
exec { commandLine 'git', 'describe', '--tags', '--always', '--dirty'; standardOutput = stdout }
32+
else // automatic build system, don't tag dirty
33+
exec { commandLine 'git', 'describe', '--tags', '--always'; standardOutput = stdout }
34+
return stdout.toString().trim().substring(1)
35+
}
36+
37+
int getMyVersionCode() {
38+
def stdout = new ByteArrayOutputStream()
39+
exec {
40+
commandLine 'git', 'rev-list', '--count', "HEAD"
41+
standardOutput = stdout
42+
}
43+
return Integer.parseInt(stdout.toString().trim())
44+
}
45+
2846
repositories {
2947
mavenCentral()
3048
}
3149

3250
dependencies {
33-
compile 'org.microg:unifiednlp-api:1.3.2'
51+
compile 'org.microg:unifiednlp-api:1.5.3'
52+
compile 'org.microg:address-formatter:0.1'
3453
}
3554

3655
android {
37-
compileSdkVersion 22
38-
buildToolsVersion "22.0.0"
56+
compileSdkVersion 24
57+
buildToolsVersion "24.0.3"
58+
59+
defaultConfig {
60+
versionName getMyVersionName()
61+
versionCode(20000 + getMyVersionCode())
62+
}
3963
}
4064

4165
if (file('user.gradle').exists()) {

gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip

src/main/AndroidManifest.xml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3-
android:versionName="1.1.1"
4-
android:versionCode="10101"
5-
package="org.microg.nlp.backend.nominatim">
2+
<manifest package="org.microg.nlp.backend.nominatim"
3+
xmlns:android="http://schemas.android.com/apk/res/android">
64

75
<uses-permission android:name="android.permission.INTERNET"/>
86

97
<uses-sdk
108
android:minSdkVersion="9"
11-
android:targetSdkVersion="22"/>
9+
android:targetSdkVersion="23"/>
1210
<application
1311
android:allowBackup="false"
1412
android:icon="@drawable/ic_launcher"

src/main/java/org/microg/nlp/backend/nominatim/BackendService.java

Lines changed: 79 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,52 @@
1+
/*
2+
* Copyright 2013-2016 microG Project Team
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+
117
package org.microg.nlp.backend.nominatim;
218

319
import android.content.Context;
4-
import android.content.pm.PackageManager;
520
import android.location.Address;
621
import android.net.Uri;
7-
import android.os.Build;
822
import android.util.Log;
923

1024
import org.json.JSONArray;
1125
import org.json.JSONException;
1226
import org.json.JSONObject;
27+
import org.microg.address.Formatter;
1328
import org.microg.nlp.api.GeocoderBackendService;
1429

1530
import java.io.ByteArrayOutputStream;
1631
import java.io.IOException;
1732
import java.io.InputStream;
1833
import java.net.HttpURLConnection;
1934
import java.net.URL;
20-
import java.net.URLConnection;
2135
import java.util.ArrayList;
36+
import java.util.HashMap;
37+
import java.util.Iterator;
2238
import java.util.List;
2339
import java.util.Locale;
40+
import java.util.Map;
2441
import java.util.concurrent.atomic.AtomicBoolean;
2542

43+
import static android.os.Build.VERSION.RELEASE;
44+
import static org.microg.nlp.backend.nominatim.BuildConfig.VERSION_NAME;
45+
2646
public class BackendService extends GeocoderBackendService {
27-
private static final String TAG = "NominatimGeocoderBackend";
47+
private static final String TAG = "NominatimBackend";
2848
private static final String SERVICE_URL_MAPQUEST = "http://open.mapquestapi.com/nominatim/v1/";
29-
private static final String SERVICE_URL_OSM = " http://nominatim.openstreetmap.org/";
49+
private static final String SERVICE_URL_OSM = "http://nominatim.openstreetmap.org/";
3050
private static final String REVERSE_GEOCODE_URL =
3151
"%sreverse?format=json&accept-language=%s&lat=%f&lon=%f";
3252
private static final String SEARCH_GEOCODE_URL =
@@ -48,10 +68,22 @@ public class BackendService extends GeocoderBackendService {
4868
private static final String WIRE_COUNTRYNAME = "country";
4969
private static final String WIRE_COUNTRYCODE = "country_code";
5070

71+
private Formatter formatter;
72+
73+
@Override
74+
public void onCreate() {
75+
super.onCreate();
76+
try {
77+
formatter = new Formatter();
78+
} catch (IOException e) {
79+
Log.w(TAG, "Could not initialize address formatter", e);
80+
}
81+
}
82+
5183
@Override
5284
protected List<Address> getFromLocation(double latitude, double longitude, int maxResults,
53-
String locale) {
54-
String url = String.format(Locale.US, REVERSE_GEOCODE_URL, SERVICE_URL_MAPQUEST,
85+
String locale) {
86+
String url = String.format(Locale.US, REVERSE_GEOCODE_URL, SERVICE_URL_OSM,
5587
locale.split("_")[0], latitude, longitude);
5688
try {
5789
JSONObject result = new JSONObject(new AsyncGetRequest(this,
@@ -82,16 +114,16 @@ private static Locale localeFromLocaleString(String localeString) {
82114

83115
@Override
84116
protected List<Address> getFromLocationName(String locationName, int maxResults,
85-
double lowerLeftLatitude, double lowerLeftLongitude, double upperRightLatitude,
86-
double upperRightLongitude, String locale) {
117+
double lowerLeftLatitude, double lowerLeftLongitude, double upperRightLatitude,
118+
double upperRightLongitude, String locale) {
87119
String query = Uri.encode(locationName);
88120
String url;
89121
if (lowerLeftLatitude == 0 && lowerLeftLongitude == 0 && upperRightLatitude == 0 &&
90122
upperRightLongitude == 0) {
91-
url = String.format(Locale.US, SEARCH_GEOCODE_URL, SERVICE_URL_MAPQUEST,
123+
url = String.format(Locale.US, SEARCH_GEOCODE_URL, SERVICE_URL_OSM,
92124
locale.split("_")[0], query, maxResults);
93125
} else {
94-
url = String.format(Locale.US, SEARCH_GEOCODE_WITH_BOX_URL, SERVICE_URL_MAPQUEST,
126+
url = String.format(Locale.US, SEARCH_GEOCODE_WITH_BOX_URL, SERVICE_URL_OSM,
95127
locale.split("_")[0], query, maxResults, lowerLeftLongitude,
96128
upperRightLatitude, upperRightLongitude, lowerLeftLatitude);
97129
}
@@ -121,49 +153,54 @@ private Address parseResponse(Locale locale, JSONObject result) throws JSONExcep
121153
address.setLatitude(result.getDouble(WIRE_LATITUDE));
122154
address.setLongitude(result.getDouble(WIRE_LONGITUDE));
123155

124-
int line = 0;
125156
JSONObject a = result.getJSONObject(WIRE_ADDRESS);
126157

127-
if (a.has(WIRE_THOROUGHFARE)) {
128-
address.setAddressLine(line++, a.getString(WIRE_THOROUGHFARE));
129-
address.setThoroughfare(a.getString(WIRE_THOROUGHFARE));
130-
}
131-
if (a.has(WIRE_SUBLOCALITY)) {
132-
address.setSubLocality(a.getString(WIRE_SUBLOCALITY));
133-
}
134-
if (a.has(WIRE_POSTALCODE)) {
135-
address.setAddressLine(line++, a.getString(WIRE_POSTALCODE));
136-
address.setPostalCode(a.getString(WIRE_POSTALCODE));
137-
}
158+
address.setThoroughfare(a.optString(WIRE_THOROUGHFARE));
159+
address.setSubLocality(a.optString(WIRE_SUBLOCALITY));
160+
address.setPostalCode(a.optString(WIRE_POSTALCODE));
161+
address.setSubAdminArea(a.optString(WIRE_SUBADMINAREA));
162+
address.setAdminArea(a.optString(WIRE_ADMINAREA));
163+
address.setCountryName(a.optString(WIRE_COUNTRYNAME));
164+
address.setCountryCode(a.optString(WIRE_COUNTRYCODE));
165+
138166
if (a.has(WIRE_LOCALITY_CITY)) {
139-
address.setAddressLine(line++, a.getString(WIRE_LOCALITY_CITY));
140167
address.setLocality(a.getString(WIRE_LOCALITY_CITY));
141168
} else if (a.has(WIRE_LOCALITY_TOWN)) {
142-
address.setAddressLine(line++, a.getString(WIRE_LOCALITY_TOWN));
143169
address.setLocality(a.getString(WIRE_LOCALITY_TOWN));
144170
} else if (a.has(WIRE_LOCALITY_VILLAGE)) {
145-
address.setAddressLine(line++, a.getString(WIRE_LOCALITY_VILLAGE));
146171
address.setLocality(a.getString(WIRE_LOCALITY_VILLAGE));
147172
}
148-
if (a.has(WIRE_SUBADMINAREA)) {
149-
address.setAddressLine(line++, a.getString(WIRE_SUBADMINAREA));
150-
address.setSubAdminArea(a.getString(WIRE_SUBADMINAREA));
151-
}
152-
if (a.has(WIRE_ADMINAREA)) {
153-
address.setAddressLine(line++, a.getString(WIRE_ADMINAREA));
154-
address.setAdminArea(a.getString(WIRE_ADMINAREA));
155-
}
156-
if (a.has(WIRE_COUNTRYNAME)) {
157-
address.setAddressLine(line++, a.getString(WIRE_COUNTRYNAME));
158-
address.setCountryName(a.getString(WIRE_COUNTRYNAME));
159-
}
160-
if (a.has(WIRE_COUNTRYCODE)) {
161-
address.setCountryCode(a.getString(WIRE_COUNTRYCODE));
173+
174+
if (formatter != null) {
175+
Map<String, String> components = new HashMap<>();
176+
for (String s : new IterableIterator<>(a.keys())) {
177+
components.put(s, String.valueOf(a.get(s)));
178+
}
179+
String[] split = formatter.formatAddress(components).split("\n");
180+
for (int i = 0; i < split.length; i++) {
181+
Log.d(TAG, split[i]);
182+
address.setAddressLine(i, split[i]);
183+
}
184+
185+
//address.setFeatureName(formatter.guessName(components));
162186
}
163187

164188
return address;
165189
}
166190

191+
private class IterableIterator<T> implements Iterable<T> {
192+
Iterator<T> i;
193+
194+
public IterableIterator(Iterator<T> i) {
195+
this.i = i;
196+
}
197+
198+
@Override
199+
public Iterator<T> iterator() {
200+
return i;
201+
}
202+
}
203+
167204
private class AsyncGetRequest extends Thread {
168205
public static final String USER_AGENT = "User-Agent";
169206
public static final String USER_AGENT_TEMPLATE = "UnifiedNlp/%s (Linux; Android %s)";
@@ -182,9 +219,8 @@ public void run() {
182219
synchronized (done) {
183220
try {
184221
Log.d(TAG, "Requesting " + url);
185-
HttpURLConnection connection = (HttpURLConnection) new URL(url)
186-
.openConnection();
187-
setUserAgentOnConnection(connection);
222+
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
223+
connection.setRequestProperty(USER_AGENT, String.format(USER_AGENT_TEMPLATE, VERSION_NAME, RELEASE));
188224
connection.setDoInput(true);
189225
InputStream inputStream = connection.getInputStream();
190226
result = readStreamToEnd(inputStream);
@@ -220,17 +256,6 @@ public String retrieveString() {
220256
return new String(retrieveAllBytes());
221257
}
222258

223-
private void setUserAgentOnConnection(URLConnection connection) {
224-
try {
225-
connection.setRequestProperty(USER_AGENT, String.format(USER_AGENT_TEMPLATE,
226-
context.getPackageManager().getPackageInfo(context.getPackageName(),
227-
0).versionName, Build.VERSION.RELEASE));
228-
} catch (PackageManager.NameNotFoundException e) {
229-
connection.setRequestProperty(USER_AGENT, String.format(USER_AGENT_TEMPLATE, 0,
230-
Build.VERSION.RELEASE));
231-
}
232-
}
233-
234259
private byte[] readStreamToEnd(InputStream is) throws IOException {
235260
ByteArrayOutputStream bos = new ByteArrayOutputStream();
236261
if (is != null) {

0 commit comments

Comments
 (0)