目录

1.GPX文件解析

2.地图轨迹绘制

3.海拔示意图绘制

4.行进模拟

开始(暂停):

前进实现:

计时模块:

其他参数


1.GPX文件解析

详见此博客:

Android Studio GPX文件的解析(总和)_.'~'.的博客-CSDN博客_gpx文件

2.地图轨迹绘制

轨迹绘制:

利用GPX解析得到的数据在百度地图SDK上利用折现的绘制方法,绘制出相应的地图路线图。

public void drawroad(){List<LatLng> points = new ArrayList<LatLng>();//构建折线点坐标for(int i=0;i<longitudes.size();i++){//System.out.println(longitudes.get(i) );// longitudes.size();LatLng p = new LatLng(latitudes.get(i), longitudes.get(i));points.add(p);}//设置折线的属性OverlayOptions mOverlayOptions = new PolylineOptions().width(10).color(0xAAFF0000).points(points);//在地图上绘制折线//mPloyline 折线对象Overlay mPolyline = mBaiduMap.addOverlay(mOverlayOptions);}

自身点标记:

在行进过程中始终标记自身所处位置(海拔示意图也会始终标记自身位置)。

public  void drawpoint(int i){//定义Maker坐标点LatLng point = new LatLng(latitudes.get(i), longitudes.get(i));
//构建Marker图标BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(R.drawable.me3);
//构建MarkerOption,用于在地图上添加MarkerOverlayOptions option = new MarkerOptions().position(point).icon(bitmap);
//在地图上添加Marker,并显示//在地图上批量添加mPolyline2 =mBaiduMap.addOverlay(option);}

3.海拔示意图绘制

将GPX文件解析得到的海拔数据,按数据的多少不同按比例进行绘制(实质为直线的绘制)

 @RequiresApi(api = Build.VERSION_CODES.N)public void drawele(int me){imageView=(ImageView) findViewById(R.id.ele);//确定最高,最低海拔Double max = Collections.max(elevations);Double min = Collections.min(elevations);int max1= Math.toIntExact(Math.round(max));int min1= Math.toIntExact(Math.round(min));runOnUiThread(new Runnable() {@Overridepublic void run() {top.setText(String.valueOf(max1)+"M");low.setText(String.valueOf(min1)+"M");}});if(max1-min1>h){double y=  (max-min)/h;Log.e("TAG", "drawele: "+y );yinterval= Math.toIntExact((long) Math.ceil(y)); //得到最大值和高的关系,依此比例绘制高度}else{double y=  h/(max-min);Log.e("TAG", "drawele: "+y );yinterval= Math.toIntExact((long) Math.ceil(y)); //得到最大值和高的关系,依此比例绘制高度}Log.e("max  min", "drawele: "+max+"__"+min+"___"+yinterval+"    ++"+h );//开始绘制海拔示意图Bitmap newb = Bitmap.createBitmap(w , h, Bitmap.Config.ARGB_8888);Canvas canvasTemp = new Canvas(newb);//Canvas canvasTemp2=new Canvas(newb);canvasTemp.drawColor(Color.TRANSPARENT);Paint p = new Paint();//防锯齿p.setAntiAlias(true);p.setStyle(Paint.Style.STROKE);//STROKE,FILLp.setStrokeWidth(5);p.setColor(Color.LTGRAY);p.setTextAlign(Paint.Align.CENTER);p.setColor(Color.BLACK);p.setStyle(Paint.Style.FILL);//STROKE,FILL//判断是否为初始化,将位置置为0if(me==0){p.setColor(Color.RED);canvasTemp.drawCircle(0,(float) (h-(elevations.get(0)-min1)/(max1-min1)*h),10,p);p.setColor(Color.BLACK);}/*if(flagwidth==1){}else{drawele(me);}*///海拔示意图,公式 h-(H-min1)/(max1-min1)*h,H为当前绘制点海拔,h为屏幕高度if(elevations.size()>w) {  //点多宽度少Log.e(TAG, "drawele:点多宽度少!!!!!!!!!!!!!!!!!!!! " );flagwidth=0;//  /*double xinterval1=1xinterval=(float) elevations.size()/(float) w; //大于1,得到手机屏幕显示宽度和需要绘制的点个数关系,以此比例取点for(int i=1;i<=w;i++){   //i为屏幕宽度点计数, *xinterval得到按比例取得的高度点, XX数组存储每个输出的海拔点的角标(位置,第几个)// if((int)(i)*xinterval>elevations.size()/2)   p.setColor(Color.RED);// canvasTemp.drawLine(0, (float)( (h-520)/yinterval),1,(float)( (h-100)/yinterval),p);canvasTemp.drawLine(i-1, (float) (h-((elevations.get((int)((i-1)*xinterval>elevations.size()-1?elevations.size()-1:(i-1)*xinterval))-min1)/(max1-min1))*h),i,(float) (h-((elevations.get((int)((i)*xinterval>elevations.size()-1?elevations.size()-1:(i)*xinterval))-min1)/(max1-min1))*h),p);//canvasTemp.drawLine(i-1, (float) (h-elevations.get((int)((i-1)*xinterval>elevations.size()-1?elevations.size()-1:(i-1)*xinterval))/yinterval),i,(float) (h-elevations.get((int)(i*xinterval>elevations.size()-1?elevations.size()-1:i*xinterval))/yinterval),p);XX[i-1]=(int)(i*xinterval>elevations.size()-1?elevations.size()-1:i*xinterval);//Log.e("000000000000000000", "drawele: "+(i-xinterval)+"__"+(float) (h-elevations.get(i-1)/yinterval) );if(XX[i-1]==me){   //计数点me 标记当前输出点的位置,等于绘制的海拔的某一点,在这个位置标记红点p.setColor(Color.RED);canvasTemp.drawCircle(i,(float) (h-((elevations.get((int)((i-1)*xinterval>elevations.size()-1?elevations.size()-1:(i-1)*xinterval))-min1)/(max1-min1))*h),10,p);//canvasTemp.drawCircle(i,(float) (h-elevations.get(XX[i-1])/yinterval),10,p);p.setColor(Color.BLACK);}}}else if(elevations.size()<w){Log.e(TAG, "drawele:未修改部分!!!!!!!!!!!!!!!!!!!! " );flagwidth=1;xinterval=(float) w/(float) elevations.size();//for(int i=1;i<elevations.size()-1;i++){canvasTemp.drawLine((i-1)*xinterval>w?w:(i-1)*xinterval, (float) (h-(elevations.get(i-1)-min1)/(max1-min1)*h),i*xinterval>w?w:i*xinterval,(float) (h-(elevations.get(i)-min1)/(max1-min1)*h),p);// canvasTemp.drawLine((i-1)*xinterval>w?w:(i-1)*xinterval, (float) (h-elevations.get(i-1)/yinterval),i*xinterval>w?w:i*xinterval,(float) (h-elevations.get(i)/yinterval),p);//Log.e("000000000000000000", "drawele: "+(i-xinterval)+"__"+(float) (h-elevations.get(i-1)/yinterval) );if(i-1==me){p.setColor(Color.RED);canvasTemp.drawCircle(i*xinterval>w?w:i*xinterval,(float) (h-(elevations.get(i)-min1)/(max1-min1)*h),10,p);//canvasTemp.drawCircle(i*xinterval>w?w:i*xinterval,(float) (h-elevations.get(i)/yinterval),10,p);p.setColor(Color.BLACK);}}}runOnUiThread(new Runnable() {@Overridepublic void run() {imageView.setImageBitmap(newb);}});}

4.行进模拟

开始(暂停):

此部分实现按钮的功能和信息展示的转换,在停止时按钮显示”开始“,点击按钮后,相应的计时模块开始进行计时,按钮信息显示为”暂停“,点击按钮,计时模块停止计时,按钮又显示为”开始“,再次点击,计时继续,按钮显示为”暂停“,如此循环。

public void startgo(View view) {if(!stop){runOnUiThread(new Runnable() {@Overridepublic void run() {startgo.setText("暂停");}});TIME2 = System.currentTimeMillis();if(Time3!=0) {Time4+=TIME2-Time3;}stop=!stop;}else{runOnUiThread(new Runnable() {@Overridepublic void run() {startgo.setText("开始");}});Time3=System.currentTimeMillis();stop=!stop;}if(!Timestart) {if(!ok){ok=!ok;}Timestart = true;TIME();}}

前进实现:

自身标记点的刷新,各项数据的刷新(重新计算)

 @RequiresApi(api = Build.VERSION_CODES.N)public void StepIn() {if(true) {if (me >= latitudes.size()||me>=elevations.size()-1) {//Toast.makeText(this, "已到达终点", Toast.LENGTH_SHORT).show();Log.e(TAG, "StepIn: "+"已到达终点" );} else {cargo++;Miles += 2;runOnUiThread(new Runnable() {@Overridepublic void run() {M.setText(String.valueOf(Miles) + "m");}});if (Miles >= (distance.getDistance(latitudes.get(me), longitudes.get(me), latitudes.get(0), longitudes.get(0)))) {mPolyline2.remove();drawpoint(me);/*//移动距离计算Miles = Miles + distance.getDistance(latitudes.get(me - 1), longitudes.get(me - 1), latitudes.get(me), longitudes.get(me));M.setText(String.valueOf(Miles) + "m");*/me++;//根据flagwidth的值,选择高度示意点的刷新方式(取样,还是拉伸)//取样刷新if (flagwidth == 0 && me > XX[xx] && me <= latitudes.size()) {Log.e("me%xinterval==0", "stepin: " + me + "++++" + xinterval);drawele(XX[xx]);if (xx < w - 1) xx++;} else if (flagwidth == 1) { //拉伸刷新,所有点都输出drawele(me);}//总和所有爬升的高度if (elevations.get(me - 1) - elevations.get(me - 2) > 0) {Hight += elevations.get(me - 1) - elevations.get(me - 2);String str = String.format("%.2f", Hight);double Hight2 = Double.parseDouble(str);runOnUiThread(new Runnable() {@Overridepublic void run() {H.setText(String.valueOf(Hight2) + "m");}});}//计算坡度,坡度=(高程差/水平距离)x100%。计算下一步设计的坡度,及即将到来的路径坡度//Miles = Miles + distance.getDistance(latitudes.get(me - 1), longitudes.get(me - 1), latitudes.get(me), longitudes.get(me));gradient = ((elevations.get(me) - elevations.get(me - 1))) / distance.getDistance(latitudes.get(me - 1), longitudes.get(me - 1), latitudes.get(me), longitudes.get(me));String str3 = String.format("%.2f", gradient);//double gr = Double.parseDouble(str3);Log.e("--------------", "stepin: " + str3);runOnUiThread(new Runnable() {@Overridepublic void run() {G.setText(str3);}});}}}}

计时模块:

开始与暂停控制的就是此模块的计时功能。

private void TIME(){if(Timestart) {TIME1 = System.currentTimeMillis();new Thread(new Runnable() {SimpleDateFormat sd = new SimpleDateFormat("HH:mm:ss");@Overridepublic void run() {while (true&&Timestart) {if (stop) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}TIME2 = System.currentTimeMillis();TIME = TIME2 - TIME1-Time4;// Log.e("______", "run: "+hours+":"+minute+":"+second );sd.setTimeZone(TimeZone.getTimeZone("GMT+0"));//**TimeZone时区,加上这句话就解决啦**runOnUiThread(new Runnable() {@Overridepublic void run() {Time.setText(sd.format(TIME));}});}/*else{try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}TIME2 = System.currentTimeMillis();Time4+=TIME2-Time3;}*/}runOnUiThread(new Runnable() {@Overridepublic void run() {Time.setText("骑行时间");}});}}).start();}}

其他参数

最大速度,最小速度,大致卡路里计算 :

private void bikespeed(){new Thread(new Runnable() {@Overridepublic void run() {String  str1;String  str2;while(true) {now = System.currentTimeMillis();   //1000=1sif(now-last>=1000){Vnow=(Miles-Mile)*1000/(now-last);str1 = String.format("%.2f",Vnow);double two = Double.parseDouble(str1);//计算卡路里if(Vnow>0){Kcal+=wight*((now-last)/120000)/(Vnow/2.22);Log.e(TAG,"run: "+Kcal+"ppp"+wight*(Miles/1000)*1.036 );}//Kcal=wight*(Miles/1000)*1.036;str2 = String.format("%.2f",Kcal);double Kcal2=Double.parseDouble(str2);//更新实时速度runOnUiThread(new Runnable() {@Overridepublic void run() {V.setText(String.valueOf(two)+"m/s");K.setText(String.valueOf(Kcal2));}});Log.e(TAG, "run:" +MINV );//更新最大速度if(two>MAXV){MAXV=two;//第一次计算速度,最大速度等于最小速度if(first==0){// first=1;//first=1之后此段代码不再执行,最小速度将始终记录最小值,去掉此段代码可实现短时间内最小速度(可能)MINV=two;runOnUiThread(new Runnable() {@Overridepublic void run() {minV.setText(String.valueOf(MINV)+"m/s");}});}runOnUiThread(new Runnable() {@Overridepublic void run() {maxV.setText(String.valueOf(MAXV)+"m/s");}});}//更新最小速度,当最小速度显示0的时候表示停止,再移动的时候最小速度不会显示0,为最小运动速度>0if(two==0){runOnUiThread(new Runnable() {@Overridepublic void run() {minV.setText(String.valueOf(two)+"m/s");}});}else if(two<MINV&&two!=0){MINV=two;runOnUiThread(new Runnable() {@Overridepublic void run() {minV.setText(String.valueOf(MINV)+"m/s");}});}else {runOnUiThread(new Runnable() {@Overridepublic void run() {minV.setText(String.valueOf(MINV)+"m/s");}});}last= System.currentTimeMillis();Mile=Miles;}}}}).start();}

Android Studio GPX文件解析显示地图轨迹和海拔示意(模拟沿轨迹前进)相关推荐

  1. android xml 未能解析文件,Android Studio提示“无法解析符号”,但项目已编译

    我在build.gradle中使用以下内容在AndroidStudio中导入twitter4j: dependencies { compile 'com.android.support:support ...

  2. Android Studio - HPROF文件查看和分析工具

    Android Studio - HPROF文件查看和分析工具 Android Studio 翻译的官方文章 原文链接 当你在Android Studio中使用Android Monitor里的Mem ...

  3. android自定义控件不显示,解决Android Studio Design界面不显示layout控件的问题

    Android Studio更新到3.1.3后,发现拖到Design中的控件在预览界面中不显示: 解决办法: 在Styles.xml中的parent="..."中的Theme前添加 ...

  4. android studio val,导入--Android Studio突然无法解析符号

    导入--Android Studio突然无法解析符号 Android Studio 0.4.2工作正常,今天我打开它,几乎所有东西都是红色,自动完成已停止工作. 我看看导入和AS似乎告诉我它突然找不到 ...

  5. 安卓 linux init.rc,[原创]Android init.rc文件解析过程详解(二)

    Android init.rc文件解析过程详解(二) 3.parse_new_section代码如下: void parse_new_section(struct parse_state *state ...

  6. Android studio 刷新文件状态

    问题 有时候Android Studio Git 文件的状态不对,比如我修改了某个文件,他并没有给我显示出来. 那怎么刷一下文件状态呢,如下图: 解决方法:

  7. Android init.rc文件解析过程详解(三)

    Android init.rc文件解析过程详解(三) 三.相关结构体 1.listnode listnode结构体用于建立双向链表,这种结构广泛用于kernel代码中, android源代码中定义了l ...

  8. Android init.rc文件解析过程详解(二)

    Android init.rc文件解析过程详解(二) 3.parse_new_section代码如下: void parse_new_section(struct parse_state *state ...

  9. Android init.rc文件解析过程详解(一)

        Android init.rc文件解析过程详解(一) 一.init.rc文件结构介绍 init.rc文件基本组成单位是section, section分为三种类型,分别由三个关键字(所谓关键字 ...

  10. android studio logcat 无筛选 显示全部日志 无应用包名区分

    android studio logcat 无筛选 显示全部日志 无应用包名区分 不显示所有应用 出现这个情况后很多同学无法解决,重启adb,重启studio,重启电脑,都是没用的... 其实是有个开 ...

最新文章

  1. 【RocketMQ工作原理】消息堆积与消费延迟
  2. 撒列实现关键字过虑二(附源码)
  3. python爬虫实例-Python爬虫案例集合
  4. C语言 · 未名湖边的烦恼
  5. springboot 2.4.4java.sql.SQLException Access denied for user ‘root‘@‘localhost‘ (using password YES)
  6. Word2Vec算法详解(CBOW和skip-gram算法详解)
  7. Hadoop1.2.0开发笔记(九)
  8. 1进程 ppid_Python每日3题什么是僵尸进程和孤儿进程?
  9. 20190930每日一句
  10. RC振荡电路——文氏桥振荡电路(OP07仿真)
  11. 一个画布有多个子图_如何把多张图拼成一张长图
  12. ThinkpadX230解决叹号_Win7系统设备管理器下的“未知设备”
  13. 数据源EPMSSqlDataSource的使用
  14. 男人说这几句话代表他不想娶你
  15. KindEditor 360浏览器系列无法显示
  16. Redis(十六),mysql索引面试题索引失效
  17. Random Forests C++实现:细节,使用与实验
  18. 【计算方法】插值法多项式的求法--利用Lagrange插值和Newton插值
  19. 心机 诚信 君子 小人 好人 坏人
  20. matlab plot作图线型及颜色及图标大全

热门文章

  1. cydia红字解决方法(cydia安装软件时出现红字怎么解决)
  2. 《终身成长》卡罗尔 德韦克_epub+mobi+azw3
  3. ThinkPHP5零食商城系统(前后台)
  4. 【转】win7旗舰版英文版下载(64位|32位)|Windows7英文版ISO镜像
  5. 国产化Demo(dm7+Tongweb7+java)
  6. steam++加速问题:出现显示443端口被 vmware-hostd(9860)占用的错误。
  7. 你需要启用steam社区界面功能以进行购买_steam官网手机版免费下载-steam官网手机客户端下载...
  8. SQL Server迁移数据库文件(ldfmdf文件)到其他盘
  9. freebsd协议栈学习
  10. 使用exceljs导出excel表格