From 318e4f037833e3440d1e55b12ff031add93a639a Mon Sep 17 00:00:00 2001 From: Gaurav Vashisth Date: Mon, 29 Jun 2015 19:05:10 +0530 Subject: [PATCH] OSMNavigator geocoding in non ui thread --- OSMNavigator/build.gradle | 3 + .../java/com/osmnavigator/MapActivity.java | 133 ++++++++++++------ 2 files changed, 95 insertions(+), 41 deletions(-) diff --git a/OSMNavigator/build.gradle b/OSMNavigator/build.gradle index 0f615a78..f55b83d9 100644 --- a/OSMNavigator/build.gradle +++ b/OSMNavigator/build.gradle @@ -28,4 +28,7 @@ dependencies { compile "com.android.support:appcompat-v7:22.2.0" compile 'org.osmdroid:osmdroid-android:4.3' compile 'org.slf4j:slf4j-android:1.6.1-RC1' + + compile 'io.reactivex:rxjava:1.0.11' + compile 'io.reactivex:rxandroid:0.24.0' } diff --git a/OSMNavigator/src/main/java/com/osmnavigator/MapActivity.java b/OSMNavigator/src/main/java/com/osmnavigator/MapActivity.java index d2664a9e..6af30e35 100644 --- a/OSMNavigator/src/main/java/com/osmnavigator/MapActivity.java +++ b/OSMNavigator/src/main/java/com/osmnavigator/MapActivity.java @@ -98,6 +98,14 @@ import android.widget.TextView; import android.widget.Toast; +import rx.Observable; +import rx.Subscriber; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.functions.Action1; +import rx.schedulers.Schedulers; +import rx.subscriptions.Subscriptions; + /** * Simple and general-purpose map/navigation Android application, including a KML viewer and editor. * It is based on osmdroid and OSMBonusPack @@ -148,6 +156,8 @@ public class MapActivity extends Activity implements MapEventsReceiver, Location static String PREF_LOCATIONS_KEY = "PREF_LOCATIONS"; OnlineTileSourceBase MAPBOXSATELLITELABELLED; + + private Subscription addressSubscription = Subscriptions.empty(); /** IMPORTANT - these API keys and accounts have been provided EXCLUSIVELY to OSMNavigator application. * Developers of other applications must request their own API key from the corresponding service provider. */ @@ -309,8 +319,7 @@ public void onClick(View view) { setPOITagButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { //Hide the soft keyboard: - InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(poiTagText.getWindowToken(), 0); + hideKeyboard(poiTagText); //Start search: String feature = poiTagText.getText().toString(); if (!feature.equals("")) @@ -516,11 +525,10 @@ public String getAddress(GeoPoint p){ /** * Geocoding of the departure or destination address */ - public void handleSearchButton(int index, int editResId){ + public void handleSearchButton(final int index, int editResId){ EditText locationEdit = (EditText)findViewById(editResId); //Hide the soft keyboard: - InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(locationEdit.getWindowToken(), 0); + hideKeyboard(locationEdit); String locationAddress = locationEdit.getText().toString(); @@ -532,43 +540,86 @@ public void handleSearchButton(int index, int editResId){ Toast.makeText(this, "Searching:\n"+locationAddress, Toast.LENGTH_LONG).show(); AutoCompleteOnPreferences.storePreference(this, locationAddress, SHARED_PREFS_APPKEY, PREF_LOCATIONS_KEY); - GeocoderNominatim geocoder = new GeocoderNominatim(this, userAgent); - geocoder.setOptions(true); //ask for enclosing polygon (if any) - try { - BoundingBoxE6 viewbox = map.getBoundingBox(); - List
foundAdresses = geocoder.getFromLocationName(locationAddress, 1, - viewbox.getLatSouthE6()*1E-6, viewbox.getLonEastE6()*1E-6, - viewbox.getLatNorthE6()*1E-6, viewbox.getLonWestE6()*1E-6, false); - if (foundAdresses.size() == 0) { //if no address found, display an error - Toast.makeText(this, "Address not found.", Toast.LENGTH_SHORT).show(); - } else { - Address address = foundAdresses.get(0); //get first address - String addressDisplayName = address.getExtras().getString("display_name"); - if (index == START_INDEX){ - startPoint = new GeoPoint(address.getLatitude(), address.getLongitude()); - markerStart = updateItineraryMarker(markerStart, startPoint, START_INDEX, - R.string.departure, R.drawable.marker_departure, -1, addressDisplayName); - map.getController().setCenter(startPoint); - } else if (index == DEST_INDEX){ - destinationPoint = new GeoPoint(address.getLatitude(), address.getLongitude()); - markerDestination = updateItineraryMarker(markerDestination, destinationPoint, DEST_INDEX, - R.string.destination, R.drawable.marker_destination, -1, addressDisplayName); - map.getController().setCenter(destinationPoint); - } - getRoadAsync(); - //get and display enclosing polygon: - Bundle extras = address.getExtras(); - if (extras != null && extras.containsKey("polygonpoints")){ - ArrayList polygon = extras.getParcelableArrayList("polygonpoints"); - //Log.d("DEBUG", "polygon:"+polygon.size()); - updateUIWithPolygon(polygon, addressDisplayName); - } else { - updateUIWithPolygon(null, ""); + + addressSubscription = getAddressesForLocation(locationAddress) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Action1>() { + @Override + public void call(List
foundAdresses) { + onGeocodingSuccess(foundAdresses, index); + } + }, new Action1() { + @Override + public void call(Throwable throwable) { + Toast.makeText(MapActivity.this, "Geocoding error", Toast.LENGTH_SHORT).show(); + } + }); + + } + + private void hideKeyboard(EditText locationEdit) { + InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(locationEdit.getWindowToken(), 0); + } + + private void onGeocodingSuccess(List
foundAdresses, int index) { + if (foundAdresses.size() == 0) { //if no address found, display an error + Toast.makeText(MapActivity.this, "Address not found.", Toast.LENGTH_SHORT).show(); + } else { + Address address = foundAdresses.get(0); //get first address + String addressDisplayName = address.getExtras().getString("display_name"); + if (index == START_INDEX){ + startPoint = new GeoPoint(address.getLatitude(), address.getLongitude()); + markerStart = updateItineraryMarker(markerStart, startPoint, START_INDEX, + R.string.departure, R.drawable.marker_departure, -1, addressDisplayName); + map.getController().setCenter(startPoint); + } else if (index == DEST_INDEX){ + destinationPoint = new GeoPoint(address.getLatitude(), address.getLongitude()); + markerDestination = updateItineraryMarker(markerDestination, destinationPoint, DEST_INDEX, + R.string.destination, R.drawable.marker_destination, -1, addressDisplayName); + map.getController().setCenter(destinationPoint); + } + getRoadAsync(); + //get and display enclosing polygon: + Bundle extras = address.getExtras(); + if (extras != null && extras.containsKey("polygonpoints")){ + ArrayList polygon = extras.getParcelableArrayList("polygonpoints"); + //Log.d("DEBUG", "polygon:"+polygon.size()); + updateUIWithPolygon(polygon, addressDisplayName); + } else { + updateUIWithPolygon(null, ""); + } + } + } + + private Observable> getAddressesForLocation(final String locationAddress) { + return Observable.create( + new Observable.OnSubscribe>() { + @Override + public void call(Subscriber> subscriber) { + GeocoderNominatim geocoder = new GeocoderNominatim(MapActivity.this, userAgent); + geocoder.setOptions(true); //ask for enclosing polygon (if any) + + BoundingBoxE6 viewbox = map.getBoundingBox(); + List
addressList = null; + try { + addressList = geocoder.getFromLocationName(locationAddress, 1, + viewbox.getLatSouthE6() * 1E-6, viewbox.getLonEastE6() * 1E-6, + viewbox.getLatNorthE6() * 1E-6, viewbox.getLonWestE6() * 1E-6, false); + } catch (IOException e) { + subscriber.onError(e); + } + + if (addressList == null) { + return; + } + subscriber.onNext(addressList); + subscriber.onCompleted(); + + } } - } - } catch (Exception e) { - Toast.makeText(this, "Geocoding error", Toast.LENGTH_SHORT).show(); - } + ); } //add or replace the polygon overlay