700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 百度地图绘制实时路线以及最短线路规划

百度地图绘制实时路线以及最短线路规划

时间:2023-01-07 01:11:50

相关推荐

百度地图绘制实时路线以及最短线路规划

如何使用百度地图绘制实时路线以及最短线路规划

最近在做百度地图的实时路线绘制,发现一些问题,比如由于定位漂移带来的路线绘制偏差,还有由于定位漂移,导致人未走动时,也会绘制路线等。百度鹰眼的线路纠偏个人感觉很一般啊。而且有限漂移了两百米的点他也没有纠正过来。所以最后还是决定自己写一个纠偏吧。而且百度地图官方的dome和示例代码真的很示例啊。然人摸不着头脑。ok进入正题,思路是这样的,因为实时绘制线路都是在室外,所以只采用gps定位,不采用无线网络定位。这样漂移一两百米的点基本不会出现。第二当人在等红绿灯时,人是静止的,但是定位有可能会漂移,所以这部分我们采用手机感应器进行判断是否移动。ok大体方向确定了,接下来就是进行功能划分然后开发了。功能模块主要涉及以下几点

需要项目源码的请移步到此下载

/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)*/@Overrideprotected 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(){@Overridepublic 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)、罗盘(PASS)//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(){@Overridepublic void onGetBikingRouteResult(BikingRouteResult arg0) {// TODO Auto-generated method stub}@Overridepublic void onGetDrivingRouteResult(DrivingRouteResult arg0) {// TODO Auto-generated method stub}@Overridepublic void onGetTransitRouteResult(TransitRouteResult arg0) {// TODO Auto-generated method stub}@Overridepublic void onGetWalkingRouteResult(WalkingRouteResult WalkingRoute) {// TODO Auto-generated method stubif(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() {@Overridepublic void onMapLongClick(LatLng arg0) {// TODO Auto-generated method stubEndLL=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); //是否打开GPSoption.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);}@Overrideprotected void onStart() {// TODO Auto-generated method stubsuper.onStart();}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();map_v.onDestroy();BaiDuMap.setMyLocationEnabled(false);locationClient.stop();map_v = null;releaseWakeLock();sm.unregisterListener(acc);mSearch.destroy();saveArray();}@Overrideprotected void onPause() {// TODO Auto-generated method stubsuper.onPause();map_v.onPause();}@Overridepublic boolean onMenuItemSelected(int featureId, MenuItem item) {// TODO Auto-generated method stubif(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);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// TODO Auto-generated method stubreturn 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 mit(); }@Overrideprotected void onResume() {// TODO Auto-generated method stubsuper.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 stubprogressDialog.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 stubAlertDialog.Builder builder = new Builder(this);builder.setMessage("您已偏移路线,是否重新规划路线?");builder.setTitle("路线偏移");builder.setPositiveButton("重新规划", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {StartRoutePlan();dialog.dismiss();}}); builder.setNegativeButton("按原规划", new OnClickListener() {@Overridepublic 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")@Overridepublic 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();}@Overridepublic void onAccuracyChanged(int arg0, int arg1) {// TODO Auto-generated method stub}/*** 感应器状态改变时自动调用此方法*/@Overridepublic void onSensorChanged(int arg0, float[] arg1) {// TODO Auto-generated method stubIsRun=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;elseCountValue++;//只有手机连续摇晃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;}}

至此就全部结束了,各位如有其他问题可直接留言给我。

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