• Android gaode高德地图小人运动轨迹动态移动handler实现,不同于官网的平滑移动,可以控制速度、地图缩放、跟随小人移动后续生成视频,类似华为运动


    package com.example.tsdemo;
    
    import android.app.Activity;
    import android.os.Handler;
    import android.os.Looper;
    
    import java.util.ArrayList;
    import android.app.Activity;
    import android.os.Handler;
    import android.os.Looper;
    import android.util.Pair;
    import com.amap.api.maps.AMap;
    import com.amap.api.maps.CameraUpdateFactory;
    import com.amap.api.maps.CustomRenderer;
    import com.amap.api.maps.MapView;
    import com.amap.api.maps.UiSettings;
    import com.amap.api.maps.model.BitmapDescriptor;
    import com.amap.api.maps.model.BitmapDescriptorFactory;
    import com.amap.api.maps.model.LatLng;
    import com.amap.api.maps.model.LatLngBounds;
    import com.amap.api.maps.model.MyLocationStyle;
    import com.amap.api.maps.model.PolylineOptions;
    
    
    import com.amap.api.maps.model.Marker;
    import com.amap.api.maps.model.MarkerOptions;
    
    public class RecordAMapHelper {
        private Activity activity;
        private AMap mAMap;
        private MapView mapView;
        private UiSettings uiSettings;
        private PolylineOptions mPolylineOptions;//画线
        private PathSmoothTool mpathSmoothTool;//平滑处理工具 官网下载
        private final int maxZoomLevel = 16;//最大缩放  23最大 1最小
        private int currentIndex;
        private Handler handler = new Handler(Looper.getMainLooper());
        private final List resultList = new ArrayList<>();//数据过滤的时候 需要注意
        private Marker tagMarker;
        private List mLatLngLists = new ArrayList<>();
        private List mLatLngLists_move = new ArrayList<>();
    
        public RecordAMapHelper(MapView mapView, Activity activity) {
            this.mapView = mapView;
            this.activity = activity;
            setMapSetting();
            setUpMap();
            currentIndex = 0;
        }
    
        private void setMapSetting() {
            mAMap = mapView.getMap();
            mAMap.setMapType(AMap.MAP_TYPE_SATELLITE)
            mAMap.setMaxZoomLevel(maxZoomLevel);
            mAMap.setMapTextZIndex(2);
            mapView.getMap().moveCamera(CameraUpdateFactory.zoomTo(maxZoomLevel))
            setMapUiSetting();
        }
    
        private void setMapUiSetting() {
            uiSettings = mAMap.getUiSettings();
            uiSettings.setMyLocationButtonEnabled(false);// 设置默认定位按钮是否显示
            uiSettings.setZoomControlsEnabled(false);// 设置默认缩放按钮是否显示
            uiSettings.setCompassEnabled(false);// 设置默认指南针是否显示
        }
    
        public void setmLatLngLists(List mLatLngLists) {
            this.mLatLngLists.addAll(mLatLngLists);
        }
    
        public void addmLatLngLists_move(List mLatLngLists_move) {
            this.mLatLngLists_move.addAll(mLatLngLists_move);
        }
    
        private void setUpMap() {
            if (mAMap == null) {
                mAMap = mapView.getMap();
            }
            mpathSmoothTool = new PathSmoothTool();
            mpathSmoothTool.setIntensity(5);
        }
    
        private PolylineOptions initPolyline(List resultList) {
            mPolylineOptions = new PolylineOptions();
            mPolylineOptions.color(0xff13E57B);
            mPolylineOptions.width(10f);
            mPolylineOptions.useGradient(false);
            mPolylineOptions.addAll(resultList);
            mPolylineOptions.setEraseColor(true, 0xffffffff);
            return mPolylineOptions;
        }
    
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                activity.runOnUiThread(() -> {
                    //提升加载速度的话   设置currentIndex的值   结束了以后移除runner
                    if (currentIndex >= mLatLngLists.size()) {
                        handler.removeCallbacks(runnable);
                        handler.postDelayed(completeRunnable, 1000);
    //走到最后一个点位的时候  移除小人显示  终点图标
                        if (tagMarker != null) {
                            tagMarker.remove();
                        }
                        if (resultList.size() > 1) {
                            mAMap.addMarker(new MarkerOptions()
                                    .icon(getIconBitmap(1))
                                    .position(mLatLngLists.get(mLatLngLists.size() - 1)));
                        }
                    } else {
                        resultList.add(mLatLngLists.get(currentIndex));
                        currentIndex = currentIndex + 2;//循环获取➕2数据  可以过滤 +1  +2 +3
                        PolylineOptions options = initPolyline(resultList);//画线 每次进来数据都会++
                        mAMap.addPolyline(options);//添加到地图
                        tagMarker.setPosition(resultList.get(resultList.size() - 1));//小人的图标
    //animateCamera 需要250毫秒才刷新一次
                        if (currentIndex % 50 == 0) {
                            mAMap.animateCamera(CameraUpdateFactory.newLatLngZoom(resultList.get(resultList.size() - 1), maxZoomLevel));
                        }
    
                        handler.postDelayed(this, 20);
                    }
                });
            }
        };
    
        Runnable completeRunnable = new Runnable() {
            @Override
            public void run() {
                activity.runOnUiThread(() -> {
                    setMapZoom(mLatLngLists);
                });
            }
        };
    
        private void setStartEndPoint() {
    // 增加起点开始
            mAMap.addMarker(new MarkerOptions()
                    .icon(getIconBitmap(0))
                    .position(mLatLngLists.get(0))
            );
            MarkerOptions option = new MarkerOptions();
            option.anchor(0.5f, 0.5f)
                    .icon(getIconBitmapTag())
                    .position(mLatLngLists.get(0));
            tagMarker = mAMap.addMarker(option);
        }
    
        public void destroyAll() {
            handler.removeCallbacks(runnable);
            handler.removeCallbacks(completeRunnable);
            handler = null;
        }
    
        public BitmapDescriptor getIconBitmap(int type) {
            if (type == 1) {
                return BitmapDescriptorFactory.fromResource(R.mipmap.ic_sport_end);
            } else {
                return BitmapDescriptorFactory.fromResource(R.mipmap.ic_sport_start);
            }
        }
    
        public BitmapDescriptor getIconBitmapTag() {
            return BitmapDescriptorFactory.fromResource(R.mipmap.ic_sport_tag);
        }
    
    
        //在地图上添加本地轨迹数据,并处理
        public void addLocpath() {
            if (mLatLngLists == null || mLatLngLists.isEmpty()) {
                return;
            }
            handler.postDelayed(runnable, 20);
    //增加起点
            setStartEndPoint();
            mAMap.animateCamera(CameraUpdateFactory.newLatLngZoom(mLatLngLists.get(0), maxZoomLevel));
        }
    
        //路线小人  平滑移动 官网上有   比自己写更加流畅  官网有的代码
        public void moveMarker() {
            LatLng latLngStart = mLatLngLists_move.get(0);
            SmoothMoveMarker smoothMarker = new SmoothMoveMarker(mAMap);
            smoothMarker.setDescriptor(BitmapDescriptorFactory.fromResource(R.mipmap.ic_sport_tag));
            Pair pair = SpatialRelationUtil.calShortestDistancePoint(mLatLngLists_move, latLngStart);
            mLatLngLists_move.set(pair.first, latLngStart);
            List subList = mLatLngLists_move.subList(pair.first, mLatLngLists_move.size());
            smoothMarker.setPoints(subList);
            smoothMarker.startSmoothMove();
        }
    
        //newLatLngBounds  第二个参数  200 越大 显示的范围越大
        public void setMapZoom(List latLngLists) {
            if (latLngLists != null && latLngLists.size() > 1) {
                LatLngBounds.Builder b = LatLngBounds.builder();
                for (LatLng latLngList : latLngLists) {
                    b.include(latLngList);
                }
                LatLngBounds bounds = b.build();
                mAMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 150));
            } else {
                LogUtil.e("缩放数据的大小小于1.....");
            }
    
        }
    }
    
    //    use:
    //    private ArrayList sportGPSData = new ArrayList<>();
    //    aMapHelper = new RecordAMapHelper(mapView, getActivity());
    //aMapHelper.setmLatLngLists(sportGPSData);
    //aMapHelper.addmLatLngLists_move(sportGPSData);
    //aMapHelper.addLocpath();

    1.使用handler  post方法控制小人移动的速度

    2.高德地图中animateCamera 跟其他移动到中心点的方法不太一样 注意,其中一个直接写地图缩放等级用的比较多  还有  bound  设置200这种  用法不一样看你自己需要

    3.官网提供的轨迹平滑移动会过滤掉很多点坐标,不建议使用

    4.在app切换到后台的时候  无法准确获取到定位坐标,会导致在路线绘制的时候一跳一跳的 ,或者本身定位的时候差异 在50米以上的时候 也会出现,目前暂时未解决,只有应用一直在前台的时候才不会出现该问题

    5.在运动的时候通过他官网的计算两个点距离的方法过滤掉小于1.5米的会更加准确

    6.计算运动移动的距离的时候如果是通过点坐标来计算获得的话 ,后面再绘制路线的时候更好把控,不然加业务需求的时候无法精准计算他的运动时间 还有每一公里的数值,导致计算不准确

    7.定义成工具类不好操作ui页面,

  • 相关阅读:
    linux系统安全及应用
    Springboot毕设项目基于SpringBoot的图片网站f3yv9(java+VUE+Mybatis+Maven+Mysql)
    mac的m1芯片安装nvm踩坑完全版
    Spring事务提交,回滚,传播属性源码分析
    Matlab:确定数值类
    构建RAG应用-day05: 如何评估 LLM 应用 评估并优化生成部分 评估并优化检索部分
    HTML按钮通过JS实现选中和取消
    学习黑马程序员JavaScript总结
    修改CentOS默认mail发件人名称
    kubernetes Auditing 实战
  • 原文地址:https://blog.csdn.net/qq_34812958/article/details/126813205