【问题标题】:Map not clickable around marker in Google Map SDK for AndroidGoogle Map SDK for Android 中的标记周围的地图不可点击
【发布时间】:2018-09-27 02:28:46
【问题描述】:

我正在构建一些如下图所示的应用程序,我想强制标记不可点击,但 Marker 或 MarkerOptions 没有 setClickable(false)。 目前标记周围的区域(见附件)不可点击(点击传递给标记,而不是地图)

【问题讨论】:

标签: android click google-maps-markers google-maps-android-api-2


【解决方案1】:

您必须在地图中使用 Overlay 而不是 marker 才能准确获得所需的内容。您可以点击此链接,类似的在 JavaScript here 中完成。

【讨论】:

    【解决方案2】:

    我找到了一种手动处理标记点击的方法。

    添加一个可触摸的包装器,如此 stackoverflow 答案中所述:https://stackoverflow.com/a/58039285/1499750

    将手势检测器添加到您的片段并聆听单击,然后根据 lat lng 找到最近的标记:

    private var gestureDetector: GestureDetector? = null
    
    ...
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    
        gestureDetector = GestureDetector(context, GoogleMapsGestureListener { e -> onMapSingleTap(e) })
    
        //id of touchable wrapper - can use findViewById here instead if not using kotlin synthetics
        googleMapsTouchableWrapper?.onTouch = {
            gestureDetector?.onTouchEvent(it)
        }
    }
    
    private fun onMapSingleTap(e: MotionEvent) {
        val latLng = map?.projection?.fromScreenLocation(Point(e.x.toInt(), e.y.toInt())) ?: return
    
        //this assumes you are maintaining a set of the latlngs for your markers
        val closestNearbyLatLng = markerLatLngs?.findClosestNearbyLatLng(latLng)
    
        //assuming you have a map of latlng to marker you can now find that marker based on latlng and do whatever you need to with it
    
    }
    
    private fun Set<LatLng>.findClosestNearbyLatLng(latLng: LatLng): LatLng? {
    
        val map = map ?: return null
    
        val screenDistance = map.projection.visibleRegion.latLngBounds.northeast.distanceBetweenInKm(map.projection.visibleRegion.latLngBounds.southwest)
    
        val closestLatLng = this.minBy { latLng.distanceBetweenInKm(it) } ?: return null
    
        if (latLng.distanceBetweenInKm(closestLatLng) < screenDistance/40) {
            return closestLatLng
        }
    
        return null
    }
    
    fun LatLong.distanceBetweenInKm(latLng: LatLng): Double {
    
        if (this == latLng) {
            return 0.0
        }
    
        val earthRadius = 6371.0 //km value;
    
        //converting to radians
        val latPoint1Radians = Math.toRadians(latitude)
        val lngPoint1Radians = Math.toRadians(longitude)
        val latPoint2Radians = Math.toRadians(latLng.latitude)
        val lngPoint2Radians = Math.toRadians(latLng.longitude)
    
        var distance = sin((latPoint2Radians - latPoint1Radians) / 2.0).pow(2.0) + (cos(latPoint1Radians) * cos(latPoint2Radians)
                * sin((lngPoint2Radians - lngPoint1Radians) / 2.0).pow(2.0))
        distance = 2.0 * earthRadius * asin(sqrt(distance))
    
        return abs(distance) //km value
    }
    
    class GoogleMapsGestureListener(private val onSingleTap: (MotionEvent) -> Unit) : GestureDetector.SimpleOnGestureListener() {
    
        override fun onSingleTapConfirmed(e: MotionEvent?): Boolean {
            super.onSingleTapConfirmed(e)
            e?.let { onSingleTap(it) }
            return true
        }
    }
    

    【讨论】:

      【解决方案3】:

      我最近能够创建一个公式来在 Google 地图上的某个位置周围创建一个区域,该区域也可以通过缩放级别进行缩放。

      在这里,我将 LatLng 坐标从标记转换为手机上的实际坐标:

      //array that holds all locations of every marker
      //after a marker is created add the position in here
      val positionList = mutableListOf<LatLng>()
      
      //map is variable type GoogleMap
      map.setOnMapClickListener {
      
        var inRange = false
      
        for(i in positionList.indices) {
      
        //establish corners of boundaries surrounding markers
        val points = positionList.toCoordinates(map)
      
        //check if clicked position falls in one of the positions' bounds
        val isInRangeLng = (points[i][2]..points[i][3]).contains(it.longitude)
        val isInRangeLat = (points[i][0]..points[i][1]).contains(it.latitude)
      
        //if click lands in of the positions' bounds, stop loop and return inRange 
        //true
        if(isInRangeLat && isInRangeLng) {
          inRange = true
          break
        }
      }
      
        if(!inRange) {
          //APPLY YOUR LOGIC IF CLICK WAS NOT IN AREA
        } else {
          //APPLY YOUR LOGIC IF CLICK WAS IN AREA
        }
      }
          
        //Extension function used to simplify logic
        /** Convert LatLng to coordinates on phone **/
        fun List<LatLng>.toCoordinates(map: GoogleMap): List<List<Double>> {
        val proj: Projection = map.projection
      
        val coordinateList = mutableListOf<List<Double>>()
      
        //create bounds for each position in list
        this.forEach {
        //get screen coordinates at the current LatLng
        val point = proj.toScreenLocation(it)
        val left = point.x - 100
        val right = point.x + 100
        val top = point.y - 100
        val bottom = point.y + 100
      
        //convert bounds into two points diagonal of each other
        val topRight = Point(right, top)
        val bottomLeft = Point(left, bottom)
      
        //convert the two points into LatLng points and get the bounds in north, 
        //south, west, and east
        val northEast = proj.fromScreenLocation(topRight)
        val north = northEast.latitude
        val east = northEast.longitude
      
        val southWest = proj.fromScreenLocation(bottomLeft)
        val south = southWest.latitude
        val west = southWest.longitude
          
        //add the bounds to be returned in a list which corresponds to a certain 
        //position
        coordinateList.add(listOf(
          south,
          north,
          west,
          east
        ))
       }
      
       return coordinateList
      }
      

      这不仅可以用于标记。

      【讨论】:

        猜你喜欢
        • 2013-04-17
        • 2015-09-26
        • 1970-01-01
        • 1970-01-01
        • 2018-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多