android 控件平滑移动,Android 百度地圖 Marker 平滑移動

首先我們大家都知道百度地圖中的Marker是基於經緯度也就是一個點來得到自身存在的位置的,但是我們如果想讓Marker 移動呢?跳點我們大家都會,只需要重新為Marker賦值一個坐標點就好了,但是如果我們要平滑移動呢,我的做法就是為坐標點頻繁賦值,使其看起來像是移動過去的,好了,廢話不多說了,看效果吧

3a9f49ded2b6bddc5bf7f4ad2a25deaa.png

上面花了條線就是為了讓我們看到Marker的移動軌跡,但是我們即使是頻繁賦值也還是有問題的,我們還要考慮到箭頭所指的方向,也就是根據起始點和目標點來計算角度

直接上代碼吧:

package com.jlau.wjyuezhao.baidumapdemo;

import android.content.Context;

import android.content.Intent;

import android.graphics.Color;

import android.os.Handler;

import android.os.Looper;

import android.util.Log;

import com.baidu.mapapi.map.BaiduMap;

import com.baidu.mapapi.map.BitmapDescriptorFactory;

import com.baidu.mapapi.map.MapStatus;

import com.baidu.mapapi.map.MapStatusUpdateFactory;

import com.baidu.mapapi.map.MapView;

import com.baidu.mapapi.map.Marker;

import com.baidu.mapapi.map.MarkerOptions;

import com.baidu.mapapi.map.OverlayOptions;

import com.baidu.mapapi.map.Polyline;

import com.baidu.mapapi.map.PolylineOptions;

import com.baidu.mapapi.model.LatLng;

import com.baidu.mapapi.utils.DistanceUtil;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.Date;

import java.util.List;

/**

* Created by Administrator on 2016/12/19.

*/

public class MarkMoveUtil {

//起始經度

private static double sl0 ;// = 125.30227000000002;

//起始緯度

private static double slt;//= 43.88362;

//結束點經度

private static double el0;//= 129.40227000000002;

//結束點緯度

private static double elt;// = 49.68362;

//決定小數點后取幾位的參數

private static double param ;//= 1000;

private BaiduMap mBaiduMap;

private Polyline mPolyline;

private Marker mMoveMarker;

//移動處理的 Handler

private Handler mHandler;

private MapView mMapView;

//把起始點和結束點等分成十份的點的容器

private static List latlngs;

//每移動一次的時間間隔(通過設置間隔時間和距離可以控制速度和圖標移動的距離)

private double time_interval = 8;

private Context context;

private final String ACTION_NAME = "發送廣播";

/**

*

* @param sl0

* @param slt

* @param param

* @param mMapView

*/

public MarkMoveUtil(double sl0,double slt,double param,MapView mMapView,Marker marker,Context context

){

this.sl0 = sl0;

this.slt = slt;

this.param = param;

this.mMapView = mMapView;

this.mBaiduMap = mMapView.getMap();

this.mMoveMarker = marker;

this.context = context;

mHandler = new Handler(Looper.getMainLooper());

MapStatus.Builder builder = new MapStatus.Builder();

builder.target(new LatLng(slt,sl0));

builder.zoom(11.0f);

mBaiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));

}

/**

* 獲取等分的十個點的集合

* @param sl0

* @param slt

* @param el0

* @param elt

*/

private static void getLatlngs(double sl0, double slt, double el0, double elt){

Log.e("CCC",el0+":"+elt);

double a = elt - slt;

double b = el0 - sl0;

double c = a/param;

double d = b/param;

latlngs = new ArrayList<>();

for(int i = 0;i < param;i++){

double lat = slt + c * i;

double lon = sl0 + d * i;

latlngs.add(new LatLng(lat,lon) );

}

}

/**

* 根據點畫出線

*/

public void drawPolyLine() {

List polylines = new ArrayList<>();

for (int index = 0; index < latlngs.size(); index++) {

polylines.add(latlngs.get(index));

}

polylines.add(latlngs.get(0));

PolylineOptions polylineOptions = new PolylineOptions().points(polylines).width(10).color(Color.RED);

mPolyline = (Polyline) mBaiduMap.addOverlay(polylineOptions);

}

/**

* 根據點獲取圖標轉的角度

*/

