查看: 498|回复: 0

OpenStreetMap开发文档

[复制链接]

219

主题

259

帖子

698

积分

高级飞友

Rank: 4

积分
698
飞币
437
注册时间
2017-7-14
发表于 2022-10-22 19:01:13 | 显示全部楼层 |阅读模式
前言


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
您需要登录后才可以回帖 登录 | 加入联盟

本版积分规则

快速回复 返回顶部 返回列表