diff options
| author | Samuel Tardieu <sam@rfc1149.net> | 2014-12-11 17:40:10 +0100 |
|---|---|---|
| committer | Samuel Tardieu <sam@rfc1149.net> | 2014-12-12 02:27:15 +0100 |
| commit | 22053233129471bd225d9310a104c3c67310acb0 (patch) | |
| tree | 73df4dccd6d45dc6421cf6ce5b328a3de9eab993 | |
| parent | 823abf47ff28e26f4cc794dbd4db4374c38ad3fe (diff) | |
| download | cgeo-22053233129471bd225d9310a104c3c67310acb0.zip cgeo-22053233129471bd225d9310a104c3c67310acb0.tar.gz cgeo-22053233129471bd225d9310a104c3c67310acb0.tar.bz2 | |
Use GC geocoder as last choice
Part of #4522.
| -rw-r--r-- | main/res/values/strings.xml | 1 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/AddressListActivity.java | 18 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/CacheListActivity.java | 8 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/connector/gc/GCParser.java | 24 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/loaders/AddressGeocacheListLoader.java | 23 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/location/GCGeocoder.java | 63 |
6 files changed, 71 insertions, 66 deletions
diff --git a/main/res/values/strings.xml b/main/res/values/strings.xml index 4be3ab6..cf1ab72 100644 --- a/main/res/values/strings.xml +++ b/main/res/values/strings.xml @@ -142,6 +142,7 @@ <string name="err_login">No Login information stored</string> <string name="err_login_failed_toast">c:geo can\'t log in. c:geo works offline with Stored caches. Check Login settings or enable your internet connection.</string> <string name="err_unknown">Unknown error</string> + <string name="err_unknown_address">c:geo was unable to map this address to an existing location</string> <string name="err_comm">Unknown communication error</string> <string name="err_missing_auth">No username and/or password set.</string> <string name="err_wrong">Login information incorrect</string> diff --git a/main/src/cgeo/geocaching/AddressListActivity.java b/main/src/cgeo/geocaching/AddressListActivity.java index f51d37c..48f761b 100644 --- a/main/src/cgeo/geocaching/AddressListActivity.java +++ b/main/src/cgeo/geocaching/AddressListActivity.java @@ -2,8 +2,10 @@ package cgeo.geocaching; import cgeo.geocaching.activity.AbstractListActivity; import cgeo.geocaching.location.AndroidGeocoder; +import cgeo.geocaching.location.GCGeocoder; import cgeo.geocaching.ui.AddressListAdapter; +import rx.Observable; import rx.android.observables.AndroidObservable; import rx.functions.Action1; @@ -19,28 +21,20 @@ public class AddressListActivity extends AbstractListActivity { public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState, R.layout.addresslist_activity); - // get parameters - final String keyword = getIntent().getStringExtra(Intents.EXTRA_KEYWORD); - - if (keyword == null) { - showToast(res.getString(R.string.err_search_address_forgot)); - finish(); - return; - } final AddressListAdapter adapter = new AddressListAdapter(this); setListAdapter(adapter); + final String keyword = getIntent().getStringExtra(Intents.EXTRA_KEYWORD); final ProgressDialog waitDialog = ProgressDialog.show(this, res.getString(R.string.search_address_started), keyword, true); waitDialog.setCancelable(true); - lookupAddressInBackground(keyword, adapter, waitDialog); } private void lookupAddressInBackground(final String keyword, final AddressListAdapter adapter, final ProgressDialog waitDialog) { - final AndroidGeocoder geocoder = new AndroidGeocoder(this); - AndroidObservable.bindActivity(this, geocoder.getFromLocationName(keyword).toList()).subscribe(new Action1<List<Address>>() { + final Observable<Address> geocoderObservable = new AndroidGeocoder(this).getFromLocationName(keyword).onErrorResumeNext(GCGeocoder.getFromLocationName(keyword)); + AndroidObservable.bindActivity(this, geocoderObservable.toList()).subscribe(new Action1<List<Address>>() { @Override public void call(final List<Address> addresses) { waitDialog.dismiss(); @@ -52,7 +46,7 @@ public class AddressListActivity extends AbstractListActivity { @Override public void call(final Throwable throwable) { finish(); - CacheListActivity.startActivityAddress(AddressListActivity.this, null, keyword); + showToast(res.getString(R.string.err_unknown_address)); } }); } diff --git a/main/src/cgeo/geocaching/CacheListActivity.java b/main/src/cgeo/geocaching/CacheListActivity.java index c8f1101..1b6a268 100644 --- a/main/src/cgeo/geocaching/CacheListActivity.java +++ b/main/src/cgeo/geocaching/CacheListActivity.java @@ -27,7 +27,6 @@ import cgeo.geocaching.list.PseudoList; import cgeo.geocaching.list.StoredList; import cgeo.geocaching.loaders.AbstractSearchLoader; import cgeo.geocaching.loaders.AbstractSearchLoader.CacheListLoaderType; -import cgeo.geocaching.loaders.AddressGeocacheListLoader; import cgeo.geocaching.loaders.CoordsGeocacheListLoader; import cgeo.geocaching.loaders.FinderGeocacheListLoader; import cgeo.geocaching.loaders.HistoryGeocacheListLoader; @@ -1549,12 +1548,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA } else { title = coords.toString(); } - if (coords != null) { - loader = new CoordsGeocacheListLoader(app, coords); - } - else { - loader = new AddressGeocacheListLoader(app, address); - } + loader = new CoordsGeocacheListLoader(app, coords); break; case FINDER: final String username = extras.getString(Intents.EXTRA_USERNAME); diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java index 33447c7..da63bbd 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCParser.java +++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java @@ -940,30 +940,6 @@ public abstract class GCParser { return searchByAny(cacheType, isSearchForMyCaches(userName), showCaptcha, params, recaptchaReceiver); } - public static SearchResult searchByAddress(final String address, final CacheType cacheType, final boolean showCaptcha, final RecaptchaReceiver recaptchaReceiver) { - if (StringUtils.isBlank(address)) { - Log.e("GCParser.searchByAddress: No address given"); - return null; - } - - final ObjectNode response = Network.requestJSON("http://www.geocaching.com/api/geocode", new Parameters("q", address)); - if (response == null) { - return null; - } - - if (!StringUtils.equalsIgnoreCase(response.path("status").asText(), "success")) { - return null; - } - - final JsonNode data = response.path("data"); - final JsonNode latNode = data.get("lat"); - final JsonNode lngNode = data.get("lng"); - if (latNode == null || lngNode == null) { - return null; - } - return searchByCoords(new Geopoint(latNode.asDouble(), lngNode.asDouble()), cacheType, showCaptcha, recaptchaReceiver); - } - @Nullable public static Trackable searchTrackable(final String geocode, final String guid, final String id) { if (StringUtils.isBlank(geocode) && StringUtils.isBlank(guid) && StringUtils.isBlank(id)) { diff --git a/main/src/cgeo/geocaching/loaders/AddressGeocacheListLoader.java b/main/src/cgeo/geocaching/loaders/AddressGeocacheListLoader.java deleted file mode 100644 index e1573c9..0000000 --- a/main/src/cgeo/geocaching/loaders/AddressGeocacheListLoader.java +++ /dev/null @@ -1,23 +0,0 @@ -package cgeo.geocaching.loaders; - -import cgeo.geocaching.SearchResult; -import cgeo.geocaching.connector.gc.GCParser; -import cgeo.geocaching.settings.Settings; - -import android.content.Context; - -public class AddressGeocacheListLoader extends AbstractSearchLoader { - - private final String address; - - public AddressGeocacheListLoader(Context context, String address) { - super(context); - this.address = address; - } - - @Override - public SearchResult runSearch() { - return GCParser.searchByAddress(address, Settings.getCacheType(), Settings.isShowCaptcha(), this); - } - -} diff --git a/main/src/cgeo/geocaching/location/GCGeocoder.java b/main/src/cgeo/geocaching/location/GCGeocoder.java new file mode 100644 index 0000000..1591523 --- /dev/null +++ b/main/src/cgeo/geocaching/location/GCGeocoder.java @@ -0,0 +1,63 @@ +package cgeo.geocaching.location; + +import cgeo.geocaching.network.Network; +import cgeo.geocaching.network.Parameters; +import cgeo.geocaching.settings.Settings; +import cgeo.geocaching.utils.Log; +import cgeo.geocaching.utils.RxUtils; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.jdt.annotation.NonNull; + +import rx.Observable; +import rx.functions.Func0; + +import android.location.Address; + +import java.util.Locale; + +public class GCGeocoder { + + private GCGeocoder() { + // Do not instantiate + } + + /** + * Retrieve addresses from a textual location using geocaching.com geocoding API. The works happens on the network scheduler. + * + * @param address the location + * @return an observable containing zero or more locations + * + * @see android.location.Geocoder#getFromLocationName(String, int) + */ + public static Observable<Address> getFromLocationName(@NonNull final String address) { + return Observable.defer(new Func0<Observable<Address>>() { + @Override + public Observable<Address> call() { + if (!Settings.isGCConnectorActive()) { + return Observable.error(new RuntimeException("geocaching.com connector is not active")); + } + final ObjectNode response = Network.requestJSON("https://www.geocaching.com/api/geocode", new Parameters("q", address)); + if (response == null || !StringUtils.equalsIgnoreCase(response.path("status").asText(), "success")) { + return Observable.error(new RuntimeException("unable to use geocaching.com geocoder")); + } + + final JsonNode data = response.path("data"); + final Address geocodedAddress = new Address(Locale.getDefault()); + try { + geocodedAddress.setLatitude(data.get("lat").asDouble()); + geocodedAddress.setLongitude(data.get("lng").asDouble()); + geocodedAddress.setAddressLine(0, address); + return Observable.just(geocodedAddress); + } catch (final Exception e) { + Log.e("unable to decode answer from geocaching.com geocoder", e); + return Observable.error(e); + } + } + }).subscribeOn(RxUtils.networkScheduler); + } + +} |
