Flutter地图渲染插件mapbox_gl_modified的使用
Flutter 地图渲染插件 mapbox_gl_modified 的使用
简介
此 Flutter 插件允许在 Flutter 小部件中嵌入交互式且可自定义的矢量地图。对于 Android 和 iOS 集成,我们使用了 mapbox-gl-native。对于 Web,我们依赖于 mapbox-gl-js。本项目仅支持这些库所暴露 API 的子集。
设置
此包可以在 pub.dev 上找到。
通过运行以下命令将其添加到你的项目中:
flutter pub add mapbox_gl
移动端
秘密 Mapbox 访问令牌
为了使底层 Mapbox SDK 能够下载,需要一个具有 Downloads: Read
作用域的秘密访问令牌。更多信息可在 Mapbox 文档中找到:
如果未正确配置令牌,则构建过程会失败并出现以下错误(分别为 Android 和 iOS):
* What went wrong:
A problem occurred evaluating project ':mapbox_gl'.
> SDK Registry token is null. See README.md for more information.
[!] Error installing Mapbox-iOS-SDK
curl: (22) The requested URL returned error: 401 Unauthorized
Web
在 <head>
中包含 JavaScript 和 CSS 文件:
<script src='https://api.mapbox.com/mapbox-gl-js/v2.8.2/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v2.8.2/mapbox-gl.css' rel='stylesheet' />
<style>
.mapboxgl-map {
position: relative;
width: 100%;
height: 100%;
}
</style>
注意:请查看最新的版本在 Mapbox GL JS 文档。
所有平台
公共 Mapbox 访问令牌
需要为 MapboxMap 小部件提供公共访问令牌以检索样式和资源。虽然你可以直接将令牌硬编码到源文件中,但最好从外部源(如配置文件或环境变量)获取访问令牌。示例应用使用以下技术:
通过命令行参数传递访问令牌:
flutter build <platform> --dart-define ACCESS_TOKEN=YOUR_TOKEN_HERE
或运行应用程序时:
flutter run --dart-define ACCESS_TOKEN=YOUR_TOKEN_HERE
然后在 Dart 中获取它:
MapboxMap(
...
accessToken: const String.fromEnvironment("ACCESS_TOKEN"),
...
)
支持的 API
特性 | Android | iOS | Web |
---|---|---|---|
样式 | ✅ | ✅ | ✅ |
相机 | ✅ | ✅ | ✅ |
手势 | ✅ | ✅ | ✅ |
用户位置 | ✅ | ✅ | ✅ |
样式 DSL | ❌ | ❌ | ❌ |
栅格层 | ✅ | ✅ | ✅ |
符号层 | ✅ | ✅ | ✅ |
圆形层 | ✅ | ✅ | ✅ |
线条层 | ✅ | ✅ | ✅ |
填充层 | ✅ | ✅ | ✅ |
填充拉伸层 | ✅ | ✅ | ✅ |
高光层 | ✅ | ✅ | ✅ |
热力图层 | ✅ | ✅ | ✅ |
向量源 | ✅ | ✅ | ✅ |
栅格源 | ✅ | ✅ | ✅ |
GeoJSON 源 | ✅ | ✅ | ✅ |
图像源 | ✅ | ✅ | ✅ |
表达式 | ✅ | ✅ | ✅ |
符号注解 | ✅ | ✅ | ✅ |
圆形注解 | ✅ | ✅ | ✅ |
线条注解 | ✅ | ✅ | ✅ |
填充注解 | ✅ | ✅ | ✅ |
地图样式
可以通过在 MapOptions
中设置 styleString
来提供地图样式。支持以下格式:
- 传递地图样式的 URL。这可以是内置的地图样式,也可以是使用 URL 开头为 ‘http(s)://’ 或 ‘mapbox://’ 远程服务的地图样式。
- 作为本地资源传递样式。在
assets
文件夹中创建一个 JSON 文件,并在pubspec.yml
中添加引用。设置样式字符串为该资产的相对路径,以便将其加载到地图中。 - 作为本地文件传递样式。在应用程序目录中创建一个 JSON 文件(例如 ApplicationDocumentsDirectory)。设置样式字符串为该 JSON 文件的绝对路径。
- 传递原始地图样式的 JSON。这仅在 Android 上受支持。
离线地图侧载
通过侧载所需的地图瓦片并将它们包括在你的 assets
文件夹中,支持离线地图。
- 按照 此处 提供的指南创建你的瓦片包。
- 将第一步生成的
tiles.db
文件放置在你的 assets 目录中,并在pubspec.yml
文件中添加引用。
assets:
- assets/cache.db
- 在应用程序启动时调用
installOfflineMapTiles
方法,以将你的瓦片复制到 Mapbox 可以访问的位置。注意:此方法应在加载 Map 小部件之前调用,以防止在复制文件时发生冲突。
try {
await installOfflineMapTiles(join("assets", "cache.db"));
} catch (err) {
print(err);
}
下载离线区域
离线区域是一个定义的地图区域,在有限或无网络连接的情况下可供使用。使用适当的 SDK 方法从 Mapbox 下载选定区域、样式和精度的瓦片,并存储在应用程序的缓存中。
- 注意选择大区域可能会导致显著的大小。这里有一个在线估算器 https://docs.mapbox.com/playground/offline-estimator/。
- 使用预定义的
OfflineRegion
调用downloadOfflineRegionStream
并在回调函数中可选地跟踪进度。
final Function(DownloadRegionStatus event) onEvent = (DownloadRegionStatus status) {
if (status.runtimeType == Success) {
// ...
} else if (status.runtimeType == InProgress) {
int progress = (status as InProgress).progress.round();
// ...
} else if (status.runtimeType == Error) {
// ...
}
};
final OfflineRegion offlineRegion = OfflineRegion(
bounds: LatLngBounds(
northeast: LatLng(52.5050648, 13.3915634),
southwest: LatLng(52.4943073, 13.4055383),
),
id: 1,
minZoom: 6,
maxZoom: 18,
mapStyleUrl: 'mapbox://styles/mapbox/streets-v11',
);
downloadOfflineRegionStream(offlineRegion, onEvent);
创建静态地图快照
snapshotManager
生成地图的静态栅格图像。每个快照图像由你提供的 SnapshotOptions
对象定义的地图部分组成。
调用 takeSnapshot
方法与预定义的 SnapshotOptions
。
final renderBox = mapKey.currentContext?.findRenderObject() as RenderBox;
final snapshotOptions = SnapshotOptions(
width: renderBox.size.width,
height: renderBox.size.height,
writeToDisk: true,
withLogo: false,
);
final uri = await mapController?.takeSnapshot(snapshotOptions);
定位功能
Android
在 <application>/android/app/src/main/AndroidManifest.xml
中添加 <code><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /></code>
或 <code><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /></code>
以启用 Android 应用程序中的定位功能。
从 Android API 级别 23 开始,还需要在运行时请求权限。此插件不会为你处理这一点。示例应用使用 flutter 的 'location' 插件
来处理这个问题。
iOS
要在 iOS 应用程序中启用定位功能:
如果你访问用户的位置,还应向 ios/Runner/Info.plist
添加以下键来解释为什么你需要访问他们的位置数据:
<key>NSLocationWhenInUseUsageDescription</key>
<string>[Your explanation here]</string>
更多关于Flutter地图渲染插件mapbox_gl_modified的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter地图渲染插件mapbox_gl_modified的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
mapbox_gl_modified
是一个基于 Mapbox 的 Flutter 地图渲染插件,它允许开发者在 Flutter 应用中集成 Mapbox 地图,并支持自定义地图样式、添加标记、绘制路径等功能。这个插件是对 mapbox_gl
插件的修改版本,可能修复了一些问题或添加了一些额外功能。
1. 安装插件
首先,你需要在 pubspec.yaml
文件中添加 mapbox_gl_modified
插件的依赖:
dependencies:
flutter:
sdk: flutter
mapbox_gl_modified: ^0.0.1 # 使用最新版本
然后运行 flutter pub get
来安装插件。
2. 获取 Mapbox 访问令牌
在使用 Mapbox 地图之前,你需要一个 Mapbox 访问令牌。你可以在 Mapbox 官网 注册并获取一个访问令牌。
3. 配置 Mapbox 访问令牌
在你的 Flutter 项目中,你需要在 Android
和 iOS
项目中配置 Mapbox 访问令牌。
Android 配置
在 android/app/src/main/AndroidManifest.xml
文件中添加以下代码:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.yourapp">
<application>
<meta-data
android:name="com.mapbox.token"
android:value="YOUR_MAPBOX_ACCESS_TOKEN" />
...
</application>
</manifest>
iOS 配置
在 ios/Runner/Info.plist
文件中添加以下代码:
<key>MGLMapboxAccessToken</key>
<string>YOUR_MAPBOX_ACCESS_TOKEN</string>
4. 使用 mapbox_gl_modified
插件
基本地图显示
import 'package:flutter/material.dart';
import 'package:mapbox_gl_modified/mapbox_gl_modified.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MapboxMapExample(),
);
}
}
class MapboxMapExample extends StatefulWidget {
@override
_MapboxMapExampleState createState() => _MapboxMapExampleState();
}
class _MapboxMapExampleState extends State<MapboxMapExample> {
MapboxMapController? mapController;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Mapbox GL Modified Example')),
body: MapboxMap(
accessToken: 'YOUR_MAPBOX_ACCESS_TOKEN',
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: LatLng(37.7749, -122.4194), // 旧金山坐标
zoom: 12.0,
),
),
);
}
void _onMapCreated(MapboxMapController controller) {
setState(() {
mapController = controller;
});
}
}
添加标记
void _addMarker() async {
if (mapController != null) {
await mapController!.addMarker(
MarkerOptions(
geometry: LatLng(37.7749, -122.4194), // 旧金山坐标
iconImage: 'assets/icon.png', // 标记图标
),
);
}
}
绘制路径
void _drawPolyline() async {
if (mapController != null) {
await mapController!.addPolyline(
PolylineOptions(
geometry: [
LatLng(37.7749, -122.4194), // 起点
LatLng(34.0522, -118.2437), // 终点
],
color: '#FF0000', // 路径颜色
width: 5.0, // 路径宽度
),
);
}
}
5. 处理地图事件
你可以监听地图的各种事件,例如点击、拖动等。
void _onMapCreated(MapboxMapController controller) {
setState(() {
mapController = controller;
});
controller.onMapClick.listen((point) {
print('Map clicked at: ${point.latitude}, ${point.longitude}');
});
}
6. 自定义地图样式
你可以使用 Mapbox Studio 创建自定义地图样式,并在 MapboxMap
组件中指定样式 URL。
MapboxMap(
accessToken: 'YOUR_MAPBOX_ACCESS_TOKEN',
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: LatLng(37.7749, -122.4194), // 旧金山坐标
zoom: 12.0,
),
styleString: 'mapbox://styles/mapbox/streets-v11', // 自定义样式 URL
);