1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 百度地图——显示小车轨迹动画回放

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

时间:2020-10-24 13:50:46

相关推荐

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

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

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

代码片段

地图移动到某一点,并且设置缩放比例。

@Overridepublic void MoveToPoint(List<LatLng> 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<LatLng> 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,10int i,j;double max=0,temp;for(i=0;i<pointlist.size();i++){for(j=i+1;j<pointlist.size();j++){temp=DistanceUtil.getDistance(pointlist.get(i),pointlist.get(j));if(temp>max){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<zoomSize[i+1]*12) {Log.i(TAG,"ixiabio: "+i);return 20 - i;}}if(max<zoomSize[0]*12)return 21;else return 10;}

利用向量知识计算方向角,顺时针旋转为正,逆时针为负。

//计算两个向量的方向角,并根据顺时针返回正值,逆时针返回负值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<Point> list){//ObjectAnimator的父类是valueAnimator,爷爷类是Animator.List<Animator> lt= new ArrayList<Animator>();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<size-1;i++){Animator animator,animator2;int k=i;//计数车子不动相同的经纬度情况while(i<size-1&&list.get(i).x==list.get(i+1).x&&list.get(i).y==list.get(i+1).y)i++;if(i==size-1)break;Log.i(TAG,"坐标: "+list.get(i).x+"____"+list.get(i).y);//PropertyValuesHolder属性holder,分别设置X,Y方向的移动值,然后调用ofPropertyValuesHolder设置属性值,这个是异步叠加动画。//参数指的是相对于view最初位置的偏移值PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("translationX", list.get(i).x-list.get(0).x,list.get(i+1).x-list.get(0).x);PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("translationY", list.get(i).y-list.get(0).y,list.get(i+1).y-list.get(0).y);PropertyValuesHolder pvhR;//监听在小车运行的时候如果下一个坐标点不在地图内,则将地图的中心点设置为下一个坐标点。class newAnListener implements Animator.AnimatorListener{private int center;public newAnListener(int center_){center=center_;}@Overridepublic void onAnimationStart(Animator animation) {WindowManager wm = (WindowManager) BaiduMapActivity.this.getSystemService(Context.WINDOW_SERVICE);int width = wm.getDefaultDisplay().getWidth();int height = wm.getDefaultDisplay().getHeight();Log.i(TAG, "width: " + width + "height: " + height + "mapCenter: " + center);Log.i(TAG, "x: " + list.get(center + 1).x + "y: " + list.get(center + 1).y);if (list.get(center + 1).x < 0 ||list.get(center + 1).y < 0 ||list.get(center + 1).x > width ||list.get(center + 1).y > height) {Log.i(TAG, "不是大了就是小了");MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newLatLng(carPathlist.get(center));// 改变地图状态mBaiduMap.setMapStatus(mMapStatusUpdate);}}@Overridepublic void onAnimationEnd(Animator animation) {}@Overridepublic void onAnimationCancel(Animator animation) {}@Overridepublic 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() {@Overridepublic void onAnimationStart(Animator animation) {//所有手势不可用mUiSettings.setAllGesturesEnabled(false);mMapView.showZoomControls(false);lay_showpath.setClickable(false);Log.i(TAG, "set_____________start");}@Overridepublic void onAnimationEnd(Animator animation) {mMapView.removeViewInLayout(view);//所有手势可用mUiSettings.setAllGesturesEnabled(true);mMapView.showZoomControls(true);lay_showpath.setClickable(true);Log.i(TAG, "set_____________end");}@Overridepublic void onAnimationCancel(Animator animation) {}@Overridepublic void onAnimationRepeat(Animator animation) {}});//可以将会设置绘制动画,设置在监听百度地图已经加载完毕的事件里set.start();Log.i(TAG, "lt end size: " + lt.size());}

添加该view到百度地图。

@Overridepublic void DrawDynaPath(final List<LatLng> pointlist) {//获取小车的viewBitmap 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<Point> list=new ArrayList<Point>();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();}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。