Flutter地图绘制插件mapbox_maps_flutter_draw的使用

Flutter 地图绘制插件 mapbox_maps_flutter_draw 的使用

简介

mapbox_maps_flutter_draw 是一个 Flutter 包,用于在 Mapbox 地图上绘制、编辑和删除点、线和多边形。该包通过 mapbox_maps_flutter 库实现,帮助创建和管理交互式的标注。

特性

  • 绘制几何图形:可以在地图上添加点、线和多边形。
  • 删除几何图形:可以移除已存在的几何图形。
  • 撤销上次编辑:可以撤销最后的编辑操作。
  • 管理几何图形:可以存储和检索多个几何图形。

示例图

开始使用

要在项目中使用此包,请将 mapbox_maps_flutter_draw 及其依赖项添加到 pubspec.yaml 文件中:

dependencies:
  mapbox_maps_flutter: ^<最新版本>
  mapbox_maps_flutter_draw:
  provider:

使用示例

请查看 示例项目 获取完整的示例代码。

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart';
import 'package:mapbox_maps_flutter_draw/mapbox_maps_flutter_draw.dart';
import 'package:provider/provider.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (_) => MapboxDrawController(),
        ),
      ],
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
          useMaterial3: true,
        ),
        home: const MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late MapboxDrawController _mapboxDrawController;

  [@override](/user/override)
  Widget build(BuildContext context) {
    _mapboxDrawController = Provider.of<MapboxDrawController>(context);

    MapboxOptions.setAccessToken("YOUR_MAPBOX_ACCESS_TOKEN");

    return Scaffold(
      appBar: AppBar(
        title: const Text('Mapbox Draw'),
      ),
      body: Stack(
        children: [
          MapWidget(
            styleUri: MapboxStyles.STANDARD,
            cameraOptions: CameraOptions(
              center: Point(
                coordinates: Position(9.738585205431917, 50.54399019335429),
              ),
              zoom: 3.0,
            ),
            onMapCreated: (mapInstance) async {
              void onChangeHandler(GeometryChangeEvent event) {
                print(event);
              }

              final geometryStyles = GeometryStyles(
                  lineStyle: GeometryStyle(
                color: Colors.red,
                width: 4,
                opacity: 0.8,
              ));

              await _mapboxDrawController.initialize(mapInstance,
                  onChange: onChangeHandler, styles: geometryStyles);

              final pointStrings = [
                '{"type":"Point","coordinates":[6.570985857967685,55.90719196736157]}',
              ];

              _mapboxDrawController.addPoints(
                pointStrings.map((e) => Point.fromJson(jsonDecode(e))).toList(),
              );

              final lineString = [
                '{"type":"LineString","coordinates": [[5.064497149207369,54.4540017101983],[3.813159322052627,53.370235277869114]]}',
              ];

              _mapboxDrawController.addLines(
                lineString
                    .map((e) => LineString.fromJson(jsonDecode(e)))
                    .toList(),
              );

              final polygonString = [
                '{"type":"Polygon","coordinates":[[[2.4126939197327033,48.854917603709794],[16.345373363928786,48.19160560896381],[4.302329069480351,50.799690739582275]]]}',
              ];

              _mapboxDrawController.addPolygons(
                polygonString
                    .map((e) => Polygon.fromJson(jsonDecode(e)))
                    .toList(),
              );
            },
          ),
          // 绘制动作按钮
          Positioned(
            right: 8,
            top: 64,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.end,
              children: [
                IconButton.filled(
                  icon: const Icon(Icons.undo),
                  onPressed: () => _mapboxDrawController.undoLastAction(),
                ),
                IconButton.filled(
                  icon: const Icon(Icons.radio_button_checked),
                  onPressed: () => _mapboxDrawController.toggleEditing(EditingMode.DRAW_POINT),
                ),
                IconButton.filled(
                  icon: const Icon(Icons.timeline),
                  onPressed: () => _mapboxDrawController.toggleEditing(EditingMode.DRAW_LINE),
                ),
                IconButton.filled(
                  icon: const Icon(Icons.crop_square_outlined),
                  onPressed: () => _mapboxDrawController.toggleEditing(EditingMode.DRAW_POLYGON),
                ),
                IconButton.filled(
                  icon: const Icon(Icons.delete),
                  onPressed: () => _mapboxDrawController.toggleDeleteMode(),
                ),
              ],
            ),
          ),
          // 保存按钮
          Positioned(
            left: 8,
            top: 64,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                IconButton.filled(
                  icon: const Icon(Icons.save),
                  onPressed: () {
                    final points = _mapboxDrawController.getAllPoints();
                    final lines = _mapboxDrawController.getAllLines();
                    final polygons = _mapboxDrawController.getAllPolygons();

                    // 显示功能计数对话框
                    showDialog(
                      context: context,
                      builder: (context) {
                        return AlertDialog(
                          title: const Text('Saved Features'),
                          content: Column(
                            mainAxisSize: MainAxisSize.min,
                            children: [
                              Text('Points: ${points.length}'),
                              Text('Lines: ${lines.length}'),
                              Text('Polygons: ${polygons.length}'),
                            ],
                          ),
                          actions: [
                            TextButton(
                              onPressed: () => Navigator.of(context).pop(),
                              child: const Text('OK'),
                            ),
                          ],
                        );
                      },
                    );
                  },
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

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

1 回复

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


当然,以下是如何在Flutter应用中使用mapbox_maps_flutter_draw插件来绘制地图上的形状的代码示例。这个插件允许用户在Mapbox地图上绘制多边形、折线、点等形状。

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

dependencies:
  flutter:
    sdk: flutter
  mapbox_maps_flutter: ^x.y.z  # 请替换为最新版本号
  mapbox_maps_flutter_draw: ^a.b.c  # 请替换为最新版本号

然后运行flutter pub get来安装这些依赖项。

接下来,在你的Flutter应用中,你可以按照以下步骤设置和使用mapbox_maps_flutter_draw插件:

  1. 初始化Mapbox和Draw插件
import 'package:flutter/material.dart';
import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart';
import 'package:mapbox_maps_flutter_draw/mapbox_maps_flutter_draw.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Mapbox Draw Example'),
        ),
        body: MapboxDrawExample(),
      ),
    );
  }
}

