如何在 android 中添加多个 GeoJsonLayer 运行时并获取点击事件

How to add multiple GeoJsonLayer runtime and get click event in android

我正在尝试添加多个 GeoJsonLayer 运行 时间我的要求是响应 api 我必须在地图中突出显示多个国家,这工作正常但我没有得到单击事件多层我知道只有单层单击仅受 android 支持,但是是否有任何方法可以添加多层并获得所有事件的单独单击事件

这是我的代码

import android.location.Address
import android.location.Geocoder
import android.os.AsyncTask
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.gson.Gson
import com.google.maps.android.data.geojson.GeoJsonLayer
import com.google.maps.android.data.geojson.GeoJsonPolygonStyle
import org.json.JSONException
import org.json.JSONObject
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import java.net.URL
import java.util.*


class MapsNewActivity : AppCompatActivity(), OnMapReadyCallback {
    private val TAG = javaClass.simpleName
    private lateinit var mMap: GoogleMap

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_maps)
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        val mapFragment = supportFragmentManager
                .findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)

    }

    /**
     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    override fun onMapReady(googleMap: GoogleMap) {
        mMap = googleMap

        mMap.setOnMapClickListener {
            val geocoder = Geocoder(this, Locale.getDefault())
            val addresses: List<Address> = geocoder.getFromLocation(it.latitude, it.longitude, 1)
            if (addresses.isNotEmpty()) {
                val country: String? = addresses[0].getCountryName()
                Log.e(TAG, "country is ${country.toString()}")
                Toast.makeText(this, country.toString(), Toast.LENGTH_SHORT).show()
            }
        }

        mMap.uiSettings.isZoomControlsEnabled = true

        val madrid = LatLng(40.416775, -3.70379)
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(madrid, 3f))

        retrieveFileFromUrl()
    }

    private fun retrieveFileFromUrl() {
        DownloadGeoJsonFile().execute("https://raw.githubusercontent.com/xomena-so/so41431384/master/app/src/main/res/raw/es_geojson.json")
        DownloadGeoJsonFile().execute("https://raw.githubusercontent.com/xomena-so/so41431384/master/app/src/main/res/raw/us_geojson.json")
    }

    inner class DownloadGeoJsonFile : AsyncTask<String?, Void?, GeoJsonLayer?>() {
        override fun doInBackground(vararg params: String?): GeoJsonLayer? {
            try {
                // Open a stream from the URL
                val stream = URL(params[0]).openStream()
                var line: String?
                val result = StringBuilder()
                val reader = BufferedReader(InputStreamReader(stream))
                while (reader.readLine().also { line = it } != null) {
                    // Read and save each line of the stream
                    result.append(line)
                }

                // Close the stream
                reader.close()
                stream.close()

                return GeoJsonLayer(mMap, JSONObject(result.toString()))
//                return JSONObject(result.toString())
            } catch (e: IOException) {
                Log.e(TAG, "GeoJSON file could not be read")
            } catch (e: JSONException) {
                Log.e(TAG, "GeoJSON file could not be converted to a JSONObject")
            }
            return null
        }

        override fun onPostExecute(layer: GeoJsonLayer?) {
            layer?.let { addGeoJsonLayerToMap(it) }
        }
    }

    private fun addGeoJsonLayerToMap(layer: GeoJsonLayer) {
        val style: GeoJsonPolygonStyle = layer.defaultPolygonStyle
        style.fillColor = R.color.map_highlight
        style.strokeColor = R.color.map_highlight_border
        style.strokeWidth = 1f
        layer.addLayerToMap()

        layer.setOnFeatureClickListener {
            Log.e(TAG, "layer click ${it.getProperty("title")}")
            Log.e(TAG, "layer click Data = = = ${Gson().toJson(it)}")
            Toast.makeText(
                this,
                "Feature clicked: " + it.getProperty("title"),
                Toast.LENGTH_SHORT
            ).show()

        }
    }
}

这就是我得到的

我还在 toast 中点击任何其他国家/地区时获得国家名称,但在 setOnFeatureClickListenersetOnMapClickListener 中点击突出显示时未获得国家/地区名称或点击事件部分

那么如何获取点击地图中突出显示部分的数据?

请帮助我如何实现这个

非常感谢任何帮助。

这不是最好的解决方案,但如果您禁用层的单击,那么您将在 setOnMapClickListener

中收到一个事件

所以我添加了这个来获取点击事件style.isClickable = false这会破坏图层点击事件

val style: GeoJsonPolygonStyle = layer.defaultPolygonStyle
        style.fillColor = R.color.map_highlight
        style.strokeColor = R.color.map_highlight_border
        style.strokeWidth = 1f
        style.isClickable = false // this will pervert setOnFeatureClickListener so  mMap.setOnMapClickListener work
        layer.addLayerToMap()

您将在这部分收到点击事件

mMap.setOnMapClickListener {
            val geocoder = Geocoder(this, Locale.getDefault())
            val addresses: List<Address> = geocoder.getFromLocation(it.latitude, it.longitude, 1)
            if (addresses.isNotEmpty()) {
                val country: String? = addresses[0].getCountryName()
                Log.e(TAG, "country is ${country.toString()}")
                Toast.makeText(this, country.toString(), Toast.LENGTH_SHORT).show()
            }
        }

这对我有用,如果我做错了请纠正我