|
前言
OpenStreetMap社区是一个由地图制作爱好者组成的社区,这些爱好者提供并维护世界各地关于道路、小道、咖啡馆、铁路车站等各种各样的数据。OpenStreetMap开源项目可以让程序开发更加灵活,图源更加丰富,例如可以使用谷歌地图,以解决国内无法使用谷歌服务的尴尬。国内户外导航软件,例如:行者、户外帮和小狼信标都使用了OpenStreetMap。
Android版OpenStreetMap的github地址:osmdroid
5.2地图缓存的是瓦片,5.4之后地图缓存到数据库
一、环境配置
1、Gradle中添加依赖
compile 'org.osmdroid:osmdroid-android:5.2@aar'2、权限配置
<uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
提示:编译版本为23或以上版本,要注意动态获取读写存储空间权限,否则地图可能不显示
二、基础MapView使用
1、使用内置地图源
(1)、在布局文件中添加MapView控件,在代码中找到控件并设置图源
<org.osmdroid.views.MapView android:id="@+id/mapView" android:layout_width="match_parent" android:layout_height="match_parent"/>MapView mMapView= (MapView) findViewById(R.id.mapView);mMapView.setTileSource(TileSourceFactory.CYCLEMAP);//(OCM等高)若不设置,则默认使用的是MAPNIK(OSM街道)(2)、直接在代码中new MapView,然后设置图源,并将MapView添加到父布局中
MapView mMapView=new MapView(this);mMapView.setTileSource(TileSourceFactory.MAPNIK);2、设置其他地图源
(1)、谷歌图源
a、新建一个谷歌图源类,继承OnlineTileSourceBase
public class GoogleMapsTileSource extends OnlineTileSourceBase { /** * @param aName a human-friendly name for this tile source 自定图源义名字,会在手机外部存储中新建以该名字命名的文件夹,瓦片存储在其中 * @param aZoomMinLevel the minimum zoom level this tile source can provide 最小缩放级别 * @param aZoomMaxLevel the maximum zoom level this tile source can provide 最大缩放级别 * @param aTileSizePixels the tile size in pixels this tile source provides 瓦片质量 (256) * @param aImageFilenameEnding the file name extension used when constructing the filename 瓦片格式(jpg[有损压缩率高、不透明]、png[无损、透明]) * @param aBaseUrl the base url(s) of the tile server used when constructing the url to download the tiles 下载瓦片的链接(前缀) */ public GoogleMapsTileSource(String aName, int aZoomMinLevel, int aZoomMaxLevel, int aTileSizePixels, String aImageFilenameEnding, String[] aBaseUrl) { super(aName, aZoomMinLevel, aZoomMaxLevel, aTileSizePixels, aImageFilenameEnding, aBaseUrl); } @Override public String getTileURLString(MapTile aTile) { return getBaseUrl() + "&x=" + aTile.getX() + "&y=" + aTile.getY() + "&z=" + aTile.getZoomLevel(); }}b、new一个谷歌图源对象,并设置MapView图源
String str1 = "http://mt0.google.cn/vt/lyrs=m&hl=zh-CN&gl=cn&scale=2";String str2 = "http://mt1.google.cn/vt/lyrs=m&hl=zh-CN&gl=cn&scale=2";String str3 = "http://mt2.google.cn/vt/lyrs=m&hl=zh-CN&gl=cn&scale=2";String str4 = "http://mt3.google.cn/vt/lyrs=m&hl=zh-CN&gl=cn&scale=2";GoogleMapsTileSource googleMapsTileSource = new GoogleMapsTileSource("GoogleNormal", 2, 19, 256, ".png", new String[]{str1, str2, str3, str4});mMapView.setTileSource(googleMapsTileSource);(2)、必应等图源,使用方法类似于谷歌图源
参考文档:http://blog.csdn.net/youngkingyj/article/details/23365849
3、让瓦片适应不同像素密度
默认地图显示的字体小,图片像素高,可设置以下代码,使地图适应不同像素密度,更美观
mMapView.setTilesScaledToDpi(true);4、添加指南针
CompassOverlay mCompassOverlay = new CompassOverlay(MainActivity.this, new InternalCompassOrientationProvider(MainActivity.this), mMapView);mMapView.getOverlays().add(mCompassOverlay);mCompassOverlay.enableCompass();
按此方法添加指南针之后,部分手机仍不显示指南针,原因未知
5、添加比例尺ScaleBarOverlay mScaleBarOverlay = new ScaleBarOverlay(mMapView);mMapView.getOverlays().add(mScaleBarOverlay);
添加上面代码后,比例尺显示在左上角,而且不美观,可以继续添加下面代码,使比例尺显示在左下角
mScaleBarOverlay.setAlignBottom(true);mScaleBarOverlay.setLineWidth(1 * (getResources().getDisplayMetrics()).density);mScaleBarOverlay.setMaxLength(0.85f);6、设置地图中心
GeoPoint geopoint = new GeoPoint(39.986250, 116.400025);MapController mMapController= (MapController) mMapView.getController();//获取MapView控制器mMapController.setCenter(geopoint);//设置地图中心7、其他设置
(1)、设置缩放界别
mMapController.setZoom(15);//设置缩放级(2)、设置缩放按钮可见
mMapView.setBuiltInZoomControls(true);//设置缩放按钮可见(3)、设置多指触控可用
mMapView.setMultiTouchControls(true);//设置多指触控可用(4)、关闭硬件加速
mMapView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);//关闭硬件加速(绘制轨迹时需要)(5)、地图可旋转
RotationGestureOverlay mRotationGestureOverlay = new RotationGestureOverlay(this, mMapView);mRotationGestureOverlay.setEnabled(true);mMapView.getOverlays().add(mRotationGestureOverlay);三、进阶使用
1、自定义瓦片缓存位置
默认会在外部存储中新建名为somdroid的文件夹,瓦片就存储在其中。
自定义缓存位置就是在外部存储中创建一个文件夹,然后设置为瓦片的缓存位置,放在MapView初始化之前 例如:
File dir = new File(Environment.getExternalStorageDirectory(), "AAA");//新建文件夹if (dir.exists()) { File nomedia = new File(dir.getAbsoluteFile() + "/.nomedia"); if (!nomedia.exists()) { try { nomedia.createNewFile(); } catch (IOException e) { e.printStackTrace(); } }} else { dir.mkdirs(); File file = dir.getAbsoluteFile(); try { new File(file + "/.nomedia").createNewFile(); } catch (Exception ex) { android.util.Log.e(IMapView.LOGTAG, "unable to create a nomedia file. downloaded tiles may be visible to the gallery.", ex); }}OpenStreetMapTileProviderConstants.setCachePath(dir + "");//设置MapView的缓存路径2、添加Marker
Marker marker = new Marker(mMapView);marker.setIcon(getResources().getDrawable(R.mipmap.ic_launcher));//设置图标marker.setPosition(geopoint);//设置位置marker.setAnchor(0.5f, 0.5f);//设置偏移量marker.setTitle("我是Titile");//设置标题marker.setSubDescription("我是SubDescription");//设置说明mMapView.getOverlays().add(marker);//添加marker到MapView
点击Marker之后会出现气泡,显示title和subDescription
3、连线
PathOverlay pathOverlay = new PathOverlay(Color.BLUE, 10, this);pathOverlay.addPoint(new GeoPoint(39.986250, 116.400025));pathOverlay.addPoint(new GeoPoint(39.886250, 116.300025));mMapView.getOverlays().add(pathOverlay);
连线时务必关闭硬件加速,否则可能显示不出来连的线
4、离线地图下载
CacheManager cacheManager = new CacheManager(mMapView);//获取下载器 BoundingBoxE6 boundingBoxE6 = mMapView.getBoundingBox();//获取当前区域 int tileNum = cacheManager.possibleTilesInArea(boundingBoxE6, 8, 16);//计算当前区域8-16级的瓦片数量 cacheManager.downloadAreaAsync(this, boundingBoxE6, 8, 16, new CacheManager.CacheManagerCallback() {//下载 @Override public void onTaskComplete() { //下载完成后的回调 } });
下载时会有进度框,若点击进度框以外的区域会取消下载,若想修改逻辑可参考CacheManager,自定义一个CacheManage
|
|