class MapboxDrawExample extends StatefulWidget {
  @override
  _MapboxDrawExampleState createState() => _MapboxDrawExampleState();
}

class _MapboxDrawExampleState extends State<MapboxDrawExample> {
  late MapboxMapController _controller;
  late DrawController _drawController;

  @override
  Widget build(BuildContext context) {
    return MapboxMap(
      accessToken: 'YOUR_MAPBOX_ACCESS_TOKEN', // 请替换为你的Mapbox访问令牌
      initialCameraPosition: CameraPosition(
        target: LatLng(0.0, 0.0),
        zoom: 2.0,
      ),
      myLocationEnabled: true,
      mapboxMapOptions: MapboxMapOptions(
        styleFromMapbox: 'mapbox://styles/mapbox/streets-v11',
      ),
      onMapCreated: (controller) {
        _controller = controller;
        _initDrawController();
      },
    );
  }

  void _initDrawController() {
    _drawController = DrawController(_controller);
    _drawController.addDrawModes([
      DrawMode.polygon,
      DrawMode.polyline,
      DrawMode.point,
    ]);

    // 添加形状创建完成监听器
    _drawController.onDrawCreated.listen((event) {
      print('Shape created: ${event.geometry}');
    });

    // 激活绘制模式
    _drawController.changeMode(DrawMode.polygon);
  }
}
  1. android/app/src/main/AndroidManifest.xml中添加必要的权限(如果需要定位功能):
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  1. 处理Mapbox访问令牌:确保你已经从Mapbox官网获取了访问令牌,并替换代码中的YOUR_MAPBOX_ACCESS_TOKEN

这个示例展示了如何初始化Mapbox地图,并启用绘制功能。用户可以在地图上绘制多边形、折线和点。当形状创建完成时,会打印出创建的几何形状。

注意:在实际应用中,你可能需要处理更多的状态管理和UI交互,比如切换绘制模式、清除绘制形状等。你可以参考mapbox_maps_flutter_draw的官方文档和示例代码来获取更多高级用法。

回到顶部