Android地图—— Mapbox 10.3.0 接入与基础使用
Android地圖—— Mapbox 10.3.0 接入與基礎使用
- Mapbox初始配置:依賴添加
- 1. 編輯 項目目錄/build.gradle (設置maven庫的訪問);
- 2. 前往mapbox官網 創建賬號 并 申請密鑰;
- 3. 在項目中配置公鑰、私鑰;
- 4. 在 模塊目錄 /build.gradle 中添加依賴;
- 5. 配置獲取用戶定位權限;(可選)
- MapBox部分功能的Android實現:
- · 地圖MapView的添加
- · MapBox初始化以及地圖顯示:
- 1. 相機設置:
- 2. 地圖加載:
- · MapBox各種功能插件獲取:
- 1. 地圖 Logo 插件
- 2. 地圖Logo旁屬性按鈕插件
- 3. 比例尺Scalebar插件
- 4. 指南針插件
- 5. 相機動畫插件
- 6. 地圖手勢監聽插件
- 7. 用戶地理位置獲取插件
- 8. 地圖標記插件
Mapbox初始配置:依賴添加
官網教程指引: https://docs.mapbox.com/android/maps/guides/install/
我使用的android studio版本是舊版,依賴添加方式如下:
1. 編輯 項目目錄/build.gradle (設置maven庫的訪問);
Android Studio less than Arctic Fox (2020.3.1) and Gradle less than v6.0:
注意,是在 allprojects 內設置!
2. 前往mapbox官網 創建賬號 并 申請密鑰;
Token申請地址: https://account.mapbox.com/
申請token時記得勾選 Downloads:Read 以獲取從maven庫下載mapbox依賴文件的許可。
創建完成之后在Token頁面會有兩個Token:
其中一個為初始就有的公鑰;一個為你剛剛申請好的帶有Downloads:Read權限的私鑰。
(注意:私鑰申請完成后要直接復制保存,刷新頁面后會被隱藏)。
3. 在項目中配置公鑰、私鑰;
在 項目目錄下的 gradle.properites 中添加以下代碼,用于從maven庫下載mapbox相關依賴的身份驗證。
MAPBOX_DOWNLOADS_TOKEN=自己申請的私鑰在 res/valuses/strings.xml 文件中添加以下代碼。mapbox默認你 將token放置在 strings.xml 中,在調用相關api時會 自動 在此文件夾下面獲取token。
<string name="mapbox_access_token">公鑰</string>4. 在 模塊目錄 /build.gradle 中添加依賴;
// mapbox地圖組件 implementation 'com.mapbox.maps:android:10.3.0'5. 配置獲取用戶定位權限;(可選)
在 AndroidManifest.xml 文件中添加以下代碼*(當你需要在地圖上顯示用戶位置時才需要配置)*
注意: 還需要在代碼中動態請求該權限,Mapbox也提供了PermissionsManager(可參考官網示例)工具用于動態請求權限,這里不展開)
可能遇到的問題:
① sync gradle文件時報warnning:
問題: Failed to resolve: com.mapbox.maps:android:10.0.3
解決: 檢查自己申請的token是否帶有 Downloads:Read,在創建token時記得勾選上,系統默認提供的token是不帶這個scope的,需要自行申請。
————————————————————————————————————————————
MapBox部分功能的Android實現:
這部分對MapBox的主要用例的Android實現和原理進行相關解釋(示例版本10.3.0)。
由于官網有kotlin代碼的例子,以下功能展示均使用 java代碼 進行舉例。
以下介紹的功能代碼我都封裝到了MapBoxUtil.java文件中,可以在這個項目里面自行獲取。(結合這個示例項目的代碼閱讀更佳哦)
效果圖先行:
· 地圖MapView的添加
layout文件中添加MapView視圖:
<com.mapbox.maps.MapViewandroid:id="@+id/mapview"android:layout_width="match_parent"android:layout_height="match_parent"/>Java文件:
MapView mMapView = findViewById(R.id.mapview); MapboxMap mMapboxMap = mapView.getMapboxMap();· MapBox初始化以及地圖顯示:
1. 相機設置:
相機部分參數初始變量定義:
private static final double DEFAULT_LOCATION_LATITUDE = 22.55; // 初始地圖顯示坐標(深圳) private static final double DEFAULT_LOCATION_LONGITUDE = 114.06; private static final double DEFAULT_ZOOM_VALUE = 8.0; // 初始地圖縮放大小相機設置:
mMapboxMap.setCamera( // 設置地圖相機初始位置new CameraOptions.Builder().center(Point.fromLngLat(DEFAULT_LOCATION_LONGITUDE, DEFAULT_LOCATION_LATITUDE)).zoom(DEFAULT_ZOOM_VALUE).build());相機更多參數設置:
https://docs.mapbox.com/android/maps/guides/camera-and-animation/camera/
2. 地圖加載:
地圖類型變量定義:
private static final String DEFAULT_MAP_STYLE = Style.MAPBOX_STREETS; // 地圖顯示樣式加載地圖:
mMapboxMap.loadStyleUri( // 加載地圖DEFAULT_MAP_STYLE, style -> {// style 加載完成回調});更多地圖類型:
https://docs.mapbox.com/android/maps/guides/styles/set-a-style/
· MapBox各種功能插件獲取:
mMapView .getPlugin(Plugin.MAPBOX_XXX_PLUGIN_ID); //XXX因插件而異1. 地圖 Logo 插件
LogoPlugin logoPlugin = mMapView .getPlugin(Plugin.MAPBOX_LOGO_PLUGIN_ID); // 隱藏 Logo if (logoPlugin != null) {logoPlugin.setEnabled(false); }2. 地圖Logo旁屬性按鈕插件
AttributionPlugin attributionPlugin = mMapView .getPlugin(Plugin.MAPBOX_ATTRIBUTION_PLUGIN_ID); // 隱藏 屬性按鈕 if (attributionPlugin != null) {attributionPlugin.setEnabled(false); }3. 比例尺Scalebar插件
ScaleBarPlugin scaleBarPlugin = mMapView .getPlugin(Plugin.MAPBOX_SCALEBAR_PLUGIN_ID); // 隱藏 比例尺 if (scaleBarPlugin != null) {scaleBarPlugin.setEnabled(false); }4. 指南針插件
CompassPlugin compassPlugin = mMapView .getPlugin(Plugin.MAPBOX_COMPASS_PLUGIN_ID); if (compassPlugin == null) {return; } compassPlugin.setEnabled(isEnable); // 隱藏指南針 compassPlugin.setImage(drawable); // 更換指南針icon以上UI相關的插件均可以通過相關api設置顯示位置和大小,這里不舉例說明。
5. 相機動畫插件
相機位置改變:
若只是簡單的直接改變相機位置的話,使用上述相機初始化中的mMapboxMap.setCamera方法即可。
若想要添加移動的動畫,如從當前顯示位置緩慢變換到目的位置,則需要相機動畫插件CameraAnimationsPlugin
相機移動方法舉例:
/*** 將攝像頭移動到指定位置* @param point 目標坐標* @param zoom 目標縮放比例* @param duration 滑動總時間 0為無動畫*/ public void moveCameraTo(Point point, double zoom, int duration) {if (mMapView == null) {return;}if (duration != 0 && cameraAnimationsPlugin != null) {cameraAnimationsPlugin .flyTo(new CameraOptions.Builder().center(point).zoom(zoom).build(),new MapAnimationOptions.Builder().duration(duration).build());} else {mMapboxMap.setCamera(new CameraOptions.Builder().center(point).zoom(zoom).build());} }更多相機動畫:
https://docs.mapbox.com/android/maps/guides/camera-and-animation/animations
6. 地圖手勢監聽插件
可以監聽地圖相關運行中狀態,Mapbox提供了手勢插件供我們監聽各種地圖狀態:
GesturesPlugin gesturesPlugin = mMapView.getPlugin(Plugin.MAPBOX_GESTURES_PLUGIN_ID);下面以監聽地圖移動為例:
if (gesturesPlugin != null) {gesturesPlugin .addOnMoveListener(onMoveListener); // 注意onDestroy時要remove掉Listener } // 地圖移動監聽 private final OnMoveListener onMoveListener = new OnMoveListener() {@Overridepublic void onMoveBegin(@NotNull MoveGestureDetector moveGestureDetector) {// 地圖開始移動}@Overridepublic boolean onMove(@NotNull MoveGestureDetector moveGestureDetector) {return false;}@Overridepublic void onMoveEnd(@NotNull MoveGestureDetector moveGestureDetector) {// 地圖移動結束} };更多用戶交互監聽:
https://docs.mapbox.com/android/maps/guides/user-interaction
7. 用戶地理位置獲取插件
效果圖先行:
MapBox獲取用戶位置主要通過 LocationComponentPlugin 插件獲取:
LocationComponentPlugin locationPlugin = mMapView.getPlugin(Plugin.MAPBOX_LOCATION_COMPONENT_PLUGIN_ID);① 設置用戶位置點顯示UI樣式:
設置脈沖顯示效果:
locationPlugin.updateSettings(locationComponentSettings -> {locationComponentSettings.setEnabled(true);locationComponentSettings.setPulsingEnabled(true); // 脈沖效果return null; });設置位置點樣式:
通過插件的 setLocationPuck() 方法進行設置,方法接受四個參數。前三個為上\中\下層圖標樣式設置,最后一個接受 Expression表達式 用于配置 位置點圖標的縮放scale數值規則。
(Expression表達式的本質是Json語句,是Mapbox自定義的一種描述性變量,具體Expression所涵蓋的運算符可參考官網,我們可以在使用的過程中逐漸了解各運算符具體含義)
這里我們選擇 生成一個隨地圖縮放變化規則的Expression:
我們使用 InterpolatorBuilder 來生成一個插值表達式。
下面例子的插值表達式表示當地圖zoom為0時,圖標scale為1;當zoom為20時,圖標scale為1.5;其間值線性插值獲得。
- linear運算符用于對一隊stop值間的數據做線性插值運算;
- zoom表達式添加上了圖標大小隨地圖縮放大小的羈絆。
從結果上來看即生成了如下json表達式:(清楚Expression編寫規則后,直接編寫json表達式也可以實現同樣的效果)
["interpolate",["linear"],["zoom"],0.0,1.0,20.0,1.5]代碼如下所示:
// 設置圖標隨地圖縮放比例變化 Expression.InterpolatorBuilder interpolatorBuilder = new Expression.InterpolatorBuilder("interpolate"); interpolatorBuilder.linear(); interpolatorBuilder.zoom(); interpolatorBuilder.stop(expressionBuilder -> {expressionBuilder.literal(0.0);expressionBuilder.literal(1.0);return null; }); interpolatorBuilder.stop(expressionBuilder -> {expressionBuilder.literal(20.0);expressionBuilder.literal(1.5);return null; }); // 設置用戶位置圖標樣式 locationPlugin.setLocationPuck(new LocationPuck2D(null,AppCompatResources.getDrawable(mContext, R.drawable.mapbox_user_icon),AppCompatResources.getDrawable(mContext, R.drawable.mapbox_user_stroke_icon),interpolatorBuilder.build().toJson()));官網例子:
https://docs.mapbox.com/help/tutorials/mapbox-gl-js-expressions/#add-a-zoom-expression
② 添加用戶位置監聽器
// 添加用戶位置監聽器 // 注意onDestroy時要remove掉Listener locationPlugin.addOnIndicatorPositionChangedListener(onIndicatorPositionChangedListener); // 用戶位置改變監聽 private final OnIndicatorPositionChangedListener onIndicatorPositionChangedListener =new OnIndicatorPositionChangedListener() {@Overridepublic void onIndicatorPositionChanged(@NotNull Point point) {// point即為用戶位置} };③ 移動相機到用戶的位置:
移動相機方法參見 5.相機動畫插件 部分,在onIndicatorPositionChanged回調中根據point參數進行移動即可。
需要注意的是,onIndicatorPositionChanged監聽器在remove前會持續回調,需編寫相關移動相機的條件,否則地圖移動手勢將會失效。
官網教程:
https://docs.mapbox.com/android/maps/guides/user-location/
8. 地圖標記插件
Mapbox提供了annotationPlugin 插件供用戶在地圖上快捷添加標記。添加標記的方法如下所示
注意:以下標記的添加需要在地圖初始化加載完成后進行,即style加載完后進行。
[舉例] 向地圖添加點標記(可以顯示icon + text)
// 注冊點標記管理器 PointAnnotationManager pointAnnotationManager = (PointAnnotationManager)annotationPlugin .createAnnotationManager(AnnotationType.PointAnnotation, null);/*** 在地圖中添加Point類型標記* @param longitude 添加坐標X* @param latitude 添加坐標Y*/ public void addPointAnnotationInMap(int drawable, double longitude, double latitude) {if(annotationPlugin == null){return;}if (pointAnnotationManager == null) {pointAnnotationManager = (PointAnnotationManager)annotationPlugin .createAnnotationManager(AnnotationType.PointAnnotation, null);}// Set options for the resulting symbol layer.PointAnnotationOptions pointAnnotationOptions = new PointAnnotationOptions().withPoint(Point.fromLngLat(longitude, latitude)).withIconImage(BitmapUtil.getBitmapFromDrawable(mContext, drawable));// Add the pointAnnotation to the map.pointAnnotationManager .create(pointAnnotationOptions); }pointAnnotationOptions中還有很多方法可以設置,這里不再舉例。
更多標記類型:
https://docs.mapbox.com/android/maps/guides/annotations/annotations/
除次之外Mapbox還提供了ViewAnnotation,用戶可以利用此添加自定義樣式的標記,添加方法如下所示:
ViewAnnotationManager viewAnnotationManager = mMapView.getViewAnnotationManager();以下方法舉例了如何在ViewAnnotationManager添加自定義的View標記:
/*** 在地圖中添加View標記 [需補充代碼后使用]* @param longitude 添加坐標* @param latitude 添加坐標* @param onClickListener view點擊回調*/public void addViewAnnotationInMap(double longitude, double latitude, View.OnClickListener onClickListener) {if (viewAnnotationManager == null) {viewAnnotationManager = mMapView.getViewAnnotationManager();} // View markView = viewAnnotationManager.addViewAnnotation(R.layout.item_map_image_view, // view的layout id // new ViewAnnotationOptions.Builder() // .geometry(Point.fromLngLat(longitude, latitude)) // .allowOverlap(true) // 允許markView重疊 // .build());// 初始化 layout中的組件 markView.findViewById(R.id.xxx)// ...}上述兩種添加方式在 少量(<200) 標記時不會造成地圖組件卡頓(應設備而異),若要添加大量標記,上述方法性能問題不容樂觀。
mapbox對此提供了 style layer 的解決方案,用于添加 大量圖標 時的性能保證。
style layer 添加地圖標記,并實現聚類的方法見下一篇文章:Android地圖—— Mapbox 10.3.0 聚類標簽實現。
總結
以上是生活随笔為你收集整理的Android地图—— Mapbox 10.3.0 接入与基础使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 重学JavaScript深入理解系列(六
- 下一篇: 前端学习(3206):初始化state