【笔记】在Android上绘制小车行进路线图并标记
老样子,先看看视频,到底小车是怎么绘路线图的:基于OpenCV和Android的语音物标识别车
如何在Android显示小车的行进路线并且当遇到重要事物时在地图上标记?前面一篇文章已经讲了两台手机的socket双向通信,这里就以此进行数据信息的传输。
我以小车上的手机作为server,以手上的手机作为client,server用于陀螺仪和磁力计信息和图像信息(摄像头获取QR码和是否找到小球的信息)发送给client,client根据获得的信息绘制出小车的行进路线图和标记图标。
首先说说server发给client的数据格式,是四位数组 String[] a ={"S","0","0","0"},至于如何发送请看上一篇,我就不累犊了……
a[0]中S表示停止,F表示前进,B表示后退
a[1]存的是陀螺仪角度,和小车初始方向角处理得到当前小车朝向
a[2]存的是磁力角角度,确定小车初始方向角
a[3]记录发现的物体,比如 "ball" 和QR码
client部分绘制路线图,具体思路是:借用google map为小车路线图,server获得磁力计的角度,确定小车初始位置。然后根据陀螺仪角度实时获得小车方位,从而在地图上画出具有方向性的路线图。当小车获取QR码并发送给client,地图上将标记出QR码,点击就可以获取QR信息。同理,当找到小球时,地图上也会出现图标告诉你小车是在哪找到小球的。下面是client的绘图部分:
appState = ((RosminState)getApplicationContext());mapView =(MapView)findViewById(R.id.map);mapcontroller = mapView.getController();originMaker = getResources().getDrawable(R.drawable.origin);//起点图标currMaker = getResources().getDrawable(R.drawable.sign); //当前位置图标ballMaker = getResources().getDrawable(R.drawable.goal); //发现小球图标lat1 = 0;lng1 = 0;//画出起点,小车路线原理就是画出两点并连线,周而复始points.add(new GeoPoint((int) (lat1 * 1000000),(int) (lng1 * 1000000)));//添加自定义的图层PathOverLay polyline = new PathOverLay(points); //添加polyline图层,负责画出路线mapView.getOverlays().add(polyline);mapView.invalidate();mapView.setBuiltInZoomControls(true);//设置中心和放大倍数GeoPoint point=new GeoPoint((int) (lat1 * 1000000),(int) (lng1 * 1000000));mapcontroller.setCenter(point);mapcontroller.setZoom(15);//这个图层负责添加图标,这里添加“起点”图标myOverlay = new MapOverlay(originMaker);myOverlay.setItem(point);myOverlay.setQR("起点");mapView.getOverlays().add(myOverlay);mapcontroller.animateTo(point);
小车路线原理就是画出两点并连线,周而复始……这里布置两个图层,一个负责画出路线,另一个负责标记图标。
下面具体方法,放入thread实时进行:
//在地图上画出路线以及做出标记Thread time = new Thread(new Runnable(){public void run() {long t1 = 0,t2 = 0 ;while(true){while(!Control.a[0].equals("F") && !Control.a[0].equals("B"))//未获得行动命令就等待{if(!Control.a[3].equals("0") && !Control.a[3].equals("ball")){break;} if(Control.a[3].equals("ball")){break; }}t1 = System.currentTimeMillis();if(!Control.a[3].equals("0") && !Control.a[3].equals("ball"))//发现QR码并保存,在地图上标记{QRmsg = Control.a[3];getQR =true;addMarker(); }if(Control.a[3].equals("ball")) //发现小球,在地图上标记{findBALL=true;addMarker();}try{Thread.sleep(50);}catch (InterruptedException e){// TODO Auto-generated catch blocke.printStackTrace();}t2 = System.currentTimeMillis();moveTimeGap = t2 -t1 ;Handler01.post(rDraw);}}//run});time.start();
当检测QR码时,把QR的信息保存到QRmsg中,并addMarker()在地图上添加图标。当检测到小球时,同样在地图上添加小球图标。用handler传递绘制路线。
/**画图部分,这里使用经纬度来表示小车朝向与行进路线* 最初用磁力计得到方向角,然后与陀螺仪得到的角度进行处理得到当前小车朝向* */private Runnable rDraw = new Runnable(){public void run(){if(ori){oriAngle = Integer.parseInt(Control.a[2]);ori = false;}gyroAngle = Integer.parseInt( Control.a[1] );if(Control.a[0].equals("F")){lat1 += (moveTimeGap*0.000001)*Math.cos((oriAngle-gyroAngle)*0.017452);lng1 += (moveTimeGap*0.000001)*Math.sin((oriAngle-gyroAngle)*0.017452);points.add(new GeoPoint((int) (lat1 * 1000000),(int) (lng1 * 1000000)));}if(Control.a[0].equals("B")){lat1 -= (moveTimeGap*0.000001)*Math.cos((oriAngle-gyroAngle)*0.017452);lng1 -= (moveTimeGap*0.000001)*Math.sin((oriAngle-gyroAngle)*0.017452);points.add(new GeoPoint((int) (lat1 * 1000000),(int) (lng1 * 1000000)));}}};
当得到磁力计角度确定小车当前初始角度后就不再处理磁力计获得的角度,也就是说它只用来定位初始位置,后面的姿态都是由陀螺仪获得。因为陀螺仪的精度远远大于磁力计获得的方位角,磁力计的方位角老飘……这里通过对坐标两个值的增减来近似定出小车当前的坐标。
private void addMarker() {if(getQR) //发现QR码后,存储坐标,显示图标,记录QR信息{GeoPoint myGeoPoint = new GeoPoint((int) (lat1 * 1000000),(int) (lng1 * 1000000));myOverlay = new MapOverlay(currMaker);myOverlay.setItem(myGeoPoint);myOverlay.setQR(QRmsg);mapView.getOverlays().add(myOverlay);getQR = false;}if(findBALL) //发现球后,存储坐标,显示图标,记录球信息{GeoPoint myGeoPoint = new GeoPoint((int) (lat1 * 1000000),(int) (lng1 * 1000000));myOverlay = new MapOverlay(ballMaker);myOverlay.setItem(myGeoPoint);myOverlay.setQR("发现小球");mapView.getOverlays().add(myOverlay);findBALL = false;}}
如代码注解所示,不过MapOverlay具体是怎么工作的,我们继续……
public class MapOverlay extends ItemizedOverlay<OverlayItem> {private List<GeoPoint> mItems = new ArrayList<GeoPoint>();public List<String> QRmessage = new ArrayList<String>();public MapOverlay(Drawable marker) {super(boundCenterBottom(marker));}public void setItems(ArrayList<GeoPoint> items) {mItems = items;populate();}public void setItem(GeoPoint item) {mItems.add(item);populate();}public void setQR(String s) {QRmessage.add(s);populate();}@Overrideprotected OverlayItem createItem(int i) {return new OverlayItem(mItems.get(i), null, null);}@Overridepublic int size() {return mItems.size();}@Overrideprotected boolean onTap(int i) {Toast.makeText(Map.this, "获得信息\n "+ QRmessage, Toast.LENGTH_SHORT).show();return true;}}
这里可以看出,我们可以记录单独点坐标和单独的信息,这些数据以ArrayList的方式存储。当小车发现了小球,这时地图上就标记出了一个图标,点击就会显示“发现小球”……上面就是对专门负责画图标的MapOverlay图层进行的说明,那我再回头看看专门负责画路线的PathOverLay图层是怎么实现路线绘制功能的……
public class PathOverLay extends Overlay {List<GeoPoint> points; Paint paint; /** * 构造函数,使用GeoPoint List构造Polyline * * @param points * GeoPoint点List */ public PathOverLay(List<GeoPoint> points) { this.points = points; paint = new Paint(); paint.setColor(Color.rgb(59,88,235));paint.setAlpha(150); paint.setAntiAlias(true); paint.setStyle(Paint.Style.FILL_AND_STROKE); paint.setStrokeWidth(4); } /** * 使用GeoPoint点List和Paint对象来构造Polyline * * @param points * GeoPoint点List,所有的拐点 * @param paint * Paint对象,用来控制划线样式 */ public PathOverLay(List<GeoPoint> points, Paint paint) { this.points = points; this.paint = paint; } /** * 真正将线绘制出来 只需将线绘制到canvas上即可,主要是要转换经纬度到屏幕坐标 */ @Override public void draw(Canvas canvas, MapView mapView, boolean shadow) { int i;if (!shadow) {// 不是绘制shadow层 Projection projection = mapView.getProjection(); if (points != null) { if (points.size() >= 2) { Point start = projection.toPixels(points.get(0), null);// 需要转换坐标 for ( i = 1; i < points.size(); i++) { Point end = projection.toPixels(points.get(i), null); canvas.drawLine(start.x, start.y, end.x, end.y, paint);// 绘制到canvas上即可 start = end;if(i == points.size()-1){paint.setColor(Color.rgb(250,20,85));end = projection.toPixels(points.get(i), null); canvas.drawCircle(end.x, end.y, 6, paint);paint.setColor(Color.rgb(59,88,235));}} } } } }
}
点坐标是以List的方式存储,最先是对它的粗细、颜色等进行设置。这里绘图的方法具体是:确定当前点,和前面一个点进行连线,同时将当前点设置成不同于前面的蓝色,从而明显显示当前小车位置。
PS:google map因为是google的核心技术,所以看源代码就别想了,接口的调用需要慢慢熟悉。原先google map有地图解析什么的,这是真实地图用的,我这里只是借用google map来绘制小车路线而已,所以只用了2个图层和点点连线的绘图方式,然后借用经度纬度反应出小车的具体方向。
by:season
【笔记】在Android上绘制小车行进路线图并标记相关推荐
- android 设置画布颜色,如何在颜色变化的画布上在Android上绘制渐变颜色?
这个问题仍然是有效的,几乎在2017年中旬,我想为我的自定义视图颜色变化的平稳过渡.我使用了LinearGradients着色器. 我的目的是让betweeen我的观点的anabled和禁用状态的平稳 ...
- python绘制彩色地震剖面_在地图上绘制饼图时“爆炸”楔形图(Python,matplotlib)...
所以我成功地在地图上绘制了饼图作为标记轴向散射,但我遇到了一些问题,一些楔子"爆炸"出了饼图.我似乎在我的代码中找不到原因,也无法在网上找到解释.这段代码基于示例here,一位同事 ...
- opencv进阶学习笔记6:使用鼠标在图像上绘制矩形框或者多边形框
基础版笔记传送门: python3+opencv学习笔记汇总目录(适合基础入门学习) 进阶版笔记目录: python+opencv进阶版学习笔记目录(适合有一定基础) 感兴趣区域传统绘制: openc ...
- android paint 圆角 绘制_Android系统上绘制圆角和阴影的几种姿势
0x01 前言 在实际的开发工程中,对视图增加圆角和阴影效果的绘制是比较常见的需求,Android系统提供了一系列的方法以帮助开发者实现基础的视图圆角和阴影效果,但在面对实际的视觉需求时,想要完美达到 ...
- android对图片拉线测量,如何在谷歌地图上绘制线条叠加Android
我想在我的地图项目上绘制一条线,但无法绘制线条.我在哪里以及如何声明覆盖图?我尝试了各种方法,但无法让它工作.即代码只是在Eclipse中显示错误.我不想做的是画一条从A到B的路线,而是在我移动时绘制 ...
- android百度地图轨迹实现,android 获取GPS经纬度在百度地图上绘制轨迹
实现将一组GPS模块获取的经纬度数据在百度地图上绘制轨迹 1.将经纬度转换成百度地图坐标 /** * 标准的GPS经纬度坐标直接在地图上绘制会有偏移,这是测绘局和地图商设置的加密,要转换成百度地图坐标 ...
- android地图画线,绘制折线-在地图上绘制-开发指南-Android 轻量版地图SDK | 高德地图API...
地图上绘制的线是由 Polyline 类定义实现的,线由一组经纬度(LatLng对象)点连接而成. 绘制一条线 与点标记一样,Polyine的属性操作集中在PolylineOptions类中,添加一条 ...
- android百度地图api两点画线,android百度地图:在地图上绘制点、线、多边形、圆形和文字...
转载自:http://blog.csdn.net/rt77777/article/details/9186691 首先介绍一个类:GraphicsOverlay 这是一个在地图上绘制图形的overla ...
- Android百度地图绘制多边形,android百度地图:在地图上绘制点、线、多边形、圆形和文字...
首先介绍一个类:GraphicsOverlay 这是一个在地图上绘制图形的overlay.GraphicsOverlay通过调用setData(Graphic g) 完成图形绘制. Graphic 通 ...
最新文章
- 【Android UI设计与开发】第06期:底部菜单栏(一)使用TabActivity实现底部菜单栏
- AWS EC2 Root密码重置
- c++读取txt文件中的数字_在Python中读取包中的数据文件的三种方式
- JavaScript---设计模式之观察者模式
- 一步一步写算法(之函数堆栈显示)
- scala 基础 ——关键字与特殊符号
- 安装Ubuntu Linux系统时硬盘分区
- Java程序员培训班有用吗?是否专业
- js进行txt文件下载方式或oss文件访问下载跨域解决
- java生成eml_用Java创建一个.eml(email)文件
- Python--pyaudio声卡录音
- 使用pip来对相应的版本进行降低的过程的
- Android高级UI系列教程(二)
- Linux系统GIC介绍与编程
- 电影资源详细信息爬取
- 高级算法梳理之LightGBM
- matlab级数求和阶乘,(阶乘)数列求和 - 数学 - 小木虫 - 学术 科研 互动社区
- jQuery 时间插件My97DatePicker动态获取选中值及修改默认时间
- 电脑双核CPU具体是什么意思?
- Eclipse 的常用快捷键