【问题标题】:Symbol layer icon size change Mapbox - Android dont work符号层图标大小更改 Mapbox - Android 不工作
【发布时间】:2020-04-18 11:05:32
【问题描述】:

我试图做一个例子,当我点击符号层时,它会展开以知道按下了哪个符号层。由于我使用 Mapbox Studio 创建的两个 geojson 文件,我输入了数据。我试着按照这个例子https://docs.mapbox.com/android/maps/examples/icon-size-change-on-click/ 但要么没有缩放,要么缩放所有相同的颜色(同一层)。有任何想法吗?我究竟做错了什么?现在我只是想用“first-layer-id”层来缩放那些。 非常感谢。

我的代码在这里。

package com.novadev.mapboxexample.marker

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import com.mapbox.geojson.Feature
import com.mapbox.geojson.FeatureCollection
import com.mapbox.mapboxsdk.Mapbox
import com.mapbox.mapboxsdk.geometry.LatLng
import com.mapbox.mapboxsdk.maps.MapView
import com.mapbox.mapboxsdk.maps.MapboxMap
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
import com.mapbox.mapboxsdk.maps.Style
import com.mapbox.mapboxsdk.style.layers.Property
import com.mapbox.mapboxsdk.style.layers.PropertyFactory
import com.mapbox.mapboxsdk.style.layers.SymbolLayer
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource
import com.novadev.mapboxexample.R
import kotlinx.android.synthetic.main.activity_marker.*
import java.net.URI
import java.net.URISyntaxException


