Flutter for OpenHarmony:maps_toolkit 地理空间计算工具箱,无需地图 SDK 也能玩转 GIS(距离、面积、点线关系) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:maps_toolkit 地理空间计算工具箱,无需地图 SDK 也能玩转 GIS(距离、面积、点线关系) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net

在这里插入图片描述

前言

在地图应用开发中,我们经常需要计算两个坐标点之间的距离(如打车预估)、判断一个点是否在围栏内(电子围栏)、或者计算多边形的面积(地块测量)。虽然 Google Maps 或百度地图 SDK 提供了这些功能,但它们体积庞大且依赖原生/网络。

maps_toolkit 是 Google Maps Android Utility Library 的纯 Dart 移植版。它包含了一系列轻量级、高性能的几何与球面计算算法,完全不依赖任何地图 SDK,即可进行复杂的 GIS 运算。

一、概念介绍/原理解析

1.1 基础概念

  • LatLng: 经纬度坐标 (latitude, longitude)。
  • SphericalUtil (球面工具): 计算大圆距离 (Haversine)、方位角、插值点。
  • PolygonUtil (多边形工具): 判断点在多边形内/外、是否在线段附近、面积计算。

计算距离 (球面曲率)

计算方位角

包含性判定

计算面积

坐标点 A

坐标点 B

多边形区域

坐标点 P

输出结果 (平方米)

1.2 进阶概念

地球不是完美的球体,maps_toolkit 默认采用 WGS84 椭球模型进行近似计算,精度足以满足绝大多数民用场景。

二、核心 API/组件详解

2.1 基础用法

计算两点距离。

import'package:maps_toolkit/maps_toolkit.dart';voidmain(){final p1 =LatLng(39.9042,116.4074);// 北京final p2 =LatLng(31.2304,121.4737);// 上海// 计算直线(大圆)距离,单位:米final distance =SphericalUtil.computeDistanceBetween(p1, p2);print('距离: ${(distance /1000).toStringAsFixed(2)} km');// ~1067 km}
在这里插入图片描述

2.2 电子围栏判定

判断用户位置是否在指定区域内。

bool checkGeofence(LatLng user,List<LatLng> polygon){// geodesic: true 表示考虑地球曲率(更精确),false 视为平面returnPolygonUtil.containsLocation(user, polygon,true);}
在这里插入图片描述

2.3 面积计算

double area =SphericalUtil.computeArea(polygonPoints);print('面积: $area 平方米');
在这里插入图片描述

三、常见应用场景

3.1 场景 1:打卡签到

判断员工 GPS 坐标是否在公司大楼圆心 100 米范围内。

bool canCheckIn(LatLng userPos,LatLng officePos){// 计算两点间距离(单位:米)final distance =SphericalUtil.computeDistanceBetween(userPos, officePos);return distance <=100;// 100米内允许打卡}

3.2 场景 2:共享单车禁停区

判断停车点是否位于红色的多边形禁停区内。

bool isForbiddenParking(LatLng bikePos){// 定义禁停区域(多边形顶点)final forbiddenZone =[LatLng(39.90,116.30),LatLng(39.91,116.30),LatLng(39.91,116.31),LatLng(39.90,116.31),];// true 表示测地线模式(考虑地球曲率)returnPolygonUtil.containsLocation(bikePos, forbiddenZone,true);}

3.3 场景 3:运动轨迹平滑

收到一系列稀疏的 GPS 点,利用插值算法(Interpolate)补充中间点,使路线更平滑。

List<LatLng>smoothPath(LatLng start,LatLng end){List<LatLng> path =[];// 在起点和终点之间插值 10 个点for(double f =0; f <=1.0; f +=0.1){ path.add(SphericalUtil.computeOffset(start,0,0));// 注意:maps_toolkit 的插值通常用 interpolate// 修正:使用 interpolate 方法 path.add(SphericalUtil.interpolate(start, end, f));}return path;}

四、OpenHarmony 平台适配

4.1 纯 Dart 实现

完全无原生依赖。

4.2 坐标系转换

国内地图常通过 GCJ-02 (火星坐标) 或 BD-09 (百度坐标) 加密。maps_toolkit 基于标准 WGS-84。如果输入源是高德/百度,务必先转换为 WGS-84,否则计算偏差可能达数百米。虽然库本身未内置转换,但社区有很多 Dart 实现。

五、完整示例代码

本示例构建一个简单的地理工具箱,包含距离计算器和围栏检测器。

import'package:flutter/material.dart';import'package:maps_toolkit/maps_toolkit.dart';voidmain(){runApp(constMaterialApp(home:GeometryPage()));}classGeometryPageextendsStatefulWidget{constGeometryPage({super.key});@overrideState<GeometryPage>createState()=>_GeometryPageState();}class _GeometryPageState extendsState<GeometryPage>{// 模拟故宫多边形围栏 (简化版)finalList<LatLng> _forbiddenZone =[LatLng(39.9221,116.3908),// 西北LatLng(39.9221,116.4025),// 东北LatLng(39.9130,116.4025),// 东南LatLng(39.9130,116.3908),// 西南];final _userPos =LatLng(39.9160,116.3970);// 在故宫内final _testDistPos =LatLng(39.9087,116.3975);// 天安门广场 (南侧)String _status ='';String _distanceInfo ='';@overridevoidinitState(){super.initState();_check();}void_check(){// 1. 围栏检测 bool inside =PolygonUtil.containsLocation(_userPos, _forbiddenZone,true);// 2. 距离计算 num dist =SphericalUtil.computeDistanceBetween(_userPos, _testDistPos);setState((){ _status = inside ?'⚠️ 在禁飞区内 (故宫)':'✅ 安全区域'; _distanceInfo ='距天安门广场: ${dist.toStringAsFixed(1)} 米';});}@overrideWidgetbuild(BuildContext context){returnScaffold( appBar:AppBar(title:constText('GIS 工具箱')), body:Center( child:Column( mainAxisAlignment:MainAxisAlignment.center, children:[constIcon(Icons.map, size:80, color:Colors.blue),constSizedBox(height:20),Text('当前位置: ${_userPos.latitude}, ${_userPos.longitude}'),constSizedBox(height:10),Container( padding:constEdgeInsets.all(16), color: _status.contains('⚠️')?Colors.red[100]:Colors.green[100], child:Text(_status, style:constTextStyle(fontSize:20, fontWeight:FontWeight.bold)),),constSizedBox(height:20),Text(_distanceInfo),constSizedBox(height:40),Text('围栏面积: ${SphericalUtil.computeArea(_forbiddenZone).toStringAsFixed(0)} m²', style:constTextStyle(color:Colors.grey),),],),),);}}
在这里插入图片描述

六、总结

maps_toolkit 剥离了地图 SDK 中最通用的数学部分。如果你的应用只需后台判断位置关系而不需要展示地图(如地理围栏服务),它是最佳选择。

最佳实践

  1. 坐标系:始终明确你使用的坐标系(WGS84 vs GCJ02)。
  2. 精度:对于小范围(如室内),平面几何计算可能比球面计算更快且误差可忽略;但跨城市必须用球面计算。
  3. 多边形简化:围栏点数过多会影响性能,可用道格拉斯-普克算法(Douglas-Peucker)简化轨迹。

Read more

【OpenClaw从入门到精通】第10篇:OpenClaw生产环境部署全攻略:性能优化+安全加固+监控运维(2026实测版)

【OpenClaw从入门到精通】第10篇:OpenClaw生产环境部署全攻略:性能优化+安全加固+监控运维(2026实测版)

摘要:本文聚焦OpenClaw从测试环境走向生产环境的核心痛点,围绕“性能优化、安全加固、监控运维”三大维度展开实操讲解。先明确生产环境硬件/系统选型标准,再通过硬件层资源管控、模型调度策略、缓存优化等手段提升响应速度(实测响应效率提升50%+);接着从网络、权限、数据三层构建安全防护体系,集成火山引擎安全方案拦截高危操作;最后落地TenacitOS可视化监控与Prometheus告警体系,配套完整故障排查清单和虚拟实战案例。全文所有配置、代码均经实测验证,兼顾新手入门实操性和进阶读者的生产级部署需求,帮助开发者真正实现OpenClaw从“能用”到“放心用”的跨越。 优质专栏欢迎订阅! 【DeepSeek深度应用】【Python高阶开发:AI自动化与数据工程实战】【YOLOv11工业级实战】 【机器视觉:C# + HALCON】【大模型微调实战:平民级微调技术全解】 【人工智能之深度学习】【AI 赋能:Python 人工智能应用实战】【数字孪生与仿真技术实战指南】 【AI工程化落地与YOLOv8/v9实战】【C#工业上位机高级应用:高并发通信+性能优化】 【Java生产级避坑指南:

By Ne0inhk
ARM Linux 驱动开发篇--- Linux 并发与竞争实验(互斥体实现 LED 设备互斥访问)--- Ubuntu20.04互斥体实验

ARM Linux 驱动开发篇--- Linux 并发与竞争实验(互斥体实现 LED 设备互斥访问)--- Ubuntu20.04互斥体实验

🎬 渡水无言:个人主页渡水无言 ❄专栏传送门: 《linux专栏》《嵌入式linux驱动开发》《linux系统移植专栏》 ❄专栏传送门: 《freertos专栏》《STM32 HAL库专栏》 ⭐️流水不争先,争的是滔滔不绝  📚博主简介:第二十届中国研究生电子设计竞赛全国二等奖 |国家奖学金 | 省级三好学生 | 省级优秀毕业生获得者 | ZEEKLOG新星杯TOP18 | 半导纵横专栏博主 | 211在读研究生 在这里主要分享自己学习的linux嵌入式领域知识;有分享错误或者不足的地方欢迎大佬指导,也欢迎各位大佬互相三连 目录 前言  一、实验基础说明 1.1、互斥体简介 1.2 本次实验设计思路 二、硬件原理分析(看过之前博客的可以忽略) 三、实验程序编写 3.1 互斥体 LED 驱动代码(mutex.c) 3.2.1、设备结构体定义(28-39

By Ne0inhk
Flutter for OpenHarmony:swagger_dart_code_generator 接口代码自动化生成的救星(OpenAPI/Swagger) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:swagger_dart_code_generator 接口代码自动化生成的救星(OpenAPI/Swagger) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 后端工程师扔给你一个 Swagger (OpenAPI) 文档地址,你会怎么做? 1. 对着文档,手写 Dart Model 类(容易写错字段类型)。 2. 手写 Retrofit/Dio 的 API 接口定义(容易拼错 URL)。 3. 当后端修改了字段名,你对着报错修半天。 这是重复劳动的地狱。 swagger_dart_code_generator 可以将 Swagger (JSON/YAML) 文件直接转换为高质量的 Dart 代码,包括: * Model 类:支持 json_serializable,带 fromJson/

By Ne0inhk
Linux 开发别再卡壳!makefile/git/gdb 全流程实操 + 作业解析,新手看完直接用----《Hello Linux!》(5)

Linux 开发别再卡壳!makefile/git/gdb 全流程实操 + 作业解析,新手看完直接用----《Hello Linux!》(5)

文章目录 * 前言 * make/makefile * 文件的三个时间 * Linux第一个小程序-进度条 * 回车和换行 * 缓冲区 * 程序的代码展示 * git指令 * 关于gitee * Linux调试器-gdb使用 * 作业部分 前言 做 Linux 开发时,你是不是也遇到过这些 “卡脖子” 时刻?写 makefile 时,明明语法没错却报错,最后发现是依赖方法行没加 Tab;想提交代码到 gitee,记不清 git add/commit/push 的 “三板斧”,还得反复搜教程;用 gdb 调试程序,输了命令没反应,才想起编译时没加-g生成 debug 版本;甚至连写个进度条,都搞不懂\r和\n的区别,导致进度条乱跳…… 其实这些问题,

By Ne0inhk