new "mini" marker variant to avoid clustering for zoom levels 11-13

This commit is contained in:
johan12345
2022-06-12 19:36:06 +02:00
parent 93787fae74
commit aa5c36d1aa
9 changed files with 173 additions and 74 deletions

View File

@@ -126,6 +126,7 @@ class GoingElectricApiWrapper(
baseurl: String = "https://api.goingelectric.de", baseurl: String = "https://api.goingelectric.de",
context: Context? = null context: Context? = null
) : ChargepointApi<GEReferenceData> { ) : ChargepointApi<GEReferenceData> {
private val clusterThreshold = 11f
val api = GoingElectricApi.create(apikey, baseurl, context) val api = GoingElectricApi.create(apikey, baseurl, context)
override fun getName() = "GoingElectric.de" override fun getName() = "GoingElectric.de"
@@ -173,7 +174,7 @@ class GoingElectricApiWrapper(
val categories = formatMultipleChoice(categoriesVal) val categories = formatMultipleChoice(categoriesVal)
// do not use clustering if filters need to be applied locally. // do not use clustering if filters need to be applied locally.
val useClustering = zoom < 13 val useClustering = zoom < clusterThreshold
val geClusteringAvailable = minConnectors == null || minConnectors <= 1 val geClusteringAvailable = minConnectors == null || minConnectors <= 1
val useGeClustering = useClustering && geClusteringAvailable val useGeClustering = useClustering && geClusteringAvailable
val clusterDistance = if (useClustering) getClusterDistance(zoom) else null val clusterDistance = if (useClustering) getClusterDistance(zoom) else null
@@ -267,7 +268,7 @@ class GoingElectricApiWrapper(
val categories = formatMultipleChoice(categoriesVal) val categories = formatMultipleChoice(categoriesVal)
// do not use clustering if filters need to be applied locally. // do not use clustering if filters need to be applied locally.
val useClustering = zoom < 13 val useClustering = zoom < clusterThreshold
val geClusteringAvailable = minConnectors == null || minConnectors <= 1 val geClusteringAvailable = minConnectors == null || minConnectors <= 1
val useGeClustering = useClustering && geClusteringAvailable val useGeClustering = useClustering && geClusteringAvailable
val clusterDistance = if (useClustering) getClusterDistance(zoom) else null val clusterDistance = if (useClustering) getClusterDistance(zoom) else null
@@ -330,7 +331,7 @@ class GoingElectricApiWrapper(
}.map { it.convert(apikey, false) } }.map { it.convert(apikey, false) }
// apply clustering // apply clustering
val useClustering = zoom < 13 val useClustering = zoom < clusterThreshold
val geClusteringAvailable = minConnectors == null || minConnectors <= 1 val geClusteringAvailable = minConnectors == null || minConnectors <= 1
val clusterDistance = if (useClustering) getClusterDistance(zoom) else null val clusterDistance = if (useClustering) getClusterDistance(zoom) else null
if (!geClusteringAvailable && useClustering) { if (!geClusteringAvailable && useClustering) {

View File

@@ -105,6 +105,7 @@ class OpenChargeMapApiWrapper(
baseurl: String = "https://api.openchargemap.io/v3/", baseurl: String = "https://api.openchargemap.io/v3/",
context: Context? = null context: Context? = null
) : ChargepointApi<OCMReferenceData> { ) : ChargepointApi<OCMReferenceData> {
private val clusterThreshold = 11
val api = OpenChargeMapApi.create(apikey, baseurl, context) val api = OpenChargeMapApi.create(apikey, baseurl, context)
override fun getName() = "OpenChargeMap.org" override fun getName() = "OpenChargeMap.org"
@@ -238,7 +239,7 @@ class OpenChargeMapApiWrapper(
}.map { it.convert(referenceData, false) }.distinct() as List<ChargepointListItem> }.map { it.convert(referenceData, false) }.distinct() as List<ChargepointListItem>
// apply clustering // apply clustering
val useClustering = zoom < 13 val useClustering = zoom < clusterThreshold
if (useClustering) { if (useClustering) {
val clusterDistance = getClusterDistance(zoom) val clusterDistance = getClusterDistance(zoom)
Dispatchers.IO.run { Dispatchers.IO.run {

View File

@@ -518,7 +518,8 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
highlight = true, highlight = true,
fault = charger.faultReport != null, fault = charger.faultReport != null,
multi = charger.isMulti(vm.filteredConnectors.value), multi = charger.isMulti(vm.filteredConnectors.value),
fav = fav == null fav = fav == null,
mini = vm.useMiniMarkers.value == true
) )
) )
} }
@@ -585,6 +586,9 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
updateMap(chargepoints) updateMap(chargepoints)
} }
}) })
vm.useMiniMarkers.observe(viewLifecycleOwner) {
vm.chargepoints.value?.data?.let { updateMap(it) }
}
vm.favorites.observe(viewLifecycleOwner, Observer { vm.favorites.observe(viewLifecycleOwner, Observer {
updateFavoriteToggle() updateFavoriteToggle()
}) })
@@ -650,7 +654,8 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
highlight = false, highlight = false,
fault = c.faultReport != null, fault = c.faultReport != null,
multi = c.isMulti(vm.filteredConnectors.value), multi = c.isMulti(vm.filteredConnectors.value),
fav = c.id in vm.favorites.value?.map { it.charger.id } ?: emptyList() fav = c.id in vm.favorites.value?.map { it.charger.id } ?: emptyList(),
mini = vm.useMiniMarkers.value == true
) )
) )
} }
@@ -665,10 +670,11 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
highlight = true, highlight = true,
fault = charger.faultReport != null, fault = charger.faultReport != null,
multi = charger.isMulti(vm.filteredConnectors.value), multi = charger.isMulti(vm.filteredConnectors.value),
fav = charger.id in vm.favorites.value?.map { it.charger.id } ?: emptyList() fav = charger.id in vm.favorites.value?.map { it.charger.id } ?: emptyList(),
mini = vm.useMiniMarkers.value == true
) )
) )
animator.animateMarkerBounce(marker) animator.animateMarkerBounce(marker, vm.useMiniMarkers.value == true)
// un-highlight all other markers // un-highlight all other markers
markers.forEach { (m, c) -> markers.forEach { (m, c) ->
@@ -679,7 +685,8 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
highlight = false, highlight = false,
fault = c.faultReport != null, fault = c.faultReport != null,
multi = c.isMulti(vm.filteredConnectors.value), multi = c.isMulti(vm.filteredConnectors.value),
fav = c.id in vm.favorites.value?.map { it.charger.id } ?: emptyList() fav = c.id in vm.favorites.value?.map { it.charger.id } ?: emptyList(),
mini = vm.useMiniMarkers.value == true
) )
) )
} }
@@ -823,15 +830,22 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
map.uiSettings.setRotateGesturesEnabled(prefs.mapRotateGesturesEnabled) map.uiSettings.setRotateGesturesEnabled(prefs.mapRotateGesturesEnabled)
map.setIndoorEnabled(false) map.setIndoorEnabled(false)
map.uiSettings.setIndoorLevelPickerEnabled(false) map.uiSettings.setIndoorLevelPickerEnabled(false)
map.setOnCameraIdleListener { map.setOnCameraIdleListener {
vm.mapPosition.value = MapPosition( vm.mapPosition.value = MapPosition(
map.projection.visibleRegion.latLngBounds, map.cameraPosition.zoom map.projection.visibleRegion.latLngBounds, map.cameraPosition.zoom
) )
binding.scaleView.update(map.cameraPosition.zoom, map.cameraPosition.target.latitude) vm.reloadChargepoints()
} }
map.setOnCameraMoveListener { map.setOnCameraMoveListener {
vm.mapPosition.value = MapPosition(
map.projection.visibleRegion.latLngBounds, map.cameraPosition.zoom
)
}
vm.mapPosition.observe(viewLifecycleOwner) {
binding.scaleView.update(map.cameraPosition.zoom, map.cameraPosition.target.latitude) binding.scaleView.update(map.cameraPosition.zoom, map.cameraPosition.target.latitude)
} }
map.setOnCameraMoveStartedListener { reason -> map.setOnCameraMoveStartedListener { reason ->
if (reason == AnyMap.OnCameraMoveStartedListener.REASON_GESTURE) { if (reason == AnyMap.OnCameraMoveStartedListener.REASON_GESTURE) {
if (vm.myLocationEnabled.value == true) { if (vm.myLocationEnabled.value == true) {
@@ -1034,9 +1048,11 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
highlight = highlight, highlight = highlight,
fault = charger.faultReport != null, fault = charger.faultReport != null,
multi = charger.isMulti(vm.filteredConnectors.value), multi = charger.isMulti(vm.filteredConnectors.value),
fav = charger.id in vm.favorites.value?.map { it.charger.id } ?: emptyList() fav = charger.id in vm.favorites.value?.map { it.charger.id } ?: emptyList(),
mini = vm.useMiniMarkers.value == true
) )
) )
marker.setAnchor(0.5f, if (vm.useMiniMarkers.value == true) 0.5f else 1f)
} }
if (chargers.toSet() != markers.values) { if (chargers.toSet() != markers.values) {
@@ -1054,7 +1070,10 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
val multi = charger.isMulti(vm.filteredConnectors.value) val multi = charger.isMulti(vm.filteredConnectors.value)
val fav = val fav =
charger.id in vm.favorites.value?.map { it.charger.id } ?: emptyList() charger.id in vm.favorites.value?.map { it.charger.id } ?: emptyList()
animator.animateMarkerDisappear(marker, tint, highlight, fault, multi, fav) animator.animateMarkerDisappear(
marker, tint, highlight, fault, multi, fav,
vm.useMiniMarkers.value == true
)
} else { } else {
animator.deleteMarker(marker) animator.deleteMarker(marker)
} }
@@ -1082,12 +1101,16 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
highlight, highlight,
fault, fault,
multi, multi,
fav fav,
vm.useMiniMarkers.value == true
) )
) )
.anchor(0.5f, 1f) .anchor(0.5f, if (vm.useMiniMarkers.value == true) 0.5f else 1f)
)
animator.animateMarkerAppear(
marker, tint, highlight, fault, multi, fav,
vm.useMiniMarkers.value == true
) )
animator.animateMarkerAppear(marker, tint, highlight, fault, multi, fav)
markers[marker] = charger markers[marker] = charger
} }
} }

