Changeset View
Changeset View
Standalone View
Standalone View
app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt
| Show First 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
| import it.reyboz.bustorino.backend.gtfs.GtfsUtils | import it.reyboz.bustorino.backend.gtfs.GtfsUtils | ||||
| import it.reyboz.bustorino.backend.gtfs.LivePositionUpdate | import it.reyboz.bustorino.backend.gtfs.LivePositionUpdate | ||||
| import it.reyboz.bustorino.backend.gtfs.PolylineParser | import it.reyboz.bustorino.backend.gtfs.PolylineParser | ||||
| import it.reyboz.bustorino.backend.utils | import it.reyboz.bustorino.backend.utils | ||||
| import it.reyboz.bustorino.data.MatoTripsDownloadWorker | import it.reyboz.bustorino.data.MatoTripsDownloadWorker | ||||
| import it.reyboz.bustorino.data.gtfs.MatoPattern | import it.reyboz.bustorino.data.gtfs.MatoPattern | ||||
| import it.reyboz.bustorino.data.gtfs.MatoPatternWithStops | import it.reyboz.bustorino.data.gtfs.MatoPatternWithStops | ||||
| import it.reyboz.bustorino.data.gtfs.TripAndPatternWithStops | import it.reyboz.bustorino.data.gtfs.TripAndPatternWithStops | ||||
| import it.reyboz.bustorino.map.BusInfoWindow | import it.reyboz.bustorino.map.* | ||||
| import it.reyboz.bustorino.map.BusPositionUtils | |||||
| import it.reyboz.bustorino.map.CustomInfoWindow.TouchResponder | 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 | import it.reyboz.bustorino.viewmodels.LinesViewModel | ||||
| import it.reyboz.bustorino.viewmodels.MQTTPositionsViewModel | import it.reyboz.bustorino.viewmodels.LivePositionsViewModel | ||||
| import kotlinx.coroutines.delay | import kotlinx.coroutines.delay | ||||
| import kotlinx.coroutines.launch | import kotlinx.coroutines.launch | ||||
| import org.osmdroid.config.Configuration | import org.osmdroid.config.Configuration | ||||
| import org.osmdroid.tileprovider.tilesource.TileSourceFactory | import org.osmdroid.tileprovider.tilesource.TileSourceFactory | ||||
| import org.osmdroid.util.BoundingBox | import org.osmdroid.util.BoundingBox | ||||
| import org.osmdroid.util.GeoPoint | import org.osmdroid.util.GeoPoint | ||||
| import org.osmdroid.views.MapView | import org.osmdroid.views.MapView | ||||
| import org.osmdroid.views.overlay.FolderOverlay | import org.osmdroid.views.overlay.FolderOverlay | ||||
| ▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | class LinesDetailFragment() : ScreenBaseFragment() { | ||||
| private val stopTouchResponder = TouchResponder { stopID, stopName -> | private val stopTouchResponder = TouchResponder { stopID, stopName -> | ||||
| Log.d(DEBUG_TAG, "Asked to show arrivals for stop ID: $stopID") | Log.d(DEBUG_TAG, "Asked to show arrivals for stop ID: $stopID") | ||||
| fragmentListener.requestArrivalsForStopID(stopID) | fragmentListener.requestArrivalsForStopID(stopID) | ||||
| } | } | ||||
| private var showOnTopOfLine = true | private var showOnTopOfLine = true | ||||
| private var recyclerInitDone = false | private var recyclerInitDone = false | ||||
| private var useMQTTPositions = true | |||||
| //position of live markers | //position of live markers | ||||
| private val busPositionMarkersByTrip = HashMap<String,Marker>() | private val busPositionMarkersByTrip = HashMap<String,Marker>() | ||||
| private var busPositionsOverlay = FolderOverlay() | private var busPositionsOverlay = FolderOverlay() | ||||
| private val tripMarkersAnimators = HashMap<String, ObjectAnimator>() | private val tripMarkersAnimators = HashMap<String, ObjectAnimator>() | ||||
| private val liveBusViewModel: MQTTPositionsViewModel by viewModels() | private val liveBusViewModel: LivePositionsViewModel by viewModels() | ||||
| @SuppressLint("SetTextI18n") | @SuppressLint("SetTextI18n") | ||||
| override fun onCreateView( | override fun onCreateView( | ||||
| inflater: LayoutInflater, container: ViewGroup?, | inflater: LayoutInflater, container: ViewGroup?, | ||||
| savedInstanceState: Bundle? | savedInstanceState: Bundle? | ||||
| ): View? { | ): View? { | ||||
| val rootView = inflater.inflate(R.layout.fragment_lines_detail, container, false) | val rootView = inflater.inflate(R.layout.fragment_lines_detail, container, false) | ||||
| lineID = requireArguments().getString(LINEID_KEY, "") | lineID = requireArguments().getString(LINEID_KEY, "") | ||||
| switchButton = rootView.findViewById(R.id.switchImageButton) | switchButton = rootView.findViewById(R.id.switchImageButton) | ||||
| Show All 12 Lines | ): View? { | ||||
| initializeRecyclerView() | initializeRecyclerView() | ||||
| switchButton.setOnClickListener{ | switchButton.setOnClickListener{ | ||||
| if(map.visibility == View.VISIBLE){ | if(map.visibility == View.VISIBLE){ | ||||
| map.visibility = View.GONE | map.visibility = View.GONE | ||||
| stopsRecyclerView.visibility = View.VISIBLE | stopsRecyclerView.visibility = View.VISIBLE | ||||
| viewModel.setMapShowing(false) | viewModel.setMapShowing(false) | ||||
| liveBusViewModel.stopPositionsListening() | liveBusViewModel.stopMatoUpdates() | ||||
| switchButton.setImageDrawable(AppCompatResources.getDrawable(requireContext(), R.drawable.ic_map_white_30)) | switchButton.setImageDrawable(AppCompatResources.getDrawable(requireContext(), R.drawable.ic_map_white_30)) | ||||
| } else{ | } else{ | ||||
| stopsRecyclerView.visibility = View.GONE | stopsRecyclerView.visibility = View.GONE | ||||
| map.visibility = View.VISIBLE | map.visibility = View.VISIBLE | ||||
| viewModel.setMapShowing(true) | viewModel.setMapShowing(true) | ||||
| liveBusViewModel.requestPosUpdates(lineID) | if(useMQTTPositions) | ||||
| liveBusViewModel.requestMatoPosUpdates(lineID) | |||||
| else | |||||
| liveBusViewModel.requestGTFSUpdates() | |||||
| switchButton.setImageDrawable(AppCompatResources.getDrawable(requireContext(), R.drawable.ic_list_30)) | switchButton.setImageDrawable(AppCompatResources.getDrawable(requireContext(), R.drawable.ic_list_30)) | ||||
| } | } | ||||
| } | } | ||||
| viewModel.setRouteIDQuery(lineID) | viewModel.setRouteIDQuery(lineID) | ||||
| val keySourcePositions = getString(R.string.pref_positions_source) | |||||
| useMQTTPositions = PreferenceManager.getDefaultSharedPreferences(requireContext()) | |||||
| .getString(keySourcePositions, "mqtt").contentEquals("mqtt") | |||||
| viewModel.patternsWithStopsByRouteLiveData.observe(viewLifecycleOwner){ | viewModel.patternsWithStopsByRouteLiveData.observe(viewLifecycleOwner){ | ||||
| patterns -> savePatternsToShow(patterns) | patterns -> savePatternsToShow(patterns) | ||||
| } | } | ||||
| /* | /* | ||||
| We have the pattern and the stops here, time to display them | We have the pattern and the stops here, time to display them | ||||
| */ | */ | ||||
| viewModel.stopsForPatternLiveData.observe(viewLifecycleOwner) { stops -> | viewModel.stopsForPatternLiveData.observe(viewLifecycleOwner) { stops -> | ||||
| if(map.visibility ==View.VISIBLE) | if(map.visibility ==View.VISIBLE) | ||||
| Show All 37 Lines | ): View? { | ||||
| //live bus positions | //live bus positions | ||||
| liveBusViewModel.updatesWithTripAndPatterns.observe(viewLifecycleOwner){ | liveBusViewModel.updatesWithTripAndPatterns.observe(viewLifecycleOwner){ | ||||
| if(map.visibility == View.GONE || viewingPattern ==null){ | if(map.visibility == View.GONE || viewingPattern ==null){ | ||||
| //DO NOTHING | //DO NOTHING | ||||
| return@observe | return@observe | ||||
| } | } | ||||
| val filtdLineID = GtfsUtils.stripGtfsPrefix(lineID) | |||||
| //filter buses with direction, show those only with the same direction | //filter buses with direction, show those only with the same direction | ||||
| val outmap = HashMap<String, Pair<LivePositionUpdate, TripAndPatternWithStops?>>() | val outmap = HashMap<String, Pair<LivePositionUpdate, TripAndPatternWithStops?>>() | ||||
| val currentPattern = viewingPattern!!.pattern | val currentPattern = viewingPattern!!.pattern | ||||
| val numUpds = it.entries.size | val numUpds = it.entries.size | ||||
| Log.d(DEBUG_TAG, "Got $numUpds updates, current pattern is: ${currentPattern.name}, directionID: ${currentPattern.directionId}") | Log.d(DEBUG_TAG, "Got $numUpds updates, current pattern is: ${currentPattern.name}, directionID: ${currentPattern.directionId}") | ||||
| val patternsDirections = HashMap<String,Int>() | val patternsDirections = HashMap<String,Int>() | ||||
| for((tripId, pair) in it.entries){ | for((tripId, pair) in it.entries){ | ||||
| //remove trips with wrong line ideas | |||||
| if(pair.first.routeID!=filtdLineID) | |||||
| continue | |||||
| if(pair.second!=null && pair.second?.pattern !=null){ | if(pair.second!=null && pair.second?.pattern !=null){ | ||||
| val dir = pair.second?.pattern?.directionId | val dir = pair.second?.pattern?.directionId | ||||
| if(dir !=null && dir == currentPattern.directionId){ | if(dir !=null && dir == currentPattern.directionId){ | ||||
| outmap.set(tripId, pair) | outmap[tripId] = pair | ||||
| } | } | ||||
| patternsDirections.set(tripId,if (dir!=null) dir else -10) | patternsDirections.set(tripId,if (dir!=null) dir else -10) | ||||
| } else{ | } else{ | ||||
| outmap[tripId] = pair | outmap[tripId] = pair | ||||
| //Log.d(DEBUG_TAG, "No pattern for tripID: $tripId") | //Log.d(DEBUG_TAG, "No pattern for tripID: $tripId") | ||||
| patternsDirections.set(tripId, -10) | patternsDirections[tripId] = -10 | ||||
| } | } | ||||
| } | } | ||||
| Log.d(DEBUG_TAG, " Filtered updates are ${outmap.keys.size}") // Original updates directs: $patternsDirections\n | Log.d(DEBUG_TAG, " Filtered updates are ${outmap.keys.size}") // Original updates directs: $patternsDirections\n | ||||
| updateBusPositionsInMap(outmap) | updateBusPositionsInMap(outmap) | ||||
| //if not using MQTT positions | |||||
| if(!useMQTTPositions){ | |||||
| liveBusViewModel.requestDelayedGTFSUpdates(2000) | |||||
| } | |||||
| } | } | ||||
| //download missing tripIDs | //download missing tripIDs | ||||
| liveBusViewModel.tripsGtfsIDsToQuery.observe(viewLifecycleOwner){ | liveBusViewModel.tripsGtfsIDsToQuery.observe(viewLifecycleOwner){ | ||||
| //gtfsPosViewModel.downloadTripsFromMato(dat); | //gtfsPosViewModel.downloadTripsFromMato(dat); | ||||
| MatoTripsDownloadWorker.downloadTripsFromMato( | MatoTripsDownloadWorker.downloadTripsFromMato( | ||||
| it, requireContext().applicationContext, | it, requireContext().applicationContext, | ||||
| "BusTO-MatoTripDownload" | "BusTO-MatoTripDownload" | ||||
| ▲ Show 20 Lines • Show All 386 Lines • ▼ Show 20 Lines | private fun updateBusPositionsInMap(tripsPatterns: java.util.HashMap<String, Pair<LivePositionUpdate, TripAndPatternWithStops?>> | ||||
| } | } | ||||
| } | } | ||||
| override fun onResume() { | override fun onResume() { | ||||
| super.onResume() | super.onResume() | ||||
| Log.d(DEBUG_TAG, "Resetting paused from onResume") | Log.d(DEBUG_TAG, "Resetting paused from onResume") | ||||
| pausedFragment = false | pausedFragment = false | ||||
| liveBusViewModel.requestPosUpdates(GtfsUtils.getLineNameFromGtfsID(lineID)) | val keySourcePositions = getString(R.string.pref_positions_source) | ||||
| useMQTTPositions = PreferenceManager.getDefaultSharedPreferences(requireContext()) | |||||
| .getString(keySourcePositions, "mqtt").contentEquals("mqtt") | |||||
| //separate paths | |||||
| if(useMQTTPositions) | |||||
| liveBusViewModel.requestMatoPosUpdates(GtfsUtils.getLineNameFromGtfsID(lineID)) | |||||
| else | |||||
| liveBusViewModel.requestGTFSUpdates() | |||||
| if(mapViewModel.currentLat.value!=MapViewModel.INVALID) { | if(mapViewModel.currentLat.value!=MapViewModel.INVALID) { | ||||
| Log.d(DEBUG_TAG, "mapViewModel posi: ${mapViewModel.currentLat.value}, ${mapViewModel.currentLong.value}"+ | Log.d(DEBUG_TAG, "mapViewModel posi: ${mapViewModel.currentLat.value}, ${mapViewModel.currentLong.value}"+ | ||||
| " zoom ${mapViewModel.currentZoom.value}") | " zoom ${mapViewModel.currentZoom.value}") | ||||
| val controller = map.controller | val controller = map.controller | ||||
| viewLifecycleOwner.lifecycleScope.launch { | viewLifecycleOwner.lifecycleScope.launch { | ||||
| delay(100) | delay(100) | ||||
| Log.d(DEBUG_TAG, "zooming back to point") | Log.d(DEBUG_TAG, "zooming back to point") | ||||
| controller.animateTo(GeoPoint(mapViewModel.currentLat.value!!, mapViewModel.currentLong.value!!), | controller.animateTo(GeoPoint(mapViewModel.currentLat.value!!, mapViewModel.currentLong.value!!), | ||||
| mapViewModel.currentZoom.value!!,null,null) | mapViewModel.currentZoom.value!!,null,null) | ||||
| //controller.setCenter(GeoPoint(mapViewModel.currentLat.value!!, mapViewModel.currentLong.value!!)) | //controller.setCenter(GeoPoint(mapViewModel.currentLat.value!!, mapViewModel.currentLong.value!!)) | ||||
| //controller.setZoom(mapViewModel.currentZoom.value!!) | //controller.setZoom(mapViewModel.currentZoom.value!!) | ||||
| } | } | ||||
| //controller.setZoom() | //controller.setZoom() | ||||
| } | } | ||||
| //initialize GUI here | //initialize GUI here | ||||
| fragmentListener.readyGUIfor(FragmentKind.LINES) | fragmentListener.readyGUIfor(FragmentKind.LINES) | ||||
| } | } | ||||
| override fun onPause() { | override fun onPause() { | ||||
| super.onPause() | super.onPause() | ||||
| liveBusViewModel.stopPositionsListening() | liveBusViewModel.stopMatoUpdates() | ||||
| pausedFragment = true | pausedFragment = true | ||||
| //save map | //save map | ||||
| val center = map.mapCenter | val center = map.mapCenter | ||||
| mapViewModel.currentLat.value = center.latitude | mapViewModel.currentLat.value = center.latitude | ||||
| mapViewModel.currentLong.value = center.longitude | mapViewModel.currentLong.value = center.longitude | ||||
| mapViewModel.currentZoom.value = map.zoomLevel.toDouble() | mapViewModel.currentZoom.value = map.zoomLevel.toDouble() | ||||
| } | } | ||||
| Show All 40 Lines | companion object { | ||||
| //Log.d(DEBUG_TAG,"Stop ${stop.ID} old pos: ($sLat, $sLong), new pos ($latNew,$longNew)") | //Log.d(DEBUG_TAG,"Stop ${stop.ID} old pos: ($sLat, $sLong), new pos ($latNew,$longNew)") | ||||
| return GeoPoint(latNew,longNew) | return GeoPoint(latNew,longNew) | ||||
| } | } | ||||
| private const val DEFAULT_CENTER_LAT = 45.12 | private const val DEFAULT_CENTER_LAT = 45.12 | ||||
| private const val DEFAULT_CENTER_LON = 7.6858 | private const val DEFAULT_CENTER_LON = 7.6858 | ||||
| } | } | ||||
| } | } | ||||
| No newline at end of file | No newline at end of file | ||||
Public contents are in Creative Commons Attribution-ShareAlike 4.0 (CC-BY-SA) or GNU Free Documentation License (at your option) unless otherwise noted. · Contact / Register