自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

基于MapBox在Android應(yīng)用中集成地圖支持

譯文
移動(dòng)開(kāi)發(fā) Android
MapBox是一個(gè)開(kāi)源的矢量地圖SDK。此框架的承諾是在開(kāi)發(fā)視頻游戲方面將提供優(yōu)質(zhì)的渲染速度和平滑度。如果你有興趣將地圖功能集成到你的應(yīng)用程序,那么MapBox將是值得你考慮的選擇方案之一。

一、 簡(jiǎn)介

MapBox是一個(gè)開(kāi)源的矢量地圖SDK。此框架的承諾是在開(kāi)發(fā)視頻游戲方面將提供優(yōu)質(zhì)的渲染速度和平滑度。如果你有興趣將地圖功能集成到你的應(yīng)用程序,那么MapBox將是值得你考慮的選擇方案之一。

二、權(quán)限設(shè)置

首先需要說(shuō)明的是,你可以從GitHub網(wǎng)站下載到本文提供的源代碼,地址是https://github.com/sitepoint-editors/MapBox-App。

要想在你的應(yīng)用程序如使用Mapbox,你需要一個(gè)API訪問(wèn)令牌。為此,你需要先創(chuàng)建一個(gè)Mapbox帳戶,你可以在網(wǎng)站https://www.mapbox.com/studio/account/tokens處找到你需要的有類數(shù)據(jù)。

然后,把令牌添加到你的Android程序的文件strings.xml中:

  1. <string name="accessToken">Your access token</string> 

接下來(lái),在配置文件AndroidManifest.xml中加入如下所示的Internet和位置訪問(wèn)權(quán)限:

 

  1. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>  
  2. <uses-permission android:name="android.permission.INTERNET"/>   
  3. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> 
  4. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 
  5. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> 

請(qǐng)注意:在Android Marshmallow (API 23)及更高的版本中在運(yùn)行時(shí)是需要上述權(quán)限的。

三、安裝MapBox

