Skip to content

Commit 7126109

Browse files
committed
extract exchange layer setup
1 parent 5257385 commit 7126109

4 files changed

Lines changed: 184 additions & 163 deletions

File tree

app/src/main/kotlin/org/btcmap/map/MapFragment.kt

Lines changed: 27 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import android.annotation.SuppressLint
55
import android.content.Intent
66
import android.content.pm.PackageManager
77
import android.content.res.Configuration
8-
import android.graphics.Color
98
import android.location.Location
109
import android.os.Bundle
1110
import android.util.Log
@@ -60,8 +59,6 @@ import org.maplibre.android.location.LocationComponentOptions
6059
import org.maplibre.android.location.engine.LocationEngineRequest
6160
import org.maplibre.android.maps.MapLibreMap
6261
import org.maplibre.android.maps.Style
63-
import org.maplibre.android.style.layers.CircleLayer
64-
import org.maplibre.android.style.layers.PropertyFactory
6562
import org.maplibre.android.style.sources.GeoJsonSource
6663
import org.btcmap.area.AreaFragment
6764
import org.btcmap.place.isMerchant
@@ -84,10 +81,9 @@ import org.btcmap.db
8481
import org.btcmap.sync
8582
import org.btcmap.db.table.place.Marker
8683
import org.btcmap.db.table.event.Event
87-
import org.maplibre.android.style.expressions.Expression
88-
import org.maplibre.android.style.layers.Property.ICON_ANCHOR_CENTER
89-
import org.maplibre.android.style.layers.SymbolLayer
90-
import org.maplibre.android.style.sources.GeoJsonOptions
84+
import org.btcmap.map.layer.createEventLayers
85+
import org.btcmap.map.layer.createExchangeLayers
86+
import org.btcmap.map.layer.createMerchantLayers
9187
import org.btcmap.search.SearchAdapterItem
9288
import org.btcmap.settings.badgeBackgroundColor
9389
import org.btcmap.settings.badgeTextColor
@@ -216,7 +212,7 @@ class MapFragment : Fragment() {
216212
}
217213

