I have many(250+) polygons drawn on map. And I need to able to click on them. So i created custom class, that extented Polygon, where i override onSingleTapUp func(code below). The click works, but there is some delay before click action was executed:
This delay exists both on the emulator and on the device, as well as in the release version. I assume the delay is due to the large number of polygon classes and it takes time to find the right one. What is the best solution to implement the click and remove the delay?
Custom polygon:
class CustomPolygon(geoPoints: List<GeoPoint>) : Polygon() {
private var perimeterMarker: Marker? = null
init {
fillPaint.color = Color.TRANSPARENT
this.points = geoPoints
outlinePaint.color = Color.BLUE
outlinePaint.strokeWidth = 5f
}
var isChecked = false
private fun showPolygonPerimeterMarkers(polygon: CustomPolygon, map: MapView) {
perimeterMarker = Marker(map)
perimeterMarker!!.apply {
textLabelBackgroundColor = Color.TRANSPARENT
textLabelForegroundColor = Color.DKGRAY
setTextIcon("P= ${(polygon.distance / 1000).toInt()} km")
title= "P= ${(polygon.distance / 1000).toInt()} km"
position = calculateCenter(polygon.actualPoints)
}
}
override fun onSingleTapUp(e: MotionEvent?, mapView: MapView?): Boolean {
if (e?.action == MotionEvent.ACTION_UP && contains(e) && !isChecked) {
isChecked = true
this.fillPaint.color = Color.BLUE
this.fillPaint.alpha = 40
mapView?.let{ showPolygonPerimeterMarkers(this, it)}
perimeterMarker?.let { mapView?.overlayManager?.add(it) }
return true
}
if (e?.action == MotionEvent.ACTION_UP && contains(e) && isChecked) {
this.fillPaint.color = Color.TRANSPARENT
this.fillPaint.alpha = 0
perimeterMarker?.textLabelForegroundColor = Color.TRANSPARENT
isChecked = false
perimeterMarker?.let { mapView?.overlayManager?.remove(it) }
return true
}
return super.onSingleTapUp(e, mapView)
}
}
Every polygons added to map in viewmodel:
fun getPolygons(map: MapView) {
viewModelScope.launch {
_isLoading.value = true
val result = geoRepository.getPolygons()
when (result) {
is RepoResult.Success -> {
result.geoClusters.forEach { geoCluster ->
geoCluster.list.forEach { multiPolygon ->
try {
multiPolygon.polygons.forEach { polygon ->
map.overlays.add(polygon) // here
Log.e("Polygon added", "poly number")
}
} catch (e: Exception) {
Log.e("Point_exception", "exception $e")
}
}
_clusterPerimeter.value = geoCluster.perimeterLengthKm
}
_isLoading.value = false
}
}
}
}
You could try to simplify your polygons using the Douglas-Peucker reducer: https://github.com/osmdroid/osmdroid/blob/master/osmdroid-android/src/main/java/org/osmdroid/util/PointReducer.java
More complex, if your use case is mainly based on numerous small polygons: implement a fast "no tap" check, based on non-inclusion of the tapped point inside the polygon boundingbox (precomputed boundingbox, of course). With your own PolygonCheck class, subclassing Polygon.