Изменение размера иконки слоя символов Mapbox - Android не работает - PullRequest
0 голосов
/ 18 апреля 2020

Я пытаюсь сделать пример, в котором, когда я нажимаю на слой символов, он расширяется, чтобы знать, какой из них нажат. Я ввожу данные благодаря двум geo json файлам, которые я создал в Mapbox Studio. Я попытался следовать этому примеру 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)
    }

}

1 Ответ

0 голосов
/ 30 апреля 2020

Похоже, что вы не устанавливаете источник GeoJSON для выбранного слоя маркера.

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

Если не установить источник geo JSON, источником останется geo JSON, содержащий FeatureCollection, содержащую все маркеры. -> Все маркеры будут расширены вместо того, на который вы нажали.

...