private double getAngle(int startIndex) {

if ((startIndex + 1) >= mPolyline.getPoints().size()) {

throw new RuntimeException("index out of bonds");

}

LatLng startPoint = mPolyline.getPoints().get(startIndex);

LatLng endPoint = mPolyline.getPoints().get(startIndex + 1);

return getAngle(startPoint, endPoint);

}

/**

* 根據兩點算取圖標轉的角度

*/

private double getAngle(LatLng fromPoint, LatLng toPoint) {

double slope = getSlope(fromPoint, toPoint);

if (slope == Double.MAX_VALUE) {

if (toPoint.latitude > fromPoint.latitude) {

return 0;

} else {

return 180;

}

}

float deltAngle = 0;

if ((toPoint.latitude - fromPoint.latitude) * slope < 0) {

deltAngle = 180;

}

double radio = Math.atan(slope);

double angle = 180 * (radio / Math.PI) + deltAngle - 90;

return angle;

}

/**

* 根據點和斜率算取截距

*/

private double getInterception(double slope, LatLng point) {

double interception = point.latitude - slope * point.longitude;

return interception;

}

/**

* 算斜率

*/

private double getSlope(LatLng fromPoint, LatLng toPoint) {

if (toPoint.longitude == fromPoint.longitude) {

return Double.MAX_VALUE;

}

double slope = ((toPoint.latitude - fromPoint.latitude) / (toPoint.longitude - fromPoint.longitude));

return slope;

}

private double getDistance(){

double distance = DistanceUtil.getDistance(latlngs.get(0), latlngs.get((int) param -1));

double v = distance /10000;

double theDistance = v * (time_interval/1000);

return theDistance;

}

/**

* 循環進行移動邏輯

*/

public void moveLooper() {

new Thread() {

public void run() {

// while (true) {

Log.e("TAG", "start time:"+getCurrentTime());

for (int i = 0; i < latlngs.size() - 1; i++) {

final LatLng startPoint = latlngs.get(i);

final LatLng endPoint = latlngs.get(i+1);

mMoveMarker

.setPosition(startPoint);

mHandler.post(new Runnable() {

@Override

public void run() {

// refresh marker's rotate

if (mMapView == null) {

return;

}

mMoveMarker.setRotate((float) getAngle(startPoint,

endPoint));

}

});

double slope = getSlope(startPoint, endPoint);

// 是不是正向的標示

boolean isReverse = (startPoint.latitude > endPoint.latitude);

double intercept = getInterception(slope, startPoint);

double xMoveDistance = isReverse ? getDistance() :

-1 * getDistance();

for (double j = startPoint.latitude; !((j > endPoint.latitude) ^ isReverse);

j = j - xMoveDistance) {

LatLng latLng = null;

if (slope == Double.MAX_VALUE) {

latLng = new LatLng(j, startPoint.longitude);

} else {

latLng = new LatLng(j, (j - intercept) / slope);

}

final LatLng finalLatLng = latLng;

mHandler.post(new Runnable() {

@Override

public void run() {

if (mMapView == null) {

return;

}

mMoveMarker.setPosition(finalLatLng);

}

});

try {

Thread.sleep((int)time_interval);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

Log.e("TAG", "end time:"+getCurrentTime());

sl0 = el0;

slt = elt;

Intent mIntent = new Intent(ACTION_NAME);

mIntent.putExtra("yaner", "發送廣播,相當於在這里傳送數據");

//發送廣播

context.sendBroadcast(mIntent);

// }

}

}.start();

}

public static void start(LatLng latLng){

el0 = latLng.longitude;

elt =latLng.latitude;

getLatlngs(sl0,slt,el0,elt);

}

private String getCurrentTime(){

SimpleDateFormat formatter = new SimpleDateFormat ("yyyy年MM月dd日 HH:mm:ss ");

Date curDate = new Date(System.currentTimeMillis());//獲取當前時間

String str = formatter.format(curDate);

return str;

}

// private Marker createMarker(LatLng latLng){

// OverlayOptions markerOptions = new MarkerOptions().flat(true).anchor(0.5f, 0.5f)

// .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)).position(latLng)

// .rotate(0);

// return (Marker) mBaiduMap.addOverlay(markerOptions);

// }

}

至於具體的調用方法就不多說了,直接初始化這個工具之后調用划線和移動的方法就好了,這樣我們的Marker移動就支持平滑,拐點,計算角度了,由於源碼程序太大,暫時不支持CSDN下載,有需要的朋友可以留言。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值