根据公司业务需求的展开,需要接入地图,并且在地图上画轨迹曲线以及自定义画区域等等。地图api可以接入百度,高德,或者google。下面以项目接入的高德地图api为例;

高德开放平台文档:https://lbs.amap.com/api/webservice/guide/create-project/get-key;

按照项目具体需求下载相应的SDK,放入项目libs中;

(注意为了兼容不同手机配置的地图.so文件比较多,而.so文件比较大,为了控制包大小,可以放弃部分兼容,这涉及到包大小优化,在文章里面有讲到 https://blog.csdn.net/and_caicai/article/details/105508306)

1.配置 AndroidManifest.xml 文件

在AndroidManifest.xml的application标签中配置Key:(key需要在高德开放平台创建项目获得)

<meta-dataandroid:name="com.amap.api.v2.apikey"android:value="您的Key"/>

2.在AndroidManifest.xml中配置权限:

//地图包、搜索包需要的基础权限 <!--允许程序打开网络套接字--> <uses-permission android:name="android.permission.INTERNET" /> <!--允许程序设置内置sd卡的写权限--> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!--允许程序获取网络状态--> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!--允许程序访问WiFi网络信息--> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!--允许程序读写手机状态和身份--> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!--允许程序访问CellID或WiFi热点来获取粗略的位置--> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

3.配置XML布局文件  在布局xml文件中添加地图控件;

<com.amap.api.maps.MapViewandroid:id="@+id/map"android:layout_width="match_parent"android:layout_height="match_parent">
</com.amap.api.maps.MapView>

4..地图展示

@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.basicmap_activity);//设置对应的XML布局文件MapView mapView = (MapView) findViewById(R.id.map);mapView.onCreate(savedInstanceState);// 此方法必须重写AMap aMap = mapView.getMap();}

5.地图显示时候的一些设置

     mMapTracking.onCreate(savedInstanceState);// 此方法须覆写。//地图if (mAMap == null) {mAMap = mMapTracking.getMap();}UiSettings mUiSettings = mAMap.getUiSettings();mUiSettings.setZoomGesturesEnabled(true);//设置地图是否可以手势缩放大小mUiSettings.setScrollGesturesEnabled(true);//设置地图是否可以手势滑动mUiSettings.setMyLocationButtonEnabled(false);// 设置默认定位按钮是否显示mUiSettings.setZoomControlsEnabled(false);//设置地图默认的缩放按钮是否显示mUiSettings.setLogoBottomMargin(-100);//隐藏logomAMap.moveCamera(CameraUpdateFactory.zoomTo(8));/*将GPS定位坐标类型转换为高德*/CoordinateConverter converter = new CoordinateConverter(context);// CoordType.GPS 待转换坐标类型converter.from(CoordinateConverter.CoordType.GPS);

在这里需要提一句,

* WGS84: Google Earth采用,Google Map中国范围外使用
* GCJ02: 火星坐标系,中国国家测绘局制定的坐标系统,由WGS84机密后的坐标。Google Map中国和搜搜地图使用,高德
* BD09:百度坐标,GCJ02机密后的坐标系
* 搜狗坐标系,图吧坐标等,估计也是在GCJ02基础上加密而成的

百度地图 高德地图坐标系不同,通过接口获得数据点 如果是不同坐标系需要进行转换。

6.根据坐标获取具体位置

   //异步查询坐标private void getAddressByLatlng(LatLng latLng) {//逆地理编码查询条件:逆地理编码查询的地理坐标点、查询范围、坐标类型。LatLonPoint latLonPoint = new LatLonPoint(latLng.latitude, latLng.longitude);RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 500f, GeocodeSearch.AMAP);//异步查询geocodeSearch.getFromLocationAsyn(query);}//异步查询结果监听geocodeSearch = new GeocodeSearch(context);geocodeSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {@Overridepublic void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {//得到逆地理编码异步查询结果RegeocodeAddress regeocodeAddress = regeocodeResult.getRegeocodeAddress();String formatAddress = regeocodeAddress.getFormatAddress();simpleAddress = formatAddress.substring(9);if(!Tools.isEmpty(simpleAddress)){tv_out_address.setText(simpleAddress+"");}else{tv_out_address.setText("");}DLog.e("LocusFragment","查询经纬度对应详细地址:\n" + simpleAddress);}@Overridepublic void onGeocodeSearched(GeocodeResult geocodeResult, int i) {}});

