kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
refactor: convert `gpsString` to `Position` extension
rodzic
b25bdb6ff8
commit
e72b046c53
|
@ -3,6 +3,7 @@ package com.geeksville.mesh
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import com.geeksville.mesh.MeshProtos.User
|
import com.geeksville.mesh.MeshProtos.User
|
||||||
|
import com.geeksville.mesh.util.GPSFormat
|
||||||
import com.geeksville.mesh.util.bearing
|
import com.geeksville.mesh.util.bearing
|
||||||
import com.geeksville.mesh.util.latLongToMeter
|
import com.geeksville.mesh.util.latLongToMeter
|
||||||
import com.geeksville.mesh.util.anonymize
|
import com.geeksville.mesh.util.anonymize
|
||||||
|
@ -79,6 +80,14 @@ data class Position(
|
||||||
(longitude >= -180 && longitude <= 180)
|
(longitude >= -180 && longitude <= 180)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun gpsString(gpsFormat: Int): String = when (gpsFormat) {
|
||||||
|
ConfigProtos.Config.DisplayConfig.GpsCoordinateFormat.DEC_VALUE -> GPSFormat.DEC(this)
|
||||||
|
ConfigProtos.Config.DisplayConfig.GpsCoordinateFormat.DMS_VALUE -> GPSFormat.DMS(this)
|
||||||
|
ConfigProtos.Config.DisplayConfig.GpsCoordinateFormat.UTM_VALUE -> GPSFormat.UTM(this)
|
||||||
|
ConfigProtos.Config.DisplayConfig.GpsCoordinateFormat.MGRS_VALUE -> GPSFormat.MGRS(this)
|
||||||
|
else -> GPSFormat.DEC(this)
|
||||||
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "Position(lat=${latitude.anonymize}, lon=${longitude.anonymize}, alt=${altitude.anonymize}, time=${time})"
|
return "Position(lat=${latitude.anonymize}, lon=${longitude.anonymize}, alt=${altitude.anonymize}, time=${time})"
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import android.net.Uri
|
||||||
import android.os.RemoteException
|
import android.os.RemoteException
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.lifecycle.asFlow
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
@ -31,7 +30,6 @@ import com.geeksville.mesh.database.PacketRepository
|
||||||
import com.geeksville.mesh.repository.datastore.RadioConfigRepository
|
import com.geeksville.mesh.repository.datastore.RadioConfigRepository
|
||||||
import com.geeksville.mesh.repository.radio.RadioInterfaceService
|
import com.geeksville.mesh.repository.radio.RadioInterfaceService
|
||||||
import com.geeksville.mesh.service.MeshService
|
import com.geeksville.mesh.service.MeshService
|
||||||
import com.geeksville.mesh.util.GPSFormat
|
|
||||||
import com.geeksville.mesh.util.positionToMeter
|
import com.geeksville.mesh.util.positionToMeter
|
||||||
import com.google.protobuf.MessageLite
|
import com.google.protobuf.MessageLite
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
@ -403,16 +401,6 @@ class UIViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun gpsString(p: Position): String {
|
|
||||||
return when (config.display.gpsFormat) {
|
|
||||||
Config.DisplayConfig.GpsCoordinateFormat.DEC -> GPSFormat.DEC(p)
|
|
||||||
Config.DisplayConfig.GpsCoordinateFormat.DMS -> GPSFormat.DMS(p)
|
|
||||||
Config.DisplayConfig.GpsCoordinateFormat.UTM -> GPSFormat.UTM(p)
|
|
||||||
Config.DisplayConfig.GpsCoordinateFormat.MGRS -> GPSFormat.MGRS(p)
|
|
||||||
else -> GPSFormat.DEC(p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// managed mode disables all access to configuration
|
// managed mode disables all access to configuration
|
||||||
val isManaged: Boolean get() = config.device.isManaged
|
val isManaged: Boolean get() = config.device.isManaged
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ import android.os.Build
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.appcompat.content.res.AppCompatResources
|
import androidx.appcompat.content.res.AppCompatResources
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.graphics.drawable.toBitmap
|
import androidx.core.graphics.drawable.toBitmapOrNull
|
||||||
import com.geeksville.mesh.MainActivity
|
import com.geeksville.mesh.MainActivity
|
||||||
import com.geeksville.mesh.R
|
import com.geeksville.mesh.R
|
||||||
import com.geeksville.mesh.android.notificationManager
|
import com.geeksville.mesh.android.notificationManager
|
||||||
|
@ -116,10 +116,10 @@ class MeshServiceNotifications(
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a bitmap from a vector drawable (even on old builds)
|
* Generate a bitmap from a vector drawable (even on old builds)
|
||||||
* https://stackoverflow.com/questions/33696488/getting-bitmap-from-vector-drawable
|
* https://stackoverflow.com/questions/33696488/getting-bitmap-from-vector-drawable/#51742167
|
||||||
*/
|
*/
|
||||||
private fun getBitmapFromVectorDrawable(drawableId: Int): Bitmap? =
|
private fun getBitmapFromVectorDrawable(drawableId: Int): Bitmap? =
|
||||||
AppCompatResources.getDrawable(context, drawableId)?.toBitmap()
|
AppCompatResources.getDrawable(context, drawableId)?.toBitmapOrNull()
|
||||||
|
|
||||||
private fun commonBuilder(channel: String): NotificationCompat.Builder {
|
private fun commonBuilder(channel: String): NotificationCompat.Builder {
|
||||||
val builder = NotificationCompat.Builder(context, channel)
|
val builder = NotificationCompat.Builder(context, channel)
|
||||||
|
|
|
@ -58,6 +58,9 @@ class UsersFragment : ScreenFragment("Users"), Logging {
|
||||||
private var nodes = arrayOf<NodeInfo>()
|
private var nodes = arrayOf<NodeInfo>()
|
||||||
val ignoreIncomingList: MutableList<Int> = mutableListOf()
|
val ignoreIncomingList: MutableList<Int> = mutableListOf()
|
||||||
|
|
||||||
|
private val gpsFormat by lazy { model.config.display.gpsFormat.number }
|
||||||
|
private val displayUnits by lazy { model.config.display.units.number }
|
||||||
|
|
||||||
private fun CharSequence.strike() = SpannableString(this).apply {
|
private fun CharSequence.strike() = SpannableString(this).apply {
|
||||||
setSpan(StrikethroughSpan(), 0, this.length, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE)
|
setSpan(StrikethroughSpan(), 0, this.length, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
}
|
}
|
||||||
|
@ -215,7 +218,7 @@ class UsersFragment : ScreenFragment("Users"), Logging {
|
||||||
if (pos != null) {
|
if (pos != null) {
|
||||||
val html = "<a href='geo:${pos.latitude},${pos.longitude}?z=17&label=${
|
val html = "<a href='geo:${pos.latitude},${pos.longitude}?z=17&label=${
|
||||||
URLEncoder.encode(name, "utf-8")
|
URLEncoder.encode(name, "utf-8")
|
||||||
}'>${model.gpsString(pos)}</a>"
|
}'>${pos.gpsString(gpsFormat)}</a>"
|
||||||
holder.coordsView.text = HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY)
|
holder.coordsView.text = HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY)
|
||||||
holder.coordsView.movementMethod = LinkMovementMethod.getInstance()
|
holder.coordsView.movementMethod = LinkMovementMethod.getInstance()
|
||||||
holder.coordsView.visibility = View.VISIBLE
|
holder.coordsView.visibility = View.VISIBLE
|
||||||
|
@ -224,7 +227,7 @@ class UsersFragment : ScreenFragment("Users"), Logging {
|
||||||
}
|
}
|
||||||
|
|
||||||
val ourNodeInfo = model.ourNodeInfo.value
|
val ourNodeInfo = model.ourNodeInfo.value
|
||||||
val distance = ourNodeInfo?.distanceStr(n, model.config.display.units.number)
|
val distance = ourNodeInfo?.distanceStr(n, displayUnits)
|
||||||
if (distance != null) {
|
if (distance != null) {
|
||||||
holder.distanceView.text = distance
|
holder.distanceView.text = distance
|
||||||
holder.distanceView.visibility = View.VISIBLE
|
holder.distanceView.visibility = View.VISIBLE
|
||||||
|
|
|
@ -81,11 +81,9 @@ import org.osmdroid.util.GeoPoint
|
||||||
import org.osmdroid.views.CustomZoomButtonsController
|
import org.osmdroid.views.CustomZoomButtonsController
|
||||||
import org.osmdroid.views.MapView
|
import org.osmdroid.views.MapView
|
||||||
import org.osmdroid.views.overlay.CopyrightOverlay
|
import org.osmdroid.views.overlay.CopyrightOverlay
|
||||||
import org.osmdroid.views.overlay.DefaultOverlayManager
|
|
||||||
import org.osmdroid.views.overlay.MapEventsOverlay
|
import org.osmdroid.views.overlay.MapEventsOverlay
|
||||||
import org.osmdroid.views.overlay.Marker
|
import org.osmdroid.views.overlay.Marker
|
||||||
import org.osmdroid.views.overlay.Polygon
|
import org.osmdroid.views.overlay.Polygon
|
||||||
import org.osmdroid.views.overlay.TilesOverlay
|
|
||||||
import org.osmdroid.views.overlay.gridlines.LatLonGridlineOverlay2
|
import org.osmdroid.views.overlay.gridlines.LatLonGridlineOverlay2
|
||||||
import org.osmdroid.views.overlay.infowindow.InfoWindow
|
import org.osmdroid.views.overlay.infowindow.InfoWindow
|
||||||
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay
|
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay
|
||||||
|
@ -188,23 +186,28 @@ fun MapView(model: UIViewModel = viewModel()) {
|
||||||
var showEditWaypointDialog by remember { mutableStateOf<Waypoint?>(null) }
|
var showEditWaypointDialog by remember { mutableStateOf<Waypoint?>(null) }
|
||||||
var showCurrentCacheInfo by remember { mutableStateOf(false) }
|
var showCurrentCacheInfo by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
val markerIcon by lazy {
|
||||||
|
AppCompatResources.getDrawable(context, R.drawable.ic_baseline_location_on_24)
|
||||||
|
}
|
||||||
|
|
||||||
fun MapView.onNodesChanged(nodes: Collection<NodeInfo>): List<MarkerWithLabel> {
|
fun MapView.onNodesChanged(nodes: Collection<NodeInfo>): List<MarkerWithLabel> {
|
||||||
val nodesWithPosition = nodes.filter { it.validPosition != null }
|
val nodesWithPosition = nodes.filter { it.validPosition != null }
|
||||||
val ic = ContextCompat.getDrawable(context, R.drawable.ic_baseline_location_on_24)
|
|
||||||
val ourNode = model.ourNodeInfo.value
|
val ourNode = model.ourNodeInfo.value
|
||||||
|
val gpsFormat = model.config.display.gpsFormat.number
|
||||||
|
val displayUnits = model.config.display.units.number
|
||||||
return nodesWithPosition.map { node ->
|
return nodesWithPosition.map { node ->
|
||||||
val (p, u) = node.position!! to node.user!!
|
val (p, u) = node.position!! to node.user!!
|
||||||
MarkerWithLabel(this, "${u.longName} ${formatAgo(p.time)}").apply {
|
MarkerWithLabel(this, "${u.shortName} ${formatAgo(p.time)}").apply {
|
||||||
id = u.id
|
id = u.id
|
||||||
title = "${u.longName} ${node.batteryStr}"
|
title = "${u.longName} ${node.batteryStr}"
|
||||||
snippet = model.gpsString(p)
|
snippet = p.gpsString(gpsFormat)
|
||||||
ourNode?.distanceStr(node, model.config.display.units.number)?.let { dist ->
|
ourNode?.distanceStr(node, displayUnits)?.let { dist ->
|
||||||
subDescription =
|
subDescription =
|
||||||
context.getString(R.string.map_subDescription, ourNode.bearing(node), dist)
|
context.getString(R.string.map_subDescription, ourNode.bearing(node), dist)
|
||||||
}
|
}
|
||||||
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
|
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
|
||||||
position = GeoPoint(p.latitude, p.longitude)
|
position = GeoPoint(p.latitude, p.longitude)
|
||||||
icon = ic
|
icon = markerIcon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -594,7 +597,6 @@ fun MapView(model: UIViewModel = viewModel()) {
|
||||||
setTileSource(loadOnlineTileSourceBase())
|
setTileSource(loadOnlineTileSourceBase())
|
||||||
setDestroyMode(false) // keeps map instance alive when in the background
|
setDestroyMode(false) // keeps map instance alive when in the background
|
||||||
isVerticalMapRepetitionEnabled = false // disables map repetition
|
isVerticalMapRepetitionEnabled = false // disables map repetition
|
||||||
overlayManager = DefaultOverlayManager(TilesOverlay(tileProvider, context))
|
|
||||||
setMultiTouchControls(true)
|
setMultiTouchControls(true)
|
||||||
setScrollableAreaLimitLatitude( // bounds scrollable map
|
setScrollableAreaLimitLatitude( // bounds scrollable map
|
||||||
overlayManager.tilesOverlay.bounds.actualNorth,
|
overlayManager.tilesOverlay.bounds.actualNorth,
|
||||||
|
|
Ładowanie…
Reference in New Issue