Flutter地图展示插件mapbox_map_gl的使用

Flutter 地图展示插件 mapbox_map_gl 的使用

简介

此 Flutter 插件允许您将 Mapbox 地图嵌入到您的 Flutter 应用程序中。此插件使用最新版本的 Mapbox 地图 SDK,因此您可以体验到所有最新功能。目前此插件仅支持 Android 平台,并基于 Mapbox 地图 SDK 版本 v10.10.0

设置

Android

您需要在应用程序中包含您的 Mapbox 地图密钥令牌和访问令牌才能使用 Mapbox 地图。

Mapbox 地图密钥令牌

将您的 Mapbox 地图密钥令牌添加到 gradle.properties 文件中。您可以在 Mapbox 账户页面上获取您的 Mapbox 地图密钥令牌。它以 sk. 开头。

MAPBOX_SECRET_TOKEN=your-mapbox-map-secret-token

同时,在项目级别的 build.gradle 文件中加入以下代码:

allprojects {
    repositories {
        google()
        mavenCentral()
        
        // 添加这一行
        maven {
            url 'https://api.mapbox.com/downloads/v2/releases/maven'
            authentication {
                basic(BasicAuthentication)
            }
            credentials {
                username = "mapbox"
                password = project.properties['MAPBOX_SECRET_TOKEN']
            }
        }
    }
}
Mapbox 地图访问令牌

将您的 Mapbox 地图访问令牌添加到 strings.xml 文件中,位于 app/src/main/res/values/ 目录下的 Android 部分。它以 pk. 开头。

<string name="mapbox_access_token">your-access-token</string>
iOS

此插件在 iOS 上尚不可用。

如何添加 MapboxMap?

您需要使用 MapboxMap() 小部件来在页面中添加地图。

MapboxMap(
  initialCameraPosition: CameraPosition(
    center: Point.fromLatLng(29.837785, 87.538961),
    zoom: 15.0,
    animationOptions: AnimationOptions.mapAnimationOptions(
      startDelay: 0,
      duration: const Duration(milliseconds: 750),
    ),
  ),
  style: MapStyle.light,
  showCurrentLocation: true,
  onMapCreated: (controller) {
    // controller - MapboxMapController 实例
  },
  onStyleLoaded: () async {
    final isAlreadyAdded =
        await _controller?.isSourceExist("my-data-source") ?? false;
    if (!isAlreadyAdded) {
      _addGeoJson();
    }
  },
  onStyleLoadError: (err) {
    if (kDebugMode) {
      print("[onStyleLoadError] ---&gt; $err");
    }
  },
  onMapClick: (point, coordinates) {},
  onMapLongClick: (point, coordinates) {},
  onFeatureClick: (details) {
    // details 包含:
    // - point (纬度和经度),
    // - coordinates (屏幕坐标 x 和 y),
    // - feature (Feature 对象),
    // - source,
    // - sourceLayer
  },
  onFeatureLongClick: (details) {},
),

如何添加样式源?

此 API 支持所有由最新版 Mapbox 地图 SDK 支持的样式源。您可以像这样添加样式源。

await _controller.addSource&lt;GeoJsonSource&gt;(
  source: GeoJsonSource(
    sourceId: "geojson-source-id",
    url: "https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_10m_land_ocean_label_points.geojson",
    sourceProperties: GeoJsonSourceProperties(
      cluster: true,
      clusterRadius: 50,
      clusterMaxZoom: 14,
      maxZoom: 20,
    ),
  ),
);

如何添加样式层?

与样式源类似,此 API 还支持所有由最新版 Mapbox 地图 SDK 支持的样式层。您可以像这样添加样式层。

