Skip to content

Commit

Permalink
#267 feat : ClusterManager생성
Browse files Browse the repository at this point in the history
  • Loading branch information
BENDENG1 committed Feb 8, 2024
1 parent d93bf61 commit 273fc54
Showing 1 changed file with 114 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package com.avengers.presentation.ui.main.home

import com.avengers.nibobnebob.presentation.ui.main.home.model.UiRestaurantData
import com.avengers.presentation.util.DistanceUtil.haversineDistance
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject
import kotlin.math.abs


class ClusterManager @Inject constructor() {

private val _clusteredMarkers = MutableStateFlow<List<Cluster>>(emptyList())
val clusteredMarkers: StateFlow<List<Cluster>> = _clusteredMarkers

fun updateCluster(
markers: List<UiRestaurantData>,
cameraLatitude: Double,
cameraLongitude: Double,
cameraRadius: Double,
) {
val visibleMarkers = getVisibleMarkers(markers,cameraLatitude,cameraLongitude,cameraRadius)
val newClusters = clusterMarkers(visibleMarkers, cameraRadius)
_clusteredMarkers.value = newClusters
}

fun getClusterList(): List<Cluster> {
return clusteredMarkers.value
}

private fun getVisibleMarkers(
markersList: List<UiRestaurantData>,
cameraLatitude: Double,
cameraLongitude: Double,
cameraRadius: Double
): List<UiRestaurantData> {
val visibleMarkers = mutableListOf<UiRestaurantData>()

for (marker in markersList) {
val distance = haversineDistance(
cameraLatitude,
cameraLongitude,
marker.latitude,
marker.longitude
)

if (distance <= cameraRadius * 2) {
visibleMarkers.add(marker)
}
}

return visibleMarkers
}

private fun clusterMarkers(
markers: List<UiRestaurantData>,
cameraRadius: Double
): List<Cluster> {
val clusteredMarkers = mutableListOf<Cluster>()

val clusterWidth = cameraRadius
val divisions = 20

val divisionWidth = clusterWidth / divisions

for (marker in markers) {
var isClustered = false

for (cluster in clusteredMarkers) {
val distance = haversineDistance(
cluster.centerLatitude,
cluster.centerLongitude,
marker.latitude,
marker.longitude
)

if (distance < clusterWidth) {
val xDistance = abs(cluster.centerLatitude - marker.latitude)
val yDistance = abs(cluster.centerLongitude - marker.longitude)

val xDivision = (xDistance / divisionWidth).toInt()
val yDivision = (yDistance / divisionWidth).toInt()

val clusterIndex = xDivision * divisions + yDivision

cluster.markers.add(marker)
cluster.clusterId.add(clusterIndex)

isClustered = true
break
}
}

if (!isClustered) {
val xDivision = ((marker.latitude % divisionWidth) / divisionWidth).toInt()
val yDivision = ((marker.longitude % divisionWidth) / divisionWidth).toInt()

val clusterIndex = xDivision * divisions + yDivision

val newCluster = Cluster(
marker.latitude,
marker.longitude,
mutableListOf(marker),
mutableListOf(clusterIndex)
)

clusteredMarkers.add(newCluster)
}
}
return clusteredMarkers.filter { it.markers.size >= 10 }
}


}

0 comments on commit 273fc54

Please sign in to comment.