class MarkerGeojson : AppCompatActivity(),
    OnMapReadyCallback,
    MapboxMap.OnMapClickListener {

    private lateinit var mapboxMap: MapboxMap
    private lateinit var markerAnimator: ValueAnimator
    private var markerSelected = false



    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // Mapbox access token is configured here. This needs to be called either in your application
        // object or in the same activity which contains the mapview.
        Mapbox.getInstance(this, getString(R.string.map_box_auth_key))
        // This contains the MapView in XML and needs to be called after the access token is configured.
        setContentView(R.layout.activity_marker)
        mapView.onCreate(savedInstanceState)
        mapView.getMapAsync(this)
        initListeners()

    }

    override fun onMapReady(mapboxMap: MapboxMap) {
        this.mapboxMap = mapboxMap
        getMap()
        mapboxMap.addOnMapClickListener(this)
    }

    override fun onMapClick(point: LatLng): Boolean {
        val pixel = mapboxMap.projection.toScreenLocation(point)
        val features = mapboxMap.queryRenderedFeatures(pixel,"first-layer-id")
        val selectedFeature = mapboxMap.queryRenderedFeatures(
            pixel, "selected-marker-layer"
        )

        mapboxMap.getStyle{ style->
            val selectedMarkerSymbolLayer =
                (style.getLayer("selected-marker-layer") as SymbolLayer)




            if (selectedFeature.size > 0 && markerSelected) false

            if (features.isEmpty()) if (markerSelected) {
                deselectMarker(selectedMarkerSymbolLayer)
            }else false

            val source: GeoJsonSource? = style.getSourceAs("selected-marker")
            source?.setGeoJson(
                FeatureCollection.fromFeatures(
                    arrayOf(
                        Feature.fromGeometry(
                            features[0].geometry()
                        )
                    )
                )
            )

            if (markerSelected) {
                deselectMarker(selectedMarkerSymbolLayer)
            }
            if (features.size > 0) {
                selectMarker(selectedMarkerSymbolLayer)
            }
            // Get the first feature within the list if one exist
            if (features.size > 0) {
                val feature = features[0]

                // Ensure the feature has properties defined
                for ((key, value) in feature.properties()!!.entrySet()) {
                    // Log all the properties
                    Log.d("TAG", String.format("%s = %s", key, value))
                    when (key) {
                        "NOMBRE" -> {
                            tvTitleMarker.text = value.toString()
                            cvInfo.visibility = View.VISIBLE
                        }
                        "TELEFONO" -> tvSubtitlemarker.text = value.toString()
                    }


                }

            }
        }

        return true
    }

    private fun initListeners() {
        ivClose.setOnClickListener {
            cvInfo.visibility = View.GONE
        }
    }

    private fun getMap() {
        mapboxMap.setStyle(
            Style.MAPBOX_STREETS
        ) {
            // Map is set up and the style has loaded. Now you can add data or make other map adjustments.
            geoJSONToMap(
                "first-source-id",
                "first-layer-id",
                "asset://madridmujeres.geojson",
                it
            )
            geoJSONToMap(
                "second-source-id",
                "second-layer-id",
                "asset://madridoficinascorreos.geojson",
                it
            )
        }
    }


    private fun drawableToBitmap (drawable : Drawable): Bitmap {
        if (drawable is BitmapDrawable) {
            return drawable.bitmap
        }

        var  bitmap = Bitmap.createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888)
        var canvas =  Canvas(bitmap)
        drawable.setBounds(0, 0, canvas.width, canvas.height)
        drawable.draw(canvas)

        return bitmap
    }



    private fun geoJSONToMap(
        sourceId: String,
        layerId: String,
        asset_id: String,
        style: Style) {
        try {
            val source = GeoJsonSource(sourceId, URI(asset_id))
            style.addSource(source)
            if (layerId == "first-layer-id") {
                var icon = drawableToBitmap(this.resources.getDrawable(R.drawable.ic_location_purple))

                style.addImage("img", icon)
                val symbolLayer = SymbolLayer(layerId, sourceId)
                symbolLayer.withProperties(
                    PropertyFactory.iconImage("img"),
                    PropertyFactory.iconAllowOverlap(true),
                    PropertyFactory.iconOffset(arrayOf(0f, -9f)),
                    PropertyFactory.iconAnchor(Property.ICON_ANCHOR_BOTTOM),
                    PropertyFactory.iconIgnorePlacement(true)
                )
                style.addLayer(symbolLayer)

                val sourceMarker = GeoJsonSource("selected-marker")
                style.addSource(sourceMarker)
                val symbolLayerSelected = SymbolLayer("selected-marker-layer", "selected-marker")
                symbolLayerSelected.withProperties(
                    PropertyFactory.iconImage("img"),
                    PropertyFactory.iconAllowOverlap(true),
                    PropertyFactory.iconOffset(arrayOf(0f, -9f)),
                    PropertyFactory.iconAnchor(Property.ICON_ANCHOR_BOTTOM),
                    PropertyFactory.iconIgnorePlacement(true))
                style.addLayer(symbolLayerSelected)

            } else {
                style.addImage("$layerId marker", this.resources.getDrawable(R.drawable.ic_location_yellow))
                val symbolLayer = SymbolLayer(layerId, sourceId)
                symbolLayer.setProperties(
                    PropertyFactory.iconImage("$layerId marker"),
                    PropertyFactory.iconAllowOverlap(true),
                    PropertyFactory.iconAnchor(Property.ICON_ANCHOR_BOTTOM),
                    PropertyFactory.iconIgnorePlacement(true)
                )
                style.addLayer(symbolLayer)
            }

        } catch (e: URISyntaxException) {
            e.printStackTrace()
        }

    }

    private fun selectMarker(iconLayer: SymbolLayer) {
        markerAnimator = ValueAnimator()
        markerAnimator.setObjectValues(1f, 2f)
        markerAnimator.duration = 300
        markerAnimator.addUpdateListener { animator ->
            iconLayer.setProperties(
                PropertyFactory.iconSize(animator.animatedValue as Float)
            )
        }
        markerAnimator.start()
        markerSelected = true
    }

    private fun deselectMarker(iconLayer: SymbolLayer) {
        markerAnimator.setObjectValues(2f, 1f)
        markerAnimator.duration = 300
        markerAnimator.addUpdateListener { animator ->
            iconLayer.setProperties(
                PropertyFactory.iconSize(animator.animatedValue as Float)
            )
        }
        markerAnimator.start()
        markerSelected = false
    }


    // Add the mapView lifecycle to the activity's lifecycle methods
    public override fun onResume() {
        super.onResume()
        mapView!!.onResume()
    }

    override fun onStart() {
        super.onStart()
        mapView!!.onStart()
    }

    override fun onStop() {
        super.onStop()
        mapView!!.onStop()
    }

    public override fun onPause() {
        super.onPause()
        mapView!!.onPause()
    }

    override fun onLowMemory() {
        super.onLowMemory()
        mapView!!.onLowMemory()
    }

    override fun onDestroy() {
        super.onDestroy()
        mapView!!.onDestroy()
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        mapView!!.onSaveInstanceState(outState)
    }

}

【问题讨论】:

    标签: android kotlin geojson mapbox-android


    【解决方案1】:

    看起来好像您没有为所选标记层设置 GeoJSONsource。

    GeoJsonSource source = style.getSourceAs("selected-marker");
    if (source != null) {
    source.setGeoJson(FeatureCollection.fromFeatures(
    new Feature[]{Feature.fromGeometry(features.get(0).geometry())}));
    }

    通过不设置 geoJSON 源,源将保留包含包含所有标记的 FeatureCollection 的 geoJSON。 --> 所有标记都将被展开,而不仅仅是您点击的那个。

    【讨论】:

    • 感谢您的回复。感谢您的回答,我得到了展开的图标,但是,它展开但留下了下面的初始值,如果我再次单击该图标,应用程序崩溃(java.lang.ArrayIndexOutOfBoundsException:length = 0; index = 0)我试图解决它,但我不明白该怎么做。我会将代码更新到目前为止。
    • 你能详细说明哪个数组越界了吗?
    猜你喜欢
    • 2020-12-12
    • 1970-01-01
    • 2012-08-29
    • 2018-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多