百度地图——显示小车轨迹动画回放

百度地图,Android显示车辆轨迹动画

初次设计想就用百度自带的显示覆盖物的方式,计算两个坐标点的距离,添加短距离的坐标点,然后在密密麻麻的坐标点之间显示,隐藏覆盖物,形成移动的视觉效果。
后来发现会创建较大的内存,而且效果不佳。
最后选择添加View的方法,利用addView方法添加小车的view,利用Android动画,同步和异步结合显示小车运行。
主要几个注意点和方案是:
  1. 计算小车转弯的角度,判断顺时逆时针。
  2. 计算地图缩放比例,依据是一组经纬度的最大距离值
  3. 在显示动画的时候地图是不能缩放的,因为经纬度和屏幕坐标转化不是实时的,数据是在调用接口时屏幕当前的比例尺转化。
  4. 还有就是当动画前屏幕被缩放了,轨迹已经超出了屏幕显示,就计算下一个车辆到达的点在不在屏幕上,不在的话就移动地图,将该点设置为中心点,这个并不完善
  5. 百度地图——显示小车轨迹动画回放_第1张图片

代码片段

地图移动到某一点,并且设置缩放比例。
    @Override
    public void MoveToPoint(List list) {
        /**
         * 设置地图移动到指定位置
         */
        // 定义地图状态
        //数字越小,比例尺越大
        Double lat=new Double(0),lng=new Double(0);
        double latlng[]=new double[2];
        int zooms=getZoomnum(latlng,list);
        Log.i(TAG, "lat lng:" + latlng[0] + "__  " + latlng[1]+"zoom   "+zooms);
        MapStatus mMapStatus = new MapStatus.Builder().target(new LatLng(latlng[0],latlng[1])).zoom(zooms)
                .build();
        // 定义MapStatusUpdate对象,以便描述地图状态将要发生的变化
        MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory
                .newMapStatus(mMapStatus);
        // 改变地图状态
        mBaiduMap.setMapStatus(mMapStatusUpdate);
    }
