Flutter地图多边形绘制及面积计算插件mapbox_draw_polygon_area的使用

发布于 1周前 作者 gougou168 来自 Flutter

Flutter 地图多边形绘制及面积计算插件 mapbox_draw_polygon_area 的使用

本 Flutter 插件允许你在 Mapbox 地图上绘制一个多边形并计算其面积。

特性

示例

该插件高度依赖于 Get 状态管理包。请从 pub.dev 安装最新的 Get 包。

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:mapbox_draw_polygon_area/src/mapbox_draw_polygon.dart' as myPacakge;
import 'package:mapbox_gl_modified/mapbox_gl_modified.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return GetMaterialApp(
      home: MapboxMapExample(),
    );
  }
}

class MapboxMapExample extends StatefulWidget {
  [@override](/user/override)
  _MapboxMapExampleState createState() => _MapboxMapExampleState();
}

class _MapboxMapExampleState extends State<MapboxMapExample> {
  var myController = Get.put(myPacakge.MapBoxGetController());

  void _onMapCreated(MapboxMapController controller) {
    myController.mapBoxcontrollerInstance = controller;
    myController.onMapCreateFun();
  }

  [@override](/user/override)
  void initState() {
    // myController = myPacakge.MapBoxGetController();
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButtonLocation: FloatingActionButtonLocation.miniCenterDocked,
      floatingActionButton: Stack(
        fit: StackFit.expand,
        children: [
          myController.drawPad(), // 抓取面板以绘制点
          myController.centerTargetiIcon(), // 中心目标图标放置在屏幕中央
        ],
      ),
      body: MapboxMap(
        styleString: MapboxStyles.LIGHT,
        accessToken: 'Mapboox public token', // 你的 Mapbox 公共令牌
        onMapCreated: _onMapCreated,
        trackCameraPosition: true,
        initialCameraPosition: const CameraPosition(
          target: LatLng(40.384950128422496, -85.56492779229464),
          zoom: 16,
        ),
        // 这是一个辅助线,将引导你完成过程
        onCameraIdle: (() {
          if (myController.listOfDrawLatLlongs.isNotEmpty && 
              !myController.isPolygonSaved.value && 
              !myController.isDiagonalSaved.value) {
            myController.drawActiveline(); // 绘制活动线
          }
        }),
      ),
    );
  }
}

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

1 回复

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


当然,以下是一个使用 mapbox_draw_polygon_area 插件在 Flutter 中绘制地图多边形并计算其面积的示例代码。这个插件结合了 Mapbox GL 和多边形绘制及面积计算功能。

首先,确保在你的 pubspec.yaml 文件中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  mapbox_gl: ^0.14.0  # 请确保版本与插件兼容
  mapbox_draw_polygon_area: ^latest_version  # 使用最新版本

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

接下来是示例代码,展示如何在 Flutter 应用中使用 mapbox_draw_polygon_area 插件绘制多边形并计算面积:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MapScreen(),
    );
  }
}

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

class _MapScreenState extends State<MapScreen> {
  MapboxMapController? _controller;
  List<LatLng> _polygonCoordinates = [];
  double? _area;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Mapbox Polygon Drawing and Area Calculation'),
      ),
      body: Stack(
        children: [
          MapboxMap(
            accessToken: 'YOUR_MAPBOX_ACCESS_TOKEN',  // 替换为你的 Mapbox 访问令牌
            initialCameraPosition: CameraPosition(
              target: LatLng(0.0, 0.0),
              zoom: 2.0,
            ),
            onMapCreated: (MapboxMapController controller) {
              _controller = controller;
            },
            myLocationEnabled: true,
            myLocationTrackingMode: MyLocationTrackingMode.FOLLOWING,
            polygons: MapboxPolygons.fromData({
              'polygon-id': PolygonOptions(
                points: _polygonCoordinates.map((e) => Point<double>(e.longitude, e.latitude)).toList(),
                geodesic: true,
                color: Colors.blue.withOpacity(0.5),
                fillColor: Colors.blueAccent.withOpacity(0.2),
                strokeWidth: 2.0,
              ),
            }),
          ),
          Positioned(
            bottom: 20,
            left: 20,
            child: FloatingActionButton(
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => DrawPolygonScreen(_controller!)),
                ).then((result) {
                  if (result is List<LatLng>) {
                    setState(() {
                      _polygonCoordinates = result;
                      _area = calculatePolygonArea(result);
                    });
                  }
                });
              },
              tooltip: 'Draw Polygon',
              child: Icon(Icons.add_location),
            ),
          ),
          if (_area != null)
            Positioned(
              bottom: 80,
              left: 20,
              child: Text(
                'Area: $_area sqm',
                style: TextStyle(fontSize: 18),
              ),
            ),
        ],
      ),
    );
  }

  double? calculatePolygonArea(List<LatLng> coordinates) {
    // 使用简单的 Shoelace formula 计算面积,注意这是二维平面的计算方式,如果考虑地球表面,需要更复杂的方法
    double area = 0.0;
    int j = coordinates.length - 1;
    for (int i = 0; i < coordinates.length; i++) {
      area += (coordinates[j].longitude + coordinates[i].longitude) *
          (coordinates[j].latitude - coordinates[i].latitude);
      j = i;
    }
    return Math.abs(area / 2.0);
  }
}

class DrawPolygonScreen extends StatefulWidget {
  final MapboxMapController controller;

  DrawPolygonScreen(this.controller);

  @override
  _DrawPolygonScreenState createState() => _DrawPolygonScreenState();
}

class _DrawPolygonScreenState extends State<DrawPolygonScreen> {
  final MapboxDrawPlugin _drawPlugin = MapboxDrawPlugin();

  @override
  void initState() {
    super.initState();
    widget.controller.addPlugin(_drawPlugin);
    _drawPlugin.addOnDrawCreatedListener((features) {
      if (features.isNotEmpty) {
        final firstFeature = features.first;
        if (firstFeature.geometry['type'] == 'Polygon') {
          final coordinates = firstFeature.geometry['coordinates'].first
              .map((coord) => LatLng(coord[1], coord[0]))
              .toList();
          Navigator.pop(context, coordinates);
        }
      }
    });
    _drawPlugin.changeMode(DrawMode.drawPolygon);
  }

  @override
  void dispose() {
    _drawPlugin.remove();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Draw Polygon'),
      ),
      body: Container(),
    );
  }
}

注意事项:

  1. Mapbox Access Token:确保你已经替换了 YOUR_MAPBOX_ACCESS_TOKEN 为你的实际 Mapbox 访问令牌。
  2. 依赖版本:确保 mapbox_glmapbox_draw_polygon_area 插件的版本是兼容的。
  3. 面积计算:示例中的面积计算使用了简单的 Shoelace formula,这种方法在二维平面上是准确的,但如果在地球表面绘制多边形,需要考虑地球的曲率,可能需要更复杂的算法。

这个示例展示了如何在 Flutter 应用中使用 mapbox_draw_polygon_area 插件绘制多边形并计算其面积。你可以根据需求进一步扩展和优化代码。

回到顶部