7.根据获取的点在地图上画轨迹曲线(及自定义画线)

 /*车辆行驶轨迹*/private void setMapTracking(final List<GPSDataBean> gpsDataList, RealTimeTruckBean bean) {List<Integer> colorList=new ArrayList<>();List<LatLng> latList=new ArrayList<>();mPolylineOptions = new PolylineOptions();mPolylineOptions.width(10);mPolylineOptions.zIndex(10f);markerOption = new MarkerOptions();if (NotNull.isNotNull(bean)) {//         addTruckOnTimeMarker(bean);}mAMap.setOnMarkerClickListener(new AMap.OnMarkerClickListener() {@Overridepublic boolean onMarkerClick(Marker marker) {LatLng latLngMarker = new LatLng(marker.getPosition().latitude, marker.getPosition().longitude);newbounds.include(latLngMarker);CameraUpdate mCameraUpdate = CameraUpdateFactory.newLatLngBounds(newbounds.build(), 15);//加上这句好像点击mark后不能显示在屏幕内// mAMap.animateCamera(mCameraUpdate);return false;}});mAMap.setOnInfoWindowClickListener(new AMap.OnInfoWindowClickListener() {@Overridepublic void onInfoWindowClick(Marker marker) {marker.hideInfoWindow();}});if (!NotNull.isNotNull(gpsDataList) || gpsDataList.size() <= 0) {mHandler.post(new Runnable() {@Overridepublic void run() {showTips("无GPS数据");closeProgressDialog();}});if (bean != null) {if (NotNull.isNotNull(bean.getY()) && NotNull.isNotNull(bean.getX())) {LatLng mCenterLatLng = new LatLng(Double.parseDouble(bean.getY()), Double.parseDouble(bean.getX()));CameraUpdate mCameraUpdate = CameraUpdateFactory.newCameraPosition(new CameraPosition(mCenterLatLng, 10, 0, 0));mAMap.animateCamera(mCameraUpdate);}}return;}double x=0;double y=0;for (int i = 0; i < gpsDataList.size(); i++) {// sourceLatLng待转换坐标点 LatLng类型if (NotNull.isNotNull(gpsDataList.get(i).getY())&& NotNull.isNotNull(gpsDataList.get(i).getX())){LatLng sourceLatLng = new LatLng(Double.parseDouble(gpsDataList.get(i).getY()), Double.parseDouble(gpsDataList.get(i).getX()));converter.coord(sourceLatLng);// 执行转换操作LatLng desLatLng = converter.convert();latList.add(desLatLng);colorList.add(getColorList(gpsDataList.get(i)));x += sourceLatLng.latitude;y += sourceLatLng.longitude;if (i == 0) {converter.coord(new LatLng(Double.parseDouble(gpsDataList.get(0).getY()), Double.parseDouble(gpsDataList.get(0).getX())));// 执行转换操作LatLng startLatLng = converter.convert();markerOption.position(startLatLng);if (NotNull.isNotNull(gpsDataList.get(0).getWeight())) {double gpsDataWeight = Double.parseDouble(gpsDataList.get(0).getWeight());gpsWeightStart = myformat.format(gpsDataWeight);}markerOption.title("设备ID:" + truckModel.getDeviceId() + "\n车牌号:" + truckModel.getCarNumber() + "\n车重:" + gpsWeightStart + "(吨)").snippet("日期:" + gpsDataList.get(0).getDate());markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.start)));} else if (i == gpsDataList.size() - 1) {converter.coord(new LatLng(Double.parseDouble(gpsDataList.get(gpsDataList.size() - 1).getY()), Double.parseDouble(gpsDataList.get(gpsDataList.size() - 1).getX())));// 执行转换操作LatLng endtLatLng = converter.convert();markerOption.position(endtLatLng);if (NotNull.isNotNull(gpsDataList.get(gpsDataList.size() - 1).getWeight())) {double gpsDataWeight = Double.parseDouble(gpsDataList.get(gpsDataList.size() - 1).getWeight());gpsWeightEnd = myformat.format(gpsDataWeight);}markerOption.title("设备ID:" + truckModel.getDeviceId() + "\n车牌号:" + truckModel.getCarNumber() + "\n车重:" + gpsWeightEnd + "(吨)").snippet("日期:" + gpsDataList.get(i).getDate());markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.end)));}markerOption.setFlat(true);mAMap.addMarker(markerOption);newbounds.include(desLatLng);//轨迹全部显示在屏幕内}}CameraUpdate mCameraUpdate = CameraUpdateFactory.newLatLng(new LatLng((double) (x/gpsDataList.size()),(double)(y/gpsDataList.size())));mAMap.animateCamera(mCameraUpdate);//第二个参数为四周留空宽度.mAMap.setMinZoomLevel(6f);mAMap.setMaxZoomLevel(13f);mAMap.moveCamera(CameraUpdateFactory.zoomTo(8));mPolylineOptions.addAll(latList);mPolylineOptions.colorValues(colorList);mAMap.addPolyline(mPolylineOptions);}

如果有类似如上图的轨迹曲线,曲线点没有依附在道路上,可以尝试用 高德的轨迹纠偏

https://lbs.amap.com/api/android-sdk/guide/draw-on-map/track-sdk

8.在地图上显示实时位置,并用图标标记

//添加实时位置private void addAddr(MarkerOptions opt, OnLineTruckBean bean, String speed) {if (NotNull.isNotNull(bean.getY()) && NotNull.isNotNull(bean.getX())) {if (addMarker != null) {addMarker.remove();}float zoom= mAMap.getCameraPosition().zoom;if(zoom <4){zoom=10f;}Bitmap bitmap = doAddBit(bean,speed);//图标LatLng gpsLatLng = new LatLng(Double.parseDouble(bean.getY()), Double.parseDouble(bean.getX()));//当前坐标(x,y)converter.coord(gpsLatLng);// 执行转换操作LatLng gdlatLng = converter.convert();opt.position(gdlatLng);opt.icon(BitmapDescriptorFactory.fromBitmap(bitmap));addMarker = mAMap.addMarker(opt);newbounds.include(gdlatLng);//轨迹全部显示在屏幕内CameraUpdate mCameraUpdate = CameraUpdateFactory.changeLatLng(gdlatLng);//改变位置mAMap.moveCamera(mCameraUpdate);//第二个参数为四周留空宽度.mAMap.moveCamera(CameraUpdateFactory.zoomTo(zoom));}}

9.在地图自定义区域 圆或者多边形

  //画圆,圆心坐标(lat1,lon) 半径r3    Double lat1 = Double.parseDouble(lat);Double lon2 = Double.parseDouble(lon);Double r3 = Double.parseDouble(r);LatLng latLng = new LatLng(lat1,lon2);Circle myCircle=mAMap.addCircle(new CircleOptions().center(latLng).radius(r3).fillColor(Color.argb(170, 238, 89, 83)).strokeColor(Color.argb(170, 13, 130, 235)).strokeWidth(3f));
//画多边形
List<WeiLan> wllis  =jsonToBeanList(data,WeiLan.class); //点listList<LatLng>  list3=new ArrayList<>();for (int i = 0; i < wllis.size(); i++) {WeiLan point = wllis.get(i);Double lat1 = Double.parseDouble(point.getLat());Double lat2 = Double.parseDouble(point.getLng());LatLng lat = new LatLng(lat1, lat2);list3.add(lat);llis.add(lat);}// 声明 多边形参数对象PolygonOptions polygonOptions = new PolygonOptions();// 添加 多边形的每个顶点(顺序添加)for (int t = 0; t < list3.size(); t++) {LatLng latp = list3.get(t);polygonOptions.add(latp);}polygonOptions.strokeWidth(4) // 多边形的边框 深绿色:#98ED84.strokeColor(Color.argb(100, 13, 130, 235)) // 边框颜色.fillColor(Color.argb(100, 238, 89, 83));   // 多边形的填充色mAMap.addPolygon(polygonOptions);

效果图如下:

以上代码涉及的项目可以再github上查看:https://github.com/ctgu1988/hd_wnq-yufeng

Android 开发日志之LBS相关开发相关推荐

  1. IOS-开发日志-UILabel相关

    UILabel属性 1.text:设置标签显示文本. 2.attributedText:设置标签属性文本. Ios代码 NSString *text = @"first"; NSM ...

  2. android实习日志_【安卓开发实习生工作总结_安卓开发实习生个人年终总结】-看准网...

    三个月的试用期下来,自己努力了不少,也进步了不少,学到了很多以前没有的东西,我想这不仅是工作,更重要的是给了我一个学习和锻炼的机会.从这一阶段来看,发现自己渴求的知识正源源不断的向自己走来,到这个大溶 ...

  3. .NET Core开发日志——WCF Client

    WCF作为.NET Framework3.0就被引入的用于构建面向服务的框架在众多项目中发挥着重大作用.时至今日,虽然已有更新的技术可以替代它,但对于那些既存项目或产品,使用新框架重构的代价未必能找到 ...

  4. .NET Core开发日志——HttpClientFactory

    当需要向某特定URL地址发送HTTP请求并得到相应响应时,通常会用到HttpClient类.该类包含了众多有用的方法,可以满足绝大多数的需求.但是如果对其使用不当时,可能会出现意想不到的事情. 博客园 ...

  5. .NET Core开发日志——从ASP.NET Core Module到KestrelServer

    ASP.NET Core程序现在变得如同控制台(Console)程序一般,同样通过Main方法启动整个应用.而Main方法要做的事情很简单,创建一个WebHostBuilder类,调用其Build方法 ...

  6. .NET Core开发日志——Runtime IDentifier

    .NET Core对于传统.NET开发人员而言是既熟悉又陌生的新平台,所以有时遇上出乎意料的事情也纯属正常情况.这时只需点耐心,多查查资料,努力找到原因,也未尝不是件有意义的体验. 比如当建完一个最简 ...

  7. 独立游戏Godot游戏开发日志

    独立游戏 Godot游戏 开发日志1 游戏已开发半年多了,目前以实现的功能: 种植系统,种树,砍树,种菜,摘菜,可以用不同工具收获,得到不同的物品.物品分稀有度,罕见的物品更能得到.收集到物品可以制作 ...

  8. 勇者与羁绊 游戏开发日志(八)

    勇者与羁绊 游戏开发日志(八) 开发进度 流程图 流程叙述 PlayMaker的坑 测试用例 寻找合作 开发进度 完成了使用卡牌选择目标的功能 流程图 流程叙述 该状态机主要负责控制敌人目标的选择. ...

  9. Android开发环境——Eclipse ADT相关内容汇总

     Android开发环境将分为SDK相关内容.Eclipse ADT相关内容.模拟器AVD相关内容.调试器DDMS相关内容.日志LogCat相关内容.连接驱动ADB相关内容.内存泄露检测工具MAT相关 ...

  10. Android开发环境——模拟器AVD相关内容汇总

    Android开发环境将分为SDK相关内容.Eclipse ADT相关内容.模拟器AVD相关内容.调试器DDMS相关内容.日志LogCat相关内容.连接驱动ADB相关内容.内存泄露检测工具MAT相关内 ...

最新文章

  1. TensorRT-安装-使用
  2. LeetCode实战:环形链表 II
  3. Android 自带图标库 android.R.drawable
  4. 如何去掉手机php,dedecms怎么关闭手机版
  5. 文件上传漏洞——upload-labs(11-20)
  6. 电脑中毒的表现有哪些?电脑中毒了怎么办?
  7. 『软件工程13』浅谈面向对象方法,统一建模语言UML
  8. 跨性别,你所不知道的事
  9. 2015 HUAS Summer Trainning #5~N
  10. cups 2.4.1编译办法
  11. 《Java编程规范学习笔记》
  12. 从零开始的数模学习(7):插值方法(预测类模型)
  13. Android AVD 存放路径修改
  14. design pattern scard
  15. 花式打印菱形图案!!
  16. 命运/天使/恶魔 操纵人类的方法
  17. [UOJ409]Highway Tolls
  18. 为什么这些年都不快乐
  19. RK3399 Android7.1使用网络连接ADB
  20. Vuetify学习记录(三)-- v-data-table

热门文章

  1. 一文讲清楚机械硬盘和固态硬盘的工作原理
  2. 原创Maya mel系列插件推荐
  3. SQL round()函数
  4. WAPI协议完整性测试解析系列(之一)WAI子类型的协议完整性测试
  5. 远程控制设置 串口服务器,TCP232串口服务器连接远程控制电脑设置方法
  6. Python实现图片转pdf
  7. ThinkPad如何禁用触摸板
  8. Manjaro安装以及美化教程
  9. 酒桌上的那些礼仪规矩~
  10. C++二维数组的定义及理解