• 腾讯地图GPS轨迹录制


    前言

    在地图的使用中,尤其在导航场景下,进行GPS轨迹录制是十分必要并且有用的,本文会对于安卓系统下的轨迹录制部分做一个分享。

    系统架构

    16202923779379.jpg

    对于一个GPSRecordSystem(GPS轨迹录制系统)主要分成3个部分:开始录制,录制GPS定位,结束录制并存储,如上图右方所示。在实际应用中,以导航系统为例:(1)在开始导航时(start navi),进行录制工作的相关配置;(2)收到安卓系统的onLocationChanged的callback进行GPSLocation的记录;(3)结束导航(stop navi)时,停止记录并存入文件。

    相关代码展示

    用到的相关变量

    	private LocationManager mLocationManager;   // 系统locationManager
    	private LocationListener mLocationListener; // 系统locationListener
    	
    	private boolean mIsRecording = false;       // 是否正在录制 
    
    	private List<String> mGpsList;              // 记录gps的list
    	private String mRecordFileName;             // gps文件名称
    
    • 开始录制

    开始录制一般是在整个系统工作之初,比如在导航场景下,当“开始导航”时,可以开始进行“startRecordLocation” 的配置

    	public void startRecordLocation(Context context, String fileName) {
    		// 已经在录制中不进行录制
    		if (mIsRecording) {
    			return;
    		}
    		Toast.makeText(context, "start record location...", Toast.LENGTH_SHORT).show();
    		
    		// 初始化locationManager和locationListener
    		mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
    		mLocationListener = new MyLocationListener();
    		try {
    			// 添加listener
    			mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mLocationListener);
    		} catch (SecurityException e) {
    			Toast.makeText(context, "start record location error!!!", Toast.LENGTH_SHORT).show();
                Log.e(TAG, "startRecordLocation Exception", e);
    			e.printStackTrace();
    		}
    
    // 记录文件名称,笔者这里使用“realLocationRecord + routeID”形式进行记录
    		mRecordFileName = fileName;
    		if (!mRecordFileName.endsWith(".gps")) {
    			mRecordFileName += ".gps";
    		}
    
    		mIsRecording = true;
    	}
    
    • 录制中记录轨迹
      记录location一般是在获取安卓系统onLocationChanged回调时调用“recordGPSLocation”
    	public void recordGPSLocation(Location location) {
    		if (mIsRecording && location != null) {
    		// 记录location to list
    			mGpsList.add(locationToString(location));
    		}
    	}
    

    locationToString工具方法

    驱动导航工作的GPS轨迹点一般要包含以下几个要素,经度,纬度,精度,角度,速度,时间,海拔高度,所以在此记录下,为后期轨迹回放做准备。

    	private String locationToString(Location location) {
    		StringBuilder sb = new StringBuilder();
    		
    		long time = System.currentTimeMillis();
    		String timeStr = gpsDataFormatter.format(new Date(time));
    
    		sb.append(location.getLatitude());
    		sb.append(",");
    		sb.append(location.getLongitude());
    		sb.append(",");
    		sb.append(location.getAccuracy());
    		sb.append(",");
    		sb.append(location.getBearing());
    		sb.append(",");
    		sb.append(location.getSpeed());
    		sb.append(",");
    		sb.append(timeStr);
    		sb.append(",");
    		sb.append(df.format((double) time / 1000.0));
    		// sb.append(df.format(System.currentTimeMillis()/1000.0));
    		// sb.append(df.format(location.getTime()/1000.0));
    		sb.append(",");
    		sb.append(location.getAltitude());
    		sb.append("
    ");
    		return sb.toString();
    	}
    
    
    • 结束录制并保存gps文件

    结束录制一般作用在整个系统的结尾,例如在导航场景下,“结束导航”时停止录制调用“stopRecordLocation”

    	public void stopRecordLocation(Context context) {
            Toast.makeText(context, "stop record location, save to file...", Toast.LENGTH_SHORT).show();
            
            // 移除listener
    		mLocationManager.removeUpdates(mLocationListener);
    		String storagePath = StorageUtil.getStoragePath(context); // 存储的路径
    		String filePath = storagePath + mRecordFileName;
    
    		saveGPS(filePath);
    		mIsRecording = false;
    	}
    

    GPS轨迹存储工具方法

    	private void saveGPS(String path) {
    		OutputStreamWriter writer = null;
    		try {
    			File outFile = new File(path);
    			File parent = outFile.getParentFile();
    			if (parent != null && !parent.exists()) {
    				parent.mkdirs();
    			}
    			OutputStream out = new FileOutputStream(outFile);
    			writer = new OutputStreamWriter(out);
    			for (String line : mGpsList) {
    				writer.write(line);
    			}
    		} catch (Exception e) {
    			Log.e(TAG, "saveGPS Exception", e);
    			e.printStackTrace();
    		} finally {
    			if (writer != null) {
    				try {
    					writer.flush();
    				} catch (IOException e) {
    					e.printStackTrace();
    					Log.e(TAG, "Failed to flush output stream", e);
    				}
    				try {
    					writer.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    					Log.e(TAG, "Failed to close output stream", e);
    				}
    			}
    		}
    	}
    	
    

    StorageUtil的getStoragePath工具方法

    // 存储在跟路径下/TencentMapSDK/navigation
        private static final String NAVIGATION_PATH = "/tencentmapsdk/navigation";
    
    // getStoragePath工具方法
        public static String getStoragePath(Context context) {
            if (context == null) {
                return null;
            }
            String strFolder;
            boolean hasSdcard;
            try {
                hasSdcard = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
            } catch (Exception e) {
                Log.e(TAG, "getStoragePath Exception", e);
                e.printStackTrace();
                hasSdcard = false;
            }
            if (!hasSdcard) {
                strFolder = context.getFilesDir().getPath() + NAVIGATION_PATH;
                File file = new File(strFolder);
                if (!file.exists()) {
                    file.mkdirs();
                }
            } else {
                strFolder = Environment.getExternalStorageDirectory().getPath() + NAVIGATION_PATH;
                File file = new File(strFolder);
                if (!file.exists()) { // 目录不存在,创建目录
                    if (!file.mkdirs()) {
                        strFolder = context.getFilesDir().getPath() + NAVIGATION_PATH;
                        file = new File(strFolder);
                        if (!file.exists()) {
                            file.mkdirs();
                        }
                    }
                } else { // 目录存在,创建文件测试是否有权限
                    try {
                        String newFile = strFolder + "/.test";
                        File tmpFile = new File(newFile);
                        if (tmpFile.createNewFile()) {
                            tmpFile.delete();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        Log.e(TAG, "getStoragePath Exception", e);
                        strFolder = context.getFilesDir().getPath() + NAVIGATION_PATH;
                        file = new File(strFolder);
                        if (!file.exists()) {
                            file.mkdirs();
                        }
                    }
                }
            }
            return strFolder;
        }
    

    结果展示

    最终存储在了手机目录下的navigation目录

    16202872001222.jpg

    后续工作

    后续可以对于录制的gps文件讲解在导航场景下进行轨迹回放的分享

    作者:腾讯位置服务

    链接:https://my.oschina.net/u/4209404/blog/5048899

    来源:开源中国

    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 相关阅读:
    访问Ice-Pick Lodge:假设公众筹款网站Kickstarter在成功
    Hadoop2.2.0--Hadoop Federation、Automatic HA、Yarn完全分布式集群结构
    严重:IOException while loading persisted sessions:java.io.EOFException.
    工作注意事项
    Java设计模式偷跑系列(21)建模和实现享受metapatterns
    Java多线程的~~~Lock接口和ReentrantLock使用
    从头学起android&lt;AutoCompleteTextView文章提示文本框.十九.&gt;
    FPGA笔记-阅读.dat文件
    ORA-00932: inconsistent datatypes: expected
    HTML中Select的使用具体解释
  • 原文地址:https://www.cnblogs.com/Dreamholder/p/14768452.html
Copyright © 2020-2023  润新知