diff --git a/app/src/main/java/org/y20k/trackbook/MapFragment.kt b/app/src/main/java/org/y20k/trackbook/MapFragment.kt index 797cd13..2dc8610 100644 --- a/app/src/main/java/org/y20k/trackbook/MapFragment.kt +++ b/app/src/main/java/org/y20k/trackbook/MapFragment.kt @@ -17,20 +17,39 @@ package org.y20k.trackbook import android.Manifest +import android.app.Activity import android.content.* import android.content.pm.PackageManager +import android.content.res.Resources +import android.graphics.Color +import android.graphics.drawable.Drawable import android.location.Location import android.os.* +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.WindowManager import androidx.activity.result.contract.ActivityResultContracts.RequestPermission import androidx.core.content.ContextCompat +import androidx.core.view.isVisible import androidx.fragment.app.Fragment -import org.y20k.trackbook.Track +import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton +import com.google.android.material.floatingactionbutton.FloatingActionButton +import com.google.android.material.snackbar.Snackbar +import org.osmdroid.api.IMapController +import org.osmdroid.tileprovider.tilesource.TileSourceFactory +import org.osmdroid.util.GeoPoint +import org.osmdroid.views.MapView +import org.osmdroid.views.overlay.FolderOverlay +import org.osmdroid.views.overlay.ItemizedIconOverlay +import org.osmdroid.views.overlay.OverlayItem +import org.osmdroid.views.overlay.Polygon +import org.osmdroid.views.overlay.TilesOverlay +import org.osmdroid.views.overlay.compass.CompassOverlay +import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider +import org.osmdroid.views.overlay.simplefastpoint.SimpleFastPointOverlay import org.y20k.trackbook.helpers.* -import org.y20k.trackbook.ui.MapFragmentLayoutHolder /* * MapFragment class @@ -48,11 +67,25 @@ class MapFragment : Fragment() private var networkProviderActive: Boolean = false private lateinit var track: Track private lateinit var currentBestLocation: Location - private lateinit var layout: MapFragmentLayoutHolder private lateinit var trackerService: TrackerService + lateinit var rootView: View + var userInteraction: Boolean = false + lateinit var currentLocationButton: FloatingActionButton + lateinit var mainButton: ExtendedFloatingActionButton + private lateinit var mapView: MapView + private lateinit var current_position_folder: FolderOverlay + private var currentTrackOverlay: SimpleFastPointOverlay? = null + private var currentTrackSpecialMarkerOverlay: ItemizedIconOverlay? = null + private lateinit var locationErrorBar: Snackbar + private lateinit var controller: IMapController + private var zoomLevel: Double = Keys.DEFAULT_ZOOM_LEVEL + private lateinit var homepoints_overlay_folder: FolderOverlay + /* Overrides onCreate from Fragment */ - override fun onCreate(savedInstanceState: Bundle?) { + override fun onCreate(savedInstanceState: Bundle?) + { + Log.i("VOUSSOIR", "MapFragment.onCreate") super.onCreate(savedInstanceState) // TODO make only MapFragment's status bar transparent - see: // https://gist.github.com/Dvik/a3de88d39da9d1d6d175025a56c5e797#file-viewextension-kt and @@ -61,28 +94,84 @@ class MapFragment : Fragment() currentBestLocation = getLastKnownLocation(activity as Context) // get saved tracking state trackingState = PreferencesHelper.loadTrackingState() - requireActivity().window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } /* Overrides onStop from Fragment */ - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { - // initialize layout - val statusBarHeight: Int = UiHelper.getStatusBarHeight(activity as Context) - layout = MapFragmentLayoutHolder(activity as Context, inflater, container, statusBarHeight, currentBestLocation, trackingState) + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View + { + Log.i("VOUSSOIR", "MapFragment.onCreateView") + val context = activity as Context + // find views + rootView = inflater.inflate(R.layout.fragment_map, container, false) + mapView = rootView.findViewById(R.id.map) + currentLocationButton = rootView.findViewById(R.id.location_button) + mainButton = rootView.findViewById(R.id.main_button) + locationErrorBar = Snackbar.make(mapView, String(), Snackbar.LENGTH_INDEFINITE) + + // basic map setup + controller = mapView.controller + mapView.isTilesScaledToDpi = true + mapView.setTileSource(TileSourceFactory.MAPNIK) + mapView.setMultiTouchControls(true) + mapView.zoomController.setVisibility(org.osmdroid.views.CustomZoomButtonsController.Visibility.NEVER) + zoomLevel = PreferencesHelper.loadZoomLevel() + controller.setZoom(zoomLevel) + + // set dark map tiles, if necessary + if (AppThemeHelper.isDarkModeOn(requireActivity())) + { + mapView.overlayManager.tilesOverlay.setColorFilter(TilesOverlay.INVERT_COLORS) + } + + // store Density Scaling Factor + val densityScalingFactor: Float = UiHelper.getDensityScalingFactor(context) + + // add compass to map + val compassOverlay = CompassOverlay(context, InternalCompassOrientationProvider(context), mapView) + compassOverlay.enableCompass() + // compassOverlay.setCompassCenter(36f, 36f + (statusBarHeight / densityScalingFactor)) // TODO uncomment when transparent status bar is re-implemented + val screen_width = Resources.getSystem().displayMetrics.widthPixels; + compassOverlay.setCompassCenter((screen_width / densityScalingFactor) - 36f, 36f) + mapView.overlays.add(compassOverlay) + + val app: Trackbook = (context.applicationContext as Trackbook) + app.load_homepoints() + homepoints_overlay_folder = FolderOverlay() + mapView.overlays.add(homepoints_overlay_folder) + createHomepointOverlays(context, mapView, app.homepoints) + + // add my location overlay + current_position_folder = FolderOverlay() + mapView.overlays.add(current_position_folder) + + + centerMap(currentBestLocation) + + // initialize track overlays + currentTrackOverlay = null + currentTrackSpecialMarkerOverlay = null + + // initialize main button state + updateMainButton(trackingState) + + // listen for user interaction + addInteractionListener() // set up buttons - layout.currentLocationButton.setOnClickListener { - layout.centerMap(currentBestLocation, animated = true) + currentLocationButton.setOnClickListener { + centerMap(currentBestLocation, animated = true) } - layout.mainButton.setOnClickListener { + mainButton.setOnClickListener { handleTrackingManagementMenu() } - return layout.rootView + requireActivity().window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) + return rootView } /* Overrides onStart from Fragment */ - override fun onStart() { + override fun onStart() + { super.onStart() // request location permission if denied if (ContextCompat.checkSelfPermission(activity as Context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED) { @@ -93,27 +182,34 @@ class MapFragment : Fragment() } /* Overrides onResume from Fragment */ - override fun onResume() { + override fun onResume() + { + Log.i("VOUSSOIR", "MapFragment.onResume") super.onResume() -// if (bound) { -// trackerService.addGpsLocationListener() -// trackerService.addNetworkLocationListener() -// } + requireActivity().window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) + // if (bound) { + // trackerService.addGpsLocationListener() + // trackerService.addNetworkLocationListener() + // } } /* Overrides onPause from Fragment */ - override fun onPause() { + override fun onPause() + { + Log.i("VOUSSOIR", "MapFragment.onPause") super.onPause() - layout.saveState(currentBestLocation) + saveBestLocationState(currentBestLocation) if (bound && trackingState != Keys.STATE_TRACKING_ACTIVE) { trackerService.removeGpsLocationListener() trackerService.removeNetworkLocationListener() trackerService.trackbook.database.commit() } + requireActivity().window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) } /* Overrides onStop from Fragment */ - override fun onStop() { + override fun onStop() + { super.onStop() // unbind from TrackerService if (bound) @@ -123,6 +219,13 @@ class MapFragment : Fragment() } } + override fun onDestroy() + { + Log.i("VOUSSOIR", "MapFragment.onDestroy") + super.onDestroy() + requireActivity().window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) + } + /* Register the permission launcher for requesting location */ private val requestLocationPermissionLauncher = registerForActivityResult(RequestPermission()) { isGranted: Boolean -> if (isGranted) { @@ -134,26 +237,24 @@ class MapFragment : Fragment() // permission denied - unbind service activity?.unbindService(connection) } - layout.toggleLocationErrorBar(gpsProviderActive, networkProviderActive) + toggleLocationErrorBar(gpsProviderActive, networkProviderActive) } /* Register the permission launcher for starting the tracking service */ private val startTrackingPermissionLauncher = registerForActivityResult(RequestPermission()) { isGranted: Boolean -> - logPermissionRequestResult(isGranted) + if (isGranted) + { + LogHelper.i(TAG, "Request result: Activity Recognition permission has been granted.") + } + else + { + LogHelper.i(TAG, "Request result: Activity Recognition permission has NOT been granted.") + } // start service via intent so that it keeps running after unbind startTrackerService() trackerService.startTracking() } - /* Logs the request result of the Activity Recognition permission launcher */ - private fun logPermissionRequestResult(isGranted: Boolean) { - if (isGranted) { - LogHelper.i(TAG, "Request result: Activity Recognition permission has been granted.") - } else { - LogHelper.i(TAG, "Request result: Activity Recognition permission has NOT been granted.") - } - } - /* Start recording waypoints */ private fun startTracking() { // request activity recognition permission on Android Q+ if denied @@ -211,11 +312,153 @@ class MapFragment : Fragment() if (activity != null) { trackingState = PreferencesHelper.loadTrackingState() - layout.updateMainButton(trackingState) + updateMainButton(trackingState) } } } } + private fun addInteractionListener() { + mapView.setOnTouchListener { v, event -> + userInteraction = true + false + } + } + + fun centerMap(location: Location, animated: Boolean = false) { + val position = GeoPoint(location.latitude, location.longitude) + when (animated) { + true -> controller.animateTo(position) + false -> controller.setCenter(position) + } + userInteraction = false + } + + fun saveBestLocationState(currentBestLocation: Location) { + PreferencesHelper.saveCurrentBestLocation(currentBestLocation) + PreferencesHelper.saveZoomLevel(mapView.zoomLevelDouble) + // reset user interaction state + userInteraction = false + } + + /* Mark current position on map */ + fun markCurrentPosition(location: Location, trackingState: Int = Keys.STATE_TRACKING_STOPPED) + { + Log.i("VOUSSOIR", "MapFragmentLayoutHolder.markCurrentPosition") + val locationIsOld: Boolean = !(isRecentEnough(location)) + + // create marker + val newMarker: Drawable + val fillcolor: Int + if (trackingState == Keys.STATE_TRACKING_ACTIVE) + { + fillcolor = Color.argb(64, 220, 61, 51) + if (locationIsOld) + { + newMarker = ContextCompat.getDrawable(requireContext(), R.drawable.ic_marker_location_black_24dp)!! + } + else + { + newMarker = ContextCompat.getDrawable(requireContext(), R.drawable.ic_marker_location_red_24dp)!! + } + } + else + { + fillcolor = Color.argb(64, 60, 152, 219) + if(locationIsOld) + { + newMarker = ContextCompat.getDrawable(requireContext(), R.drawable.ic_marker_location_black_24dp)!! + } + else + { + newMarker = ContextCompat.getDrawable(requireContext(), R.drawable.ic_marker_location_blue_24dp)!! + } + } + + current_position_folder.items.clear() + + val current_location_radius = Polygon() + current_location_radius.points = Polygon.pointsAsCircle(GeoPoint(location.latitude, location.longitude), location.accuracy.toDouble()) + current_location_radius.fillPaint.color = fillcolor + current_location_radius.outlinePaint.color = Color.argb(0, 0, 0, 0) + current_position_folder.add(current_location_radius) + + val overlayItems: java.util.ArrayList = java.util.ArrayList() + val overlayItem: OverlayItem = createOverlayItem(requireContext(), location.latitude, location.longitude, location.accuracy, location.provider.toString(), location.time) + overlayItem.setMarker(newMarker) + overlayItems.add(overlayItem) + current_position_folder.add(createOverlay(requireContext(), overlayItems)) + } + + fun createHomepointOverlays(context: Context, map_view: MapView, homepoints: List) + { + Log.i("VOUSSOIR", "MapFragmentLayoutHolder.createHomepointOverlays") + val overlayItems: java.util.ArrayList = java.util.ArrayList() + + val newMarker: Drawable = ContextCompat.getDrawable(context, R.drawable.ic_homepoint_24dp)!! + + homepoints_overlay_folder.items.clear() + + for (homepoint in homepoints) + { + val overlayItem: OverlayItem = createOverlayItem(context, homepoint.location.latitude, homepoint.location.longitude, homepoint.location.accuracy, homepoint.location.provider.toString(), homepoint.location.time) + overlayItem.setMarker(newMarker) + overlayItems.add(overlayItem) + homepoints_overlay_folder.add(createOverlay(context, overlayItems)) + + val p = Polygon() + p.points = Polygon.pointsAsCircle(GeoPoint(homepoint.location.latitude, homepoint.location.longitude), homepoint.location.accuracy.toDouble()) + p.fillPaint.color = Color.argb(64, 255, 193, 7) + p.outlinePaint.color = Color.argb(0, 0, 0, 0) + homepoints_overlay_folder.add(p) + } + } + + /* Overlay current track on map */ + fun overlayCurrentTrack(track: Track, trackingState: Int) { + if (currentTrackOverlay != null) { + mapView.overlays.remove(currentTrackOverlay) + } + if (currentTrackSpecialMarkerOverlay != null) { + mapView.overlays.remove(currentTrackSpecialMarkerOverlay) + } + if (track.trkpts.isNotEmpty()) { + createTrackOverlay(requireContext(), mapView, track, trackingState) + createSpecialMakersTrackOverlay(requireContext(), mapView, track, trackingState) + } + } + + /* Toggles state of main button and additional buttons (save & resume) */ + fun updateMainButton(trackingState: Int) + { + when (trackingState) { + Keys.STATE_TRACKING_STOPPED -> { + mainButton.setIconResource(R.drawable.ic_fiber_manual_record_inactive_24dp) + mainButton.text = requireContext().getString(R.string.button_start) + mainButton.contentDescription = requireContext().getString(R.string.descr_button_start) + currentLocationButton.isVisible = true + } + Keys.STATE_TRACKING_ACTIVE -> { + mainButton.setIconResource(R.drawable.ic_fiber_manual_stop_24dp) + mainButton.text = requireContext().getString(R.string.button_pause) + mainButton.contentDescription = requireContext().getString(R.string.descr_button_pause) + currentLocationButton.isVisible = true + } + } + } + + fun toggleLocationErrorBar(gpsProviderActive: Boolean, networkProviderActive: Boolean) { + if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED) { + // CASE: Location permission not granted + locationErrorBar.setText(R.string.snackbar_message_location_permission_denied) + if (!locationErrorBar.isShown) locationErrorBar.show() + } else if (!gpsProviderActive && !networkProviderActive) { + // CASE: Location setting is off + locationErrorBar.setText(R.string.snackbar_message_location_offline) + if (!locationErrorBar.isShown) locationErrorBar.show() + } else { + if (locationErrorBar.isShown) locationErrorBar.dismiss() + } + } /* * End of declaration */ @@ -231,7 +474,7 @@ class MapFragment : Fragment() trackerService = binder.service // get state of tracking and update button if necessary trackingState = trackerService.trackingState - layout.updateMainButton(trackingState) + updateMainButton(trackingState) // register listener for changes in shared preferences PreferencesHelper.registerPreferenceChangeListener(sharedPreferenceChangeListener) // start listening for location updates @@ -259,15 +502,15 @@ class MapFragment : Fragment() networkProviderActive = trackerService.networkProviderActive trackingState = trackerService.trackingState // update location and track - layout.markCurrentPosition(currentBestLocation, trackingState) - layout.overlayCurrentTrack(track, trackingState) + markCurrentPosition(currentBestLocation, trackingState) + overlayCurrentTrack(track, trackingState) // center map, if it had not been dragged/zoomed before - if (!layout.userInteraction) + if (!userInteraction) { - layout.centerMap(currentBestLocation, true) + centerMap(currentBestLocation, true) } // show error snackbar if necessary - layout.toggleLocationErrorBar(gpsProviderActive, networkProviderActive) + toggleLocationErrorBar(gpsProviderActive, networkProviderActive) // use the handler to start runnable again after specified delay handler.postDelayed(this, Keys.REQUEST_CURRENT_LOCATION_INTERVAL) } diff --git a/app/src/main/java/org/y20k/trackbook/ui/MapFragmentLayoutHolder.kt b/app/src/main/java/org/y20k/trackbook/ui/MapFragmentLayoutHolder.kt deleted file mode 100644 index 83c949e..0000000 --- a/app/src/main/java/org/y20k/trackbook/ui/MapFragmentLayoutHolder.kt +++ /dev/null @@ -1,283 +0,0 @@ -/* - * MapFragmentLayoutHolder.kt - * Implements the MapFragmentLayoutHolder class - * A MapFragmentLayoutHolder hold references to the main views of a map fragment - * - * This file is part of - * TRACKBOOK - Movement Recorder for Android - * - * Copyright (c) 2016-22 - Y20K.org - * Licensed under the MIT-License - * http://opensource.org/licenses/MIT - * - * Trackbook uses osmdroid - OpenStreetMap-Tools for Android - * https://github.com/osmdroid/osmdroid - */ - -package org.y20k.trackbook.ui - -import android.Manifest -import android.annotation.SuppressLint -import android.app.Activity -import android.content.Context -import android.content.pm.PackageManager -import android.content.res.Resources -import android.graphics.Color -import android.graphics.Paint -import android.graphics.drawable.Drawable -import android.location.Location -import android.util.Log -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.core.content.ContextCompat -import androidx.core.view.isVisible -import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton -import com.google.android.material.floatingactionbutton.FloatingActionButton -import com.google.android.material.snackbar.Snackbar -import org.osmdroid.api.IMapController -import org.osmdroid.tileprovider.tilesource.TileSourceFactory -import org.osmdroid.util.GeoPoint -import org.osmdroid.views.MapView -import org.osmdroid.views.overlay.ItemizedIconOverlay -import org.osmdroid.views.overlay.OverlayItem -import org.osmdroid.views.overlay.Polygon -import org.osmdroid.views.overlay.TilesOverlay -import org.osmdroid.views.overlay.compass.CompassOverlay -import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider -import org.osmdroid.views.overlay.simplefastpoint.SimpleFastPointOverlay -import org.y20k.trackbook.Homepoint -import org.y20k.trackbook.Keys -import org.y20k.trackbook.R -import org.y20k.trackbook.Trackbook -import org.y20k.trackbook.Track -import org.y20k.trackbook.helpers.* - -/* - * MapFragmentLayoutHolder class - */ -data class MapFragmentLayoutHolder( - private var context: Context, - private var inflater: LayoutInflater, - private var container: ViewGroup?, - private var statusBarHeight: Int, - private val startLocation: Location, - private val trackingState: Int -) -{ - val rootView: View - var userInteraction: Boolean = false - val currentLocationButton: FloatingActionButton - val mainButton: ExtendedFloatingActionButton - private val mapView: MapView - private var currentPositionOverlay: ItemizedIconOverlay - private var current_location_radius: Polygon = Polygon() - private var currentTrackOverlay: SimpleFastPointOverlay? - private var currentTrackSpecialMarkerOverlay: ItemizedIconOverlay? - private var locationErrorBar: Snackbar - private var controller: IMapController - private var zoomLevel: Double - - init - { - Log.i("VOUSSOIR", "MapFragmentLayoutHolder.init") - // find views - rootView = inflater.inflate(R.layout.fragment_map, container, false) - mapView = rootView.findViewById(R.id.map) - currentLocationButton = rootView.findViewById(R.id.location_button) - mainButton = rootView.findViewById(R.id.main_button) - locationErrorBar = Snackbar.make(mapView, String(), Snackbar.LENGTH_INDEFINITE) - - // basic map setup - controller = mapView.controller - mapView.isTilesScaledToDpi = true - mapView.setTileSource(TileSourceFactory.MAPNIK) - mapView.setMultiTouchControls(true) - mapView.zoomController.setVisibility(org.osmdroid.views.CustomZoomButtonsController.Visibility.NEVER) - zoomLevel = PreferencesHelper.loadZoomLevel() - controller.setZoom(zoomLevel) - - // set dark map tiles, if necessary - if (AppThemeHelper.isDarkModeOn(context as Activity)) { - mapView.overlayManager.tilesOverlay.setColorFilter(TilesOverlay.INVERT_COLORS) - } - - // store Density Scaling Factor - val densityScalingFactor: Float = UiHelper.getDensityScalingFactor(context) - - // add compass to map - val compassOverlay = CompassOverlay(context, InternalCompassOrientationProvider(context), mapView) - compassOverlay.enableCompass() -// compassOverlay.setCompassCenter(36f, 36f + (statusBarHeight / densityScalingFactor)) // TODO uncomment when transparent status bar is re-implemented - val screen_width = Resources.getSystem().getDisplayMetrics().widthPixels; - compassOverlay.setCompassCenter((screen_width / densityScalingFactor) - 36f, 36f) - mapView.overlays.add(compassOverlay) - - val app: Trackbook = (context.applicationContext as Trackbook) - app.load_homepoints() - createHomepointOverlays(context, mapView, app.homepoints) - - // add my location overlay - currentPositionOverlay = createOverlay(context, ArrayList()) - mapView.overlays.add(currentPositionOverlay) - centerMap(startLocation) - - // initialize track overlays - currentTrackOverlay = null - currentTrackSpecialMarkerOverlay = null - - // initialize main button state - updateMainButton(trackingState) - - // listen for user interaction - addInteractionListener() - } - - /* Listen for user interaction */ - @SuppressLint("ClickableViewAccessibility") - private fun addInteractionListener() { - mapView.setOnTouchListener { v, event -> - userInteraction = true - false - } - } - - /* Set map center */ - fun centerMap(location: Location, animated: Boolean = false) { - val position = GeoPoint(location.latitude, location.longitude) - when (animated) { - true -> controller.animateTo(position) - false -> controller.setCenter(position) - } - userInteraction = false - } - - /* Save current best location and state of map to shared preferences */ - fun saveState(currentBestLocation: Location) { - PreferencesHelper.saveCurrentBestLocation(currentBestLocation) - PreferencesHelper.saveZoomLevel(mapView.zoomLevelDouble) - // reset user interaction state - userInteraction = false - } - - /* Mark current position on map */ - fun markCurrentPosition(location: Location, trackingState: Int = Keys.STATE_TRACKING_STOPPED) - { - Log.i("VOUSSOIR", "MapFragmentLayoutHolder.markCurrentPosition") - val locationIsOld: Boolean = !(isRecentEnough(location)) - - // create marker - val newMarker: Drawable - val fillcolor: Int - if (trackingState == Keys.STATE_TRACKING_ACTIVE) - { - fillcolor = Color.argb(64, 220, 61, 51) - if (locationIsOld) - { - newMarker = ContextCompat.getDrawable(context, R.drawable.ic_marker_location_black_24dp)!! - } - else - { - newMarker = ContextCompat.getDrawable(context, R.drawable.ic_marker_location_red_24dp)!! - } - } - else - { - fillcolor = Color.argb(64, 60, 152, 219) - if(locationIsOld) - { - newMarker = ContextCompat.getDrawable(context, R.drawable.ic_marker_location_black_24dp)!! - } - else - { - newMarker = ContextCompat.getDrawable(context, R.drawable.ic_marker_location_blue_24dp)!! - } - } - - // add marker to list of overlay items - val overlayItem: OverlayItem = createOverlayItem(context, location.latitude, location.longitude, location.accuracy, location.provider.toString(), location.time) - overlayItem.setMarker(newMarker) - currentPositionOverlay.removeAllItems() - currentPositionOverlay.addItem(overlayItem) - - if (current_location_radius in mapView.overlays) - { - mapView.overlays.remove(current_location_radius) - } - current_location_radius = Polygon() - current_location_radius.points = Polygon.pointsAsCircle(GeoPoint(location.latitude, location.longitude), location.accuracy.toDouble()) - current_location_radius.fillPaint.color = fillcolor - current_location_radius.outlinePaint.color = Color.argb(0, 0, 0, 0) - mapView.overlays.add(current_location_radius) - } - - fun createHomepointOverlays(context: Context, map_view: MapView, homepoints: List) - { - Log.i("VOUSSOIR", "MapFragmentLayoutHolder.createHomepointOverlays") - val overlayItems: java.util.ArrayList = java.util.ArrayList() - - val newMarker: Drawable = ContextCompat.getDrawable(context, R.drawable.ic_homepoint_24dp)!! - - for (homepoint in homepoints) - { - val overlayItem: OverlayItem = createOverlayItem(context, homepoint.location.latitude, homepoint.location.longitude, homepoint.location.accuracy, homepoint.location.provider.toString(), homepoint.location.time) - overlayItem.setMarker(newMarker) - overlayItems.add(overlayItem) - map_view.overlays.add(createOverlay(context, overlayItems)) - - val p = Polygon() - p.points = Polygon.pointsAsCircle(GeoPoint(homepoint.location.latitude, homepoint.location.longitude), homepoint.location.accuracy.toDouble()) - p.fillPaint.color = Color.argb(64, 255, 193, 7) - p.outlinePaint.color = Color.argb(0, 0, 0, 0) - map_view.overlays.add(p) - } - } - - /* Overlay current track on map */ - fun overlayCurrentTrack(track: Track, trackingState: Int) { - if (currentTrackOverlay != null) { - mapView.overlays.remove(currentTrackOverlay) - } - if (currentTrackSpecialMarkerOverlay != null) { - mapView.overlays.remove(currentTrackSpecialMarkerOverlay) - } - if (track.trkpts.isNotEmpty()) { - createTrackOverlay(context, mapView, track, trackingState) - createSpecialMakersTrackOverlay(context, mapView, track, trackingState) - } - } - - /* Toggles state of main button and additional buttons (save & resume) */ - fun updateMainButton(trackingState: Int) - { - when (trackingState) { - Keys.STATE_TRACKING_STOPPED -> { - mainButton.setIconResource(R.drawable.ic_fiber_manual_record_inactive_24dp) - mainButton.text = context.getString(R.string.button_start) - mainButton.contentDescription = context.getString(R.string.descr_button_start) - currentLocationButton.isVisible = true - } - Keys.STATE_TRACKING_ACTIVE -> { - mainButton.setIconResource(R.drawable.ic_fiber_manual_stop_24dp) - mainButton.text = context.getString(R.string.button_pause) - mainButton.contentDescription = context.getString(R.string.descr_button_pause) - currentLocationButton.isVisible = true - } - } - } - - /* Toggles content and visibility of the location error snackbar */ - fun toggleLocationErrorBar(gpsProviderActive: Boolean, networkProviderActive: Boolean) { - if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED) { - // CASE: Location permission not granted - locationErrorBar.setText(R.string.snackbar_message_location_permission_denied) - if (!locationErrorBar.isShown) locationErrorBar.show() - } else if (!gpsProviderActive && !networkProviderActive) { - // CASE: Location setting is off - locationErrorBar.setText(R.string.snackbar_message_location_offline) - if (!locationErrorBar.isShown) locationErrorBar.show() - } else { - if (locationErrorBar.isShown) locationErrorBar.dismiss() - } - } -}