refactor(map): remove fixed zoom level for offline downloads (#694)

This commit is contained in:
Andre K 2023-08-27 06:31:27 -03:00 committed by GitHub
parent 80cee441c6
commit ef11af6e0b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 30 additions and 175 deletions

View file

@ -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
}
}

View file

@ -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(

View file

@ -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 = { },
)
}

View file

@ -138,9 +138,6 @@
<string name="nodedb_reset">Нулиране на базата данни с възли</string>
<string name="nodedb_reset_description">Това ще изчисти всички възли от този списък.</string>
<string name="map_select_download_region">Избор на регион за сваляне</string>
<string name="map_5_miles">5 мили</string>
<string name="map_10_miles">10 мили</string>
<string name="map_15_miles">15 мили</string>
<string name="map_tile_download_estimate">Прогноза за изтегляне на картинки:</string>
<string name="map_start_download">Започни свалянето</string>
<string name="request_position">Поискване на позиция</string>

View file

@ -141,9 +141,6 @@
<string name="nodedb_reset">Reset NodeDB</string>
<string name="nodedb_reset_description">Tímto vymažete všechny uzly z tohoto seznamu.</string>
<string name="map_select_download_region">Vyberte oblast stahování</string>
<string name="map_5_miles">5 mil</string>
<string name="map_10_miles">10 mil</string>
<string name="map_15_miles">15 mil</string>
<string name="map_tile_download_estimate">Odhad stažení dlaždic:</string>
<string name="map_start_download">Zahájit stahování</string>
<string name="request_position">Vyžádat pozici</string>

View file

@ -139,9 +139,6 @@
<string name="nodedb_reset">Node-Datenbank zurücksetzen</string>
<string name="nodedb_reset_description">Dies löscht alle Knoten von dieser Liste.</string>
<string name="map_select_download_region">Herunterlade-Region auswählen</string>
<string name="map_5_miles">5 Meilen/8 km</string>
<string name="map_10_miles">10 Meilen/15 km</string>
<string name="map_15_miles">15 Meilen/24 km</string>
<string name="map_tile_download_estimate">Kachel-Herunterladen-Schätzung:</string>
<string name="map_start_download">Herunterladen starten</string>
<string name="request_position">Position anfordern</string>

View file

@ -140,9 +140,6 @@
<string name="nodedb_reset">NodeDB reset</string>
<string name="nodedb_reset_description">Αυτό θα καθαρίσει όλους τους κόμβους από αυτήν τη λίστα.</string>
<string name="map_select_download_region">Επιλογή περιοχής λήψης</string>
<string name="map_5_miles">5 Μίλια</string>
<string name="map_10_miles">10 μίλια</string>
<string name="map_15_miles">15 μίλια</string>
<string name="map_tile_download_estimate">Tile download estimate:</string>
<string name="map_start_download">Εκκίνηση Λήψης</string>
<string name="request_position">Αίτηση θέσης</string>

View file

@ -137,9 +137,6 @@
<string name="nodedb_reset">Reconfiguration de NodeDB</string>
<string name="nodedb_reset_description">Ceci effacera tous les nœuds de cette liste.</string>
<string name="map_select_download_region">Sélectionnez la région de téléchargement</string>
<string name="map_5_miles">8 kilomètres</string>
<string name="map_10_miles">16 kilomètres</string>
<string name="map_15_miles">24 kilomètres</string>
<string name="map_tile_download_estimate">Estimation du téléchargement de tuiles :</string>
<string name="map_start_download">Commencer le téléchargement</string>
<string name="request_position">Demander la position</string>

View file

@ -139,9 +139,6 @@
<string name="nodedb_reset">NodeDB törlése</string>
<string name="nodedb_reset_description">Ezzel minden állomást törölni fogsz erről listáról.</string>
<string name="map_select_download_region">Válassz letöltési régiót</string>
<string name="map_5_miles">5 mérföld</string>
<string name="map_10_miles">10 mérföld</string>
<string name="map_15_miles">15 mérföld</string>
<string name="map_tile_download_estimate">Csempe letöltés számítása:</string>
<string name="map_start_download">Letöltés indítása</string>
<string name="request_position">Pozíció kérése</string>

View file

@ -137,9 +137,6 @@
<string name="nodedb_reset">Endurræsa NodeDB</string>
<string name="nodedb_reset_description">Þetta mun hreinsa út allar nóður af listanum.</string>
<string name="map_select_download_region">Veldu svæði til að niðurhala</string>
<string name="map_5_miles">8 kílómetrar</string>
<string name="map_10_miles">16 kílómetrar</string>
<string name="map_15_miles">24 kílómetrar</string>
<string name="map_tile_download_estimate">Áætlaður niðurhalstími reits:</string>
<string name="map_start_download">Hefja niðurhal</string>
<string name="request_position">Óska eftir staðsetningu</string>

View file

@ -137,9 +137,6 @@
<string name="nodedb_reset">NodeDB reset</string>
<string name="nodedb_reset_description">Questo cancellerà tutti i nodi da questo elenco.</string>
<string name="map_select_download_region">Seleziona regione di download</string>
<string name="map_5_miles">5 Miles</string>
<string name="map_10_miles">10 miles</string>
<string name="map_15_miles">15 miles</string>
<string name="map_tile_download_estimate">Tile stima download:</string>
<string name="map_start_download">Inizia download</string>
<string name="request_position">Richiedi posizione</string>

View file

