Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2633625
  • 博文数量: 333
  • 博客积分: 4817
  • 博客等级: 上校
  • 技术积分: 4413
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-28 10:51
文章分类

全部博文(333)

文章存档

2017年(20)

2016年(57)

2015年(27)

2014年(20)

2013年(21)

2012年(164)

2011年(24)

分类: Android平台

2017-05-15 14:46:56

首先我们大家都知道百度地图中的Marker是基于经纬度也就是一个点来得到自身存在的位置的,但是我们如果想让Marker 移动呢?跳点我们大家都会,只需要重新为Marker赋值一个坐标点就好了,但是如果我们要平滑移动呢,我的做法就是为坐标点频繁赋值,使其看起来像是移动过去的,好了,废话不多说了,看效果吧

上面花了条线就是为了让我们看到Marker的移动轨迹,但是我们即使是频繁赋值也还是有问题的,我们还要考虑到箭头所指的方向,也就是根据起始点和目标点来计算角度

直接上代码吧:


[java] view plain copy
  1. package com.jlau.wjyuezhao.baidumapdemo;  
  2.   
  3. import android.content.Context;  
  4. import android.content.Intent;  
  5. import android.graphics.Color;  
  6. import android.os.Handler;  
  7. import android.os.Looper;  
  8. import android.util.Log;  
  9.   
  10. import com.baidu.mapapi.map.BaiduMap;  
  11. import com.baidu.mapapi.map.BitmapDescriptorFactory;  
  12. import com.baidu.mapapi.map.MapStatus;  
  13. import com.baidu.mapapi.map.MapStatusUpdateFactory;  
  14. import com.baidu.mapapi.map.MapView;  
  15. import com.baidu.mapapi.map.Marker;  
  16. import com.baidu.mapapi.map.MarkerOptions;  
  17. import com.baidu.mapapi.map.OverlayOptions;  
  18. import com.baidu.mapapi.map.Polyline;  
  19. import com.baidu.mapapi.map.PolylineOptions;  
  20. import com.baidu.mapapi.model.LatLng;  
  21. import com.baidu.mapapi.utils.DistanceUtil;  
  22.   
  23. import java.text.SimpleDateFormat;  
  24. import java.util.ArrayList;  
  25. import java.util.Date;  
  26. import java.util.List;  
  27.   
  28. /** 
  29.  * Created by Administrator on 2016/12/19. 
  30.  */  
  31.   
  32. public class MarkMoveUtil {  
  33.     //起始经度  
  34.     private static double sl0 ;// = 125.30227000000002;  
  35.     //起始纬度  
  36.     private static double   slt;//= 43.88362;  
  37.     //结束点经度  
  38.     private static double   el0;//= 129.40227000000002;  
  39.     //结束点纬度  
  40.     private static double elt;// = 49.68362;  
  41.     //决定小数点后取几位的参数  
  42.     private static double param ;//= 1000;  
  43.     private BaiduMap mBaiduMap;  
  44.     private Polyline mPolyline;  
  45.     private Marker mMoveMarker;  
  46.     //移动处理的 Handler  
  47.     private Handler mHandler;  
  48.     private MapView mMapView;  
  49.     //把起始点和结束点等分成十份的点的容器  
  50.     private static List latlngs;  
  51.     //每移动一次的时间间隔(通过设置间隔时间和距离可以控制速度和图标移动的距离)  
  52.     private double time_interval = 8;  
  53.     private Context context;  
  54.   
  55.     private final String ACTION_NAME = "发送广播";  
  56.   
  57.   
  58.   
  59.     /** 
  60.      * 
  61.      * @param sl0 
  62.      * @param slt 
  63.      * @param param 
  64.      * @param mMapView 
  65.      */  
  66.     public MarkMoveUtil(double sl0,double slt,double param,MapView mMapView,Marker marker,Context context  
  67.     ){  
  68.         this.sl0 = sl0;  
  69.         this.slt = slt;  
  70.         this.param = param;  
  71.         this.mMapView = mMapView;  
  72.         this.mBaiduMap = mMapView.getMap();  
  73.         this.mMoveMarker = marker;  
  74.         this.context = context;  
  75.         mHandler = new Handler(Looper.getMainLooper());  
  76.         MapStatus.Builder builder = new MapStatus.Builder();  
  77.         builder.target(new LatLng(slt,sl0));  
  78.         builder.zoom(11.0f);  
  79.         mBaiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));  
  80.     }  
  81.   
  82.   
  83.     /** 
  84.      * 获取等分的十个点的集合 
  85.      * @param sl0 
  86.      * @param slt 
  87.      * @param el0 
  88.      * @param elt 
  89.      */  
  90.     private static void getLatlngs(double sl0, double slt, double el0, double elt){  
  91.         Log.e("CCC",el0+":"+elt);  
  92.         double a = elt - slt;  
  93.         double b = el0 - sl0;  
  94.         double c = a/param;  
  95.         double d = b/param;  
  96.         latlngs = new ArrayList<>();  
  97.         for(int i = 0;i < param;i++){  
  98.             double lat = slt + c * i;  
  99.             double lon = sl0 + d * i;  
  100.             latlngs.add(new LatLng(lat,lon) );  
  101.         }  
  102.     }  
  103.   
  104.     /** 
  105.      * 根据点画出线 
  106.      */  
  107.     public void drawPolyLine() {  
  108.         List polylines = new ArrayList<>();  
  109.         for (int index = 0; index < latlngs.size(); index++) {  
  110.             polylines.add(latlngs.get(index));  
  111.         }  
  112.         polylines.add(latlngs.get(0));  
  113.         PolylineOptions polylineOptions = new PolylineOptions().points(polylines).width(10).color(Color.RED);  
  114.         mPolyline = (Polyline) mBaiduMap.addOverlay(polylineOptions);  
  115.     }  
  116.   
  117.     /** 
  118.      * 根据点获取图标转的角度 
  119.      */  
  120.     private double getAngle(int startIndex) {  
  121.         if ((startIndex + 1) >= mPolyline.getPoints().size()) {  
  122.             throw new RuntimeException("index out of bonds");  
  123.         }  
  124.         LatLng startPoint = mPolyline.getPoints().get(startIndex);  
  125.         LatLng endPoint = mPolyline.getPoints().get(startIndex + 1);  
  126.         return getAngle(startPoint, endPoint);  
  127.     }  
  128.   
  129.     /** 
  130.      * 根据两点算取图标转的角度 
  131.      */  
  132.     private double getAngle(LatLng fromPoint, LatLng toPoint) {  
  133.         double slope = getSlope(fromPoint, toPoint);  
  134.         if (slope == Double.MAX_VALUE) {  
  135.             if (toPoint.latitude > fromPoint.latitude) {  
  136.                 return 0;  
  137.             } else {  
  138.                 return 180;  
  139.             }  
  140.         }  
  141.         float deltAngle = 0;  
  142.         if ((toPoint.latitude - fromPoint.latitude) * slope < 0) {  
  143.             deltAngle = 180;  
  144.         }  
  145.         double radio = Math.atan(slope);  
  146.         double angle = 180 * (radio / Math.PI) + deltAngle - 90;  
  147.         return angle;  
  148.     }  
  149.   
  150.     /** 
  151.      * 根据点和斜率算取截距 
  152.      */  
  153.     private double getInterception(double slope, LatLng point) {  
  154.   
  155.         double interception = point.latitude - slope * point.longitude;  
  156.         return interception;  
  157.     }  
  158.   
  159.     /** 
  160.      * 算斜率 
  161.      */  
  162.     private double getSlope(LatLng fromPoint, LatLng toPoint) {  
  163.         if (toPoint.longitude == fromPoint.longitude) {  
  164.             return Double.MAX_VALUE;  
  165.         }  
  166.         double slope = ((toPoint.latitude - fromPoint.latitude) / (toPoint.longitude - fromPoint.longitude));  
  167.         return slope;  
  168.     }  
  169.     private double getDistance(){  
  170.         double distance = DistanceUtil.getDistance(latlngs.get(0), latlngs.get((int) param -1));  
  171.         double v =  distance /10000;  
  172.        double  theDistance = v * (time_interval/1000);  
  173.         return  theDistance;  
  174.     }  
  175.   
  176.     /** 
  177.      * 循环进行移动逻辑 
  178.      */  
  179.     public void moveLooper() {  
  180.         new Thread() {  
  181.   
  182.             public void run() {  
  183.   
  184. //                while (true) {  
  185.               Log.e("TAG""start time:"+getCurrentTime());  
  186.                     for (int i = 0; i < latlngs.size() - 1; i++) {  
  187.                         final LatLng startPoint = latlngs.get(i);  
  188.                         final LatLng endPoint = latlngs.get(i+1);  
  189.                         mMoveMarker  
  190.                                 .setPosition(startPoint);  
  191.   
  192.                         mHandler.post(new Runnable() {  
  193.                             @Override  
  194.                             public void run() {  
  195.                                 // refresh marker's rotate  
  196.                                 if (mMapView == null) {  
  197.                                     return;  
  198.                                 }  
  199.                                 mMoveMarker.setRotate((float) getAngle(startPoint,  
  200.                                         endPoint));  
  201.                             }  
  202.                         });  
  203.                         double slope = getSlope(startPoint, endPoint);  
  204.                         // 是不是正向的标示  
  205.                         boolean isReverse = (startPoint.latitude > endPoint.latitude);  
  206.                         double intercept = getInterception(slope, startPoint);  
  207.                         double xMoveDistance = isReverse ? getDistance() :  
  208.                                 -1 * getDistance();  
  209.                         for (double j = startPoint.latitude; !((j > endPoint.latitude) ^ isReverse);  
  210.                              j = j - xMoveDistance) {  
  211.                             LatLng latLng = null;  
  212.                             if (slope == Double.MAX_VALUE) {  
  213.                                 latLng = new LatLng(j, startPoint.longitude);  
  214.                             } else {  
  215.                                 latLng = new LatLng(j, (j - intercept) / slope);  
  216.                             }  
  217.                             final LatLng finalLatLng = latLng;  
  218.                             mHandler.post(new Runnable() {  
  219.                                 @Override  
  220.                                 public void run() {  
  221.                                     if (mMapView == null) {  
  222.                                         return;  
  223.                                     }  
  224.                                     mMoveMarker.setPosition(finalLatLng);  
  225.                                 }  
  226.                             });  
  227.                             try {  
  228.                                 Thread.sleep((int)time_interval);  
  229.                             } catch (InterruptedException e) {  
  230.                                 e.printStackTrace();  
  231.                             }  
  232.                         }  
  233.                     }  
  234.                 Log.e("TAG""end time:"+getCurrentTime());  
  235.                     sl0 = el0;  
  236.                     slt = elt;  
  237.                     Intent mIntent = new Intent(ACTION_NAME);  
  238.                     mIntent.putExtra("yaner""发送广播,相当于在这里传送数据");  
  239.                     //发送广播  
  240.                     context.sendBroadcast(mIntent);  
  241. //                }  
  242.             }  
  243.         }.start();  
  244.     }  
  245.   
  246.     public static void start(LatLng latLng){  
  247.         el0 = latLng.longitude;  
  248.         elt =latLng.latitude;  
  249.         getLatlngs(sl0,slt,el0,elt);  
  250.     }  
  251.     private String getCurrentTime(){  
  252.         SimpleDateFormat formatter    =   new    SimpleDateFormat    ("yyyy年MM月dd日    HH:mm:ss     ");  
  253.         Date curDate =   new    Date(System.currentTimeMillis());//获取当前时间  
  254.         String    str    =    formatter.format(curDate);  
  255.         return str;  
  256.     }  
  257.   
  258. //    private Marker createMarker(LatLng latLng){  
  259. //        OverlayOptions markerOptions = new MarkerOptions().flat(true).anchor(0.5f, 0.5f)  
  260. //                .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)).position(latLng)  
  261. //                .rotate(0);  
  262. //        return (Marker) mBaiduMap.addOverlay(markerOptions);  
  263. //    }  
  264. }  

至于具体的调用方法就不多说了,直接初始化这个工具之后调用划线和移动的方法就好了,这样我们的Marker移动就支持平滑,拐点,计算角度了,由于源码程序太大,暂时不支持CSDN下载,有需要的朋友可以留言。。
阅读(9118) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

海天冰雪2018-03-13 14:03:50

请发我一下,谢谢,邮箱是2466503780@qq.com