如何在 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
中点击任何其他国家/地区时获得国家名称,但在 setOnFeatureClickListener
或 setOnMapClickListener
中点击突出显示时未获得国家/地区名称或点击事件部分
那么如何获取点击地图中突出显示部分的数据?
请帮助我如何实现这个
非常感谢任何帮助。
这不是最好的解决方案,但如果您禁用层的单击,那么您将在 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()
}
}
这对我有用,如果我做错了请纠正我
我正在尝试添加多个 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
中点击任何其他国家/地区时获得国家名称,但在 setOnFeatureClickListener
或 setOnMapClickListener
中点击突出显示时未获得国家/地区名称或点击事件部分
那么如何获取点击地图中突出显示部分的数据?
请帮助我如何实现这个
非常感谢任何帮助。
这不是最好的解决方案,但如果您禁用层的单击,那么您将在 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()
}
}
这对我有用,如果我做错了请纠正我