接下來(lái),打開(kāi)配置文件build.gradle(對(duì)應(yīng)于Module: app文件夾下的那個(gè)),添加對(duì)MapBox的依賴。請(qǐng)參考如下所示配置代碼:

  1. repositories { 
  2.     mavenCentral() 
  3. dependencies { 
  4.     . . .   
  5.     compile('com.mapbox.mapboxsdk:mapbox-android-sdk:3.2.0@aar') { 
  6.         transitive = true 
  7.    } 
  8.     compile ('com.mapbox.mapboxsdk:mapbox-android-directions:1.0.0@aar'){  
  9.         transitive=true 
  10.     } 

上面代碼中的***處配置描述了Mapbox,后面的配置則對(duì)應(yīng)于目錄庫(kù)(Directions library)描述,用于向應(yīng)用程序提供駕車、步行以及跨自行車等調(diào)用函數(shù),并支持在地圖中繪制其行蹤。

四、MapBox布局

接下來(lái),打開(kāi)布局文件content_main.xml,使用如下內(nèi)容替換原來(lái)的內(nèi)容:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3.     xmlns:mapbox="http://schemas.android.com/apk/res-auto" 
  4.     xmlns:tools="http://schemas.android.com/tools" 
  5.     android:layout_width="match_parent" 
  6.     android:layout_height="match_parent" 
  7.     tools:context="com.example.valdio.mapboxintegration.MainActivity" 
  8.     tools:showIn="@layout/activity_main"> 
  9.     <com.mapbox.mapboxsdk.views.MapView 
  10.         android:id="@+id/mapview" 
  11.         android:layout_width="fill_parent" 
  12.         android:layout_height="fill_parent" 
  13.         mapbox:access_token="@string/accessToken" /> 
  14. </RelativeLayout> 

接下來(lái),初始化你需要在MainActivity文件中使用的變量:

  1. public class MainActivity extends AppCompatActivity { 
  2.   private MapView mapView = null
  3.   private String MAPBOX_ACCESS_TOKEN = ""
  4.   private DirectionsRoute currentRoute = null
  5.   ... 

接下來(lái),在MainActivity.java文件中,把onCreate()方法中的創(chuàng)建工具欄和浮動(dòng)按鈕的代碼刪除,添加如下代碼來(lái)初始化地圖:

  1. String MAPBOX_ACCESS_TOKEN = getResources().getString(R.string.accessToken); 
  2. // Set up a standard Mapbox map 
  3. MapView mapView = (MapView) findViewById(R.id.mapview); 
  4. mapView.setAccessToken(MAPBOX_ACCESS_TOKEN); 
  5. mapView.setStyleUrl(Style.MAPBOX_STREETS); // specify the map style  
  6. mapView.setZoom(14); // zoom level  
  7. mapView.onCreate(savedInstanceState); 

Mapbox需要實(shí)現(xiàn)Activity的生命同期方法以避免運(yùn)行時(shí)錯(cuò)誤;因此,需要添加如下的重寫函數(shù):

  1. @Override  
  2. protected void onStart() {  
  3.     super.onStart();  
  4.     mapView.onStart();  
  5. @Override 
  6. protected void onStop() {  
  7.     super.onStop();  
  8.     mapView.onStop();  
  9. @Override  
  10. protected void onDestroy() { 
  11.     super.onDestroy();  
  12.     mapView.onDestroy();  
  13.  
  14. @Override  
  15. protected void onResume() { 
  16.     super.onResume(); 
  17.     mapView.onResume(); 
  18. @Override 
  19. protected void onPause() {  
  20.     super.onPause(); 
  21.     mapView.onPause(); 
  22.  
  23. @Override 
  24. protected void onSaveInstanceState(Bundle outState) {  
  25.     super.onSaveInstanceState(outState); 
  26.     mapView.onSaveInstanceState(outState); 

好了?,F(xiàn)在配置好了Mapbox,可以構(gòu)建應(yīng)用程序了。

五、把標(biāo)記添加到地圖中

現(xiàn)在,請(qǐng)把如下代碼添加到MainActivity的onCreate函數(shù)的***部:

  1. @Override 
  2. protected void onStart() { 
  3.     super.onStart(); 
  4.     mapView.onStart(); 
  5. @Override  
  6. protected void onStop() { 
  7.     super.onStop(); 
  8.     mapView.onStop(); 
  9. @Override 
  10. protected void onDestroy() { 
  11.     super.onDestroy(); 
  12.     mapView.onDestroy(); 
  13. @Override 
  14. protected void onResume() {  
  15.     super.onResume();  
  16.     mapView.onResume();  
  17.  
  18. @Override  
  19. protected void onPause() {  
  20.     super.onPause(); 
  21.     mapView.onPause();  
  22.  
  23. @Override  
  24. protected void onSaveInstanceState(Bundle outState) { 
  25.     super.onSaveInstanceState(outState);  
  26.     mapView.onSaveInstanceState(outState);  

這段代碼中的CameraPosition是一個(gè)非常有用的Mapbox類,可用于設(shè)置用戶視圖的位置、角度、縮放和傾斜度,等等信息。

到現(xiàn)在,我們的地圖看起來(lái)是如下所示的模樣:

 

六、獲取設(shè)備位置

為了使Mapbox能夠訪問(wèn)到設(shè)置的位置信息,必須啟動(dòng)設(shè)置的位置服務(wù),程序應(yīng)當(dāng)有使用它們的權(quán)限。如前面所提到的,在Android Marshmallow (API 23)及后續(xù)更高的版本中,在運(yùn)行時(shí)是需要這些權(quán)限的。

現(xiàn)在,我們來(lái)創(chuàng)建一個(gè)新的函數(shù),在其中加入取得當(dāng)前位置的代碼:

  1. private void myLocation() { 
  2.         if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
  3.             // TODO: Consider calling  
  4.             //    ActivityCompat#requestPermissions  
  5.             // here to request the missing permissions, and then overriding  
  6.             //   public void onRequestPermissionsResult(int requestCode, String[] permissions,  
  7.             //                                          int[] grantResults)  
  8.             // to handle the case where the user grants the permission. See the documentation  
  9.             // for ActivityCompat#requestPermissions for more details.  
  10.             return;  
  11.         } 
  12.         mapView.setMyLocationEnabled(true); 
  13.         mapView.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);  
  14.         mapView.getMyLocation();  
  15.     } 

然后,在地圖初始化代碼后添加如下函數(shù)調(diào)用:

  1. ...  
  2. mapView.onCreate(savedInstanceState);  
  3. myLocation(); 

在現(xiàn)在的情況中,我們把跟蹤方式設(shè)置為TRACKING_FOLLOW,這意味著用戶的位置將持續(xù)不斷地被監(jiān)控,而且地圖會(huì)不斷地隨著變化不斷更新。

七、在地圖上繪制線路

現(xiàn)在,我們創(chuàng)建了標(biāo)記與位置,接下來(lái)就是在地圖上繪制線路了。

這要使用前面在依賴性設(shè)置時(shí)所導(dǎo)入的第二個(gè)庫(kù)(Directions library),這也是Mapbox團(tuán)隊(duì)自行開(kāi)發(fā)的。

下面描述了其工作原理:

1、創(chuàng)建兩個(gè)航點(diǎn)位置,一個(gè)是出發(fā)點(diǎn),一個(gè)對(duì)應(yīng)目的地。

2、創(chuàng)建一個(gè)MapboxDirections生成器對(duì)象,用于向Mapbox API發(fā)出網(wǎng)絡(luò)請(qǐng)求,其中的數(shù)據(jù)包含對(duì)應(yīng)于出發(fā)點(diǎn)和目的點(diǎn)的航點(diǎn)位置信息,還有方向路線有關(guān)的配置信息(駕駛、步行或騎自行車等)。

3、異步執(zhí)行方向要求。其中,MapboxDirections類提供了一個(gè)使用Retrofit API的內(nèi)置的異步請(qǐng)求。具體地說(shuō),是使用enqueue()函數(shù)來(lái)執(zhí)行請(qǐng)求。

4、OnResponse()方法返回Retrofit響應(yīng)結(jié)果,這是一個(gè)標(biāo)準(zhǔn)的JSON API響應(yīng)。

5、響應(yīng)正文中包含位置坐標(biāo)對(duì)信息,稍后這些坐標(biāo)將繪制在地圖上。

6、采用Mapbox Polyline函數(shù)把坐標(biāo)繪制在地圖上。折線(Polyline)是一種幾何特征,通過(guò)多條線段首尾相連而形成一條不封閉的折線。

為了使用Direction庫(kù),我們需要獲得設(shè)備的位置作為起源航點(diǎn),以及由用戶通過(guò)長(zhǎng)按方式來(lái)指定目的地航點(diǎn)的位置信息。

八、加入航點(diǎn)位置并在目標(biāo)地添加標(biāo)記

現(xiàn)在,請(qǐng)把如下代碼添加到onCreate方法的***面:

  1. mapView.setOnMapLongClickListener(new MapView.OnMapLongClickListener() {  
  2.     @Override  
  3.     public void onMapLongClick(LatLng point) { 
  4.         //Remove previously added markers  
  5.         //Marker is an annotation that shows an icon image at a geographical location  
  6.         //so all markers can be removed with the removeAllAnnotations() method. 
  7.          mapView.removeAllAnnotations();  
  8.         // Set the origin waypoint to the devices location  
  9.         Waypoint origin = new Waypoint(mapView.getMyLocation().getLongitude(), mapView.getMyLocation().getLatitude());  
  10.         // Set the destination waypoint to the location point long clicked by the user  
  11.         Waypoint destination = new Waypoint(point.getLongitude(), point.getLatitude());  
  12.         // Add marker to the destination waypoint  
  13.         mapView.addMarker(new MarkerOptions()  
  14.                 .position(new LatLng(point))  
  15.                 .title("Destination Marker") 
  16.                 .snippet("My destination")); 
  17.         // Get route from API 
  18.         getRoute(origin, destination);     } 
  19.  
  20. }); 

九、創(chuàng)建MapboxDirections網(wǎng)絡(luò)請(qǐng)求并異步運(yùn)行

接下來(lái),再創(chuàng)建一個(gè)如下所示的方法,以便取得***路由信息:

  1. private void getRoute(Waypoint origin, Waypoint destination) { 
  2.   MapboxDirections directions = new MapboxDirections.Builder()  
  3.           .setAccessToken(MAPBOX_ACCESS_TOKEN) 
  4.           .setOrigin(origin) 
  5.           .setDestination(destination)  
  6.           .setProfile(DirectionsCriteria.PROFILE_WALKING)  
  7.           .build(); 
  8.   directions.enqueue(new Callback<DirectionsResponse>() {  
  9.       @Override  
  10.       public void onResponse(Response<DirectionsResponse> response, Retrofit retrofit) {  
  11.           // Display some info about the route  
  12.           currentRoute = response.body().getRoutes().get(0); 
  13.           showToastMessage(String.format("You are %d meters \nfrom your destination", currentRoute.getDistance()));     
  14.           // Draw the route on the map  
  15.           drawRoute(currentRoute);  
  16.       } 
  17.       @Override  
  18.       public void onFailure(Throwable t) { 
  19.           showToastMessage("Error: " + t.getMessage());  
  20.       }  
  21.   });  

十、使用地圖上的坐標(biāo)點(diǎn)繪制折線

再添加一個(gè)如下方法來(lái)實(shí)現(xiàn)路由繪制:

  1. private void drawRoute(DirectionsRoute route) {  
  2.   // Convert List<Waypoint> into LatLng[]  
  3.   List<Waypoint> waypoints = route.getGeometry().getWaypoints();  
  4.   LatLng[] point = new LatLng[waypoints.size()];  
  5.   for (int i = 0; i < waypoints.size(); i++) {  
  6.       point[i] = new LatLng(  
  7.               waypoints.get(i).getLatitude(),  
  8.               waypoints.get(i).getLongitude());  
  9.   }
  10.    // Draw Points on MapView  
  11.   mapView.addPolyline(new PolylineOptions()  
  12.           .add(point)  
  13.           .color(Color.parseColor("#38afea"))  
  14.           .width(5));  
  15. private void showToastMessage(String message) {  
  16.   Toast.makeText(this, message, Toast.LENGTH_SHORT).show();  

好了,現(xiàn)在運(yùn)行你的工程。在地圖上選擇兩個(gè)點(diǎn),你會(huì)觀察到類似于下圖所示結(jié)果:

十一、小結(jié)

本文中,我們介紹了使用MapBox SDK及其Directory庫(kù)的基本知識(shí)。其實(shí),MapBox還有更多更豐富的內(nèi)容可應(yīng)用于你的程序中,例如不同的地圖風(fēng)格,實(shí)現(xiàn)定制的矢量地圖繪制等等。

作為本文補(bǔ)充,我還推薦另一個(gè)庫(kù)Geocoding(https://github.com/mapbox/mapbox-geocoder-android)。這個(gè)庫(kù)可以把坐標(biāo)信息轉(zhuǎn)換成地圖,或者實(shí)現(xiàn)相反的轉(zhuǎn)換。當(dāng)然,要想了解更多的有關(guān)MapBox信息,建議學(xué)習(xí)其移動(dòng)應(yīng)用有關(guān)實(shí)例(https://www.mapbox.com/mobile/)。在這個(gè)網(wǎng)址中你會(huì)發(fā)現(xiàn)更多的庫(kù)可用。

責(zé)任編輯:李英杰 來(lái)源: 51CTO
相關(guān)推薦

2009-01-03 15:01:16

ibmdwLptus

2009-06-23 09:33:20

FCKEditorJSFJSP

2009-06-01 16:18:30

SpringJPA集成

2011-07-20 17:10:05

iPhone iAd

2009-01-03 14:43:55

ibmdwPHPsMash

2014-09-28 14:53:39

滲透BurpSuiteSqlmap

2011-06-29 09:42:12

Visual Stud Qt Opensource

2009-06-11 13:28:18

Glassfish集成

2012-10-18 10:12:42

IBMdw

2011-03-04 09:40:42

AJAX開(kāi)發(fā)集成數(shù)據(jù)庫(kù)

2023-03-13 00:16:28

2024-01-31 09:42:11

RabbitMQ消息隊(duì)列.NET

2023-12-26 14:52:52

谷歌

2011-03-02 17:42:35

2011-08-23 09:50:29

LuaPlusLua 腳本

2012-06-07 09:57:13

Android版Goo

2018-01-02 08:30:45

IntelCPU

2021-03-17 08:07:56

Python可視化工具

2014-12-31 09:56:29

Ehcache

2025-02-27 00:00:00

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)