218214
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
219-
val merchantLayers = createMerchantsSourceAndLayers(
215+
val merchantLayers = createMerchantLayers(
220216
markerBackgroundColor = prefs.markerBackgroundColor(requireContext()),
221217
markerBadgeBackgroundColor = prefs.badgeBackgroundColor(requireContext()),
222218
markerBadgeTextColor = prefs.badgeTextColor(requireContext()),
@@ -226,17 +222,25 @@ class MapFragment : Fragment() {
226222
markerBackgroundColor = prefs.markerBackgroundColor(requireContext()),
227223
usingOpenFreeMap = usingOpenFreeMap(),
228224
)
225+
val exchangeLayers = createExchangeLayers(
226+
markerBackgroundColor = prefs.markerBackgroundColor(requireContext()),
227+
markerBadgeBackgroundColor = prefs.badgeBackgroundColor(requireContext()),
228+
markerBadgeTextColor = prefs.badgeTextColor(requireContext()),
229+
usingOpenFreeMap = usingOpenFreeMap(),
230+
)
229231
merchantsSource = merchantLayers.first
230232
eventsSource = eventLayers.first
233+
exchangesSource = exchangeLayers.first
231234
binding.map.getMapAsync { map ->
232235
map.getStyle { style ->
233236
style.addSource(merchantLayers.first)
234237
merchantLayers.second.forEach { style.addLayer(it) }
235238
style.addSource(eventLayers.first)
236239
eventLayers.second.forEach { style.addLayer(it) }
240+
style.addSource(exchangeLayers.first)
241+
exchangeLayers.second.forEach { style.addLayer(it) }
237242
}
238243
}
239-
initExchangesMap()
240244

241245
initSearchBar(binding)
242246

@@ -770,144 +774,6 @@ class MapFragment : Fragment() {
770774
private lateinit var eventsSource: GeoJsonSource
771775
private lateinit var exchangesSource: GeoJsonSource
772776

773-
private fun initExchangesMap() {
774-
val exchangesSource = GeoJsonSource(
775-
"exchangesSource",
776-
EMPTY_GEOJSON,
777-
GeoJsonOptions()
778-
.withCluster(true)
779-
.withClusterMaxZoom(14)
780-
.withClusterRadius(50)
781-
)
782-
783-
val exchangesClusterBackgroundLayer by lazy {
784-
CircleLayer("exchangesClusterBackground", exchangesSource.id).apply {
785-
setProperties(
786-
PropertyFactory.circleColor(prefs.markerBackgroundColor(requireContext())),
787-
PropertyFactory.circleRadius(23f),
788-
)
789-
val pointCount = Expression.toNumber(Expression.get("point_count"))
790-
setFilter(
791-
Expression.all(
792-
Expression.has("point_count"),
793-
Expression.gte(
794-
pointCount,
795-
Expression.literal(1)
796-
)
797-
)
798-
)
799-
}
800-
}
801-
802-
val exchangesClusterCountLayer =
803-
SymbolLayer("exchangesClusterCount", exchangesSource.id).apply {
804-
if (usingOpenFreeMap()) {
805-
setProperties(PropertyFactory.textFont(arrayOf("Noto Sans Regular")))
806-
}
807-
setProperties(
808-
PropertyFactory.textField(Expression.toString(Expression.get("point_count"))),
809-
PropertyFactory.textSize(16f),
810-
PropertyFactory.textColor(Color.WHITE),
811-
)
812-
}
813-
814-
val exchangesLayer =
815-
SymbolLayer(LAYER_EXCHANGES, exchangesSource.id).apply {
816-
setProperties(
817-
PropertyFactory.iconImage("btcmap-marker"),
818-
PropertyFactory.iconAnchor(Expression.literal("bottom")),
819-
PropertyFactory.iconAllowOverlap(true),
820-
PropertyFactory.iconIgnorePlacement(true)
821-
)
822-
setFilter(
823-
Expression.neq(Expression.get("cluster"), true)
824-
)
825-
}
826-
827-
val exchangesCategoryIconsLayer =
828-
SymbolLayer(LAYER_EXCHANGES_CATEGORY_ICONS, exchangesSource.id).apply {
829-
setProperties(
830-
PropertyFactory.iconImage(
831-
Expression.match(
832-
Expression.get("iconId"),
833-
*matcher().toTypedArray()
834-
)
835-
),
836-
PropertyFactory.iconAnchor(ICON_ANCHOR_CENTER),
837-
PropertyFactory.iconOffset(
838-
arrayOf(
839-
0f,
840-
ICON_OFFSET_Y
841-
)
842-
),
843-
PropertyFactory.iconAllowOverlap(true),
844-
PropertyFactory.iconIgnorePlacement(true)
845-
)
846-
setFilter(
847-
Expression.neq(Expression.get("cluster"), true)
848-
)
849-
}
850-
851-
val exchangesCommentsLayer =
852-
CircleLayer("exchangesComments", exchangesSource.id).apply {
853-
setProperties(
854-
PropertyFactory.circleColor(prefs.badgeBackgroundColor(requireContext())),
855-
PropertyFactory.circleRadius(9f),
856-
PropertyFactory.circleOpacity(1f),
857-
PropertyFactory.circleTranslate(arrayOf(13f, -43f)),
858-
PropertyFactory.circleTranslateAnchor("viewport")
859-
)
860-
setFilter(
861-
Expression.all(
862-
Expression.neq(Expression.get("cluster"), true),
863-
Expression.gt(Expression.get("comments"), 0)
864-
)
865-
)
866-
}
867-
868-
val exchangesCommentsCountLayer =
869-
SymbolLayer("exchangesCommentsCount", exchangesSource.id).apply {
870-
if (usingOpenFreeMap()) {
871-
setProperties(PropertyFactory.textFont(arrayOf("Noto Sans Bold")))
872-
}
873-
setProperties(
874-
PropertyFactory.textField(
875-
Expression.switchCase(
876-
Expression.gte(Expression.get("comments"), Expression.literal(10)),
877-
Expression.literal("9+"),
878-
Expression.toString(Expression.get("comments"))
879-
)
880-
),
881-
PropertyFactory.textSize(11f),
882-
PropertyFactory.textColor(prefs.badgeTextColor(requireContext())),
883-
PropertyFactory.textTranslate(arrayOf(13f, -43f)),
884-
PropertyFactory.textTranslateAnchor("viewport"),
885-
PropertyFactory.textAllowOverlap(true)
886-
)
887-
setFilter(
888-
Expression.all(
889-
Expression.neq(Expression.get("cluster"), true),
890-
Expression.gt(Expression.get("comments"), 0)
891-
)
892-
)
893-
}
894-
895-
binding.map.getMapAsync { map ->
896-
map.getStyle { style ->
897-
style.addSource(exchangesSource)
898-
899-
style.addLayer(exchangesClusterBackgroundLayer)
900-
style.addLayer(exchangesClusterCountLayer)
901-
style.addLayer(exchangesLayer)
902-
style.addLayer(exchangesCategoryIconsLayer)
903-
style.addLayer(exchangesCommentsLayer)
904-
style.addLayer(exchangesCommentsCountLayer)
905-
}
906-
}
907-
908-
this.exchangesSource = exchangesSource
909-
}
910-
911777
private fun usingOpenFreeMap(): Boolean {
912778
val nightMode =
913779
requireContext().resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
@@ -924,7 +790,10 @@ class MapFragment : Fragment() {
924790
binding.map.getMapAsync { map ->
925791
val bounds = map.projection.visibleRegion.latLngBounds
926792
val expandedBounds = expandBounds(bounds, CLUSTERING_SCALE_FACTOR)
927-
Log.d("MapFragment", "showMerchants: bounds=$bounds, expanded=$expandedBounds, cacheBounds=${merchantsCache.bounds}")
793+
Log.d(
794+
"MapFragment",
795+
"showMerchants: bounds=$bounds, expanded=$expandedBounds, cacheBounds=${merchantsCache.bounds}"
796+
)
928797
viewLifecycleOwner.lifecycleScope.launch {
929798
if (!merchantsCache.contains(expandedBounds)) {
930799
Log.d("MapFragment", "showMerchants: cache miss, fetching")
@@ -939,7 +808,10 @@ class MapFragment : Fragment() {
939808
)
940809
}
941810
lastDbCallTimeMs = System.currentTimeMillis() - startTime
942-
Log.d("MapFragment", "showMerchants: fetched ${newMerchants.size} merchants in ${lastDbCallTimeMs}ms")
811+
Log.d(
812+
"MapFragment",
813+
"showMerchants: fetched ${newMerchants.size} merchants in ${lastDbCallTimeMs}ms"
814+
)
943815
merchantsCache = merchantsCache.add(newMerchants, expandedBounds)
944816
} else {
945817
Log.d("MapFragment", "showMerchants: cache hit")
@@ -1041,17 +913,19 @@ class MapFragment : Fragment() {
1041913
}
1042914
val viewportInfo = if (currentBounds != null) {
1043915
val latSpanKm = currentBounds.latitudeSpan * 111
1044-
val lonSpanKm = currentBounds.longitudeSpan * 111 * kotlin.math.cos(Math.toRadians(currentBounds.center.latitude))
916+
val lonSpanKm =
917+
currentBounds.longitudeSpan * 111 * kotlin.math.cos(Math.toRadians(currentBounds.center.latitude))
1045918
"%.1fkm x %.1fkm".format(latSpanKm, lonSpanKm)
1046919
} else {
1047920
"no bounds"
1048921
}
1049922
Log.d("MapFragment", "updateDebugStats: filter=$filter, cacheSize=$cacheSize")
1050923
if (prefs.showDebugInfo) {
1051924
binding.debugStats.apply {
1052-
text = "memcache: %d items\nmemcache bounds: %s\ndb queries: %d\nlast query: %dms".format(
1053-
cacheSize, viewportInfo, dbCallCount, lastDbCallTimeMs
1054-
)
925+
text =
926+
"memcache: %d items\nmemcache bounds: %s\ndb queries: %d\nlast query: %dms".format(
927+
cacheSize, viewportInfo, dbCallCount, lastDbCallTimeMs
928+
)
1055929
isVisible = true
1056930
}
1057931
} else {

app/src/main/kotlin/org/btcmap/map/EventLayers.kt renamed to app/src/main/kotlin/org/btcmap/map/layer/EventLayers.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.btcmap.map
1+
package org.btcmap.map.layer
22

33
import android.graphics.Color
44
import org.btcmap.map.MapFragment.Companion.ICON_OFFSET_Y

0 commit comments

Comments
 (0)