//根据轨迹,一组坐标值计算缩放比例
    public int getZoomnum(double[] lalg,final List pointlist){
        int zoomSize[]={5,10,20,50,100,200,500,1000,2000,5000,10000,20000};//分别对应于zoom 21,20,19,18,17,16,15,14,13,12,11,10
        int i,j;
        double max=0,temp;
        for(i=0;imax){
                    max=temp;
                    lalg[0]=(pointlist.get(i).latitude+pointlist.get(j).latitude)/2;
                    lalg[1]=(pointlist.get(i).longitude+pointlist.get(j).longitude)/2;
                    Log.i(TAG,"lat lng:"+lalg[0]+"_dadsa_  "+lalg[1]);

                }
            }
        }
        Log.i(TAG,"max:  "+max);
        for(i=0;i<11;i++)
        {
            if(max>zoomSize[i]*12&&max
利用向量知识计算方向角,顺时针旋转为正,逆时针为负。
  //计算两个向量的方向角,并根据顺时针返回正值,逆时针返回负值
    public float getangle(Point p1,Point p2,Point p3){
        double xp1p2=p2.x-p1.x;
        double yp1p2=p2.y-p1.y;
        double xp2p3=p3.x-p2.x;
        double yp2p3=p3.y-p2.y;
        double a1=Math.sqrt(xp1p2*xp1p2+yp1p2*yp1p2);
        double b1=Math.sqrt(xp2p3*xp2p3+yp2p3*yp2p3);
        double ab=xp1p2*xp2p3+yp1p2*yp2p3;
        float angle;
        if((a1*b1)!=0)
            angle =(float)Math.acos(ab/(a1*b1));
        else angle=0;
        double a_b=xp1p2*yp2p3-xp2p3*yp1p2;
        if(a_b<0)angle=-angle;
        return angle*180/(float)Math.PI;
    }

核心部分,动画绘制
//行车的时候,地图不能缩放,因为经纬度转化成坐标值是以当时地图的比例尺进行转化的
    public void rotateyAnimRun(final View view,final List list)
    {
        //ObjectAnimator的父类是valueAnimator,爷爷类是Animator.
        List lt= new ArrayList();
        Log.i(TAG,"lt size: "+lt.size());
        int size=list.size();
        float t1=0f;
        AnimatorSet set = new AnimatorSet();
        int i=0;
        carPathlist_point=list;
        for (i=0;i width ||
                            list.get(center + 1).y > height) {
                        Log.i(TAG, "不是大了就是小了");
                        MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newLatLng(carPathlist.get(center));
                        // 改变地图状态
                        mBaiduMap.setMapStatus(mMapStatusUpdate);
                    }
                }
                @Override
                public void onAnimationEnd(Animator animation) {}
                @Override
                public void onAnimationCancel(Animator animation) {}
                @Override
                public void onAnimationRepeat(Animator animation) {}
            };
            if(k==0) {
                float angle =getangle(new Point(list.get(i).x-1,list.get(i).y),list.get(i),list.get(i+1));
                Log.i(TAG, "angle:   "+angle);
                t1=t1+angle;
                pvhR = PropertyValuesHolder.ofFloat("rotation", t1);
                animator2=ObjectAnimator.ofPropertyValuesHolder(view, pvhR).setDuration(500);
                animator2.addListener(new newAnListener(i));
            }
            else{
                Log.i(TAG,"k:   "+k+"i:   "+i);
                float angle =getangle(list.get(k-1),list.get(i),list.get(i+1));
                Log.i(TAG, "angle:   "+angle);
                t1=t1+angle;
                pvhR = PropertyValuesHolder.ofFloat("rotation", t1);
                animator2=ObjectAnimator.ofPropertyValuesHolder(view, pvhR).setDuration(500);
                animator2.addListener(new newAnListener(i));
            }
            animator= ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY).setDuration(1000);
            //先旋转再直行
            lt.add(animator2);
            lt.add(animator);
        }
        //顺序执行Animator list中的动画效果
            set.playSequentially(lt);
        set.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                //所有手势不可用
                mUiSettings.setAllGesturesEnabled(false);
                mMapView.showZoomControls(false);
                lay_showpath.setClickable(false);
                Log.i(TAG, "set_____________start");
            }
            @Override
            public void onAnimationEnd(Animator animation) {
                mMapView.removeViewInLayout(view);
                //所有手势可用
                mUiSettings.setAllGesturesEnabled(true);
                mMapView.showZoomControls(true);
                lay_showpath.setClickable(true);
                Log.i(TAG, "set_____________end");
            }
            @Override
            public void onAnimationCancel(Animator animation) {
            }
            @Override
            public void onAnimationRepeat(Animator animation) {
            }
        });
//可以将会设置绘制动画,设置在监听百度地图已经加载完毕的事件里
            set.start();
        Log.i(TAG, "lt end size: " + lt.size());
    }
添加该view到百度地图。
    @Override
    public void    DrawDynaPath(final List pointlist) {
        //获取小车的view
        Bitmap bitmap= BitmapFactory.decodeResource(getResources(), R.drawable.ic_vehicle_location_current);
        ImageView iv=new ImageView(this);
        iv.setImageBitmap(bitmap);
        Log.i(TAG, "size():" + pointlist.size());
        Projection pj=mBaiduMap.getProjection();
        //所有经纬度转化成坐标
        List list=new ArrayList();
        for(LatLng ll:pointlist){
          list.add(pj.toScreenLocation(ll));
        }
        mMapView.removeViewInLayout(iv);
        //	layoutMode(MapViewLayoutParams.ELayoutMode mode 指定 MapViewLayoutParams 的方式:屏幕坐标或者地图经纬度坐标
        //absoluteMode是不随地图变化而移动的,mapMode是随地图移动
        MapViewLayoutParams mlp = new MapViewLayoutParams.Builder().
                layoutMode(MapViewLayoutParams.ELayoutMode.mapMode).
                position(pointlist.get(0)).
                width(MapViewLayoutParams.WRAP_CONTENT).
                height(MapViewLayoutParams.WRAP_CONTENT).build();
        Log.i(TAG,"list.get(0):"+list.get(0).toString());
//        mMapView.removeAllViews();
        rotateyAnimRun(iv, list);
        mMapView.addView(iv, mlp);
//        layout_baidumap.removeAllViewsInLayout();
//        mMapView.addView(parent);
        mMapView.refreshDrawableState();
    }





你可能感兴趣的:(Android学习)