mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
refactor(map): remove fixed zoom level for offline downloads (#694)
This commit is contained in:
parent
80cee441c6
commit
ef11af6e0b
21 changed files with 30 additions and 175 deletions
|
|
@ -1,25 +0,0 @@
|
|||
package com.geeksville.mesh.model.map
|
||||
|
||||
import android.view.MotionEvent
|
||||
import org.osmdroid.views.MapView
|
||||
import org.osmdroid.views.overlay.DefaultOverlayManager
|
||||
import org.osmdroid.views.overlay.TilesOverlay
|
||||
|
||||
/**
|
||||
* CustomOverlayManager with disabled double taps events
|
||||
*/
|
||||
class CustomOverlayManager(tilesOverlay: TilesOverlay?) : DefaultOverlayManager(tilesOverlay) {
|
||||
/**
|
||||
* Override event & do nothing
|
||||
*/
|
||||
override fun onDoubleTap(e: MotionEvent?, pMapView: MapView?): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Override event & do nothing
|
||||
*/
|
||||
override fun onDoubleTapEvent(e: MotionEvent?, pMapView: MapView?): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -49,7 +49,6 @@ import com.geeksville.mesh.android.hasLocationPermission
|
|||
import com.geeksville.mesh.copy
|
||||
import com.geeksville.mesh.database.entity.Packet
|
||||
import com.geeksville.mesh.model.UIViewModel
|
||||
import com.geeksville.mesh.model.map.CustomOverlayManager
|
||||
import com.geeksville.mesh.model.map.CustomTileSource
|
||||
import com.geeksville.mesh.model.map.MarkerWithLabel
|
||||
import com.geeksville.mesh.ui.ScreenFragment
|
||||
|
|
@ -69,6 +68,9 @@ import dagger.hilt.android.AndroidEntryPoint
|
|||
import kotlinx.coroutines.delay
|
||||
import org.osmdroid.config.Configuration
|
||||
import org.osmdroid.events.MapEventsReceiver
|
||||
import org.osmdroid.events.MapListener
|
||||
import org.osmdroid.events.ScrollEvent
|
||||
import org.osmdroid.events.ZoomEvent
|
||||
import org.osmdroid.tileprovider.cachemanager.CacheManager
|
||||
import org.osmdroid.tileprovider.modules.SqliteArchiveTileWriter
|
||||
import org.osmdroid.tileprovider.tilesource.ITileSource
|
||||
|
|
@ -119,16 +121,9 @@ fun MapView(model: UIViewModel = viewModel()) {
|
|||
var cacheEstimate by remember { mutableStateOf("") }
|
||||
|
||||
// constants
|
||||
val defaultMinZoom = 1.5
|
||||
val defaultMaxZoom = 18.0
|
||||
val prefsName = "org.geeksville.osm.prefs"
|
||||
val mapStyleId = "map_style_id"
|
||||
|
||||
// Distance of bottom corner to top corner of bounding box
|
||||
val zoomLevelLowest = 13.0 // approx 5 miles long
|
||||
val zoomLevelMiddle = 12.25 // approx 10 miles long
|
||||
val zoomLevelHighest = 11.5 // approx 15 miles long
|
||||
|
||||
var zoomLevelMin = 0.0
|
||||
var zoomLevelMax = 0.0
|
||||
|
||||
|
|
@ -488,6 +483,7 @@ fun MapView(model: UIViewModel = viewModel()) {
|
|||
val id = mPrefs.getInt(mapStyleId, 1)
|
||||
debug("mapStyleId from prefs: $id")
|
||||
return CustomTileSource.getTileSource(id).also {
|
||||
map.maxZoomLevel = it.maximumZoomLevel.toDouble()
|
||||
showDownloadButton =
|
||||
if (it is OnlineTileSourceBase) it.tileSourcePolicy.acceptsBulkDownload() else false
|
||||
}
|
||||
|
|
@ -496,18 +492,11 @@ fun MapView(model: UIViewModel = viewModel()) {
|
|||
/**
|
||||
* Creates Box overlay showing what area can be downloaded
|
||||
*/
|
||||
fun MapView.generateBoxOverlay(zoomLevel: Double) {
|
||||
if (overlayManager !is CustomOverlayManager) {
|
||||
overlayManager = CustomOverlayManager(TilesOverlay(tileProvider, context))
|
||||
setMultiTouchControls(false)
|
||||
zoomLevelMax = tileProvider.tileSource.maximumZoomLevel.toDouble()
|
||||
drawOverlays()
|
||||
} else {
|
||||
overlays.removeAll(overlays.filterIsInstance<Polygon>())
|
||||
}
|
||||
fun MapView.generateBoxOverlay() {
|
||||
overlays.removeAll(overlays.filterIsInstance<Polygon>())
|
||||
val zoomFactor = 1.3 // zoom difference between view and download area polygon
|
||||
controller.setZoom(zoomLevel - zoomFactor)
|
||||
zoomLevelMin = zoomLevel
|
||||
zoomLevelMax = maxZoomLevel
|
||||
zoomLevelMin = maxOf(zoomLevelDouble, maxZoomLevel)
|
||||
downloadRegionBoundingBox = boundingBox.zoomIn(zoomFactor)
|
||||
val polygon = Polygon().apply {
|
||||
points = Polygon.pointsAsRect(downloadRegionBoundingBox).map {
|
||||
|
|
@ -518,7 +507,7 @@ fun MapView(model: UIViewModel = viewModel()) {
|
|||
val tileCount: Int = CacheManager(this).possibleTilesInArea(
|
||||
downloadRegionBoundingBox,
|
||||
zoomLevelMin.toInt(),
|
||||
zoomLevelMax.toInt()
|
||||
zoomLevelMax.toInt(),
|
||||
)
|
||||
cacheEstimate = context.getString(R.string.map_cache_tiles, tileCount)
|
||||
}
|
||||
|
|
@ -577,7 +566,7 @@ fun MapView(model: UIViewModel = viewModel()) {
|
|||
when (which) {
|
||||
0 -> showCurrentCacheInfo = true
|
||||
1 -> {
|
||||
map.generateBoxOverlay(zoomLevelHighest)
|
||||
map.generateBoxOverlay()
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
|
|
@ -615,17 +604,25 @@ fun MapView(model: UIViewModel = viewModel()) {
|
|||
// scales the map tiles to the display density of the screen
|
||||
isTilesScaledToDpi = true
|
||||
// sets the minimum zoom level (the furthest out you can zoom)
|
||||
minZoomLevel = defaultMinZoom
|
||||
maxZoomLevel = defaultMaxZoom
|
||||
minZoomLevel = 1.5
|
||||
// Disables default +/- button for zooming
|
||||
zoomController.setVisibility(CustomZoomButtonsController.Visibility.NEVER)
|
||||
addMapListener(object : MapListener {
|
||||
override fun onScroll(event: ScrollEvent): Boolean {
|
||||
if (downloadRegionBoundingBox != null) generateBoxOverlay()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onZoom(event: ZoomEvent): Boolean {
|
||||
return false
|
||||
}
|
||||
})
|
||||
zoomToNodes()
|
||||
}
|
||||
},
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
update = { map ->
|
||||
if (downloadRegionBoundingBox == null) map.drawOverlays()
|
||||
else map.generateBoxOverlay(zoomLevelMin)
|
||||
},
|
||||
)
|
||||
if (downloadRegionBoundingBox != null) CacheLayout(
|
||||
|
|
@ -633,10 +630,7 @@ fun MapView(model: UIViewModel = viewModel()) {
|
|||
onExecuteJob = { startDownload() },
|
||||
onCancelDownload = {
|
||||
downloadRegionBoundingBox = null
|
||||
map.apply {
|
||||
overlayManager = DefaultOverlayManager(TilesOverlay(tileProvider, context))
|
||||
setMultiTouchControls(true)
|
||||
}
|
||||
map.overlays.removeAll(map.overlays.filterIsInstance<Polygon>())
|
||||
},
|
||||
modifier = Modifier.align(Alignment.BottomCenter)
|
||||
) else Column(
|
||||
|
|
|
|||
|
|
@ -8,23 +8,16 @@ import androidx.compose.foundation.layout.Spacer
|
|||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.material.ButtonDefaults
|
||||
import androidx.compose.material.ContentAlpha
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.geeksville.mesh.R
|
||||
|
|
@ -36,8 +29,6 @@ fun CacheLayout(
|
|||
onCancelDownload: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var selectedDistance by remember { mutableStateOf(5) }
|
||||
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
|
|
@ -50,106 +41,55 @@ fun CacheLayout(
|
|||
modifier = Modifier.fillMaxWidth(),
|
||||
textAlign = TextAlign.Center,
|
||||
style = MaterialTheme.typography.h5,
|
||||
color = MaterialTheme.colors.onBackground.copy(alpha = ContentAlpha.medium)
|
||||
color = MaterialTheme.colors.onBackground.copy(alpha = ContentAlpha.medium),
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
val distances = listOf(5, 10, 15)
|
||||
val selectedDistanceIndex = distances.indexOf(selectedDistance)
|
||||
|
||||
// ToggleButton(
|
||||
// options = distances.map { it.toString() },
|
||||
// selectedOptionIndex = selectedDistanceIndex,
|
||||
// onOptionSelected = { selectedDistance = distances[it] },
|
||||
// )
|
||||
|
||||
// Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Text(
|
||||
text = stringResource(R.string.map_tile_download_estimate) + " " + cacheEstimate,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
textAlign = TextAlign.Center,
|
||||
style = MaterialTheme.typography.body1,
|
||||
color = MaterialTheme.colors.onBackground.copy(alpha = ContentAlpha.medium)
|
||||
color = MaterialTheme.colors.onBackground.copy(alpha = ContentAlpha.medium),
|
||||
)
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
) {
|
||||
Button(
|
||||
onClick = onCancelDownload,
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(start = 8.dp)
|
||||
.padding(start = 8.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.cancel),
|
||||
color = MaterialTheme.colors.onPrimary
|
||||
color = MaterialTheme.colors.onPrimary,
|
||||
)
|
||||
}
|
||||
Button(
|
||||
onClick = onExecuteJob,
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(end = 8.dp)
|
||||
.padding(end = 8.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.map_start_download),
|
||||
color = MaterialTheme.colors.onPrimary
|
||||
color = MaterialTheme.colors.onPrimary,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ToggleButton(
|
||||
options: List<String>,
|
||||
selectedOptionIndex: Int,
|
||||
onOptionSelected: (Int) -> Unit
|
||||
) {
|
||||
val backgroundColor = MaterialTheme.colors.background
|
||||
val selectedColor = MaterialTheme.colors.primary
|
||||
val textColor = MaterialTheme.colors.onBackground.copy(alpha = ContentAlpha.medium)
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
options.forEachIndexed { index, option ->
|
||||
val isSelected = index == selectedOptionIndex
|
||||
|
||||
Button(
|
||||
onClick = { onOptionSelected(index) },
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
backgroundColor = if (isSelected) selectedColor else backgroundColor,
|
||||
contentColor = textColor
|
||||
),
|
||||
modifier = Modifier.weight(1f)
|
||||
) {
|
||||
Text(
|
||||
text = option,
|
||||
textAlign = TextAlign.Center,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
|
||||
if (index != options.lastIndex) {
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun CacheLayoutPreview() {
|
||||
CacheLayout(
|
||||
cacheEstimate = "100 tiles",
|
||||
onExecuteJob = { },
|
||||
onCancelDownload = { }
|
||||
onCancelDownload = { },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue