GitHub地址:github.com/fluttify-pr…html
demo apk下載android
dependencies:
flutter:
sdk: flutter
amap_map_fluttify: ^x.x.x
複製代碼
app/build.gradle
的android
塊中配置簽名信息, 並在buildTypes
塊中指定簽名信息, 不然將沒法匹配到你在高德後臺配置的appkey, 例如:android {
signingConfigs {
release {
keyAlias 'amap_map_test'
keyPassword 'amap_map_test'
storeFile file('../amap_map_test.jks')
storePassword 'amap_map_test'
}
}
buildTypes {
debug {
signingConfig signingConfigs.release
}
profile {
signingConfig signingConfigs.release
}
release {
signingConfig signingConfigs.release
}
}
}
複製代碼
<key>io.flutter.embedded_views_preview</key>
<string>YES</string>
複製代碼
<key>NSLocationWhenInUseUsageDescription</key>
<string>須要定位權限</string>
複製代碼
<key>LSApplicationQueriesSchemes</key>
<array>
<string>iosamap</string>
<string>amapuri</string>
</array>
複製代碼
import 'package:amap_map_fluttify/amap_map_fluttify.dart';
複製代碼
在application標籤中加入以下內容:ios
<meta-data android:name="com.amap.api.v2.apikey" android:value="key">
//開發者申請的key
</meta-data>
複製代碼
點我獲取Key。
點我查看Key註冊時必要數據SHA1和包名的獲取方法。git
AmapView
是 Widget 類的一個子類, 用於在 Widget樹 中放置地圖。 AmapView 是地圖容器。用 AmapView 加載地圖的方法與 提供的其餘 Widget 同樣,具體的使用步驟以下:github
import 'package:amap_map_fluttify/amap_map_fluttify.dart';
import 'package:flutter/material.dart';
class CreateMapScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('自定義地圖')),
body: AmapView(),
);
}
}
複製代碼
插件已經在app生命週期回調中處理了相關回調。redis
AmapController
類是地圖的控制器類,用來操做地圖。它所承載的工做包括:地圖圖層切換(如衛星圖、黑夜地圖)、改變地圖狀態(地圖旋轉角度、俯仰角、中心點座標和縮放級別)、添加點標記(Marker)、繪製幾何圖形(Polyline、Polygon、Circle)、各種事件監聽(點擊、手勢等)等,AmapController
是地圖 SDK 最重要的核心類,諸多操做都依賴它完成。api
在 AmapView
對象初始化完畢以後,構造 AmapController
對象。示例代碼以下:數組
import 'package:amap_map_fluttify/amap_map_fluttify.dart';
import 'package:flutter/material.dart';
class CreateMapScreen extends StatefulWidget {
@override
_CreateMapScreenState createState() => _CreateMapScreenState();
}
class _CreateMapScreenState extends State<CreateMapScreen> {
AmapController _controller;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('自定義地圖')),
body: AmapView(
onMapCreated: (controller) async {
_controller = controller;
},
),
);
}
}
複製代碼
運行您剛完成的工程就能夠在您的 APP 中看到高德地圖了。運行後的效果以下圖所示(左Android,右iOS):
markdown
定位藍點指的是進入地圖後顯示當前位置點的功能。自Android 3D地圖 SDK 5.0.0版本以後定位藍點實現無需依賴 Android 定位 SDK ,5.0.0 版本以前須要引入地圖 SDK 和定位 SDK 到工程中。效果以下: 網絡
final option = MyLocationOption(
show: true, // 是否顯示
myLocationType: MyLocationType.Locate, //定位模式
interval: Duration.zero, // 定位間隔
strokeColor: Colors.transparent, // 精度圈邊框顏色
strokeWidth: 0, //精度圈邊框寬度
fillColor: Colors.transparent, // 精度圈填充色
iconProvider: AssetImage('圖片路徑'), // 自定義定位圖標
anchorU: 0.0, // 錨點u
anchorV: 0.0, // 錨點v
);
複製代碼
enum MyLocationType {
/// 只定位
Show,
/// 定位一次, 並移動到中心
Locate,
/// 跟隨
Follow,
/// 方向跟隨
Rotate,
}
複製代碼
經過
class AmapController {
Future<LatLng> getLocation({
Duration interval = const Duration(milliseconds: 500),
Duration timeout = const Duration(seconds: 10),
});
}
複製代碼
方法獲取經緯度信息,建議拿到位置以後調用逆地理編碼接口獲取。
Android 3D地圖 SDK 集成了室內地圖功能,支持室內外地圖一體化展現。
開啓室內地圖後,若是可見區域內包含室內地圖覆蓋區域(如:凱德Mall等知名商場),且縮放達到必定級別,即可直接在地圖上看到精細室內地圖效果。
縮放級別≥17級時,地圖上能夠顯示室內地圖。
縮放級別≥18級時,不只能夠看到室內地圖效果,還容許操做切換樓層,顯示精細化室內地圖。
以下圖示:
3D 地圖 SDK中默認會關閉室內地圖顯示,若有須要可以使用類AmapController
中的 showIndoorMap(bool enable)
自行開啓。
await controller.showIndoorMap(bool enable); //true:顯示室內地圖;false:不顯示;
複製代碼
地圖插件提供了幾種預置的地圖圖層,包括衛星圖、白晝地圖(即最多見的黃白色地圖)、夜景地圖、導航地圖、路況圖層。
插件提供圖層類型枚舉,詳細以下: 注意:路況圖層是經過開關控制,不經過常量控制。
名稱 | 說明 |
---|---|
MapType.Standard | 標準視圖 |
MapType.Satellite | 衛星視圖 |
MapType.Night | 黑夜視圖 |
MapType.Navi | 導航視圖 |
MapType.Bus | 公交視圖 |
衛星地圖在顯示衛片(衛星照片)的同時也能夠顯示路網信息,設置衛星地圖的代碼及顯示效果以下:
await controller.setMapType(MapType.Satellite);
複製代碼
顯示效果以下:
設置夜景地圖的代碼以下:
await controller.setMapType(MapType.Night);
複製代碼
顯示效果以下:
路況圖依據實時路況數據渲染,與前兩種設置方式不太相同,路況圖實現的方法以下:
await controller.showTraffic(true);
複製代碼
顯示效果以下:
高德3D 地圖 SDK支持離線地圖功能。(2D 地圖 SDK 不支持離線地圖功能)
離線地圖可知足在無網絡環境下查看地圖信息的需求,在設備本地有離線地圖數據的狀況下,SDK 會優先加載離線地圖。
離線地圖UI組件涵蓋城市下載、暫停、更新、刪除以及關鍵字城市查詢等功能,是高德地圖客戶端離線地圖功能的一個子集,UI交互風格上靠攏高德地圖app,也考慮到與開發者應用UI的融合問題,儘量的保持了簡約極致。如下方法實現一鍵完成離線地圖開發:
import 'package:amap_map_fluttify/amap_map_fluttify.dart';
import 'package:flutter/material.dart';
class OfflineManagerScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('打開離線地圖管理')),
body: Center(
child: RaisedButton(
onPressed: () {
// 打開離線地圖UI組件
AmapService.instance.openOfflineMapManager();
},
child: Text('離線地圖管理'),
),
),
);
}
}
複製代碼
UI示意:
地圖支持切換中英文顯示。具體實現代碼:
await controller.setMapLanguage(Language.English);
複製代碼
顯示效果以下:
高德地圖支持使用可視化自定義地圖模版改變底圖顏色和樣式,實現可視化的編輯和控制顯示地圖元素。
高德地圖開放平臺的開發者在取得開發者帳號後,能夠進入開發者控制檯,在地圖自定義平臺選擇「建立地圖樣式」,能夠選擇一個模板進行建立。
在建立的頁面的左側列表選擇任一要素編輯樣式屬性;也能夠單擊地圖,在彈出的列表中選擇要素進行編輯。
編輯完成後點擊右上角「保存」->「發佈」,發佈完成後,選擇「使用方法」,而後選擇「android」平臺,點擊「下載離線文件」。
1、設定離線樣式文件
一、在官網控制檯-個人地圖樣式中選擇與當前使用的地圖SDK版本號所對應的版本進行樣式文件下載:
2.下載獲得的Zip文件,內部目錄結構以下,每一個文件都會對應 setCustomMapStyle 中一個參數:
文件名稱 | 文件內容說明 | 對應參數 |
---|---|---|
style_extra.data | 擴展內容,如網格背景色等 | styleExtraPath |
style.data | 具體樣式配置 | styleDataPath |
textures.zip | 紋理圖片(zip文件) | texturePath |
import 'package:amap_map_fluttify/amap_map_fluttify.dart';
import 'package:flutter/material.dart';
class CreateMapScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: AmapView(
zoomLevel: 10,
onMapCreated: (controller) async {
// styleDataPath等參數路徑與使用Image.asset('path')時同理;
await controller.setCustomMapStyle(styleDataPath: 'raw/style.data', styleExtraPath: 'raw/style_extra.data');
},
),
);
}
}
複製代碼
顯示效果以下:
控件是指浮在地圖圖面上的一系列用於操做地圖的組件,例如縮放按鈕、指南針、定位按鈕、比例尺等。
縮放按鈕是提供給 App 端用戶控制地圖縮放級別的交換按鈕,每次點擊改變1個級別,此控件默認打開,能夠經過如下方法控制其隱藏:
await controller.showZoomControl(true);
複製代碼
指南針用於向 App 端用戶展現地圖方向,默認不顯示。經過以下接口控制其顯示:
await controller.showCompass(true);
複製代碼
App 端用戶能夠經過點擊定位按鈕在地圖上標註一個藍色定位點,表明其當前位置。不一樣於以上控件,定位按鈕內部的邏輯實現依賴定位 SDK。
SDK 沒有提供自定義定位按鈕的功能,若是您想要實現該功能,能夠瀏覽參考自定義定位按鈕的內容。
await controller.showLocateControl(true);
複製代碼
比例尺控件(最大比例是1:10m,最小比例是1:1000Km),位於地圖右下角,可控制其顯示與隱藏,設置的方法是:
await controller.showScaleControl(true);
複製代碼
地圖 SDK 提供了多種手勢供 App 端用戶與地圖之間進行交互,如縮放、旋轉、滑動、傾斜。這些手勢默認開啓,若是想要關閉某些手勢,能夠經過 AmapController 類提供的接口來控制手勢的開關。
如下是控制手勢生效與否的方法:
名稱 | 調用方法 |
---|---|
縮放手勢 | AmapController.setZoomGesturesEnabled(bool) |
滑動手勢 | AmapController.setScrollGesturesEnabled(bool) |
旋轉手勢 | AmapController.setRotateGesturesEnabled(bool) |
傾斜手勢 | AmapController.setTiltGesturesEnabled(bool) |
全部手勢 | AmapController.setAllGesturesEnabled(bool) |
縮放手勢可改變地圖的縮放級別,地圖響應的手勢以下:
也能夠禁用或啓用縮放手勢。禁用縮放手勢不會影響用戶使用地圖上的縮放控制按鈕。如下是控制縮放手勢開啓關閉的代碼:
await controller.setZoomGesturesEnabled(true);
複製代碼
您能夠用手指拖動地圖四處滾動(平移)或用手指滑動地圖(動畫效果),也能夠禁用或開啓平移(滑動)手勢。
如下介紹控制縮放手勢開啓關閉的方法,示例代碼以下:
await controller.isScrollGesturesEnabled(true);
複製代碼
您能夠用兩個手指在地圖上轉動,能夠旋轉3D矢量地圖,也能夠禁用旋轉手勢。
如下介紹控制旋轉手勢開啓關閉的方法,示例代碼以下:
await controller.setRotateGesturesEnabled(true);
複製代碼
用戶能夠在地圖上放置兩個手指,移動它們一塊兒向下或向上去增長或減少傾斜角,也能夠禁用傾斜手勢。
如下是控制傾斜手勢開啓關閉的代碼:
await controller.setTiltGesturesEnabled(true);
複製代碼
開啓以中心點進行手勢操做的方法:
await controller.setZoomByCenter(true);
複製代碼
方法交互的概念是從程序角度出發提出的。地圖 SDK 提供了不少與地圖交互的接口方法,例如:改變地圖顯示的區域(即改變地圖中心點)、改變地圖的縮放級別、限制地圖的顯示範圍等。
地圖視角交互的核心方法均依賴 AmapController
類提供的方法。
若是想改變地圖中心點,能夠經過以下方法,animated
參數能夠控制是否以動畫方式移動地圖:
await controller.setCenterCoordinate(LatLng(23.16, 113.23), animated: false);
複製代碼
若是想改變地圖的縮放級別,能夠經過以下方法,animated
參數能夠控制是否以動畫方式移動地圖:
await controller.setZoomLevel(10, animated: false);
複製代碼
手機屏幕僅顯示設定的地圖範圍,例如:但願設置僅顯示北京市區地圖,可以使用此功能。注意:若是限制了地圖顯示範圍,地圖旋轉手勢將會失效。
final southWest = LatLng(40, 116);
final northEast = LatLng(42, 118);
await controller.setMapRegionLimits(southWest, northEast);
複製代碼
地圖 SDK 支持對當前屏幕顯示區域進行截屏,能夠對地圖、覆蓋物(包含信息窗口)、Logo進行截取屏幕,這其中不包括地圖控件、Toast窗口。
詳細示例以下:
final Uint8List data = await controller.screenShot();
複製代碼
返回對象爲圖片數據,使用Image.memory(:Uint8List)
能夠直接顯示。
點標記用來在地圖上標記任何位置,例如用戶位置、車輛位置、店鋪位置等一切帶有位置屬性的事物。
地圖 SDK 提供的點標記功能包含兩大部分,一部分是點(俗稱 Marker)、另外一部分是浮於點上方的信息窗體(俗稱 InfoWindow)。同時,SDK 對 Marker 和 InfoWindow 封裝了大量的觸發事件,例如點擊事件、長按事件、拖拽事件。
Marker 有默認風格,同時也支持自定義。因爲內容豐富,如下只能展現一些基礎功能的使用,詳細內容可分別參考手冊。
Marker
MarkerOption
繪製 Marker 的代碼以下:
LatLng latLng = LatLng(39.906901,116.397972);
final Marker marker = controller.addMarker(MarkerOption(coordinate: latLng));
複製代碼
以上代碼繪製的 Marker 效果以下圖:
名稱 | 說明 |
---|---|
position | 在地圖上標記位置的經緯度值。必填參數 |
title | 點標記的標題 |
snippet | 點標記的內容 |
draggable | 點標記是否可拖拽 |
visible | 點標記是否可見 |
anchorU,anchorV | 點標記的錨點 |
alpha | 點的透明度 |
可根據實際的業務需求,在地圖指定的位置上添加自定義的 Marker。MarkerOptions 是設置 Marker 參數變量的類,自定義 Marker 時會常常用到。
下面以自定義 Marker 圖標爲例進行代碼說明:
final marker = await controller.addMarker(
MarkerOption(
coordinate: LatLng(39.906901,116.397972),
iconProvider: AssetImage('images/test_icon.png'),
),
);
複製代碼
以上代碼繪製的 Marker 效果以下圖:
插件 提供了給 Marker 設置動畫的方法,具體實現方法以下:
final marker = await controller.addMarker(
MarkerOption(
coordinate: getNextLatLng(),
iconProvider: AssetImage('images/test_icon.png'),
anchorU: 0.5,
anchorV: 1,
visible: false,
),
);
await marker.startAnimation(ScaleMarkerAnimation(
fromValue: 0.8,
toValue: 1.2,
duration: Duration(milliseconds: 1000),
repeatCount: 0,
));
await marker.setVisible(true);
複製代碼
因爲動畫顯示過程是異步的,若是直接添加marker並立刻執行動畫的話,可能會出現marker先被添加到地圖上,而後一閃而過開始執行動畫。這裏提供的是一個變通方法,能夠先添加一個隱藏的marker,等動畫開始調用以後,再顯示marker。
點擊 Marker 時會回調AmapController::setMarkerClickedListener
,監聽器的實現示例以下:
await controller.setMarkerClickedListener((marker) async {
// 點擊marker後替換圖片
marker.setIcon(
AssetImage('images/test_icon.png'),
createLocalImageConfiguration(context),
);
});
複製代碼
Marker 拖拽事件 拖拽 Marker 時會回調AmapController::setMarkerDragListener(:onMarkerDragStart:onMarkerDragging:onMarkerDragEnd)
,監聽器的實現示例以下:
await controller.setMarkerDragListener(
onMarkerDragStart: (marker) async {
// 拖拽開始
},
onMarkerDragging: (marker) async {
// 拖拽中
},
onMarkerDragEnd: (marker) async {
// 拖拽結束
},
);
複製代碼
InfoWindow 是點標記的一部分,默認的 Infowindow 只顯示 Marker 對象的兩個屬性,一個是 title 和另外一個 snippet,若是但願對InfoWindow 的樣式或者內容有自定義需求,能夠參考以下內容。
SDK 爲用戶提供了默認的 InfoWindow 樣式,調用 Marker
類的 showInfoWindow()
和 hideInfoWindow()
方法能夠控制顯示和隱藏。當改變 Marker
的 title
和 snippet
屬性時,再次調用 showInfoWindow()
,能夠更新 InfoWindow
顯示內容。效果以下:
自定義InfoWindow須要在AmapController
上調用showCustomInfoWindow
,須要傳入Marker
對象和自定義InfoWindow的widget。注意這裏的widget僅做爲截圖提供給原生端顯示,若是widget中有按鈕之類的動態內容,則轉成靜態截圖後都是無效的。實現示例以下:
await controller.setMarkerClickedListener((marker) async {
await controller.showCustomInfoWindow(
marker,
Card(
elevation: 10,
child: Container(
padding: EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.location_on),
Text(await marker.title),
],
),
),
),
);
});
複製代碼
點擊 InfoWindow 時會回調AmapController.setInfoWindowClickListener(:onInfoWindowClicked)
,監聽器的實現示例以下:
await controller.setInfoWindowClickListener((marker) async {
toast('${await marker.title}, ${await marker.coordinate}');
});
複製代碼
地圖上繪製的線是由 Polyline 類定義實現的,線由一組經緯度(LatLng對象)點鏈接而成。
與點標記同樣,Polyline
的屬性操做集中在 PolylineOption
類中,添加一條線的示例以下:
await controller.addPolyline(PolylineOption(
coordinateList: [
LatLng(39.999391, 116.135972),
LatLng(39.898323, 116.057694),
LatLng(39.900430, 116.265061),
LatLng(39.955192, 116.140092),
],
strokeColor: Colors.red,
width: 10,
));
複製代碼
上面的代碼定義該折線的顏色爲紅色,寬度爲 10 像素,效果以下圖:
名稱 | 說明 |
---|---|
coordinateList | 折線經緯度列表 |
width | 折線寬度 |
strokeColor | 折線顏色 |
textureProvider | 自定義紋理 |
lineCapType | 線段末端樣式 |
lineJoinType | 線段鏈接處樣式 |
dashType | 是否虛線 |
地圖上的面分爲圓形和多邊形兩種。
圓形由 Circle
類定義實現,構造一個圓形須要肯定它的圓心和半徑,具體的示例代碼以下:
await controller.addCircle(CircleOption(
center: LatLng(39.999391, 116.135972),
radius: 10000,
width: 10,
strokeColor: Colors.green,
));
複製代碼
上面的代碼定義該圓形的邊線顏色爲綠色,寬度10 像素,效果以下圖:
多邊形是由 Polygon
類定義的一組在地圖上的封閉線段組成的圖形,它由一組 LatLng
點按照傳入順序鏈接而成的封閉圖形。與繪製線相似,面的屬性操做集中在 PolygonOption
中。
final polygon = await controller.addPolygon(PolygonOption(
coordinateList: [
LatLng(39.999391, 116.135972),
LatLng(39.898323, 116.057694),
LatLng(39.900430, 116.265061),
LatLng(39.955192, 116.140092),
],
width: 10,
strokeColor: Colors.green,
));
複製代碼
上面的代碼定義該圓形的邊線顏色爲綠色,寬度10 像素,效果以下圖:
熱力圖功能提供將業務數據展現在地圖上,能夠給使用者直觀描述一個區域的人員,車輛等事物的熱度狀況。
如下以本地模擬數據爲例,簡單說明 SDK 熱力圖須要的是經緯度點數組/列表數據。
示例代碼以下:
await controller.addHeatmapTileOverlay(
HeatmapTileOption(
coordinateList: getNextBatchLatLng(50),
gradient: RadialGradient(
colors: [Colors.blue, Colors.yellow, Colors.red],
stops: <double>[0.08, 0.4, 1.0],
),
),
);
複製代碼
效果圖以下:
功能說明:根據輸入的關鍵點和時間參數,實現點的平滑移動效果。
使用場景:可應用到展現車輛行駛軌跡、用戶移動軌跡等場景。
效果示例:
實現平滑移動的配置參數都在SmoothMoveMarkerOption
類內,其中path
是移動路徑的經緯度列表,iconProvider
爲marker圖片,duration
爲動畫時長。
await controller.addSmoothMoveMarker(
SmoothMoveMarkerOption(
path: [for (int i = 0; i < 10; i++) getNextLatLng()],
iconProvider: AssetImage('images/test_icon.png'),
duration: Duration(seconds: 10),
),
);
複製代碼
應用於移動端的海量點圖層用於批量展示具備類似屬性的座標點數據。海量點圖層支持處理的點數量級跨度較大,從幾十個點至十萬個點(建議不超過100000個點數據)均可以應用海量點圖層進行處理。
以下圖所示的處理上萬個點的海量點圖層效果:
添加海量點與添加普通Marker相似,只須要構造對應類型參數便可。
示例代碼:
final overlay = await controller.addMultiPointOverlay(
MultiPointOption(
pointList: [
for (int i = 0; i < 10000; i++)
PointOption(
coordinate: getNextLatLng(),
id: i.toString(),
title: 'Point$i',
snippet: 'Snippet$i',
object: 'Object$i',
)
],
iconProvider: AssetImage('images/test_icon.png'),
),
);
複製代碼
在返回的overlay
對象上調用remove
方法,便可刪除對應海量點圖層。
await controller.setMultiPointClickedListener(
(id, title, snippet, object) async {
toast(
'id: $id, title: $title, snippet: $snippet, object: $object',
);
},
);
複製代碼
Copyright (C) 2020 yohom
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see www.gnu.org/licenses/.