View File

@@ -46,6 +46,7 @@ class ChargerIconGenerator(
val context: Context, val context: Context,
val factory: BitmapDescriptorFactory?, val factory: BitmapDescriptorFactory?,
val scaleResolution: Int = 20, val scaleResolution: Int = 20,
val scaleResolutionMini: Int = 10,
val oversize: Float = 1f, // increase to add padding for scale > 1 val oversize: Float = 1f, // increase to add padding for scale > 1
val height: Int = 48 val height: Int = 48
) { ) {
@@ -56,16 +57,21 @@ class ChargerIconGenerator(
val highlight: Boolean, val highlight: Boolean,
val fault: Boolean, val fault: Boolean,
val multi: Boolean, val multi: Boolean,
val fav: Boolean val fav: Boolean,
val mini: Boolean
) )
// 230 items: (21 sizes, 5 colors, multi on/off) + highlight + fault (only with scale = 1) // 340 items:
private val cacheSize = (scaleResolution + 3) * 5 * 2; // large: (21 sizes, 5 colors, multi on/off) + highlight + fault + fav (only with scale = 1)
// mini: (11 sizes, 5 colors) + highlight (only with scale = 1)
private val cacheSize = (scaleResolution + 8) * 5 * 2 + (scaleResolutionMini + 2) * 5;
private val cache = LruCache<BitmapData, BitmapDescriptor>(cacheSize) private val cache = LruCache<BitmapData, BitmapDescriptor>(cacheSize)
private val icon = R.drawable.ic_map_marker_charging private val icon = R.drawable.ic_map_marker_charging
private val multiIcon = R.drawable.ic_map_marker_charging_multiple private val multiIcon = R.drawable.ic_map_marker_charging_multiple
private val highlightIcon = R.drawable.ic_map_marker_highlight private val miniIcon = R.drawable.ic_map_marker_charging_mini
private val highlightIcon = R.drawable.ic_map_marker_charging_highlight
private val highlightIconMulti = R.drawable.ic_map_marker_charging_highlight_multiple private val highlightIconMulti = R.drawable.ic_map_marker_charging_highlight_multiple
private val highlightIconMini = R.drawable.ic_map_marker_charging_highlight_mini
private val faultIcon = R.drawable.ic_map_marker_fault private val faultIcon = R.drawable.ic_map_marker_fault
private val favIcon = R.drawable.ic_map_marker_fav private val favIcon = R.drawable.ic_map_marker_fav
@@ -82,11 +88,13 @@ class ChargerIconGenerator(
for (highlight in listOf(false, true)) { for (highlight in listOf(false, true)) {
for (multi in listOf(false, true)) { for (multi in listOf(false, true)) {
for (fav in listOf(false, true)) { for (fav in listOf(false, true)) {
for (mini in listOf(false, true)) {
for (tint in tints) { for (tint in tints) {
for (scale in 0..scaleResolution) { val scaleRes = if (mini) scaleResolutionMini else scaleResolution
for (scale in 0..scaleRes) {
getBitmapDescriptor( getBitmapDescriptor(
tint, scale.toFloat() / scaleResolution, tint, scale.toFloat() / scaleRes,
255, highlight, fault, multi, fav 255, highlight, fault, multi, fav, mini
) )
} }
} }
@@ -95,6 +103,7 @@ class ChargerIconGenerator(
} }
} }
} }
}
fun getBitmapDescriptor( fun getBitmapDescriptor(
@ColorRes tint: Int, @ColorRes tint: Int,
@@ -103,16 +112,10 @@ class ChargerIconGenerator(
highlight: Boolean = false, highlight: Boolean = false,
fault: Boolean = false, fault: Boolean = false,
multi: Boolean = false, multi: Boolean = false,
fav: Boolean = false fav: Boolean = false,
mini: Boolean = false
): BitmapDescriptor? { ): BitmapDescriptor? {
val data = BitmapData( val data = createBitmapData(tint, scale, alpha, highlight, fault, multi, fav, mini)
tint, (scale * scaleResolution).roundToInt(),
alpha,
if (scale == 1f) highlight else false,
if (scale == 1f) fault else false,
multi,
if (scale == 1f) fav else false
)
val cachedImg = cache[data] val cachedImg = cache[data]
return if (cachedImg != null) { return if (cachedImg != null) {
cachedImg cachedImg
@@ -124,6 +127,26 @@ class ChargerIconGenerator(
} }
} }
private fun createBitmapData(
tint: Int,
scale: Float,
alpha: Int,
highlight: Boolean,
fault: Boolean,
multi: Boolean,
fav: Boolean,
mini: Boolean
) = BitmapData(
tint,
(scale * (if (mini) scaleResolutionMini else scaleResolution)).roundToInt(),
alpha,
if (scale == 1f) highlight else false,
if (scale == 1f && !mini) fault else false,
if (!mini) multi else false,
if (scale == 1f && !mini) fav else false,
mini
)
fun getBitmap( fun getBitmap(
@ColorRes tint: Int, @ColorRes tint: Int,
scale: Float = 1f, scale: Float = 1f,
@@ -131,38 +154,40 @@ class ChargerIconGenerator(
highlight: Boolean = false, highlight: Boolean = false,
fault: Boolean = false, fault: Boolean = false,
multi: Boolean = false, multi: Boolean = false,
fav: Boolean = false fav: Boolean = false,
mini: Boolean = false
): Bitmap { ): Bitmap {
val data = BitmapData( val data = createBitmapData(tint, scale, alpha, highlight, fault, multi, fav, mini)
tint, (scale * scaleResolution).roundToInt(),
alpha,
if (scale == 1f) highlight else false,
if (scale == 1f) fault else false,
multi,
if (scale == 1f) fav else false,
)
return generateBitmap(data) return generateBitmap(data)
} }
private fun generateBitmap(data: BitmapData): Bitmap { private fun generateBitmap(data: BitmapData): Bitmap {
val icon = if (data.multi) multiIcon else icon val icon = if (data.mini) miniIcon else if (data.multi) multiIcon else icon
val vd: Drawable = ContextCompat.getDrawable(context, icon)!! val vd: Drawable = ContextCompat.getDrawable(context, icon)!!
DrawableCompat.setTint(vd, ContextCompat.getColor(context, data.tint)); DrawableCompat.setTint(vd, ContextCompat.getColor(context, data.tint))
DrawableCompat.setTintMode(vd, PorterDuff.Mode.MULTIPLY); DrawableCompat.setTintMode(vd, PorterDuff.Mode.MULTIPLY)
val density = context.resources.displayMetrics.density val density = context.resources.displayMetrics.density
val markerWidth = val (markerWidth, markerHeight) = if (data.mini) {
(height.toFloat() * density / vd.intrinsicHeight * vd.intrinsicWidth).roundToInt() vd.intrinsicWidth to vd.intrinsicHeight
val markerHeight = (height * density).roundToInt() } else {
val extraIconSize = (0.75 * markerWidth).roundToInt() (height.toFloat() * density / vd.intrinsicHeight * vd.intrinsicWidth).roundToInt() to
val extraIconShift = (0.25 * markerWidth).roundToInt() (height * density).roundToInt()
}
val (extraIconSize, extraIconShift) = if (data.mini) 0 to 0 else {
(0.75 * markerWidth).roundToInt() to (0.25 * markerWidth).roundToInt()
}
val totalWidth = markerWidth + 2 * extraIconShift val totalWidth = markerWidth + 2 * extraIconShift
val totalHeight = markerHeight + extraIconShift val totalHeight = markerHeight + extraIconShift
val leftPadding = ((totalWidth) * (oversize - 1) / 2).roundToInt() + extraIconShift val (leftPadding, topPadding) = if (!data.mini) {
val topPadding = ((totalHeight) * (oversize - 1)).roundToInt() + extraIconShift ((totalWidth) * (oversize - 1) / 2).roundToInt() + extraIconShift to
((totalHeight) * (oversize - 1)).roundToInt() + extraIconShift
} else {
0 to 0
}
vd.setBounds( vd.setBounds(
leftPadding, topPadding, leftPadding, topPadding,
leftPadding + markerWidth, leftPadding + markerWidth,
@@ -176,18 +201,21 @@ class ChargerIconGenerator(
) )
val canvas = Canvas(bm) val canvas = Canvas(bm)
val scale = data.scale.toFloat() / scaleResolution val scale = data.scale.toFloat() / if (data.mini) scaleResolutionMini else scaleResolution
canvas.scale( val (originX, originY) = if (data.mini) {
scale, canvas.width / 2f to
scale, canvas.height / 2f
canvas.width / 2f, } else {
canvas.width / 2f to
canvas.height.toFloat() canvas.height.toFloat()
) }
canvas.scale(scale, scale, originX, originY)
vd.draw(canvas) vd.draw(canvas)
if (data.highlight) { if (data.highlight) {
val hIcon = if (data.multi) highlightIconMulti else highlightIcon val hIcon =
if (data.mini) highlightIconMini else if (data.multi) highlightIconMulti else highlightIcon
val highlightDrawable = ContextCompat.getDrawable(context, hIcon)!! val highlightDrawable = ContextCompat.getDrawable(context, hIcon)!!
highlightDrawable.setBounds( highlightDrawable.setBounds(
leftPadding, topPadding, leftPadding, topPadding,
@@ -198,7 +226,7 @@ class ChargerIconGenerator(
highlightDrawable.draw(canvas) highlightDrawable.draw(canvas)
} }
if (data.fault) { if (data.fault && !data.mini) {
val faultDrawable = ContextCompat.getDrawable(context, faultIcon)!! val faultDrawable = ContextCompat.getDrawable(context, faultIcon)!!
faultDrawable.setBounds( faultDrawable.setBounds(
leftPadding + markerWidth + extraIconShift - extraIconSize, leftPadding + markerWidth + extraIconShift - extraIconSize,
@@ -210,7 +238,7 @@ class ChargerIconGenerator(
faultDrawable.draw(canvas) faultDrawable.draw(canvas)
} }
if (data.fav) { if (data.fav && !data.mini) {
val favDrawable = ContextCompat.getDrawable(context, favIcon)!! val favDrawable = ContextCompat.getDrawable(context, favIcon)!!
val favShiftY = extraIconShift val favShiftY = extraIconShift
val favShiftX = if (data.fault) extraIconShift - extraIconSize else extraIconShift val favShiftX = if (data.fault) extraIconShift - extraIconSize else extraIconShift

View File

@@ -38,7 +38,8 @@ class MarkerAnimator(val gen: ChargerIconGenerator) {
highlight: Boolean, highlight: Boolean,
fault: Boolean, fault: Boolean,
multi: Boolean, multi: Boolean,
fav: Boolean fav: Boolean,
mini: Boolean
) { ) {
animatingMarkers[marker]?.let { animatingMarkers[marker]?.let {
it.cancel() it.cancel()
@@ -57,7 +58,8 @@ class MarkerAnimator(val gen: ChargerIconGenerator) {
highlight = highlight, highlight = highlight,
fault = fault, fault = fault,
multi = multi, multi = multi,
fav = fav fav = fav,
mini = mini
) )
) )
} }
@@ -77,7 +79,8 @@ class MarkerAnimator(val gen: ChargerIconGenerator) {
highlight: Boolean, highlight: Boolean,
fault: Boolean, fault: Boolean,
multi: Boolean, multi: Boolean,
fav: Boolean fav: Boolean,
mini: Boolean
) { ) {
animatingMarkers[marker]?.let { animatingMarkers[marker]?.let {
it.cancel() it.cancel()
@@ -96,7 +99,8 @@ class MarkerAnimator(val gen: ChargerIconGenerator) {
highlight = highlight, highlight = highlight,
fault = fault, fault = fault,
multi = multi, multi = multi,
fav = fav fav = fav,
mini = mini
) )
) )
} }
@@ -120,7 +124,7 @@ class MarkerAnimator(val gen: ChargerIconGenerator) {
marker.remove() marker.remove()
} }
fun animateMarkerBounce(marker: Marker) { fun animateMarkerBounce(marker: Marker, mini: Boolean) {
animatingMarkers[marker]?.let { animatingMarkers[marker]?.let {
it.cancel() it.cancel()
animatingMarkers.remove(marker) animatingMarkers.remove(marker)
@@ -131,7 +135,7 @@ class MarkerAnimator(val gen: ChargerIconGenerator) {
interpolator = BounceInterpolator() interpolator = BounceInterpolator()
addUpdateListener { state -> addUpdateListener { state ->
val t = max(1f - state.animatedValue as Float, 0f) / 2 val t = max(1f - state.animatedValue as Float, 0f) / 2
marker.setAnchor(0.5f, 1.0f + t) marker.setAnchor(0.5f, (if (mini) 0.5f else 1.0f) + t)
} }
addListener(onEnd = { addListener(onEnd = {
animatingMarkers.remove(marker) animatingMarkers.remove(marker)

View File

@@ -35,9 +35,7 @@ data class MapPosition(val bounds: LatLngBounds, val zoom: Float) : Parcelable
internal fun getClusterDistance(zoom: Float): Int? { internal fun getClusterDistance(zoom: Float): Int? {
return when (zoom) { return when (zoom) {
in 0.0..7.0 -> 100 in 0.0..7.0 -> 100
in 7.0..11.5 -> 75 in 7.0..11.0 -> 75
in 11.5..12.5 -> 60
in 12.5..13.0 -> 45
else -> null else -> null
} }
} }
@@ -298,6 +296,29 @@ class MapViewModel(application: Application, private val state: SavedStateHandle
chargepointLoader(Triple(pos, filters, referenceData)) chargepointLoader(Triple(pos, filters, referenceData))
} }
private val miniMarkerThreshold = 13f
private val clusterThreshold = 11f
val useMiniMarkers: LiveData<Boolean> = MediatorLiveData<Boolean>().apply {
for (source in listOf(filteredMinPower, mapPosition)) {
addSource(source) {
val minPower = filteredMinPower.value ?: 0
val zoom = mapPosition.value?.zoom
value = when {
zoom == null -> {
false
}
minPower >= 100 -> {
// when only showing high-power chargers we can use large markers
zoom < clusterThreshold
}
else -> {
zoom < miniMarkerThreshold
}
}
}
}
}.distinctUntilChanged()
private var chargepointLoader = private var chargepointLoader =
throttleLatest( throttleLatest(
500L, 500L,
@@ -342,7 +363,7 @@ class MapViewModel(application: Application, private val state: SavedStateHandle
if (connectorsVal.all) null else connectorsVal.values.map { if (connectorsVal.all) null else connectorsVal.values.map {
GEChargepoint.convertTypeFromGE(it) GEChargepoint.convertTypeFromGE(it)
}.toSet() }.toSet()
filteredMinPower.value = filters.getSliderValue("minPower") filteredMinPower.value = filters.getSliderValue("min_power")
} else if (api is OpenChargeMapApiWrapper) { } else if (api is OpenChargeMapApiWrapper) {
val connectorsVal = filters.getMultipleChoiceValue("connectors")!! val connectorsVal = filters.getMultipleChoiceValue("connectors")!!
filteredConnectors.value = filteredConnectors.value =
@@ -352,7 +373,7 @@ class MapViewModel(application: Application, private val state: SavedStateHandle
refData as OCMReferenceData refData as OCMReferenceData
) )
}.toSet() }.toSet()
filteredMinPower.value = filters.getSliderValue("minPower") filteredMinPower.value = filters.getSliderValue("min_power")
} else { } else {
filteredConnectors.value = null filteredConnectors.value = null
filteredMinPower.value = null filteredMinPower.value = null

View File

@@ -0,0 +1,9 @@
<vector android:viewportHeight="24"
android:viewportWidth="24"
android:width="16dp"
android:height="16dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="@android:color/white"
android:pathData="M12,12m-4,0a4,4 0,1 1,8 0a4,4 0,1 1,-8 0" />
</vector>

View File

@@ -0,0 +1,12 @@
<vector android:viewportHeight="24"
android:viewportWidth="24"
android:width="16dp"
android:height="16dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="#dddddd"
android:pathData="M12,12m-8.5,0a8.5,8.5 0,1 1,17 0a8.5,8.5 0,1 1,-17 0" />
<path
android:fillColor="@android:color/white"
android:pathData="M12,12m-7.5,0a7.5,7.5 0,1 1,15 0a7.5,7.5 0,1 1,-15 0" />
</vector>