MapBoxMap 之 SymbolLayer实现标记(一)

Marker早已被废弃,SymbolLayer取而代之,本篇就介绍我自己的新的Sdk实现标记的方法

 

一. app moudle 的build.gradle引入sdk

  //Maps SDK for Android
    implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:8.1.0'

二.编辑界面

activity_map.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:mapbox="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:layout_marginTop="20dp"
        android:layout_marginRight="20dp"
        android:text="添加标记" />

    <Button
        android:id="@+id/btn_change"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right|center_vertical"
        android:layout_marginRight="20dp"
        android:text="更改标记位置" />

    <Button
        android:id="@+id/btn_delete"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right|bottom"
        android:layout_marginRight="20dp"
        android:layout_marginBottom="20dp"
        android:text="删除标记" />

    <com.mapbox.mapboxsdk.maps.MapView
        android:id="@+id/map_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</FrameLayout>

 MapActivity

public class MapActivity extends AppCompatActivity implements View.OnClickListener {
    private Button btn_add;
    private Button btn_change;
    private Button btn_delete;

    private MapView mMapView;
    private MapboxMap mMapBoxMap;
    private Style mStyle;

    private double latitude = 39.9;
    private double longitude = 119.6;
    private SingleSymbolLayer singleSymbolLayer;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map);

        btn_add = findViewById(R.id.btn_add);
        btn_change = findViewById(R.id.btn_change);
        btn_delete = findViewById(R.id.btn_delete);

        //初始化 Mapbox key
        Mapbox.getInstance(this, getString(R.string.mapbox_access_token));

        mMapView = findViewById(R.id.map_view);
        mMapView.onCreate(savedInstanceState);
        //getMapAsync
        mMapView.getMapAsync(mapboxMap -> {
            mMapBoxMap = mapboxMap;
            //setStyle
            mapboxMap.setStyle(Style.MAPBOX_STREETS, style -> {
                // Map is set up and the style has loaded. Now you can add data or make other map adjustments
                mStyle = style;
                //地图加载完毕开始我们的代码
                notifyMapReady();
            });
        });
    }

    private void notifyMapReady() {
        Toast.makeText(this, "地图初始化完毕", Toast.LENGTH_SHORT).show();
        //添加监听
        btn_add.setOnClickListener(this);
        btn_change.setOnClickListener(this);
        btn_delete.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_add:
                if (singleSymbolLayer == null) {
                    //添加一个锁图片到地图
                    singleSymbolLayer = new SingleSymbolLayer.Builder().setStyle(mStyle)
                            .setImage(getResources().getDrawable(R.drawable.mapbox_marker_icon_default))
                            .setLat(latitude)
                            .setLng(longitude)
                            .build();
                    //移动到位置
                    CameraPosition cameraPosition = new CameraPosition.Builder()
                            .target(new LatLng(latitude, longitude))
//                            .zoom(12)
                            .tilt(0)
                            .bearing(0)
                            .build();
                    CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition);
                    mMapBoxMap.animateCamera(cameraUpdate);
                }
                break;

            case R.id.btn_change:
                if (singleSymbolLayer != null) {
                    double randomValue = new Random().nextDouble();

                    double changeLongitude = latitude + randomValue;

                    singleSymbolLayer.updatePosition(latitude, changeLongitude);
                }
                break;

            case R.id.btn_delete:
                if (singleSymbolLayer != null) {
                    singleSymbolLayer.deleteSelf();
                    singleSymbolLayer = null;
                }
                break;

            default:
                break;
        }
    }

    //region MapView生命周期
    @Override
    public void onStart() {
        super.onStart();
        if (mMapView != null) {
            mMapView.onStart();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mMapView != null) {
            mMapView.onResume();
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mMapView != null) {
            mMapView.onPause();
        }
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        if (mMapView != null) {
            mMapView.onLowMemory();
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if (mMapView != null) {
            mMapView.onSaveInstanceState(outState);
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if (mMapView != null) {
            mMapView.onStop();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mMapView != null) {
            mMapView.onDestroy();
        }
    }
    //endregion
}

 SingleSymbolLayer(简单封装SymbolLayer的自定义标记,包含添加、更新、删除)

/**
 * 类描述:一个标记
 * <p>
 * 可自行扩展
 */
public class SingleSymbolLayer {
    //Source的id 不可重复
    private static final String SINGLE_SOURCE_ID = "single_source_id";
    //SymbolLayer的id 不可重复
    private static final String SINGLE_LAYER_ID = "single_layer_id";
    //图片资源的id
    private static final String SINGLE_IMAGE_ID = "single_image_id";

    private Style singleStyle;
    private GeoJsonSource singleSource;

    private SingleSymbolLayer() {

    }

    private SingleSymbolLayer(Style style, Drawable drawable, double lat, double lng) {
        singleStyle = style;
        singleSource = initSingleSource(style, lat, lng);
        initSingleLayer(style, drawable);
    }

    /**
     * 初始化添加源
     *
     * @param style
     * @param lat
     * @param lng
     * @return
     */
    private GeoJsonSource initSingleSource(Style style, double lat, double lng) {
        GeoJsonSource source = new GeoJsonSource(SINGLE_SOURCE_ID);
        source.setGeoJson(Point.fromLngLat(lng, lat));
        style.addSource(source);
        return source;
    }

    /**
     * 初始化添加SymbolLayer
     */
    private void initSingleLayer(Style style, Drawable drawable) {
        style.addImage(SINGLE_IMAGE_ID, drawable);
        SymbolLayer symbolLayer = new SymbolLayer(SINGLE_LAYER_ID, SINGLE_SOURCE_ID)
                .withProperties(
                        /* show image with id title based on the value of the name feature property */
                        iconImage(SINGLE_IMAGE_ID),
                        /* set anchor of icon to bottom */
                        iconAnchor(Property.ICON_ANCHOR_BOTTOM),
                        /* all info window and marker image to appear at the same time*/
                        iconAllowOverlap(true)
                );
        style.addLayer(symbolLayer);
    }

    /**
     * 更新位置
     *
     * @param lat
     * @param lng
     */
    public void updatePosition(double lat, double lng) {
        if (singleSource != null) {
            singleSource.setGeoJson(Point.fromLngLat(lng, lat));
        }
    }

    /**
     * 删除自己
     */
    public void deleteSelf() {
        singleStyle.removeImage(SINGLE_IMAGE_ID);
        singleStyle.removeLayer(SINGLE_LAYER_ID);
        singleStyle.removeSource(SINGLE_SOURCE_ID);
        singleStyle = null;
        singleSource = null;
    }

    /**
     * 可自行扩展
     */
    public static class Builder {
        private Style style;
        private Drawable image;
        private double lat;
        private double lng;

        public SingleSymbolLayer.Builder setStyle(Style style) {
            this.style = style;
            return this;
        }

        public SingleSymbolLayer.Builder setImage(Drawable image) {
            this.image = image;
            return this;
        }

        public SingleSymbolLayer.Builder setLat(double lat) {
            this.lat = lat;
            return this;
        }

        public SingleSymbolLayer.Builder setLng(double lng) {
            this.lng = lng;
            return this;
        }

        public SingleSymbolLayer build() {
            return new SingleSymbolLayer(style, image, lat, lng);
        }
    }
}

那么要批量添加应该怎么做呢,接下来就展示一下

MapBoxMap 之 SymbolLayer实现标记(二) 批量添加

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值