想要做一款基于位置的安卓应用,可交互的地图是重要的一部分。Google
和Leaflet
都提供接口给开发者,Leaflet
是一个开源的Javascript库,用于gis相关的应用,比google具有更高的定制性,本例就是基于Leaflet
讲解安卓应用开发的地图方面的基本配置。
地图底图用Mapbox
提供的数据来显示,其中包含大量数据,来源于OpenStreetMap,NASA等等。在Mapbox Studio
中可以定制自己的底图。
Leaflet
需要用到JavaScript
,可以先跑通js再放进java代码中编译,推荐一个轻量级的在线editor Plunker
由于Mapbox Studio
提供的是在线的地图,所以在这里需要在Layout中创建一个Webview来显示地图。
1 2 3 4 5 6
| <?xml version="1.0" encoding="utf-8"?> <WebView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" />
|
然后配置manifest
文件,以获取网络请求许可。在<manifest>
标签内添加如下元素:
1
| <uses-permission android:name="android.permission.INTERNET" />
|
在java
文件中,OnCreate()
方法中添加加载地图的参数
1 2 3
| WebView webView = (WebView) findViewById(R.id.webview); webView.getSettings().setJavaScriptEnabled(true); webView.loadUrl("file:///android_asset/map.html");
|
到此地图的地基已经搭建完成,接下来就要写html
和js
代码完成地图的定制化显示。在app这个文件夹内新建文件夹assets
,再在其中新建文件并命名为map.html
,把自定义的图标star.png
复制在assets
文件夹目录下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| <!DOCTYPE html> <html> <head> <title>Custom Map</title> <meta charset="utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.1/dist/leaflet.css"/> <script src="https://unpkg.com/leaflet@1.0.1/dist/leaflet.js"></script> <style> html, body { padding: 0; margin: 0; height: 100%; width: 100%; } #map { width: 100%; height: 100%; } </style> </head> <body> <div id='map'></div> <script> var map = L.map('map', { center: [48.12855, 13.123903], zoom: 15 }); var myIcon = L.icon({ iconUrl:'star.png', iconAnchor: [12, 12], popupAnchor: [0, -12] }); L.marker([48.12855, 13.123903], { icon: myIcon }) .addTo(map) .bindPopup("<b>This is</b><br>a demo") .on('click', clickCenter); function clickCenter(e) { map.setView(e.target.getLatLng(),map.getZoom()); } var circleOptions = { color: '#f07910', fillcolor: '#ff00dc', weight: 3, opacity: 1 }; L.circle([48.12855, 13.123903], 50, circleOptions).addTo(map); L.tileLayer( 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpandmbXliNDBjZWd2M2x6bDk3c2ZtOTkifQ._QA7i5Mpkd_m30IGElHziw', { id: 'mapbox.streets' }).addTo(map); </script> </body> </html>
|
解释一下上面这段代码,首先在html文件head
之中要包含leaflet的css和js文件。在body
部分我们添加了一个div
定义了将要显示的地图为map
。为了使地图全屏显示,在head部分用css代码控制元素的宽和高为100%。
在script
标签内,第一个变量map
指定了显示的中心和缩放等级。myIcon
指定自定义的图标,iconAnchor
指定图标显示的地理位置,默认的热点是左上角。本例中图标是24*24,所以需要向右向下各移动12个像素,这样图标才能被放置在指定位置的中间。popupAnchor
指定popups的位置,在本例中[0,-12]
表示的是图标上边缘的中点。接下来marker把图标和popup一起添加给地图。clickCenter
函数的功能是,当用户点击marker,就移动地图的显示范围,使其位于屏幕中心。然后指定一个圆圈绘制的属性,最后在地图上显示一个圆圈,并使用circleOptions
指定的属性。
最后tileLayer
提供地图底图,当然可以自己在Mapbox Studio中定制。
最后附上编译后的app示例: