【谷歌地图--DirectionsSDK集成】
上網(wǎng)查了一些資料發(fā)現(xiàn)有關(guān)谷歌地圖sdk集成的文章還是不少的,但是都缺乏系統(tǒng)性。這里做些系統(tǒng)整理,主要分以下篇幅講解,希望對(duì)初始谷歌地圖的你有所幫助:
開始正文啦:
由于眾所周知的的原因,集成谷歌地圖sdk前首先你的pc端和移動(dòng)端都是要翻墻的,不然后續(xù)的一些功能你都無法操作。
文章目錄
- 谷歌地圖--DirectionsSDK集成
- 線路規(guī)劃
- 實(shí)現(xiàn)導(dǎo)航功能
- 替換藍(lán)點(diǎn)
- 藍(lán)點(diǎn)方向
- 項(xiàng)目源碼地址
谷歌地圖–DirectionsSDK集成
開始正文之前,我們這里先做個(gè)說明哈:集成 Directions 功能時(shí),需要你的google地圖開發(fā)者賬號(hào)啟用計(jì)費(fèi)功能。而啟用計(jì)費(fèi)功能,就需要綁定一個(gè)國(guó)際的信用卡。什么!國(guó)際的信用卡,我沒有啊,只有國(guó)內(nèi)的行不行,答案是不行滴。頓時(shí)心中一萬(wàn)個(gè)不爽,集成國(guó)內(nèi)的地圖,就沒有這么麻煩!不過大家也不要擔(dān)心,無法啟用計(jì)費(fèi)功能的同學(xué),后面我會(huì)為大家提供解決辦法,走起!
截圖:
線路規(guī)劃
同樣廢話不多說,先上效果圖:
首先明確一點(diǎn),獲取這些路線信息,不像集成國(guó)內(nèi)的地圖。谷歌地圖而是一個(gè)http get請(qǐng)求。鏈接如下:
具體傳遞參數(shù)的意義大家可仔細(xì)閱讀官方文檔,這里我也貼出關(guān)鍵代碼:
/*** 獲取線路信息** origin,destination :可是以下幾種:位置ID,地址,字符串經(jīng)緯度** mode: driving (默認(rèn))表示使用道路網(wǎng)絡(luò)的標(biāo)準(zhǔn)行車路線。* walking* bicycling* transit 通過公共交通路線(如果有)請(qǐng)求路線。如果將模式設(shè)置為transit,則可以選擇指定departure_time或 arrival_time。* 如果未指定任何時(shí)間,則 departure_time默認(rèn)為現(xiàn)在(即,出發(fā)時(shí)間默認(rèn)為當(dāng)前時(shí)間)。* 您還可以選擇包含 transit_mode和和/或 transit_routing_preference。** arrival_time:指定公交路線的理想到達(dá)時(shí)間* departure_time:指定所需的出發(fā)時(shí)間。** waypoints:指定要在起點(diǎn)和終點(diǎn)之間的路徑上包括的直通或中途停留位置的中間位置數(shù)組。航點(diǎn)通過將路線引導(dǎo)通過指定位置來更改路線* API支持以下行駛模式的航點(diǎn):駕駛,步行和騎車;不中轉(zhuǎn)。** alternatives:如果設(shè)置為 true,則指定“方向”服務(wù)可以在響應(yīng)中提供多個(gè)路線選擇。* 請(qǐng)注意,提供路由選擇可能會(huì)增加服務(wù)器的響應(yīng)時(shí)間。這僅適用于沒有中間航路點(diǎn)的請(qǐng)求。** avoid: 表示計(jì)算出的路線應(yīng)避開所指示的特征。highways 表示計(jì)算出的路線應(yīng)避開高速公路。** units:指定顯示結(jié)果時(shí)要使用的單位制。有效值在下面的“單位系統(tǒng)”中指定 。**/private fun getLineInfo() {ViseHttp.GET("directions/json").tag("tag1").addParam("origin", strOrigin).addParam("destination", strDestination)//.addParam("mode", "driving").addParam("waypoints","$strWaypoints2") //航路點(diǎn),最大允許數(shù)量 waypoints為25,加上起點(diǎn)和終點(diǎn) $strWaypoints1|$strWaypoints2//.addParam("alternatives", "true") //如果設(shè)置為 true,這僅適用于沒有中間航路點(diǎn)的請(qǐng)求。//.addParam("avoid", "tolls|highways|ferries").addParam("key", Config.API_KAY).request(object : ACallback<LineModule?>() {override fun onSuccess(mBean: LineModule?) {//請(qǐng)求成功,AuthorModel為解析服務(wù)器返回?cái)?shù)據(jù)的對(duì)象,可以是String,按需定義即可dealWithData(mBean)}override fun onFail(errCode: Int, errMsg: String) {//請(qǐng)求失敗,errCode為錯(cuò)誤碼,errMsg為錯(cuò)誤描述Log.i(TAG, " errCode=${errCode} errMsg=$errMsg")}})}那我們獲取的數(shù)據(jù)是什么樣的呢?這里,我把完整的json數(shù)據(jù)貼到這里,供大家使用。不方便啟用計(jì)費(fèi)功能的同學(xué),可以完整的復(fù)制該json數(shù)據(jù)到自己的項(xiàng)目中,以讀取本地json數(shù)據(jù)的方式,模擬數(shù)據(jù)請(qǐng)求,然后解析并做后面的展示處理。每個(gè)返回參數(shù)的意義,同樣參考官方文檔 。
json數(shù)據(jù):
{"geocoded_waypoints" : [{"geocoder_status" : "OK","place_id" : "ChIJy-z5i18alTURP4V2gaGOgZY","types" : [ "establishment", "point_of_interest", "transit_station" ]},{"geocoder_status" : "OK","place_id" : "ChIJyXsMpF0alTURAOY_NJyY1U8","types" : [ "establishment", "point_of_interest" ]}],"routes" : [{"bounds" : {"northeast" : {"lat" : 36.7065579,"lng" : 119.1854509},"southwest" : {"lat" : 36.7023932,"lng" : 119.1759237}},"copyrights" : "Map data ?2020","legs" : [{"distance" : {"text" : "1.5 公里","value" : 1515},"duration" : {"text" : "4分鐘","value" : 241},"end_address" : "中國(guó)山東省濰坊市奎文區(qū)勝利東街華都魯成大廈","end_location" : {"lat" : 36.7065579,"lng" : 119.1772408},"start_address" : "中國(guó)濰坊市奎文區(qū)健康街濰縣中路口","start_location" : {"lat" : 36.7045897,"lng" : 119.1854509},"steps" : [{"distance" : {"text" : "37 米","value" : 37},"duration" : {"text" : "1分鐘","value" : 7},"end_location" : {"lat" : 36.7047135,"lng" : 119.1851888},"html_instructions" : "向\u003cb\u003e北\u003c/b\u003e行駛","polyline" : {"points" : "uz__FalmvUMBSHDVBL"},"start_location" : {"lat" : 36.7045897,"lng" : 119.1854509},"travel_mode" : "DRIVING"},{"distance" : {"text" : "52 米","value" : 52},"duration" : {"text" : "1分鐘","value" : 15},"end_location" : {"lat" : 36.70426399999999,"lng" : 119.1853314},"html_instructions" : "向\u003cb\u003e左\u003c/b\u003e轉(zhuǎn),前往\u003cb\u003e804省道\u003c/b\u003e/\u003cwbr/\u003e\u003cb\u003e健康東街\u003c/b\u003e","maneuver" : "turn-left","polyline" : {"points" : "m{__FmjmvUxA["},"start_location" : {"lat" : 36.7047135,"lng" : 119.1851888},"travel_mode" : "DRIVING"},{"distance" : {"text" : "0.8 公里","value" : 850},"duration" : {"text" : "2分鐘","value" : 127},"end_location" : {"lat" : 36.7023932,"lng" : 119.1760839},"html_instructions" : "向\u003cb\u003e右\u003c/b\u003e轉(zhuǎn),進(jìn)入\u003cb\u003e804省道\u003c/b\u003e/\u003cwbr/\u003e\u003cb\u003e健康東街\u003c/b\u003e\u003cdiv style=\"font-size:0.9em\"\u003e繼續(xù)沿健康東街前行\(zhòng)u003c/div\u003e","maneuver" : "turn-right","polyline" : {"points" : "sx__FikmvULlAVtBHp@VtB@NTlBJv@fCzSn@lFf@`ERbBTfB"},"start_location" : {"lat" : 36.70426399999999,"lng" : 119.1853314},"travel_mode" : "DRIVING"},{"distance" : {"text" : "0.5 公里","value" : 458},"duration" : {"text" : "1分鐘","value" : 64},"end_location" : {"lat" : 36.7065083,"lng" : 119.1759237},"html_instructions" : "向\u003cb\u003e右\u003c/b\u003e轉(zhuǎn),進(jìn)入\u003cb\u003e金馬路\u003c/b\u003e","maneuver" : "turn-right","polyline" : {"points" : "}l__FoqkvUoA@[@sHJ}ABoCBgABc@@}@@"},"start_location" : {"lat" : 36.7023932,"lng" : 119.1760839},"travel_mode" : "DRIVING"},{"distance" : {"text" : "0.1 公里","value" : 118},"duration" : {"text" : "1分鐘","value" : 28},"end_location" : {"lat" : 36.7065579,"lng" : 119.1772408},"html_instructions" : "向\u003cb\u003e右\u003c/b\u003e轉(zhuǎn),進(jìn)入\u003cb\u003e勝利東街\u003c/b\u003e\u003cdiv style=\"font-size:0.9em\"\u003e目的地在左側(cè)\u003c/div\u003e","maneuver" : "turn-right","polyline" : {"points" : "uf`_FopkvUCgBEsC?K"},"start_location" : {"lat" : 36.7065083,"lng" : 119.1759237},"travel_mode" : "DRIVING"}],"traffic_speed_entry" : [],"via_waypoint" : []}],"overview_polyline" : {"points" : "uz__FalmvUa@LHd@xA[LlA`@fDz@jHrFnd@TfBoA@oILyIL}@@CgBE_D"},"summary" : "健康東街和金馬路","warnings" : [],"waypoint_order" : []},{"bounds" : {"northeast" : {"lat" : 36.7069392,"lng" : 119.1854509},"southwest" : {"lat" : 36.7039003,"lng" : 119.1764395}},"copyrights" : "Map data ?2020","legs" : [{"distance" : {"text" : "1.4 公里","value" : 1357},"duration" : {"text" : "5分鐘","value" : 279},"end_address" : "中國(guó)山東省濰坊市奎文區(qū)勝利東街華都魯成大廈","end_location" : {"lat" : 36.7065579,"lng" : 119.1772408},"start_address" : "中國(guó)濰坊市奎文區(qū)健康街濰縣中路口","start_location" : {"lat" : 36.7045897,"lng" : 119.1854509},"steps" : [{"distance" : {"text" : "37 米","value" : 37},"duration" : {"text" : "1分鐘","value" : 7},"end_location" : {"lat" : 36.7047135,"lng" : 119.1851888},"html_instructions" : "向\u003cb\u003e北\u003c/b\u003e行駛","polyline" : {"points" : "uz__FalmvUMBSHDVBL"},"start_location" : {"lat" : 36.7045897,"lng" : 119.1854509},"travel_mode" : "DRIVING"},{"distance" : {"text" : "52 米","value" : 52},"duration" : {"text" : "1分鐘","value" : 15},"end_location" : {"lat" : 36.70426399999999,"lng" : 119.1853314},"html_instructions" : "向\u003cb\u003e左\u003c/b\u003e轉(zhuǎn),前往\u003cb\u003e804省道\u003c/b\u003e/\u003cwbr/\u003e\u003cb\u003e健康東街\u003c/b\u003e","maneuver" : "turn-left","polyline" : {"points" : "m{__FmjmvUxA["},"start_location" : {"lat" : 36.7047135,"lng" : 119.1851888},"travel_mode" : "DRIVING"},{"distance" : {"text" : "0.2 公里","value" : 167},"duration" : {"text" : "1分鐘","value" : 41},"end_location" : {"lat" : 36.7039003,"lng" : 119.1835148},"html_instructions" : "向\u003cb\u003e右\u003c/b\u003e轉(zhuǎn),進(jìn)入\u003cb\u003e804省道\u003c/b\u003e/\u003cwbr/\u003e\u003cb\u003e健康東街\u003c/b\u003e","maneuver" : "turn-right","polyline" : {"points" : "sx__FikmvULlAVtBHp@VtB"},"start_location" : {"lat" : 36.70426399999999,"lng" : 119.1853314},"travel_mode" : "DRIVING"},{"distance" : {"text" : "0.3 公里","value" : 340},"duration" : {"text" : "1分鐘","value" : 52},"end_location" : {"lat" : 36.7069392,"lng" : 119.1839711},"html_instructions" : "向\u003cb\u003e右\u003c/b\u003e轉(zhuǎn),進(jìn)入\u003cb\u003e222省道\u003c/b\u003e/\u003cwbr/\u003e\u003cb\u003e濰縣中路\u003c/b\u003e","maneuver" : "turn-right","polyline" : {"points" : "kv__F}_mvUgBOYCoBQkBMSAwAMa@E_AIOAEA]C"},"start_location" : {"lat" : 36.7039003,"lng" : 119.1835148},"travel_mode" : "DRIVING"},{"distance" : {"text" : "0.7 公里","value" : 672},"duration" : {"text" : "2分鐘","value" : 118},"end_location" : {"lat" : 36.70669,"lng" : 119.1764407},"html_instructions" : "向\u003cb\u003e左\u003c/b\u003e轉(zhuǎn),進(jìn)入\u003cb\u003e勝利東街\u003c/b\u003e","maneuver" : "turn-left","polyline" : {"points" : "ki`_FybmvU?PFrD@|AB|AFjGBpBDxDFbFD|DBdC"},"start_location" : {"lat" : 36.7069392,"lng" : 119.1839711},"travel_mode" : "DRIVING"},{"distance" : {"text" : "89 米","value" : 89},"duration" : {"text" : "1分鐘","value" : 46},"end_location" : {"lat" : 36.7065579,"lng" : 119.1772408},"html_instructions" : "\u003cb\u003e調(diào)頭\u003c/b\u003e\u003cdiv style=\"font-size:0.9em\"\u003e目的地在左側(cè)\u003c/div\u003e","maneuver" : "uturn-left","polyline" : {"points" : "yg`_FwskvU^?EsC?K"},"start_location" : {"lat" : 36.70669,"lng" : 119.1764407},"travel_mode" : "DRIVING"}],"traffic_speed_entry" : [],"via_waypoint" : []}],"overview_polyline" : {"points" : "uz__FalmvUa@LHd@xA[LlA`@fDVtBgBOiCUyFc@sBQL`KXzWHbI^?EsC?K"},"summary" : "222省道/濰縣中路和勝利東街","warnings" : [],"waypoint_order" : []}],"status" : "OK" }解析并處理的關(guān)鍵代碼:
private fun dealWithData(mBean: LineModule?) {val status = mBean!!.statusif (status == "OK") {//包含一個(gè)數(shù)組,其中包含有關(guān)起點(diǎn),目的地和航點(diǎn)的地理編碼的詳細(xì)信息。val geocodedWaypoints = mBean!!.geocoded_waypointsLog.i(TAG, "geocodedWaypoints.size=${geocodedWaypoints.size}")val routes = mBean!!.routes //路線 測(cè)試發(fā)現(xiàn):第一條數(shù)據(jù)就是最優(yōu)的線路if (routes != null && routes.size > 0) {Log.i(TAG, "routes.size=${routes.size}")var routesNumber = 0;routes.forEach {routesNumber++;//包含的視口邊界框 overview_polyline。val bounds = it.boundsroutesGlobalPreview(bounds);//包含一個(gè)points 對(duì)象,該對(duì)象保存路線的編碼折線表示。該折線是結(jié)果方向的近似(平滑)路徑。val overviewPolyline = it.overview_polylineval points = overviewPolyline.pointsLog.i(TAG, "points=$points")// val mLatLngList: MutableList<LatLng> = decodePoly(points) as MutableList<LatLng>val mLatLngList: MutableList<LatLng> = PolyUtil.decode(points)Log.i(TAG, " mLatLngList.size=${mLatLngList.size}")showLine(mLatLngList, routesNumber);//包含一個(gè)數(shù)組,該數(shù)組包含有關(guān)給定路線內(nèi)兩個(gè)位置之間路線段的信息。對(duì)于指定的每個(gè)航點(diǎn)或目的地,將顯示一條單獨(dú)的航段。// (沒有航路點(diǎn)的路線將在legs陣列中僅包含一條腿。)每條腿由一系列組成steps。(請(qǐng)參見下面的“ 指導(dǎo)腿”。)val legs = it.legsLog.i(TAG, "legs.size=${legs.size}")//總時(shí)間顯示處理calculateTotalTime(legs)// 包含該路線的簡(jiǎn)短文字說明,適用于對(duì)路線進(jìn)行命名和消除歧義。val summary = it.summary//包含顯示這些方向時(shí)要顯示的警告數(shù)組。您必須自己處理并顯示這些警告。val warnings = it.warnings//包含要為此路線顯示的版權(quán)文本。您必須自己處理和顯示此信息。val copyrights = it.copyrights//包含一個(gè)數(shù)組,該數(shù)組指示計(jì)算出的路線中任何路標(biāo)的順序。如果請(qǐng)求是optimize:true在其waypoints參數(shù)內(nèi) 傳遞的,則此路點(diǎn)可能會(huì)重新排序。val waypointOrder = it.waypoint_order}} else {Log.i(TAG, " routes is null")}} else {if (status == "ZERO_RESULTS") {Log.i(TAG, " status 在起點(diǎn)和終點(diǎn)之間找不到路由")} else {Log.i(TAG, " status=${status}")}}}實(shí)現(xiàn)導(dǎo)航功能
我們?cè)?谷歌地圖–MapsSDK集成 這篇文章末尾,留了這2個(gè)疑問:
那么在這里就做出一下回答。
替換藍(lán)點(diǎn)
關(guān)鍵代碼:
private fun getDeviceLocation() {val selfPermission4 =ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)if (selfPermission4 != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this,arrayOf(Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_BACKGROUND_LOCATION),12)return} else {Log.i(TAG, "getDeviceLocation: 已有權(quán)限")}//就可以去掉官方自帶的定位按鈕。mGoogleMap.isMyLocationEnabled = falsemGoogleMap.uiSettings?.isMyLocationButtonEnabled = true//這行代碼,就能發(fā)起定位請(qǐng)求val locationResult = fusedLocationProviderClient.lastLocationlocationResult.addOnCompleteListener(this) { task ->if (task.isSuccessful) {// Set the map's camera position to the current location of the device.val lastKnownLocation = task.resultif (lastKnownLocation != null) {Log.i(TAG, "getDeviceLocation: locationResult if")val currentLocation =LatLng(lastKnownLocation!!.latitude, lastKnownLocation!!.longitude)mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLocation,17.3f))if (isFirstLocation) {val fbearin = lastKnownLocation.bearing //和道路一個(gè)方向println("MainActivity.getDeviceLocation fbearin=" + fbearin)//添加自定義定位藍(lán)點(diǎn)mPositionMarker = mGoogleMap!!.addMarker(MarkerOptions().position(currentLocation).title("我的位置").rotation(fbearin).anchor(0.5f, 0.5f).icon(BitmapDescriptorFactory.fromResource(R.drawable.baseline_arrow_circle_up_red_900_24dp)))}mPositionMarker!!.position = currentLocation;//添加自定義藍(lán)點(diǎn)范圍val circle: Circle = mGoogleMap!!.addCircle(CircleOptions().apply {center(currentLocation)if (isFirstLocation) {radius(100.00)strokeWidth(3f)strokeColor(ContextCompat.getColor(this@MainActivity,R.color.purple))fillColor(ContextCompat.getColor(this@MainActivity,R.color.blue_100))clickable(true)strokePattern(getSelectedPattern(0))isFirstLocation = false}})} else {Log.i(TAG, "getDeviceLocation: locationResult else")}} else {Log.e(TAG, "Exception: %s", task.exception)}}}ps:請(qǐng)大家多看看代碼中的注釋,注釋已經(jīng)說的比較明白了。
藍(lán)點(diǎn)方向
藍(lán)點(diǎn)的方向的變化,我們這里就要依靠手機(jī)設(shè)備的傳感器了。通過讀取傳感器中的數(shù)據(jù),來設(shè)置藍(lán)點(diǎn)的方向。
關(guān)鍵代碼:
首先 獲取傳感器管理器
然后 實(shí)現(xiàn)SensorEventListener 接口
/加速度傳感器數(shù)據(jù)private val accelerometerReading = FloatArray(3)//地磁傳感器數(shù)據(jù)private val magnetometerReading = FloatArray(3)//旋轉(zhuǎn)矩陣,用來保存磁場(chǎng)和加速度的數(shù)據(jù)private val rotationMatrix = FloatArray(9)//方向數(shù)據(jù)private val orientationAngles = FloatArray(3)class MainActivity : AppCompatActivity(), OnMapReadyCallback, SensorEventListener {}接著 注冊(cè)監(jiān)聽
override fun onResume() {super.onResume()//加速度傳感器val accelerometer: Sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)if (accelerometer != null) {mSensorManager.registerListener(this,accelerometer,SensorManager.SENSOR_DELAY_NORMAL,SensorManager.SENSOR_DELAY_UI)}//地磁傳感器val magneticField: Sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)if (magneticField != null) {mSensorManager.registerListener(this,magneticField,SensorManager.SENSOR_DELAY_NORMAL,SensorManager.SENSOR_DELAY_UI)}}override fun onPause() {super.onPause()mSensorManager.unregisterListener(this);}最后 接口實(shí)現(xiàn):
var mPositionMarker: Marker? = null//var azimuth = 0foverride fun onSensorChanged(event: SensorEvent?) {//判斷sensor類型if (event!!.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {System.arraycopy(event.values,0,accelerometerReading,0,accelerometerReading.size);} else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {System.arraycopy(event.values,0,magnetometerReading,0,magnetometerReading.size);}updateOrientationAngles();}override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}fun updateOrientationAngles() {// 更新旋轉(zhuǎn)矩陣.// 參數(shù)1:// 參數(shù)2 :將磁場(chǎng)數(shù)據(jù)轉(zhuǎn)換進(jìn)實(shí)際的重力坐標(biāo)中,一般默認(rèn)情況下可以設(shè)置為null// 參數(shù)3:加速度// 參數(shù)4:地磁SensorManager.getRotationMatrix(rotationMatrix,null,accelerometerReading,magnetometerReading)//根據(jù)旋轉(zhuǎn)矩陣計(jì)算設(shè)備的方向//參數(shù)1:旋轉(zhuǎn)數(shù)組//參數(shù)2:模擬方向傳感器的數(shù)據(jù)SensorManager.getOrientation(rotationMatrix, orientationAngles)val sb = StringBuilder()if (orientationAngles.size >= 3) {sb.append("z軸:${orientationAngles[0]}\n")sb.append("x軸:${orientationAngles[1]}\n")sb.append("y軸:${orientationAngles[2]}\n")//Log.i(TAG, "updateOrientationAngles:sb=>> ${sb.toString()}")val azimuth = Math.toDegrees(orientationAngles[0].toDouble()).toFloat()if (mPositionMarker != null) {mPositionMarker!!.rotation = azimuth}}}到這里,你已經(jīng)可以替換藍(lán)點(diǎn),并能通過獲取設(shè)備傳感器的數(shù)據(jù)來設(shè)置藍(lán)點(diǎn)方向啦。在結(jié)合實(shí)時(shí)定位的功能,去開啟導(dǎo)航吧。
說明:篇幅有限,文章中也只是貼出了關(guān)鍵代碼。完整項(xiàng)目源碼請(qǐng)點(diǎn)擊這里:
項(xiàng)目源碼地址
參考博客:
官方文檔:
https://developers.google.com/maps/documentation/directions/overview
官方demo:
- android-samples
- android-places-demos
- android-maps-utils
拾取坐標(biāo)系統(tǒng)
【谷歌地圖–番外篇 android-maps-utils的使用 】
總結(jié)
以上是生活随笔為你收集整理的【谷歌地图--DirectionsSDK集成】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SSM配置redis
- 下一篇: 举个栗子!Tableau 技巧(90):