package com.ibm.mil.readyapps.telco.hotspots; import android.location.Address; import android.location.Geocoder; import android.location.Location; import com.ibm.mil.readyapps.telco.utils.MapUtils; import java.util.List; import rx.Observable; import rx.functions.Func1; import rx.functions.Func2; /** An Observable Transformer for common HotSpot operations. To use, pass in an instance of this * class to Observable.compose(), where the Observable emits values of type HotSpot. */ class HotSpotTransformer implements Observable.Transformer<HotSpot, HotSpot> { private final Geocoder geocoder; private final Location userLocation; public HotSpotTransformer(Geocoder geocoder, Location userLocation) { this.geocoder = geocoder; this.userLocation = userLocation; } private static void setLatLngAddress(HotSpot hotSpot) { hotSpot.setAddressLine1(Double.toString(hotSpot.getLatitude())); hotSpot.setAddressLine2(Double.toString(hotSpot.getLongitude())); } private static Func2<HotSpot, HotSpot, Integer> sortByDistance() { return new Func2<HotSpot, HotSpot, Integer>() { @Override public Integer call(HotSpot hotSpot, HotSpot hotSpot2) { int distance1 = (int) hotSpot.getDistanceAway(); int distance2 = (int) hotSpot2.getDistanceAway(); return distance1 - distance2; } }; } @Override public Observable<HotSpot> call(Observable<HotSpot> hotSpotObservable) { return hotSpotObservable.map(new Func1<HotSpot, HotSpot>() { @Override public HotSpot call(HotSpot hotSpot) { return calculateDistance(hotSpot); } }).map(new Func1<HotSpot, HotSpot>() { @Override public HotSpot call(HotSpot hotSpot) { return obtainAddress(hotSpot); } }).toSortedList(sortByDistance()).flatMap(new Func1<List<HotSpot>, Observable<HotSpot>>() { @Override public Observable<HotSpot> call(List<HotSpot> hotSpots) { return Observable.from(hotSpots); } }); } private HotSpot calculateDistance(HotSpot hotSpot) { Location hotSpotLocation = MapUtils.convertLatLng(hotSpot.getLatitude(), hotSpot.getLongitude()); hotSpot.setDistanceAway(MapUtils.distanceInKilometers(userLocation, hotSpotLocation)); return hotSpot; } private HotSpot obtainAddress(HotSpot hotSpot) { if (geocoder != null) { try { List<Address> addresses = geocoder.getFromLocation(hotSpot.getLatitude(), hotSpot.getLongitude(), 1); Address address = addresses.get(0); hotSpot.setAddressLine1(address.getAddressLine(0)); hotSpot.setAddressLine2(address.getAddressLine(1)); } catch (Exception e) { setLatLngAddress(hotSpot); } } else { setLatLngAddress(hotSpot); } return hotSpot; } }