@ -136,9 +136,6 @@
<string name="nodedb_reset">NodeDBをリセット</string>
<string name="nodedb_reset_description">このノードリストをクリアします。</string>
<string name="map_select_download_region">ダウンロードリージョンを選択する</string>
<string name="map_5_miles">5 マイル</string>
<string name="map_10_miles">10 マイル</string>
<string name="map_15_miles">15 マイル</string>
<string name="map_tile_download_estimate">タイルダウンロードの見積もり:</string>
<string name="map_start_download">ダウンロード開始</string>
<string name="request_position">位置を求める</string>

View file

@ -130,9 +130,6 @@
<string name="nodedb_reset">NodeDB 리셋</string>
<string name="nodedb_reset_description">이 목록의 모든 노드가 지워집니다.</string>
<string name="map_select_download_region">다운로드 지역 선택</string>
<string name="map_5_miles">8 Km</string>
<string name="map_10_miles">16 Km</string>
<string name="map_15_miles">24 Km</string>
<string name="map_tile_download_estimate">타일 다운로드 예상:</string>
<string name="map_start_download">다운로드 시작</string>
<string name="request_position">위치 요청</string>

View file

@ -131,9 +131,6 @@
<string name="nodedb_reset">NodeDB reset</string>
<string name="nodedb_reset_description">This will clear all nodes from this list.</string>
<string name="map_select_download_region">Select download region</string>
<string name="map_5_miles">5 Miles</string>
<string name="map_10_miles">10 miles</string>
<string name="map_15_miles">15 miles</string>
<string name="map_tile_download_estimate">Tile download estimate:</string>
<string name="map_start_download">Start Download</string>
<string name="request_position">Request position</string>

View file

@ -141,9 +141,6 @@
<string name="nodedb_reset">NodeDB reset</string>
<string name="nodedb_reset_description">To spowoduje usunięcie wszystkich węzłów z listy.</string>
<string name="map_select_download_region">Wybierz region do pobrania</string>
<string name="map_5_miles">5 mil</string>
<string name="map_10_miles">10 mil</string>
<string name="map_15_miles">15 mil</string>
<string name="map_tile_download_estimate">Szacowany czas pobrania:</string>
<string name="map_start_download">Rozpocznij pobieranie</string>
<string name="request_position">Poproś o pozycję</string>

View file

@ -137,9 +137,6 @@
<string name="nodedb_reset">Redefinir NodeDB</string>
<string name="nodedb_reset_description">Isto limpará todos os dispositivos desta lista.</string>
<string name="map_select_download_region">Selecione a região para download</string>
<string name="map_5_miles">5 milhas</string>
<string name="map_10_miles">10 milhas</string>
<string name="map_15_miles">15 milhas</string>
<string name="map_tile_download_estimate">Estimativa de download do bloco:</string>
<string name="map_start_download">Iniciar download</string>
<string name="request_position">Solicitar posição</string>

View file

@ -137,9 +137,6 @@
<string name="nodedb_reset">Redefinir NodeDB</string>
<string name="nodedb_reset_description">Isto limpará todos os dispositivos desta lista.</string>
<string name="map_select_download_region">Selecione a região para download</string>
<string name="map_5_miles">5 milhas</string>
<string name="map_10_miles">10 milhas</string>
<string name="map_15_miles">15 milhas</string>
<string name="map_tile_download_estimate">Estimativa de download do bloco:</string>
<string name="map_start_download">Iniciar download</string>
<string name="request_position">Solicitar posição</string>

View file

@ -141,9 +141,6 @@
<string name="nodedb_reset">Очистка списка узлов сети</string>
<string name="nodedb_reset_description">Это очистит все узлы из этого списка.</string>
<string name="map_select_download_region">Выберите регион загрузки</string>
<string name="map_5_miles">5 Миль</string>
<string name="map_10_miles">10 миль</string>
<string name="map_15_miles">15 миль</string>
<string name="map_tile_download_estimate">Предполагаемое время загрузки файла:</string>
<string name="map_start_download">Начать скачивание</string>
<string name="request_position">Запросить позицию</string>

View file

@ -141,9 +141,6 @@
<string name="nodedb_reset">Очищення бази вузлів</string>
<string name="nodedb_reset_description">Це очистить усі вузли зі списку.</string>
<string name="map_select_download_region">Оберіть регіон завантаження</string>
<string name="map_5_miles">5 миль</string>
<string name="map_10_miles">10 миль</string>
<string name="map_15_miles">15 миль</string>
<string name="map_tile_download_estimate">Час завантаження фрагментів:</string>
<string name="map_start_download">Почати завантаження</string>
<string name="request_position">Запит місцезнаходження</string>

View file

@ -136,9 +136,6 @@
<string name="nodedb_reset">节点数据库重置</string>
<string name="nodedb_reset_description">这将从该列表中清除所有节点。</string>
<string name="map_select_download_region">选择下载地区</string>
<string name="map_5_miles">5英里</string>
<string name="map_10_miles">10英里</string>
<string name="map_15_miles">15英里</string>
<string name="map_tile_download_estimate">瓷砖下载估计:</string>
<string name="map_start_download">开始下载</string>
<string name="request_position">要求位置</string>

View file

@ -154,9 +154,6 @@
<string name="ignore_add">Add \'%s\' to ignore list? Your radio will reboot after making this change.</string>
<string name="ignore_remove">Remove \'%s\' from ignore list? Your radio will reboot after making this change.</string>
<string name="map_select_download_region">Select download region</string>
<string name="map_5_miles">5 Miles</string>
<string name="map_10_miles">10 miles</string>
<string name="map_15_miles">15 miles</string>
<string name="map_tile_download_estimate">Tile download estimate:</string>
<string name="map_start_download">Start Download</string>
<string name="request_position">Request position</string>