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+
117package org .microg .nlp .backend .nominatim ;
218
319import android .content .Context ;
4- import android .content .pm .PackageManager ;
520import android .location .Address ;
621import android .net .Uri ;
7- import android .os .Build ;
822import android .util .Log ;
923
1024import org .json .JSONArray ;
1125import org .json .JSONException ;
1226import org .json .JSONObject ;
27+ import org .microg .address .Formatter ;
1328import org .microg .nlp .api .GeocoderBackendService ;
1429
1530import java .io .ByteArrayOutputStream ;
1631import java .io .IOException ;
1732import java .io .InputStream ;
1833import java .net .HttpURLConnection ;
1934import java .net .URL ;
20- import java .net .URLConnection ;
2135import java .util .ArrayList ;
36+ import java .util .HashMap ;
37+ import java .util .Iterator ;
2238import java .util .List ;
2339import java .util .Locale ;
40+ import java .util .Map ;
2441import 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+
2646public 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