百度地图绘制实时路线以及最短线路规划
来源:互联网 发布:淘宝退货了还能评价吗 编辑:程序博客网 时间:2024/05/29 08:30
如何使用百度地图绘制实时路线以及最短线路规划
最近在做百度地图的实时路线绘制,发现一些问题,比如由于定位漂移带来的路线绘制偏差,还有由于定位漂移,导致人未走动时,也会绘制路线等。百度鹰眼的线路纠偏个人感觉很一般啊。而且有限漂移了两百米的点他也没有纠正过来。所以最后还是决定自己写一个纠偏吧。而且百度地图官方的dome和示例代码真的很示例啊。然人摸不着头脑。ok进入正题,思路是这样的,因为实时绘制线路都是在室外,所以只采用gps定位,不采用无线网络定位。这样漂移一两百米的点基本不会出现。第二当人在等红绿灯时,人是静止的,但是定位有可能会漂移,所以这部分我们采用手机感应器进行判断是否移动。ok大体方向确定了,接下来就是进行功能划分然后开发了。功能模块主要涉及以下几点
需要项目源码的请移步到此下载
http://download.csdn.net/detail/zero172/9588471
- 地图定位
- 绘制当前位置
- 获取位置进行纠偏
- 判断是否移动
- 绘制线路
- 线路规划
程序流程图凸显
下面是完整代码
这里贴出的代码是基于各位亦有一定百度地图开发基础为参照,如果看不懂可留下邮箱我每晚发送源代码给各位,我是用jar包是3.7.3版的,各位如果使用其他版本的包,可能会出现百度地图初始化失败的现象。对我被坑过。
package com.example.baidutext;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.List;import android.app.Activity;import android.app.AlertDialog;import android.app.AlertDialog.Builder;import android.app.ProgressDialog;import android.content.Context;import android.content.DialogInterface;import android.content.DialogInterface.OnClickListener;import android.content.Intent;import android.content.IntentFilter;import android.content.SharedPreferences;import android.content.SharedPreferences.Editor;import android.graphics.Color;import android.hardware.Sensor;import android.hardware.SensorManager;import android.os.Bundle;import android.os.PowerManager;import android.os.PowerManager.WakeLock;import android.view.Menu;import android.view.MenuItem;import android.widget.Toast;import com.baidu.location.BDLocation;import com.baidu.location.BDLocationListener;import com.baidu.location.LocationClient;import com.baidu.location.LocationClientOption;import com.baidu.mapapi.SDKInitializer;import com.baidu.mapapi.map.BaiduMap;import com.baidu.mapapi.map.BaiduMap.OnMapLongClickListener;import com.baidu.mapapi.map.BitmapDescriptor;import com.baidu.mapapi.map.BitmapDescriptorFactory;import com.baidu.mapapi.map.MapStatus;import com.baidu.mapapi.map.MapStatusUpdate;import com.baidu.mapapi.map.MapStatusUpdateFactory;import com.baidu.mapapi.map.MapView;import com.baidu.mapapi.map.MarkerOptions;import com.baidu.mapapi.map.OverlayOptions;import com.baidu.mapapi.map.PolylineOptions;import com.baidu.mapapi.model.LatLng;import com.baidu.mapapi.search.route.BikingRouteResult;import com.baidu.mapapi.search.route.DrivingRouteResult;import com.baidu.mapapi.search.route.OnGetRoutePlanResultListener;import com.baidu.mapapi.search.route.PlanNode;import com.baidu.mapapi.search.route.RoutePlanSearch;import com.baidu.mapapi.search.route.TransitRouteResult;import com.baidu.mapapi.search.route.WalkingRoutePlanOption;import com.baidu.mapapi.search.route.WalkingRouteResult;import com.baidu.mapapi.utils.DistanceUtil;public class MainActivity extends Activity { /** * 百度地图视图 */ private MapView map_v=null; /** * 百度地图管理器 */ private BaiduMap BaiDuMap; // /** // * 位置管理器 // */ // private LocationManager locationManager; /** * 位置客户端 */ private LocationClient locationClient = null; /** * 获取位置时间间隔单位(秒) */ private final int time= 1000*9; // /** // * 定位数据 // */ // private MyLocationData locData; /** * 构建Marker图标 */ private BitmapDescriptor bitmap,StartBitmap,EndBitmap; /** *判断是否第一次定位 */ private boolean isFirstLoc=true; /** * 是否处于路线规划 */ private boolean isGetRoute=false; /** * 是否获取新路线 */ private boolean isGetNewRoute=true; /** * 定位位置数据 * 多线程在修改本数据,需要增加一个锁; */ private List<LatLng> pointList = new ArrayList<LatLng>(); /**// * 判断是否处于暂停// */ // private boolean isPause=false; /** * 描述地图将要发生的变化 */ protected MapStatusUpdate msUpdate = null; /** * 覆盖物 */ protected OverlayOptions overlay,StartOverlay,EndOverlay; /** * 路线覆盖物 */ private PolylineOptions polyline = null; /** * 手机加速度感应器服务注册 */ private SensorManager sm = null; private Acc acc=new Acc(); /** * 最大距离单位(米) */ private final Double MaxDistance=90.00; /** * 最小距离单位(米) */ private final Double MinDistance=2.0; /** * 电源锁 */ public static WakeLock wakeLock=null; private PowerReceiver powerReceiver = new PowerReceiver(); /** *最近位置信息 */ private LatLng latLng; /** * 因距离太大丢失的点数 */ private int LostLoc=0; /** * 第一次定位丢失的点数 */ private int FLostLoc=0; /** * 程序名称 */ private final String APP_FOLDER_NAME = "LocationDemo"; /** * 路线规划监听 */ private RoutePlanSearch mSearch; /** * 当前位置,终点位置 */ private LatLng ll,EndLL; /** * 路线规划等待进度框 */ private ProgressDialog progressDialog; /** * 获取位置距离常量 */ private int constant=0; /* (non-Javadoc) * @see android.app.Activity#onCreate(android.os.Bundle) */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); sm = (SensorManager) getSystemService(SENSOR_SERVICE); SDKInitializer.initialize(getApplicationContext());// activityList.add(this); setContentView(R.layout.activity_main); init(); //设置定位监听 locationClient.registerLocationListener(new BDLocationListener(){ @Override public void onReceiveLocation(BDLocation location) { // TODO Auto-generated method stub // locData = new MyLocationData.Builder() // .accuracy(0) // // 此处设置开发者获取到的方向信息,顺时针0-360 // .direction(0).latitude(location.getLatitude()) // .longitude(location.getLongitude()).build(); // // 设置定位数据 // BaiDuMap.setMyLocationData(locData); ll = new LatLng(location.getLatitude(), location.getLongitude()); progressDialog.dismiss(); if(isFirstLoc||isGetRoute){ if(!isGetRoute){ MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll); BaiDuMap.animateMapStatus(u); } // MyLocationConfiguration config = new MyLocationConfiguration(LocationMode.NORMAL, true, bitmap);//普通(LocationMode.NORMAL)、跟随(LocationMode.FOLLOWING)、罗盘(LocationMode.COMPASS) // BaiDuMap.setMyLocationConfigeration(config); isFirstLoc=false; if(constant<pointList.size()){ if(DistanceUtil.getDistance(pointList.get(constant),ll)>DistanceUtil.getDistance(pointList.get(constant+1),ll)){ save("距离: "+DistanceUtil.getDistance(pointList.get(constant+1),ll)+" 时间: "+getStringDate()+" 点数: "+constant); if(DistanceUtil.getDistance(pointList.get(constant+1),ll)>100&&isGetNewRoute){ IsGetNewRoute(); } constant++; }else{ save("距离: "+DistanceUtil.getDistance(pointList.get(constant),ll)+" 时间: "+getStringDate()+" 点数: "+constant); if(DistanceUtil.getDistance(pointList.get(constant),ll)>100&&isGetNewRoute){ IsGetNewRoute(); } } } drawRealtimePoint(ll); }else{ showRealtimeTrack(location); } } }); locationClient.start(); //路线规划回调 OnGetRoutePlanResultListener listener = new OnGetRoutePlanResultListener(){ @Override public void onGetBikingRouteResult(BikingRouteResult arg0) { // TODO Auto-generated method stub } @Override public void onGetDrivingRouteResult(DrivingRouteResult arg0) { // TODO Auto-generated method stub } @Override public void onGetTransitRouteResult(TransitRouteResult arg0) { // TODO Auto-generated method stub } @Override public void onGetWalkingRouteResult(WalkingRouteResult WalkingRoute) { // TODO Auto-generated method stub if(WalkingRoute.getRouteLines()!=null){ constant =0; isGetNewRoute=true; for(int i=0;i<WalkingRoute.getRouteLines().get(0).getAllStep().size();i++){ pointList.addAll(WalkingRoute.getRouteLines().get(0).getAllStep().get(i).getWayPoints()); } save("时间: "+getStringDate()+" 总点数: "+pointList.size()); } else// Toast.makeText(MainActivity.this, "获取线路失败", 3000).show(); System.out.println("ccccccccccccccccccc"); } }; mSearch.setOnGetRoutePlanResultListener(listener); //长按地图监听 BaiDuMap.setOnMapLongClickListener(new OnMapLongClickListener() { @Override public void onMapLongClick(LatLng arg0) { // TODO Auto-generated method stub EndLL=arg0; StartRoutePlan(); } });// mSearch.destroy(); Toast.makeText(this, "正在定位....", 3000).show(); } /** * 初始化资源 */ protected void init(){ map_v=(MapView)findViewById(R.id.bmapView); bitmap = BitmapDescriptorFactory.fromResource(R.drawable.map_d); StartBitmap= BitmapDescriptorFactory.fromResource(R.drawable.start_bitmap); EndBitmap= BitmapDescriptorFactory.fromResource(R.drawable.end_bitmap); // locationManager = (LocationManager) getSystemService(this.LOCATION_SERVICE); BaiDuMap=map_v.getMap(); locationClient = new LocationClient(this); LocationClientOption option = new LocationClientOption(); option.setOpenGps(true); //是否打开GPS option.setCoorType("bd09ll"); //设置返回值的坐标类型。bd09ll百度加密经纬度坐标,bd09百度加密墨卡托坐标,gcj02国测局加密经纬度坐标 option.setPriority(LocationClientOption.GpsOnly); //设置定位优先级,只取gps定位; option.setProdName(APP_FOLDER_NAME); //设置产品线名称。 option.setScanSpan(time); //设置定时定位的时间间隔。单位毫秒 locationClient.setLocOption(option); BaiDuMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);//普通地图模式 ;MAP_TYPE_SATELLITE为卫星地图;MAP_TYPE_NONE空白地图; BaiDuMap.setTrafficEnabled(false);//不开启交通视图; map_v.showZoomControls(false);//不开启底部放大缩小 图标; BaiDuMap.animateMapStatus(MapStatusUpdateFactory.zoomTo(18));//设置地图缩放 BaiDuMap.setMyLocationEnabled(true);//开启定位图层 BaiDuMap.setMaxAndMinZoomLevel(18.0f,1.0f); mSearch = RoutePlanSearch.newInstance(); progressDialog=new ProgressDialog(this); } @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); map_v.onDestroy(); BaiDuMap.setMyLocationEnabled(false); locationClient.stop(); map_v = null; releaseWakeLock(); sm.unregisterListener(acc); mSearch.destroy(); saveArray(); } @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); map_v.onPause(); } @Override public boolean onMenuItemSelected(int featureId, MenuItem item) { // TODO Auto-generated method stub if(item.getItemId()==R.id.action_settings) { progressDialog.setTitle("路线规划"); progressDialog.setMessage("正在清除路线请稍后。。"); progressDialog.show(); isGetRoute=false; if(pointList!=null||pointList.size()>0) pointList.clear(); if(StartOverlay!=null) StartOverlay=null; if(EndOverlay!=null) EndOverlay=null; } return super.onMenuItemSelected(featureId, item); } @Override public boolean onCreateOptionsMenu(Menu menu) { // TODO Auto-generated method stub return super.onCreateOptionsMenu(menu); } /* * 将数据临时保存到xml文件 */ private boolean saveArray() { deleteXML(); SharedPreferences sp= getSharedPreferences("lat", Context.MODE_APPEND); Editor mEdit1= sp.edit(); mEdit1.remove("Status_size"); mEdit1.putInt("Status_size",pointList.size()); for(int i=0;i<pointList.size();i++) { mEdit1.remove("lat_" + i); mEdit1.putString("lat_" + i,pointList.get(i).latitude+""); mEdit1.remove("lon_" + i); mEdit1.putString("lon_" + i,pointList.get(i).longitude+""); } return mEdit1.commit(); } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); map_v.onResume(); sm.registerListener(acc, Sensor.TYPE_ACCELEROMETER , SensorManager.SENSOR_DELAY_NORMAL); acquireWakeLock(); // if(latLng!=null) // drawRealtimePoint(latLng); } // /* // * 读取xml文件存储数据; // * @param mContext // */ // protected void loadArray(Context mContext) { // SharedPreferences mSharedPreference1=getSharedPreferences("lat", Context.MODE_PRIVATE); // // pointList.clear(); // int size = mSharedPreference1.getInt("Status_size", 0); // // for(int i=0;i<size;i++) { // Double lat1=Double.valueOf(mSharedPreference1.getString("lat_"+i, null)); // Double lon1=Double.valueOf(mSharedPreference1.getString("lat_"+i, null)); // pointList.add(new LatLng(lat1, lon1)); // } // } /* * 删除xml文件 */ private void deleteXML() { File file = new File("/data/data/" + getPackageName().toString() + "/shared_prefs", "lat.xml"); if (file.exists()) { file.delete(); } } /* * 显示实时轨迹 * * @param realtimeTrack */ protected void showRealtimeTrack(BDLocation location) { double latitude = location.getLatitude(); double longitude = location.getLongitude(); if (Math.abs(latitude - 0.0) < 0.000001 && Math.abs(longitude - 0.0) < 0.000001) { Toast.makeText(this, "当前无轨迹点", 3000).show(); } else { latLng = new LatLng(latitude, longitude); if (IsMove(latLng,location)) { // 绘制实时点 drawRealtimePoint(latLng); } } } /* * 绘制实时点 * * @param points */ private void drawRealtimePoint(LatLng point) { BaiDuMap.clear(); polyline=null; MapStatus mMapStatus = new MapStatus.Builder().target(point).build(); msUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus); overlay = new MarkerOptions().position(point) .icon(bitmap).zIndex(9).draggable(true); if (pointList.size() >=2 && pointList.size() <= 100000) { // 添加路线(轨迹) polyline = new PolylineOptions().width(10) .color(Color.RED).points(pointList); } addMarker(); } /* * 添加地图覆盖物 */ protected void addMarker() { if (null != msUpdate) { BaiDuMap.setMapStatus(msUpdate); } // 路线覆盖物 if (null != polyline) { BaiDuMap.addOverlay(polyline); } // 实时点覆盖物 if (null != overlay) { BaiDuMap.addOverlay(overlay); } //起点覆盖物 if (null != StartOverlay) { BaiDuMap.addOverlay(StartOverlay); } // 终点覆盖物 if (null != EndOverlay) { BaiDuMap.addOverlay(EndOverlay); } } /* *@author chenzheng_Java *保存用户输入的内容到文件 */ private void save(String content) { try { /* 根据用户提供的文件名,以及文件的应用模式,打开一个输出流.文件不存系统会为你创建一个的, * 至于为什么这个地方还有FileNotFoundException抛出,我也比较纳闷。在Context中是这样定义的 * public abstract FileOutputStream openFileOutput(String name, int mode) * throws FileNotFoundException; * openFileOutput(String name, int mode); * 第一个参数,代表文件名称,注意这里的文件名称不能包括任何的/或者/这种分隔符,只能是文件名 * 该文件会被保存在/data/data/应用名称/files/chenzheng_java.txt * 第二个参数,代表文件的操作模式 * MODE_PRIVATE 私有(只能创建它的应用访问) 重复写入时会文件覆盖 * MODE_APPEND 私有 重复写入时会在文件的末尾进行追加,而不是覆盖掉原来的文件 * MODE_WORLD_READABLE 公用 可读 * MODE_WORLD_WRITEABLE 公用 可读写 * */ content=content+"\n"; FileOutputStream outputStream = openFileOutput("Log.log",Activity.MODE_APPEND); outputStream.write(content.getBytes()); outputStream.flush(); outputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /* * 获取系统时间 */ private String getStringDate() { Date currentTime = new Date(); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateString = formatter.format(currentTime); return dateString; } /* * 判断手机是否在运动 */ private boolean IsMove(LatLng latLng,BDLocation location){ if(pointList.size()>=1){ Double dis=DistanceUtil.getDistance(pointList.get(pointList.size()-1),latLng); //判断手机是否静止,如果静止,判定采集点无效,直接抛弃 if(!acc.is_Acc&&acc.IsRun){ acc.IsRun=false; return false; } //判断是否是第一次定位置,如果是第一次定位并且因为第一次抛弃的位置数量小于10个则判断两点间距离大小 if(FLostLoc<10){ FLostLoc=FLostLoc+1; if(dis>10&&FLostLoc<6){//距离大于十米,而且被抛弃数量少于5个则说明有可能是获取位置失败 pointList.clear(); pointList.add(latLng);//更新位置 return false; } if(dis>0&&dis<10&&FLostLoc>=6)//如果距离在10米内,则表示客户正在运动,直接跳出 FLostLoc=11; } //根据两点间距离判断是否发生定位漂移,如果漂移距离小于MinDistance则抛弃,如果漂移距离大于MaxDistance则取两点的中间点. if(dis<=MinDistance){ if((dis<=MinDistance||dis>=MaxDistance)){ return false; } if(LostLoc>=4){ Double newlatitude=(latLng.latitude+pointList.get(pointList.size()-1).latitude)/2; Double newlongitude=(latLng.longitude+pointList.get(pointList.size()-1).longitude)/2; latLng = new LatLng(newlatitude, newlongitude); }else{ LostLoc=LostLoc+1; return false; } } LostLoc=0;//重置丢失点的个数 // pointList.add(latLng); acc.is_Acc=false; } pointList.add(latLng); return true; } /* * 开始规划线路 */ private void StartRoutePlan() { // TODO Auto-generated method stub progressDialog.setTitle("路线规划"); progressDialog.setMessage("正在规划路线请稍后。。"); progressDialog.show(); if(pointList!=null||pointList.size()>0) pointList.clear(); PlanNode stNode = PlanNode.withLocation(ll); StartOverlay=new MarkerOptions().position(ll) .icon(StartBitmap).zIndex(9); PlanNode enNode = PlanNode.withLocation(EndLL); EndOverlay=new MarkerOptions().position(EndLL) .icon(EndBitmap).zIndex(9); mSearch.walkingSearch((new WalkingRoutePlanOption()) .from(stNode) .to(enNode)); isGetRoute=true; } /* * 获取新路线 */ private void IsGetNewRoute() { // TODO Auto-generated method stub AlertDialog.Builder builder = new Builder(this); builder.setMessage("您已偏移路线,是否重新规划路线?"); builder.setTitle("路线偏移"); builder.setPositiveButton("重新规划", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { StartRoutePlan(); dialog.dismiss(); } }); builder.setNegativeButton("按原规划", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); builder.create().show(); isGetNewRoute=false; } /* * 申请电源锁 */ private void acquireWakeLock() { if (null == wakeLock) { PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE,getClass().getName()); } IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_SCREEN_OFF); registerReceiver(powerReceiver, filter); } /* * 释放电源锁 */ private void releaseWakeLock() { unregisterReceiver(powerReceiver); }}
下面PowerReceiver文件的内容
这里贴出的代码主要是完成电源锁的开启和撤销
package com.example.baidutext;import android.annotation.SuppressLint;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;public class PowerReceiver extends BroadcastReceiver { @SuppressLint("Wakelock") @Override public void onReceive(final Context context, final Intent intent) { final String action = intent.getAction(); //按下电源键,关闭屏幕 if (Intent.ACTION_SCREEN_OFF.equals(action)) { System.out.println("screen off,acquire wake lock!"); if (null != MainActivity.wakeLock && !(MainActivity.wakeLock.isHeld())) { MainActivity.wakeLock.acquire(); } //按下电源键,打开屏幕 } else if (Intent.ACTION_SCREEN_ON.equals(action)) { System.out.println("screen on,release wake lock!"); if (null != MainActivity.wakeLock && MainActivity.wakeLock.isHeld()) { MainActivity.wakeLock.release(); } } }}
下面Acc文件的内容
这个文件主要是获取加速感应器的值,然后通过波峰和波谷的插值,以及两个波峰之间的时间差来判断手机是否处于移动。关于详细的大家可查找计步器原理。一下算法非本人原创,但是一直找不到原创作者,如作者本人看到,可与我联系
package com.example.baidutext;import android.hardware.Sensor;import android.hardware.SensorListener;/** *根据加速度判断手机是否处于静止 * @author Administrator * */public class Acc implements SensorListener { // /** // * 手机加速度各方向状态 // */ // private float F_Acc_x,F_Acc_y,F_Acc_z; // /** // * 上次获取状态时间 // */ // private long LastUpdateTime; // /** // * 两次获取状态时间间隔单位(秒) // */ // private final int UPTATE_INTERVAL_TIME = 1000*10; // /** * 当前传感器的值 */ private float gravityNew = 0; /** * 上次传感器的值 */ private float gravityOld = 0; /** * 此次波峰的时间 */ private long timeOfThisPeak = 0; /** * 上次波峰的时间 */ private long timeOfLastPeak = 0; /** * 当前的时间 */ private long timeOfNow = 0;; /** * 波峰值 */ private float peakOfWave = 0; /** * 波谷值 */ private float valleyOfWave = 0; /** * 初始阈值 */ private float ThreadValue = (float) 2.0; /** * 动态阈值需要动态的数据,这个值用于这些动态数据的阈值 */ private final float initialValue = (float) 1.3; /** * 上一点的状态,上升还是下降 */ private boolean lastStatus = false; /** * 是否上升的标志位 */ private boolean isDirectionUp = false; /** * 持续上升次数 */ private int continueUpCount = 0; /** * 上一点的持续上升的次数,为了记录波峰的上升次数 */ private int continueUpFormerCount = 0; public boolean is_Acc=false; // private int ACC=30;//手机感应器波动范围,30以内判定手机处于静止 private int tempCount = 0; private final int valueNum = 4; /** * 用于存放计算阈值的波峰波谷差值 */ private float[] tempValue = new float[valueNum]; /** * 记录波峰数量 */ private int CountValue = 0; /** * 判断传感器是否在运行 */ public boolean IsRun=false; public Acc(){ // LastUpdateTime=System.currentTimeMillis(); } @Override public void onAccuracyChanged(int arg0, int arg1) { // TODO Auto-generated method stub } /** * 感应器状态改变时自动调用此方法 */ @Override public void onSensorChanged(int arg0, float[] arg1) { // TODO Auto-generated method stub IsRun=true; if(arg0==Sensor.TYPE_ACCELEROMETER){ // JIUjia(arg1); gravityNew = (float) Math.sqrt(arg1[0] * arg1[0] + arg1[1] * arg1[1] + arg1[2] * arg1[2]); DetectorNewStep(gravityNew); } } // protected boolean JIUjia(float[] values) { // if(F_Acc_x!=0){ // long currentUpdateTime = System.currentTimeMillis(); // long timeInterval = currentUpdateTime - LastUpdateTime; // if(timeInterval < UPTATE_INTERVAL_TIME) // return false; // LastUpdateTime=currentUpdateTime; // float tem0=values[0]-F_Acc_x; // float tem1=values[1]-F_Acc_y; // float tem2=values[2]-F_Acc_z; // System.out.println(Math.abs(tem0)+","+Math.abs(tem1)+","+Math.abs(tem2)); // if(Math.abs(tem0)>ACC||Math.abs(tem1)>ACC||Math.abs(tem2)>ACC) // is_Acc=true; // // } // F_Acc_x=values[0]; // F_Acc_y=values[1]; // F_Acc_z=values[2]; // return is_Acc; // // } /* * 检测步子 * 1.传入sersor中的数据 * 2.如果检测到了波峰,并且符合时间差以及阈值的条件,则判定为1步 * 3.符合时间差条件,波峰波谷差值大于initialValue,则将该差值纳入阈值的计算中 * */ public void DetectorNewStep(float values) { if (gravityOld == 0) { gravityOld = values; } else { if (DetectorPeak(values, gravityOld)) { timeOfLastPeak = timeOfThisPeak; timeOfNow = System.currentTimeMillis(); if ((timeOfNow - timeOfLastPeak) >= 250&& (peakOfWave - valleyOfWave >= ThreadValue)) { timeOfThisPeak = timeOfNow; //两步之间间隔大于4秒则不算 if((timeOfNow-timeOfLastPeak)>40000) CountValue=0; else CountValue++; //只有手机连续摇晃4下或者以上才判定为走路 if(CountValue>=4) is_Acc=true; // mStepListeners.onStep(); } if (timeOfNow - timeOfLastPeak >= 250&& (peakOfWave - valleyOfWave >= initialValue)) { timeOfThisPeak = timeOfNow; ThreadValue = Peak_Valley_Thread(peakOfWave - valleyOfWave); } } } gravityOld = values; } /* * 检测波峰 * 以下四个条件判断为波峰: * 1.目前点为下降的趋势:isDirectionUp为false * 2.之前的点为上升的趋势:lastStatus为true * 3.到波峰为止,持续上升大于等于4次 * 4.波峰值大于20 * 记录波谷值 * 1.观察波形图,可以发现在出现步子的地方,波谷的下一个就是波峰,有比较明显的特征以及差值 * 2.所以要记录每次的波谷值,为了和下次的波峰做对比 * */ public boolean DetectorPeak(float newValue, float oldValue) { lastStatus = isDirectionUp; if (newValue >= oldValue) { isDirectionUp = true; continueUpCount++; } else { continueUpFormerCount = continueUpCount; continueUpCount = 0; isDirectionUp = false; } if (!isDirectionUp && lastStatus&& (continueUpFormerCount >= 4 || oldValue >= 20&&oldValue<=40)) { peakOfWave = oldValue; return true; } else if (!lastStatus && isDirectionUp) { valleyOfWave = oldValue; return false; } else { return false; } } /* * 阈值的计算 * 1.通过波峰波谷的差值计算阈值 * 2.记录4个值,存入tempValue[]数组中 * 3.在将数组传入函数averageValue中计算阈值 * */ public float Peak_Valley_Thread(float value) { float tempThread = ThreadValue; if (tempCount < valueNum) { tempValue[tempCount] = value; tempCount++; } else { tempThread = averageValue(tempValue, valueNum); for (int i = 1; i < valueNum; i++) { tempValue[i - 1] = tempValue[i]; } tempValue[valueNum - 1] = value; } return tempThread; } /* * 梯度化阈值 * 1.计算数组的均值 * 2.通过均值将阈值梯度化在一个范围里 * */ public float averageValue(float value[], int n) { float ave = 0; for (int i = 0; i < n; i++) { ave += value[i]; } ave = ave / valueNum; if (ave >= 8) ave = (float) 4.3; else if (ave >= 7 && ave < 8) ave = (float) 3.3; else if (ave >= 4 && ave < 7) ave = (float) 2.3; else if (ave >= 3 && ave < 4) ave = (float) 2.0; else { ave = (float) 1.3; } return ave; }}
至此就全部结束了,各位如有其他问题可直接留言给我。
3 0
- 百度地图绘制实时路线以及最短线路规划
- 百度地图api绘制路线规划实例
- 百度地图根据多个经纬度,绘制路线
- iOS 百度地图路线绘制与小车平滑移动
- 简易绘制地图路线
- 地图绘制路线
- 百度地图---绘制圆时实时显示圆半径
- 2015,我的IT之路规划
- 我的java成熟之路规划
- 17年前端之路规划篇
- 百度地图轨迹绘制
- 百度地图绘制图形
- 百度地图绘制图形
- 百度手机地图 路线详细信息
- 百度地图之路线检索
- 百度地图之路线规划
- 百度地图2.2+路线规划
- 百度地图的路线规划
- 穿过街道(递归OR递推)(搜索)
- Mysql 特殊字符转义问题
- linux 下安装xgboost
- 7.HTML框架(老)
- 第1条 创建和销毁对象——考虑用静态工厂方法代替构造器
- 百度地图绘制实时路线以及最短线路规划
- 【算法集中营】循环冗余校验
- Game of Throne S04E02 POV Davos
- python脚本管理日记文件
- 物联网RFID射频概念
- a.out文件格式与COFF文件格式
- nginx启动、重启、关闭
- es2.2.0 无法将ik设置为默认analyzer
- Express应用生成器