// 圆形层
await _controller.addLayer&lt;CircleLayer&gt;(
  layer: CircleLayer(
    layerId: "my-layer-id",
    sourceId: "geojson-source-id",
    layerProperties: CircleLayerProperties(
      circleColor: [
        'case',
        [
          'boolean',
          ['has', 'point_count'],
          true
        ],
        'red',
        'blue'
      ],
      circleColorTransition: StyleTransition.build(
        delay: 500,
        duration: const Duration(milliseconds: 1000),
      ),
      circleRadius: [
        'case',
        [
          'boolean',
          ['has', 'point_count'],
          true
        ],
        15,
        10
      ],
      circleStrokeWidth: [
        'case',
        [
          'boolean',
          ['has', 'point_count'],
          true
        ],
        3,
        2
      ],
      circleStrokeColor: "#fff",
      circleTranslateTransition: StyleTransition.build(
        delay: 0,
        duration: const Duration(milliseconds: 1000),
      ),
    ),
  ),
);

// 符号层
await _controller.addLayer&lt;SymbolLayer&gt;(
  layer: SymbolLayer(
    layerId: "symbol-layer-example",
    sourceId: "geojson-source-id",
    layerProperties: SymbolLayerProperties(
      textField: ['get', 'point_count_abbreviated'],
      textSize: 12,
      textColor: '#fff',
      iconSize: 1,
      iconAllowOverlap: true,
    ),
  ),
);

如何添加样式图像?

您可以从您的资源文件或 URL 中添加样式图像。目前不支持 SVG 图像。

// 从资源文件添加图像
await _controller.addStyleImage&lt;LocalStyleImage&gt;(
  image: LocalStyleImage(
    imageId: "icon",
    imageName: "assets/images/your-image.png",
  ),
);

// 从 URL 添加图像
await _controller.addStyleImage&lt;NetworkStyleImage&gt;(
  image: NetworkStyleImage(
    imageId: "icon",
    url: "https://example.com/icon.png",
  ),
);

如何添加注解?

您可以添加圆形、点/符号、折线和多边形注解。

// 添加圆形注解
final id = await _controller?.addAnnotation&lt;CircleAnnotation&gt;(
  annotation: CircleAnnotation(
    annotationOptions: CircleAnnotationOptions(
      point: Point.fromLatLng(27.321, 82.323),
      circleRadius: 20.0,
      circleColor: "red",
      circleStrokeWidth: 2.0,
      circleStrokeColor: "#fff",
      data: {"id": 124, "name": "testing circle"},
      draggable: true,
    ),
  ),
);

// 添加点注解
// 您有三种选择作为要显示的图像来源
// iconUrl: 其他格式的图标 URL
// iconPath: 如果您想使用资源文件中的图像,请在此处提供路径
// iconImage: 如果您想使用通过样式图像添加的图像,请在此处提供 imageId
final id = await _controller?.addAnnotation&lt;PointAnnotation&gt;(
  annotation: PointAnnotation(
    iconUrl: "https://yourdomain.com/icons/name.png",
                或
    iconPath: "assets/icons/name.png",
                或
    iconImage: "image-Id-given-while-adding-style-image",
    annotationOptions: PointAnnotationOptions(
      point: Point.fromLatLng(27.321, 82.323),
      iconColor: "red",
      iconSize: 1.2,
      data: {"id": 124, "icon": "icon.png", "color": "#fff"},
      draggable: true,
    ),
  ),
);

// 添加折线注解
final id = await _controller?.addAnnotation&lt;PolylineAnnotation&gt;(
  annotation: PolylineAnnotation(
    annotationOptions: PolylineAnnotationOptions(
      points: [Point.fromLatLng(27.412, 82.331), Point.fromLatLng(27.432, 82.321)],
      lineColor: "red",
      lineGapWidth: 2,
      lineSortKey: 0.3,
      lineWidth: 2.0,
      data: {"id": 124, "icon": "icon.png", "color": "#fff"},
      draggable: true,
    ),
  ),
);

如何在地图上显示用户当前位置(位置小圆点)?

如果您希望在地图上显示当前定位指示器(位置小圆点),则需要在 MapboxMap() 中设置 showCurrentLocation: true

默认情况下,地图 SDK 使用 Android GPS 和网络提供商来获取原始位置更新。在使用 Android 11 的应用程序中,原始位置更新可能会遇到精度问题。为了获得准确的位置,您可以向应用的 build.gradle 添加以下依赖项:

implementation "com.google.android.gms:play-services-location:18.0.0"

并在 AndroidManifest.xml 中添加这些权限:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

支持的 Mapbox API

功能 Android iOS
样式
相机
当前位置
圆形层
折线层
填充层
符号层
栅格层
高程阴影层
热力图层
填充拉伸层
天空层
背景层
定位指示层
向量源
栅格源
栅格DEM 源
GeoJSON 源
图像源
圆形注解
点注解
折线注解
多边形注解
表达式
过渡效果

示例代码

import 'package:flutter/material.dart';
import 'package:mapbox_map_gl_example/screens/home_screen.dart';

void main() {
  runApp(const ExampleApp());
}

class ExampleApp extends StatelessWidget {
  const ExampleApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: "Mapbox Map Gl Example App",
      home: HomeScreen(),
    );
  }
}

更多关于Flutter地图展示插件mapbox_map_gl的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter地图展示插件mapbox_map_gl的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter应用中使用mapbox_gl插件来展示地图的示例代码。这个示例将展示如何初始化Mapbox地图,并在Flutter应用中显示它。

首先,你需要在你的pubspec.yaml文件中添加mapbox_gl依赖:

dependencies:
  flutter:
    sdk: flutter
  mapbox_gl: ^0.14.0  # 请检查最新版本号并替换

然后,运行flutter pub get来安装依赖。

接下来,你需要在Mapbox官网(https://www.mapbox.com/)上注册一个账户,并创建一个API访问令牌。确保你已经创建了一个Mapbox样式URL,这个URL将用于加载地图。

下面是一个完整的Flutter应用示例,展示了如何使用mapbox_gl插件:

import 'package:flutter/material.dart';
import 'package:mapbox_gl/mapbox_gl.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Mapbox GL Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MapScreen(),
    );
  }
}

class MapScreen extends StatefulWidget {
  @override
  _MapScreenState createState() => _MapScreenState();
}

class _MapScreenState extends State<MapScreen> {
  final MapboxMapController _controller = MapboxMapController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Mapbox GL Map'),
      ),
      body: MapboxMap(
        accessToken: 'YOUR_MAPBOX_ACCESS_TOKEN',  // 在这里替换为你的Mapbox访问令牌
        initialCameraPosition: CameraPosition(
          target: LatLng(40.7128, -74.0060),  // 纽约市的经纬度
          zoom: 11.0,
        ),
        onMapCreated: (MapboxMapController controller) {
          _controller.complete(controller);
        },
        styleString: '''
          {
            "version": 8,
            "name": "Bright",
            "sources": {
              "composite": {
                "type": "raster",
                "tiles": [
                  "YOUR_MAPBOX_STYLE_URL"  // 在这里替换为你的Mapbox样式URL
                ],
                "tileSize": 256
              }
            },
            "layers": [
              {
                "id": "simple-tiles",
                "type": "raster",
                "source": "composite",
                "minzoom": 0,
                "maxzoom": 22
              }
            ]
          }
        ''',
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          final CameraPosition position = await _controller.future.then((controller) {
            return controller.getCameraPosition();
          });
          print('Current camera position: ${position.target}');
        },
        tooltip: 'Get Camera Position',
        child: Icon(Icons.location_on),
      ),
    );
  }
}

注意事项:

  1. 访问令牌:确保你已经替换了YOUR_MAPBOX_ACCESS_TOKEN为你的实际Mapbox访问令牌。
  2. 样式URL:确保你已经替换了YOUR_MAPBOX_STYLE_URL为你的Mapbox样式URL。你可以在Mapbox Studio中创建和获取样式URL。
  3. 权限:如果你的应用需要在Android或iOS设备上访问位置信息,请确保在相应的AndroidManifest.xmlInfo.plist文件中添加了必要的权限声明。

这段代码将创建一个简单的Flutter应用,展示一个Mapbox地图,并允许用户通过点击浮动按钮来获取当前的相机位置。

回到顶部