原文首发于微信公众号:jzman-blog,欢迎关注交流!
最近的项目涉及到百度地图的使用,项目组通知使用天地图替代百度地图,一个缘由是天地图是国家测绘地理信息局建设的,企业可使用其公众版本进行开发以提供相关的地图信息服务,较其余地图具备权威性,固然天地图提供的服务是否较其余地图更具备权威性和实时性,这个做为普通开发者是不能肯定的,另外一个缘由是减小运用成本,我以为是否真能达到这样的目标真不必定,毕竟商业地图输出能力仍是较免费版本更强。仍是先来开始天地图 Android SDK 的学习之路吧,先从一下几个方面来学习:java
首先下载天地图地图 SDK,而后添加相应的 Jar 包和 so 文件到 libs 文件夹中,在 module 的 build.gradle 文件中指定 so 文件的目录为 libs 目录,具体以下:android
sourceSets { main { //指定so文件的查找目录是libs目录 jniLibs.srcDir 'libs' } }
按照官网指定的权限配置,使用过程当中发现少了权限,下面是完整权限列表,具体以下:微信
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.CALL_PHONE" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
若是项目 targetSdkVersion 是 23 以上记得动态申请相关危险权限,此时,天地图地图 SDK 就引入到项目中了。ide
首先在布局中引入 MapView,布局代码以下:布局
<com.tianditu.android.maps.MapView android:id="@+id/mapView" android:layout_width="match_parent" android:layout_height="match_parent"/>
此时,地图就能够正常显示了,不须要额外的配置,固然能够初始化地图相关的一些参数,经常使用配置以下:学习
private void initMapView() { //启用内置的缩放组件 mapView.setBuiltInZoomControls(true); //获得MapView的控制权,能够用它控制和驱动平移和缩放 mMapController = mapView.getController(); //用给定的经纬度构造一个GeoPoint,单位是微度 (度 * 1E6) GeoPoint point = new GeoPoint((int) (39.915 * 1E6), (int) (116.404 * 1E6)); //设置地图中心点 mMapController.setCenter(point); //设置地图缩放级别 mMapController.setZoom(12); }
天地图 Android SDK 的引入及地图显示相对百度地图、高德地图仍是比较方便的。gradle
开发中经常须要定位当前位置,而且要从以前的位置动画移动到当前位置,获取个人位置的关键类是 MyLocationOverlay ,经过该类能够轻松获取个人位置,因为该类是 Overlay 的子类,在启用个人位置后要将该类的实例添加到 MapView 中,个人位置才会正确显示,至于移动到当前位置使用到 MapController 这个类,从MapView 中获取到地图控制器就能够移动到个人位置了,代码参考以下:动画
//建立MyLocationOverlay myLocationOverlay = new MyLocationOverlay(this, mapView); //启用指南针位置更新 myLocationOverlay.enableCompass(); //启用个人位置 myLocationOverlay.enableMyLocation(); mapView.addOverlay(myLocationOverlay); //得到当前位置 mPoint = myLocationOverlay.getMyLocation(); //动画移动到当前位置 mMapController.animateTo(mPoint);
个人位置定位成功,那么如何修改默认的定位图标呢,下面告诉你如何修改默认的定位图标。ui
天地图默认定位图标是一个蓝色的小圆点图标,不少时候都会遇到修改定位图标以及偏差半径的修改,后者主要会显示一个带阴影的圆圈,以此来表示当前定位的偏差范围,关于定位主要涉及到的类是 MyLocationOverlay,这个类是一个位置覆盖类,主要负责绘制、获取个人位置以及指南针的显示等,那么如何修改这个默认的定位图标呢,下面是一点思路:this
这种修改方式基本适用于相似的修改默认图标的场景,关键一点是找到相关类及相关位置而后作一下替换工做就 OK 了,固然这里对应的就是继承 MyLocationOverlay,重写 drawMyLocation 方法,而后替换相应图标,关键代码以下:
@Override protected void drawMyLocation(GL10 gl, MapView mapView, Location lastFix, GeoPoint myLocation, long when) { //得到屏幕坐标 Point point = new Point(); mapView.getProjection().toPixels(myLocation,point); //默认精度 float accuracy = getAccuracy(); //指定精度 float accuracy = 500; //得到实际偏差距离 float distance = mapView.getProjection().metersToEquatorPixels(accuracy); AndroidJni.OpenglFillRound(point.x, point.y, (int)distance, 0, 360, 137, 170, 213, 77); //建立Drawable UtilTextureDrawable drawable = new UtilTextureDrawable(mContext, R.drawable.ic_location, BOUND_TYPE_CENTER); drawable.DrawTexture(gl,point,0.0F); }
此时,使用自定义的 MLocationOverlay 替换 MyLocationOverlay 启用个人位置,定位图标已经被更改了,这里默认定位图标修改的另外一种思路是获取到当前位置后,使用 Marker 设置标注来实现本身定义的定位图标,实践发现是没有问题的,可是这样偏差范围就不可以轻松实现了,综上,仍是上一种思路比较好,一劳永逸的解决自定义图标的修改。
这里获取具体的位置信息,须要设置逆地理编码回调结果的监听获取详细地址信息,设置坐标位置,开始搜索地址,先实现逆地理编码结果监听器,代码以下:
/** * 逆地理编码回调结果监听 */ class OnGeoResultListener implements TGeoDecode.OnGeoResultListener { @Override public void onGeoDecodeResult(TGeoAddress tGeoAddress, int errorCode) { if (TErrorCode.OK == errorCode) { // 查询点相关信息 String str = "最近的 poi 名称:" + tGeoAddress.getPoiName() + "\n"; str += "查询点 Poi 点的方位:" + tGeoAddress.getPoiDirection() + "\n"; str += "查询点 Poi 点的距离:" + tGeoAddress.getPoiDistance() + "\n"; str += "查询点行政区名称:" + tGeoAddress.getCity() + "\n"; str += "查询点地理描述全称:" + tGeoAddress.getFullName() + "\n"; str += "查询点的地址:" + tGeoAddress.getAddress() + "\n"; str += "查询点的方位:" + tGeoAddress.getAddrDirection() + "\n"; str += "查询点的距离:" + tGeoAddress.getAddrDistance() + "\n"; str += "查询点道路名称:" + tGeoAddress.getRoadName() + "\n"; str += "查询点与最近道路的距离:" + tGeoAddress.getRoadDistance(); tvAddress.setText(tGeoAddress.getFullName()); System.out.println(str); } else { System.out.println("查询出错:" + errorCode); } } }
而后,设置对逆地理编码结果的监听,代码参考以下:
//逆地理编码类,根据输入的点坐标,返回相应的地理信息 TGeoDecode tGeoDecode = new TGeoDecode(new OnGeoResultListener()); tGeoDecode.search(mPoint);
若是前面都没有问题,那么具体的位置信息确定没有问题,只是没有提供获取当前城市名称的方法,getCity() 返回的是行政区名称而不是当前城市名称,这必定对于只想定位当前城市的需求就不友好了,关于天地图的初次接触就到此为止了。
注意两次修改前和修改后的图标以及偏差范围的显示,下面是显示效果,具体以下:
实际上地图的使用大同小异,经过以上内容基本需求已经可以完成,固然地图开发中还有一块内容是地图标注,这一步内容陆续推送出来,能够添加个人微信 jamanu 互相交流学习。