diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt --- a/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt +++ b/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt @@ -51,6 +51,7 @@ import it.reyboz.bustorino.map.BusInfoWindow import it.reyboz.bustorino.map.BusPositionUtils import it.reyboz.bustorino.map.CustomInfoWindow.TouchResponder +import it.reyboz.bustorino.map.LocationOverlay import it.reyboz.bustorino.map.MapViewModel import it.reyboz.bustorino.map.MarkerUtils import it.reyboz.bustorino.viewmodels.LinesViewModel @@ -117,6 +118,7 @@ //private var stopPosList = ArrayList() private lateinit var stopsOverlay: FolderOverlay + private lateinit var locationOverlay: LocationOverlay //fragment actions private lateinit var fragmentListener: CommonFragmentListener @@ -271,18 +273,23 @@ map = rootView.findViewById(R.id.lineMap) map.let { it.setTileSource(TileSourceFactory.MAPNIK) - /* - object : OnlineTileSourceBase("USGS Topo", 0, 18, 256, "", - arrayOf("https://basemap.nationalmap.gov/ArcG IS/rest/services/USGSTopo/MapServer/tile/" )) { - override fun getTileURLString(pMapTileIndex: Long) : String{ - return baseUrl + - MapTileIndex.getZoom(pMapTileIndex)+"/" + MapTileIndex.getY(pMapTileIndex) + - "/" + MapTileIndex.getX(pMapTileIndex)+ mImageFilenameEnding; - } + + locationOverlay = LocationOverlay.createLocationOverlay(true, it, requireContext(), object : LocationOverlay.OverlayCallbacks{ + override fun onDisableFollowMyLocation() { + Log.d(DEBUG_TAG, "Follow location disabled") } - */ + + override fun onEnableFollowMyLocation() { + Log.d(DEBUG_TAG, "Follow location enabled") + } + + }) + locationOverlay.disableFollowLocation() + stopsOverlay = FolderOverlay() busPositionsOverlay = FolderOverlay() + + //map.setTilesScaledToDpi(true); //map.setTilesScaledToDpi(true); it.setFlingEnabled(true) @@ -318,6 +325,7 @@ //map.invalidate() it.overlayManager.add(stopsOverlay) + it.overlayManager.add(locationOverlay) it.overlayManager.add(busPositionsOverlay) zoomToCurrentPattern() diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java b/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java --- a/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java +++ b/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java @@ -77,8 +77,6 @@ public final static String FRAGMENT_TAG = "MainScreenFragment"; - /// UI ELEMENTS // - private ImageButton addToFavorites; private FragmentHelper fragmentHelper; private SwipeRefreshLayout swipeRefreshLayout; private EditText busStopSearchByIDEditText; @@ -277,7 +275,7 @@ Bundle savedInstanceState) { // Inflate the layout for this fragment View root = inflater.inflate(R.layout.fragment_main_screen, container, false); - addToFavorites = root.findViewById(R.id.addToFavorites); + /// UI ELEMENTS // busStopSearchByIDEditText = root.findViewById(R.id.busStopSearchByIDEditText); busStopSearchByNameEditText = root.findViewById(R.id.busStopSearchByNameEditText); progressBar = root.findViewById(R.id.progressBar); @@ -336,7 +334,7 @@ cr.setCostAllowed(true); cr.setPowerRequirement(Criteria.NO_REQUIREMENT); - locationManager = AppLocationManager.getInstance(getContext()); + locationManager = AppLocationManager.getInstance(requireContext()); Log.d(DEBUG_TAG, "OnCreateView, savedInstanceState null: "+(savedInstanceState==null)); diff --git a/app/src/main/java/it/reyboz/bustorino/map/LocationOverlay.java b/app/src/main/java/it/reyboz/bustorino/map/LocationOverlay.java --- a/app/src/main/java/it/reyboz/bustorino/map/LocationOverlay.java +++ b/app/src/main/java/it/reyboz/bustorino/map/LocationOverlay.java @@ -18,12 +18,16 @@ package it.reyboz.bustorino.map; +import android.content.Context; +import android.util.Log; import org.osmdroid.views.MapView; +import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider; import org.osmdroid.views.overlay.mylocation.IMyLocationProvider; import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay; public class LocationOverlay extends MyLocationNewOverlay { + private final static String DEBUG_TAG = "BusTOLocationOverlay"; final OverlayCallbacks callbacks; public LocationOverlay(MapView mapView, OverlayCallbacks callbacks) { @@ -49,6 +53,25 @@ callbacks.onDisableFollowMyLocation(); } + public static LocationOverlay createLocationOverlay(boolean enableLocation, MapView map, Context context, OverlayCallbacks locationCallbacks){ + if(context== null) { + Log.d(DEBUG_TAG, "Cannot start location overlay, context is null"); + return null; + } + // Location Overlay + // from OpenBikeSharing (THANK GOD) + Log.d(DEBUG_TAG, "Starting position overlay"); + GpsMyLocationProvider imlp = new GpsMyLocationProvider(context.getApplicationContext()); + imlp.setLocationUpdateMinDistance(5); + imlp.setLocationUpdateMinTime(2000); + + final LocationOverlay overlay = new LocationOverlay(imlp,map, locationCallbacks); + if (enableLocation) overlay.enableMyLocation(); + //overlay.setOptionsMenuEnabled(true); + + return overlay; + } + public interface OverlayCallbacks{ /** * Called right after disableFollowMyLocation diff --git a/app/src/main/java/it/reyboz/bustorino/middleware/AppLocationManager.java b/app/src/main/java/it/reyboz/bustorino/middleware/AppLocationManager.java deleted file mode 100644 --- a/app/src/main/java/it/reyboz/bustorino/middleware/AppLocationManager.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - BusTO (middleware) - Copyright (C) 2019 Fabio Mazza - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ -package it.reyboz.bustorino.middleware; - -import android.Manifest; -import android.content.Context; -import android.content.pm.PackageManager; -import android.location.Criteria; -import android.location.Location; -import android.location.LocationListener; -import android.location.LocationManager; -import android.location.LocationProvider; -import android.os.Bundle; -import android.util.Log; -import android.widget.Toast; - -import androidx.core.content.ContextCompat; -import androidx.core.location.LocationManagerCompat; -import androidx.core.location.LocationRequestCompat; - -import it.reyboz.bustorino.util.LocationCriteria; -import it.reyboz.bustorino.util.Permissions; - -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.ListIterator; - -/** - * Singleton class used to access location. Possibly extended with other location sources. - */ -public class AppLocationManager implements LocationListener { - - public static final int LOCATION_GPS_AVAILABLE = 22; - public static final int LOCATION_UNAVAILABLE = -22; - - private final Context appContext; - private final LocationManager locMan; - public static final String DEBUG_TAG = "BUSTO LocAdapter"; - private final String BUNDLE_LOCATION = "location"; - private static AppLocationManager instance; - private int oldGPSLocStatus = LOCATION_UNAVAILABLE; - private int minimum_time_milli = -1; - - private final ArrayList> requestersRef = new ArrayList<>(); - - - private AppLocationManager(Context context) { - this.appContext = context.getApplicationContext(); - locMan = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); - boolean isLocationPermissionGiven = checkLocationPermission(context); - } - - public static AppLocationManager getInstance(Context con) { - if(instance==null) instance = new AppLocationManager(con); - return instance; - } - - public static boolean checkLocationPermission(Context context){ - return ContextCompat.checkSelfPermission(context, - Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED; - } - - - private void requestGPSPositionUpdates() throws SecurityException{ - final int timeinterval = (minimum_time_milli>0 && minimum_time_milli> iter = requestersRef.listIterator(); - while(iter.hasNext()){ - final LocationRequester cReq = iter.next().get(); - if(cReq==null) iter.remove(); - else { - minimum_time_milli = Math.min(cReq.getLocationCriteria().getTimeInterval(),minimum_time_milli); - } - } - Log.d(DEBUG_TAG,"Updated requesters, got "+requestersRef.size()+" listeners to update every "+minimum_time_milli+" ms at least"); - } - - - public void addLocationRequestFor(LocationRequester req){ - boolean present = false; - minimum_time_milli = Integer.MAX_VALUE; - int countNull = 0; - ListIterator> iter = requestersRef.listIterator(); - while(iter.hasNext()){ - final LocationRequester cReq = iter.next().get(); - if(cReq==null) { - countNull++; - iter.remove(); - } else if(cReq.equals(req)){ - present = true; - minimum_time_milli = Math.min(cReq.getLocationCriteria().getTimeInterval(),minimum_time_milli); - } - } - Log.d(DEBUG_TAG, countNull+" listeners have been removed because null"); - if(!present) { - WeakReference newref = new WeakReference<>(req); - requestersRef.add(newref); - minimum_time_milli = Math.min(req.getLocationCriteria().getTimeInterval(),minimum_time_milli); - Log.d(DEBUG_TAG,"Added new stop requester, instance of "+req.getClass().getSimpleName()); - } - if(requestersRef.size()>0){ - Log.d(DEBUG_TAG,"Requesting location updates"); - requestGPSPositionUpdates(); - - } - - } - public void removeLocationRequestFor(LocationRequester req){ - minimum_time_milli = Integer.MAX_VALUE; - ListIterator> iter = requestersRef.listIterator(); - while(iter.hasNext()){ - final LocationRequester cReq = iter.next().get(); - if(cReq==null || cReq.equals(req)) iter.remove(); - else { - minimum_time_milli = Math.min(cReq.getLocationCriteria().getTimeInterval(),minimum_time_milli); - } - } - if(requestersRef.size()<=0){ - locMan.removeUpdates(this); - } else { - requestGPSPositionUpdates(); - } - } - private void sendLocationStatusToAll(int status){ - ListIterator> iter = requestersRef.listIterator(); - while(iter.hasNext()){ - final LocationRequester cReq = iter.next().get(); - if(cReq==null) iter.remove(); - else cReq.onLocationStatusChanged(status); - } - } - public boolean isRequesterRegistered(LocationRequester requester){ - for(WeakReference regRef: requestersRef){ - if(regRef.get()!=null && regRef.get() ==requester) return true; - } - return false; - } - - @Override - public void onLocationChanged(Location location) { - Log.d(DEBUG_TAG,"found location:\nlat: "+location.getLatitude()+" lon: "+location.getLongitude()+"\naccuracy: "+location.getAccuracy()); - ListIterator> iter = requestersRef.listIterator(); - int new_min_interval = Integer.MAX_VALUE; - while(iter.hasNext()){ - final LocationRequester requester = iter.next().get(); - if(requester==null) iter.remove(); - else{ - final long timeNow = System.currentTimeMillis(); - final LocationCriteria criteria = requester.getLocationCriteria(); - if(location.getAccuracy()criteria.getTimeInterval()){ - requester.onLocationChanged(location); - Log.d("AppLocationManager","Updating position for instance of requester "+requester.getClass().getSimpleName()); - } - //update minimum time interval - new_min_interval = Math.min(requester.getLocationCriteria().getTimeInterval(),new_min_interval); - } - } - minimum_time_milli = new_min_interval; - if(requestersRef.size()==0){ - //stop requesting the position - locMan.removeUpdates(this); - } - - - } - - @Override - public void onStatusChanged(String provider, int status, Bundle extras) { - //IF ANOTHER LOCATION SOURCE IS READY, USE IT - //OTHERWISE, SIGNAL THAT WE HAVE NO LOCATION - if(oldGPSLocStatus !=status){ - if(status == LocationProvider.OUT_OF_SERVICE || status == LocationProvider.TEMPORARILY_UNAVAILABLE) { - sendLocationStatusToAll(LOCATION_UNAVAILABLE); - }else if(status == LocationProvider.AVAILABLE){ - sendLocationStatusToAll(LOCATION_GPS_AVAILABLE); - } - oldGPSLocStatus = status; - } - Log.d(DEBUG_TAG, "Provider status changed: "+provider+" status: "+status); - } - - @Override - public void onProviderEnabled(String provider) { - cleanAndUpdateRequesters(); - requestGPSPositionUpdates(); - Log.d(DEBUG_TAG, "Provider: "+provider+" enabled"); - for(WeakReference req: requestersRef){ - if(req.get()==null) continue; - req.get().onLocationProviderAvailable(); - } - - } - - @Override - public void onProviderDisabled(String provider) { - cleanAndUpdateRequesters(); - for(WeakReference req: requestersRef){ - if(req.get()==null) continue; - req.get().onLocationDisabled(); - } - //locMan.removeUpdates(this); - Log.d(DEBUG_TAG, "Provider: "+provider+" disabled"); - } - - public boolean anyLocationProviderMatchesCriteria(Criteria cr) { - return Permissions.anyLocationProviderMatchesCriteria(locMan, cr, true); - } - /** - * Interface to be implemented to get the location request - */ - public interface LocationRequester{ - /** - * Do something with the newly obtained location - * @param loc the obtained location - */ - void onLocationChanged(Location loc); - - /** - * Inform the requester that the GPS status has changed - * @param status new status - */ - void onLocationStatusChanged(int status); - - /** - * We have a location provider available - */ - void onLocationProviderAvailable(); - /** - * Called when location is disabled - */ - void onLocationDisabled(); - - - /** - * Give the last time of update the requester has - * Set it to -1 in order to receive each new location - * @return the time for update in milliseconds since epoch - */ - long getLastUpdateTimeMillis(); - - /** - * Get the specifications for the location - * @return fully parsed LocationCriteria - */ - LocationCriteria getLocationCriteria(); - } -} diff --git a/app/src/main/java/it/reyboz/bustorino/middleware/AppLocationManager.kt b/app/src/main/java/it/reyboz/bustorino/middleware/AppLocationManager.kt new file mode 100644 --- /dev/null +++ b/app/src/main/java/it/reyboz/bustorino/middleware/AppLocationManager.kt @@ -0,0 +1,274 @@ +/* + BusTO (middleware) + Copyright (C) 2019 Fabio Mazza + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ +package it.reyboz.bustorino.middleware + +import android.Manifest +import android.content.Context +import android.content.pm.PackageManager +import android.location.* +import android.os.Bundle +import android.util.Log +import androidx.core.content.ContextCompat +import it.reyboz.bustorino.util.LocationCriteria +import it.reyboz.bustorino.util.Permissions +import java.lang.ref.WeakReference +import kotlin.math.min + +/** + * Singleton class used to access location. Possibly extended with other location sources. + */ +class AppLocationManager private constructor(context: Context) : LocationListener { + private val appContext: Context + private val locMan: LocationManager + private val BUNDLE_LOCATION = "location" + private var oldGPSLocStatus = LOCATION_UNAVAILABLE + private var minimum_time_milli = -1 + private val requestersRef = ArrayList>() + + init { + appContext = context.applicationContext + locMan = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager + } + + @Throws(SecurityException::class) + private fun requestGPSPositionUpdates(): Boolean { + val timeinterval = + if (minimum_time_milli > 0 && minimum_time_milli < Int.MAX_VALUE) minimum_time_milli else 2000 + locMan.removeUpdates(this) + if (!checkLocationPermission(appContext)){ + Log.e(DEBUG_TAG, "No location permission!!") + return false + } + if (locMan.allProviders.contains("gps")) locMan.requestLocationUpdates( + LocationManager.GPS_PROVIDER, + timeinterval.toLong(), + 5f, + this + ) + /*LocationManagerCompat.requestLocationUpdates(locMan, LocationManager.GPS_PROVIDER, + new LocationRequestCompat.Builder(timeinterval).setMinUpdateDistanceMeters(5.F).build(),this, ); + TODO: find a way to do this + */ + return true + } + + private fun cleanAndUpdateRequesters() { + minimum_time_milli = Int.MAX_VALUE + val iter = requestersRef.listIterator() + while (iter.hasNext()) { + val cReq = iter.next().get() + if (cReq == null) iter.remove() else { + minimum_time_milli = min(cReq.locationCriteria.timeInterval.toDouble(), minimum_time_milli.toDouble()) + .toInt() + } + } + Log.d( + DEBUG_TAG, + "Updated requesters, got " + requestersRef.size + " listeners to update every " + minimum_time_milli + " ms at least" + ) + } + + fun addLocationRequestFor(req: LocationRequester) { + var present = false + minimum_time_milli = Int.MAX_VALUE + var countNull = 0 + val iter = requestersRef.listIterator() + while (iter.hasNext()) { + val cReq = iter.next().get() + if (cReq == null) { + countNull++ + iter.remove() + } else if (cReq == req) { + present = true + minimum_time_milli = min(cReq.locationCriteria.timeInterval.toDouble(), minimum_time_milli.toDouble()) + .toInt() + } + } + Log.d(DEBUG_TAG, "$countNull listeners have been removed because null") + if (!present) { + val newref = WeakReference(req) + requestersRef.add(newref) + minimum_time_milli = min(req.locationCriteria.timeInterval.toDouble(), minimum_time_milli.toDouble()) + .toInt() + Log.d(DEBUG_TAG, "Added new stop requester, instance of " + req.javaClass.simpleName) + } + if (requestersRef.size > 0) { + Log.d(DEBUG_TAG, "Requesting location updates") + requestGPSPositionUpdates() + } + } + + fun removeLocationRequestFor(req: LocationRequester) { + minimum_time_milli = Int.MAX_VALUE + val iter = requestersRef.listIterator() + while (iter.hasNext()) { + val cReq = iter.next().get() + if (cReq == null || cReq == req) iter.remove() else { + minimum_time_milli = min(cReq.locationCriteria.timeInterval.toDouble(), minimum_time_milli.toDouble()) + .toInt() + } + } + if (requestersRef.size <= 0) { + locMan.removeUpdates(this) + } + } + + private fun sendLocationStatusToAll(status: Int) { + val iter = requestersRef.listIterator() + while (iter.hasNext()) { + val cReq = iter.next().get() + if (cReq == null) iter.remove() else cReq.onLocationStatusChanged(status) + } + } + + fun isRequesterRegistered(requester: LocationRequester): Boolean { + for (regRef in requestersRef) { + if (regRef.get() != null && regRef.get() === requester) return true + } + return false + } + + override fun onLocationChanged(location: Location) { + Log.d( + DEBUG_TAG, "found location: \nlat: ${location.latitude} lon: ${location.longitude} accuracy: ${location.accuracy}" + ) + val iter = requestersRef.listIterator() + var new_min_interval = Int.MAX_VALUE + while (iter.hasNext()) { + val requester = iter.next().get() + if (requester == null) iter.remove() else { + val timeNow = System.currentTimeMillis() + val criteria = requester.locationCriteria + if (location.accuracy < criteria.minAccuracy && + timeNow - requester.lastUpdateTimeMillis > criteria.timeInterval + ) { + requester.onLocationChanged(location) + Log.d( + "AppLocationManager", + "Updating position for instance of requester " + requester.javaClass.simpleName + ) + } + //update minimum time interval + new_min_interval = min(requester.locationCriteria.timeInterval.toDouble(), new_min_interval.toDouble()) + .toInt() + } + } + minimum_time_milli = new_min_interval + if (requestersRef.size == 0) { + //stop requesting the position + locMan.removeUpdates(this) + } + } + + override fun onStatusChanged(provider: String, status: Int, extras: Bundle) { + //IF ANOTHER LOCATION SOURCE IS READY, USE IT + //OTHERWISE, SIGNAL THAT WE HAVE NO LOCATION + if (oldGPSLocStatus != status) { + if (status == LocationProvider.OUT_OF_SERVICE || status == LocationProvider.TEMPORARILY_UNAVAILABLE) { + sendLocationStatusToAll(LOCATION_UNAVAILABLE) + } else if (status == LocationProvider.AVAILABLE) { + sendLocationStatusToAll(LOCATION_GPS_AVAILABLE) + } + oldGPSLocStatus = status + } + Log.d(DEBUG_TAG, "Provider status changed: $provider status: $status") + } + + override fun onProviderEnabled(provider: String) { + cleanAndUpdateRequesters() + requestGPSPositionUpdates() + Log.d(DEBUG_TAG, "Provider: $provider enabled") + for (req in requestersRef) { + if (req.get() == null) continue + req.get()!!.onLocationProviderAvailable() + } + } + + override fun onProviderDisabled(provider: String) { + cleanAndUpdateRequesters() + for (req in requestersRef) { + if (req.get() == null) continue + req.get()!!.onLocationDisabled() + } + //locMan.removeUpdates(this); + Log.d(DEBUG_TAG, "Provider: $provider disabled") + } + + fun anyLocationProviderMatchesCriteria(cr: Criteria?): Boolean { + return Permissions.anyLocationProviderMatchesCriteria(locMan, cr, true) + } + + /** + * Interface to be implemented to get the location request + */ + interface LocationRequester { + /** + * Do something with the newly obtained location + * @param loc the obtained location + */ + fun onLocationChanged(loc: Location?) + + /** + * Inform the requester that the GPS status has changed + * @param status new status + */ + fun onLocationStatusChanged(status: Int) + + /** + * We have a location provider available + */ + fun onLocationProviderAvailable() + + /** + * Called when location is disabled + */ + fun onLocationDisabled() + + /** + * Give the last time of update the requester has + * Set it to -1 in order to receive each new location + * @return the time for update in milliseconds since epoch + */ + val lastUpdateTimeMillis: Long + + /** + * Get the specifications for the location + * @return fully parsed LocationCriteria + */ + val locationCriteria: LocationCriteria + } + + companion object { + const val LOCATION_GPS_AVAILABLE = 22 + const val LOCATION_UNAVAILABLE = -22 + private const val DEBUG_TAG = "BUSTO LocAdapter" + private var instance: AppLocationManager? = null + @JvmStatic + fun getInstance(con: Context): AppLocationManager? { + if (instance == null) instance = AppLocationManager(con) + return instance + } + + fun checkLocationPermission(context: Context?): Boolean { + return ContextCompat.checkSelfPermission( + context!!, + Manifest.permission.ACCESS_FINE_LOCATION + ) == PackageManager.PERMISSION_GRANTED + } + } +} diff --git a/app/src/main/java/it/reyboz/bustorino/viewmodels/StopsMapViewModel.kt b/app/src/main/java/it/reyboz/bustorino/viewmodels/StopsMapViewModel.kt --- a/app/src/main/java/it/reyboz/bustorino/viewmodels/StopsMapViewModel.kt +++ b/app/src/main/java/it/reyboz/bustorino/viewmodels/StopsMapViewModel.kt @@ -21,26 +21,16 @@ private val executor = Executors.newFixedThreadPool(2) private val oldRepo = OldDataRepository(executor, NextGenDB.getInstance(application)) - /* - private val boundingBoxLiveData = MutableLiveData() - fun setStopBoundingBox(bb: BoundingBox){ - boundingBoxLiveData.value = bb - } - - */ val stopsInBoundingBox = MutableLiveData>() private val callback = - OldDataRepository.Callback> { result -> - result.let { - if(it.isSuccess){ - stopsInBoundingBox.postValue(it.result) + OldDataRepository.Callback> { res -> + if(res.isSuccess){ + stopsInBoundingBox.postValue(res.result) Log.d(DEBUG_TAG, "Setting value of stops in bounding box") } - - } } fun requestStopsInBoundingBox(bb: BoundingBox) {