地图打点

This commit is contained in:
mmc
2026-02-25 20:09:18 +08:00
parent 07a653fca5
commit 4d3872b576

View File

@@ -30,31 +30,21 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
AreaMode _currentAreaMode = AreaMode.work; //作业区域还是障碍物区域
WorkMode? _currentWorkMode = WorkMode.bow; // 当前作业模式
// ========== 新增:打点相关状态 ==========
List<LatLng> _markedPoints = []; // 存储所有打点的坐标
int _pointIndex = 1; // 打点序号(用于标记显示)
void _addMapMarker() {
// 1. 获取当前地图中心的坐标
LatLng centerLatLng = _mapController.center;
// 2. 记录打点坐标(带序号)
setState(() {
_markedPoints.add(centerLatLng);
});
// 3. 打印打点信息(调试用)
debugPrint(
'第$_pointIndex个点:纬度=${centerLatLng.latitude.toStringAsFixed(6)},经度=${centerLatLng.longitude.toStringAsFixed(6)}',
);
// 4. 序号自增
_pointIndex++;
}
// ========== 核心新增状态 ==========
List<LatLng> _markedPoints = []; // 存储所有打点坐标
LatLng get _mapCenter => _mapController.center; // 实时获取地图中心坐标
// =================================
@override
void initState() {
super.initState();
_initLocationEnterprise();
// 监听地图移动事件,实时更新连线
_mapController.mapEventStream.listen((event) {
if (event is MapEventMove || event is MapEventMoveEnd) {
setState(() {}); // 触发UI刷新,更新连线
}
});
}
/// ===============================
@@ -114,6 +104,16 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
_mapController.move(_currentLatLng!, 17);
}
// ========== 核心方法:打点逻辑 ==========
void _addMarkedPoint() {
setState(() {
_markedPoints.add(_mapCenter); // 在地图中心打点
});
debugPrint(
'新增打点:第${_markedPoints.length}个点,经纬度:${_mapCenter.latitude.toStringAsFixed(6)}, ${_mapCenter.longitude.toStringAsFixed(6)}',
);
}
@override
void dispose() {
_positionSub?.cancel();
@@ -129,6 +129,7 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
body: SafeArea(
child: Stack(
children: [
// 地图核心组件
FlutterMap(
mapController: _mapController,
options: MapOptions(
@@ -136,6 +137,8 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
_currentLatLng ?? const LatLng(39.9042, 116.4074),
initialZoom: 15,
maxZoom: 18,
// 禁止地图点击事件(避免和中心标冲突)
onTap: (_, __) {}, // 空实现,禁用地图点击响应
),
children: [
/// 高德瓦片(GCJ-02)
@@ -146,14 +149,30 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
'&key=bbb1f0f20eed6bf679eddf2625630aba',
),
/// ========== 新增:中心标与历史打点的虚线连线 ==========
if (_markedPoints.isNotEmpty)
PolylineLayer(
polylines: [
for (var point in _markedPoints)
Polyline(
points: [_mapCenter, point], // 中心标 ↔ 历史打点
color: Colors.orange.withOpacity(
0.5,
), // 降低透明度,模拟虚线视觉效果
strokeWidth: 1.5, // 调细一点,更接近虚线
// 去掉 dashArray,直接用实线
),
],
),
/// 当前定位 Marker
if (_currentLatLng != null)
MarkerLayer(
markers: [
Marker(
point: _currentLatLng!,
width: 40,
height: 40,
width: 20,
height: 20,
child: const Icon(
Icons.my_location,
color: Colors.blue,
@@ -162,76 +181,128 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
),
],
),
/// ========== 新增:历史打点的绿色标记 ==========
MarkerLayer(
markers: _markedPoints.asMap().entries.map((entry) {
int index = entry.key + 1; // 打点序号(从1开始)
LatLng point = entry.value;
return Marker(
point: point,
width: 80,
height: 40,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// 绿色打点标记
Container(
width: 16,
height: 16,
decoration: const BoxDecoration(
color: Color(0xFF00C853), // 绿色主题色
shape: BoxShape.circle,
boxShadow: [
BoxShadow(color: Colors.black12, blurRadius: 2),
],
),
child: Center(
child: Text(
'$index',
style: const TextStyle(
color: Colors.white,
fontSize: 10,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
);
}).toList(),
),
],
),
/// ========== 核心:地图正中心固定定位标 ==========
const Positioned(
left: 0,
right: 0,
top: 0,
bottom: 0,
child: Center(
child: Icon(
Icons.location_pin, // 定位标图标
color: Colors.red, // 红色醒目
size: 30,
shadows: [BoxShadow(color: Colors.white, blurRadius: 2)],
),
),
),
// 右侧悬浮菜单
Positioned(
height: 336,
right: 16,
top: maxTop > 10 ? 11 : maxTop, // 确保不超出屏幕范围
top: maxTop > 10 ? 11 : maxTop,
child: FloatingActionButton(
onPressed: _moveToCurrentLocation,
child: new VerticalFloatMenu(
onEditTap: (bool isOpen) {
// 关键:接收子组件的回调,修改外部的_isPanelOpen
setState(() {
_isPanelOpen = isOpen;
});
},
onWorkModeSelected: (mode) {
// 接收作业模式选择结果
_currentWorkMode = mode;
debugPrint('外部收到作业模式:$mode');
},
),
),
),
// 底部操作面板
if (_isPanelOpen)
Positioned(
left: 0,
right: 0,
bottom: 0,
child: BottomOperationPanel(
// 传入初始值
initialRobotMode: RobotMode.point,
initialAreaMode: AreaMode.work,
// 接收面板的事件回调
onComplete: () {
// 完成按钮点击:关闭面板
setState(() => _isPanelOpen = false);
},
onRobotModeChanged: (mode) {
// 接收机器人模式变更
setState(() => _currentRobotMode = mode);
debugPrint('外部收到机器人模式:$mode');
},
onAreaModeChanged: (mode) {
// 接收作业区域模式变更
setState(() => _currentAreaMode = mode);
debugPrint('外部收到区域模式:$mode');
},
// ========== 绑定加号打点事件 ==========
onAddTap: () {
// 加号按钮自定义逻辑
_addMapMarker();
debugPrint('外部处理加号按钮点击');
_addMarkedPoint(); // 点击加号打点
debugPrint('外部处理加号按钮点击,已添加打点');
},
onSettingTap: () {
// 设置按钮自定义逻辑
debugPrint('外部处理设置按钮点击');
setState(() {
_directionBoxOpen = true;
});
debugPrint('外部处理设置按钮点击');
},
onLandTap: () {
// 地块标签自定义逻辑
debugPrint('外部处理地块标签点击');
},
onRouteTap: () {
// 航线标签自定义逻辑
debugPrint('外部处理航线标签点击');
},
),
),
// 航线方向面板
if (_directionBoxOpen)
Positioned(
left: 0,
@@ -241,14 +312,12 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
initialOptimalHeading: true,
initialDirection: 0.0,
onConfirm: (result) {
// 处理确认结果
debugPrint(
'最优航向:${result['optimalHeading']},角度:${result['direction']}',
);
setState(() => _directionBoxOpen = false);
},
onCancel: () {
// 关闭面板
setState(() => _directionBoxOpen = false);
},
),
@@ -263,7 +332,6 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
/// =======================================================
/// 坐标转换:WGS84 -> GCJ02(国内高德/腾讯通用)
/// =======================================================
const double _pi = 3.14159265358979324;
const double _a = 6378245.0;
const double _ee = 0.00669342162296594323;