Mapbox Maps SDK Flutter Plugin
Mapbox Maps SDK Flutter Plugin là một giải pháp được phát triển chính thức từ Mapbox cho phép sử dụng sản phẩm Maps SDK mới nhất của chúng tôi (v10.13.0). Nó hiện đang ở giai đoạn thử nghiệm, nhưng có thể được sử dụng trong sản xuất. Plugin cho phép các nhà phát triển nhúng các bản đồ được tùy chỉnh cao bằng tiện ích Flutter trên Android và iOS.
Web và máy tính để bàn không được hỗ trợ.
API được hỗ trợ
- Style
- Camera position
- Camera animations
- Events
- Gestures
- User Location
- Circle Layer
- Fill Layer
- Fill extrusion Layer
- Line Layer
- Circle Layer
- Raster Layer
- Symbol Layer
- Hillshade Layer
- Heatmap Layer
- Sky Layer
- GeoJson Source
- Image Source
- Vector Source
- Raster Source
- Rasterdem Source
- Circle Annotations
- Point Annotations
- Line Annotations
- Fill Annotations
Yêu cầu
Plugin Maps Flutter tương thích với các ứng dụng:
- Đã triển khai trên iOS 11 trở lên
- Được xây dựng bằng Android SDK 21 trở lên
- Được xây dựng bằng Dart SDK 2.17.1 trở lên
Cài đặt
Cấu hình thông tin đăng nhập
Để chạy Plugin Maps Flutter, bạn sẽ cần định cấu hình Mã thông báo truy cập Mapbox.
Đọc thêm về access public tokens và access secret tokens tại tài liệu nền tảng Android hoặc iOS.
Secret token
Để truy cập SDK nền tảng, bạn sẽ cần tạo mã thông báo truy cập bí mật với phạm vi Downloads:Read
và sau đó:
- để tải xuống SDK Android, hãy thêm cấu hình mã thông báo vào
~/.gradle/gradle.properties
:
SDK_REGISTRY_TOKEN=YOUR_SECRET_MAPBOX_ACCESS_TOKEN
- để tải xuống SDK iOS, hãy thêm cấu hình mã thông báo vào
~/.netrc
:
machine api.mapbox.com
login mapbox
password YOUR_SECRET_MAPBOX_ACCESS_TOKEN
Public token
Để khởi tạo tiện ích MapWidget
, hãy chuyển mã thông báo truy cập công khai bằng ResourceOptions
:
MapWidget(
resourceOptions:
ResourceOptions(accessToken: PUBLIC_ACCESS_TOKEN))));
Sau đó, để lấy mã thông báo từ môi trường trong ứng dụng:
String ACCESS_TOKEN = String.fromEnvironment("PUBLIC_ACCESS_TOKEN");
Thêm plugin
Để sử dụng Plugin Maps Flutter, hãy thêm phần phụ thuộc git vào pubspec.yaml
:
dependencies:
mapbox_maps_flutter: ^0.4.4
Hiển thị bản đồ
Cài mapbox_maps_flutter
và thêm bản đồ:
import 'package:flutter/material.dart';
import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart';
void main() {
runApp(MaterialApp(
home: MapWidget(
resourceOptions: ResourceOptions(accessToken: YOUR_ACCESS_TOKEN))));
}
MapWidget widget
Tiện ích MapWidget
cung cấp các tùy chọn để tùy chỉnh bản đồ - bạn có thể đặt ResourceOptions
, MapOptions
, CameraOptions
, styleURL
.
Nó cũng cho phép hoặc thêm các sự kiện khác nhau - liên quan đến tải kiểu, hiển thị bản đồ, tải bản đồ.
MapboxMap controller
Phiên bản bộ điều khiển MapboxMap
được cung cấp với hàm gọi lại MapWidget.onMapCreated
.
MapboxMap
hiển thị một điểm vào cho hầu hết các API mà Plugin Maps Flutter cung cấp. Nó cho phép kiểm soát bản đồ, máy ảnh, phong cách, quan sát các sự kiện bản đồ,
các tính năng kết xuất truy vấn, v.v.
Để tương tác với bản đồ sau khi nó được tạo, hãy lưu trữ đối tượng MapboxMap ở đâu đó:
class FullMap extends StatefulWidget {
const FullMap();
@override
State createState() => FullMapState();
}
class FullMapState extends State<FullMap> {
MapboxMap? mapboxMap;
_onMapCreated(MapboxMap mapboxMap) {
this.mapboxMap = mapboxMap;
}
@override
Widget build(BuildContext context) {
return new Scaffold(
body: MapWidget(
key: ValueKey("mapWidget"),
resourceOptions: ResourceOptions(accessToken: ACCESS_TOKEN),
onMapCreated: _onMapCreated,
));
}
}
Kiểu bản đồ
Tài liệu nền tảng : Android, iOS.
Mapbox Maps Flutter Plugin cho phép tùy chỉnh đầy đủ giao diện của bản đồ được sử dụng trong ứng dụng của bạn.
Chỉ định kiểu bản đồ
Bạn có thể chỉ định uri kiểu ban đầu tại MapWidget.styleUri
hoặc tải nó khi chạy bằng cách sử dụng MapboxMap.loadStyleURI
/ MapboxMap.loadStyleJson
:
mapboxMap.loadStyleURI(Styles.DARK);
Markers và annotations
Tài liệu nền tảng : Android, iOS.
Bạn có một số tùy chọn để thêm chú thích trên bản đồ.
- Sử dụng API AnnotationManager để tạo chú thích hình tròn/điểm/đa giác/đa tuyến.
Tham khảo tài liệu tại đây
Tạo 6 marker bằng CircleAnnotation:
List<dynamic> Coordinates = [
{'id': 1, 'lng': 105.8342, 'lat': 21.0278},
{'id': 2, 'lng': 106.68028, 'lat': 20.86194},
{'id': 3, 'lng': 106.31250, 'lat': 20.93972},
{'id': 4, 'lng': 106.16833, 'lat': 20.42000},
{'id': 5, 'lng': 106.33750, 'lat': 20.44750},
{'id': 6, 'lng': 106.05639, 'lat': 21.18528},
];
mapboxMap?.annotations.createCircleAnnotationManager().then((value) async {
_circleAnnotationManager = value;
for (var coordinate in Coordinates) {
final id = coordinate['id'];
final lng = coordinate['lng'];
final lat = coordinate['lat'];
final options = CircleAnnotationOptions(
geometry: Point(coordinates: Position(lng, lat)).toJson(),
circleColor: Colors.blue.value,
circleRadius: 12.0,
);
await value.create(options);
}
});
Autocomplete
Sử dụng Goong API để tìm kiếm, những gợi ý tìm kiếm sẽ được đưa ra nhanh chóng và chính xác.
- Sử dụng Goong API để tìm kiếm
https://rsapi.goong.io/Place/AutoComplete?api_key={YOUR_API_KEY}&input=$input
- Sử dụng API AnnotationManager để tạo marker khi tìm kiếm địa điểm.
Tham khảo tài liệu tại đây
Future<void> fetchData(String input) async {
try {
final url = Uri.parse(
'https://rsapi.goong.io/Place/AutoComplete?api_key={YOUR_API_KEY}&input=$input');
var response = await http.get(url);
setState(() {
final jsonResponse = jsonDecode(response.body);
places = jsonResponse['predictions'] as List<dynamic>;
_circleAnnotationManager?.deleteAll();
isShow = true;
isHidden = true;
});
} catch (e) {
// ignore: avoid_print
print('$e');
}
}
Widget _buildListView() {
return ListView.builder(
itemCount: places.length,
itemBuilder: (context, index) {
final coordinate = places[index];
return ListTile(
horizontalTitleGap: 5,
title: Row(
children: [
const Icon(
Icons.location_on_outlined,
color: Colors.blue,
size: 20,
),
SizedBox(
width: 320,
child:Text(
coordinate['description'],
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: const TextStyle(
color: Colors.black54,
),
),)
],),onTap: ()async{
setState(() {
isShow = false;
isHidden= false;
});
final url = Uri.parse(
'https://rsapi.goong.io/geocode?address=${coordinate['description']}&api_key={YOUR_API_KEY}');
var response = await http.get(url);
final jsonResponse = jsonDecode(response.body);
details = jsonResponse['results'] as List<dynamic>;
// ignore: no_leading_underscores_for_local_identifiers
mapboxMap?.setCamera(CameraOptions(
center: Point(coordinates: Position(details[index]['geometry']['location']['lng'],details[index]['geometry']['location']['lat'])).toJson(),
zoom: 12.0));
mapboxMap?.flyTo(
CameraOptions(
anchor: ScreenCoordinate(x: 0, y: 0),
zoom: 15,
bearing: 0,
pitch: 0),
MapAnimationOptions(duration: 2000, startDelay: 0));
mapboxMap?.annotations.createCircleAnnotationManager().then((value) async {
setState(() {
_circleAnnotationManager = value; // Store the reference to the circle annotation manager
});
value.create(CircleAnnotationOptions(
geometry: Point(
coordinates: Position(
details[index]['geometry']['location']['lng'],
details[index]['geometry']['location']['lat'],
)).toJson(),
circleColor: Colors.blue.value,
circleRadius: 12.0,),
);
});
_searchController.text = coordinate['description'];
mainText = coordinate['structured_formatting']['main_text'];
secondText = coordinate['structured_formatting']['secondary_text'];
},
);},
);
}
Dẫn đường
Tìm kiếm quãng đường di chuyển giữa hai điểm một cách thuận tiện và nhanh nhất.
- Sử dụng Goong API để tìm kiếm quãng đường:
https://rsapi.goong.io/Direction?origin=$latStart,$lngStart&destination=$latEnd,$lngEnd&vehicle=bike&api_key={YOUR_API_KEY}
- Giá trị đầu vào là toạ độ điểm bắt đầu và điểm kết thúc
Tham khảo tài liệu tại đây
final url = Uri.parse(
'https://rsapi.goong.io/Direction?origin=$latStart,$lngStart&destination=$latEnd,$lngEnd&vehicle=bike&api_key={YOUR_API_KEY}');
mapboxMap?.setBounds(CameraBoundsOptions(
bounds: CoordinateBounds(
southwest: Point(
coordinates: Position(
lngStart!,
latStart!,
)).toJson(),
northeast: Point(
coordinates: Position(
lngEnd!,
latEnd!,
)).toJson(),
infiniteBounds: true),
maxZoom: 13,
minZoom: 0,
maxPitch: 10,
minPitch: 0));
var response = await http.get(url);
final jsonResponse = jsonDecode(response.body);
var route = jsonResponse['routes'][0]['overview_polyline']['points'];
duration = jsonResponse['routes'][0]['legs'][0]['duration']['text'];
distance = jsonResponse['routes'][0]['legs'][0]['distance']['text'];
List<PointLatLng> result = polylinePoints.decodePolyline(route);
List<List<double>> coordinates = result.map((point) => [point.longitude, point.latitude]).toList();
String geojson =
'''{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"name": "Crema to Council Crest"
},
"geometry": {
"type": "LineString",
"coordinates": $coordinates
}
}
]
}''';
await mapboxMap?.style.addSource(GeoJsonSource(id: "line", data: geojson));
var lineLayerJson = """{
"type":"line",
"id":"line_layer",
"source":"line",
"paint":{
"line-join":"round",
"line-cap":"round",
"line-color":"rgb(51, 51, 255)",
"line-width":9.0
}
}""";
await mapboxMap?.style.addPersistentStyleLayer(lineLayerJson, null);