Skip to content

Instantly share code, notes, and snippets.

@mgdiez
Last active November 6, 2017 15:07
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mgdiez/51ae180c53b1a62beb059a4b3a6600e3 to your computer and use it in GitHub Desktop.
Save mgdiez/51ae180c53b1a62beb059a4b3a6600e3 to your computer and use it in GitHub Desktop.
Rx Geocoder
public interface AddressProvider {
int MAX_RESULTS = 1;
Observable<Map<String, String>> getRealAddressList(TripLocation... locationIds);
String getImmediateRealAddress(TripLocation tripLocation);
Observable<String> getRealAddress(TripLocation tripLocation);
}
public class GoogleAddressProvider implements AddressProvider {
private final Context context;
@Inject public GoogleAddressProvider(Context context) {
this.context = context;
}
@Override
public Observable<Map<String, String>> getRealAddressList(TripLocation... tripLocations) {
return Observable.just(createMap())
.flatMap(map -> Observable.from(tripLocations)
.concatMap(tripLocation -> getAddress(map, tripLocation))
.last())
.retryWhen(this::errorPolicy);
}
@Override public Observable<String> getRealAddress(TripLocation tripLocation) {
return getRealAddressObservable(tripLocation).retryWhen(this::errorPolicy);
}
private Observable<Long> errorPolicy(Observable<? extends Throwable> errors) {
return errors.zipWith(Observable.range(1, 5), (n, i) -> i)
.flatMap(retryCount -> Observable.timer(retryCount * 100, TimeUnit.MILLISECONDS));
}
@Override public String getImmediateRealAddress(TripLocation tripLocation) {
String result = "";
if (tripLocation != null) {
try {
List<Address> locationAddresses =
new Geocoder(context, Locale.getDefault()).getFromLocation(tripLocation.getLatitude(),
tripLocation.getLongitude(), MAX_RESULTS);
if (locationAddresses != null && !locationAddresses.isEmpty()) {
Address address = locationAddresses.get(0);
result = address.getAddressLine(0);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return result;
}
private Observable<String> getRealAddressObservable(TripLocation tripLocation) {
String immediateRealAddress = getImmediateRealAddress(tripLocation);
if (immediateRealAddress.isEmpty()) {
return Observable.error(new IOException());
} else {
return Observable.just(immediateRealAddress);
}
}
private Observable<Map<String, String>> getAddress(Map<String, String> map,
TripLocation locationId) {
Geocoder geocoder = new Geocoder(context, Locale.getDefault());
try {
Observable<Address> from = Observable.from(
geocoder.getFromLocation(locationId.getLatitude(), locationId.getLongitude(),
MAX_RESULTS));
return from.map(toMap(locationId, map));
} catch (IOException e) {
return Observable.empty();
}
}
private Func1<Address, Map<String, String>> toMap(TripLocation locationId,
Map<String, String> map) {
return location -> {
map.put(generateIdForAddress(locationId), location.toString());
return map;
};
}
@NonNull private static String generateIdForAddress(TripLocation locationId) {
return String.valueOf(locationId.getLatitude()) + String.valueOf(locationId.getLongitude());
}
@NonNull private static Map<String, String> createMap() {
return new HashMap<>();
}
}
public class TripLocation {
private final double latitude;
private final double longitude;
public TripLocation(double latitude, double longitude) {
this.latitude = latitude;
this.longitude = longitude;
}
public double getLatitude() {
return latitude;
}
public double getLongitude() {
return longitude;
}
@Override public String toString() {
return "TripLocation{" + "latitude=" + latitude + ", longitude=" + longitude + '}';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment