From a29b81be20a122c51076170d94b055472240b48c Mon Sep 17 00:00:00 2001 From: mmc <1556375442@qq.com> Date: Mon, 2 Mar 2026 15:32:17 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=9D=E5=AD=98=E6=8C=89=E9=92=AE=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E9=80=BB=E8=BE=91=20=20=20=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=20=E5=8D=81=E5=AD=97=E5=87=86=E6=98=9F?= =?UTF-8?q?=E7=9A=84=E6=89=93=E7=82=B9=20=E3=80=81=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=E5=92=8C=20=E7=82=B9=E5=87=BB=E5=90=8E=E7=9A=84=E6=98=BE?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../widgets/map/testmap_pages.dart | 79 +++++++++++++------ .../presentation/widgets/startpoint_area.dart | 29 ++++--- 2 files changed, 72 insertions(+), 36 deletions(-) diff --git a/lib/features/home/presentation/widgets/map/testmap_pages.dart b/lib/features/home/presentation/widgets/map/testmap_pages.dart index ab25d8e5..11a8ade8 100644 --- a/lib/features/home/presentation/widgets/map/testmap_pages.dart +++ b/lib/features/home/presentation/widgets/map/testmap_pages.dart @@ -78,14 +78,14 @@ class _MapPageEnterpriseState extends State { bool _hasMovedOnce = false; bool _isPanelOpen = false; // 控制面板显示/隐藏 bool _directionBoxOpen = false; //航线面板显示/隐藏 - final bool _saveBoxOpen = true; //保存按钮显示/隐藏 + bool _saveBoxOpen = false; //保存按钮显示/隐藏 bool _isListBoxOpen = false; //列表面板显示/隐藏 // 新增:存储选中的地块(null表示未选中) PlotData? _selectedPlot; PlotDataPath? _selectedPlotPath; // 存储选中地块的路径数据(可选) // 新增:控制底部作业面板显示 bool _isWorkPanelOpen = false; - + bool _isWorkAreaCompleted = false; RobotMode _currentRobotMode = RobotMode.point; //打点模式 AreaMode _currentAreaMode = AreaMode.work; //作业区域还是障碍物区域 WorkMode? _currentWorkMode = WorkMode.bow; // 当前作业模式 @@ -333,18 +333,19 @@ class _MapPageEnterpriseState extends State { final Map savePath = { //'img': imgBase64 ?? '', // 截图的 Base64 字符串 'name': plotName, // 地块名称 - 'path': jsonEncode( - typedPathList - .map( - (point) => { - // 路径点数组 - 'lon': point.longitude, - 'lat': point.latitude, - }, - ) - .toList(), - ), - + 'path': _currentWorkMode == WorkMode.custom + ? jsonEncode([]) // 自定义模式 path 为空数组 + : jsonEncode( + typedPathList + .map( + (point) => { + // 路径点数组 + 'lon': point.longitude, + 'lat': point.latitude, + }, + ) + .toList(), + ), 'outer': jsonEncode( gcjOuterPoints.map((point) { final wgs84 = gcj02ToWgs84(point.latitude, point.longitude); @@ -433,6 +434,7 @@ class _MapPageEnterpriseState extends State { gcjOuterPoints.clear(); // 清空外边界 _isPanelOpen = false; // 关闭操作面板 + _isWorkAreaCompleted = false; // 重置作业区域完成状态 }); ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('地块「$plotName」保存成功!'), backgroundColor: Colors.green)); @@ -530,6 +532,8 @@ class _MapPageEnterpriseState extends State { gcjPathPoints.clear(); gcjOuterPoints.clear(); _currentTracePoints = null; + _isWorkAreaCompleted = false; + _saveBoxOpen = false; // 重置面板状态 _isPanelOpen = false; @@ -878,6 +882,7 @@ class _MapPageEnterpriseState extends State { setState(() { gcjPathPoints = newPathPoints; gcjOuterPoints = newOuterPoints; + if (_currentWorkMode == WorkMode.custom) gcjPathPoints = newOuterPoints; // 自定义模式不显示路径 _selectedPlot = plot; _isListBoxOpen = false; _isWorkPanelOpen = true; @@ -1297,6 +1302,17 @@ class _MapPageEnterpriseState extends State { // ========== 抽象:生成路径的核心函数 ========== Future _generatePath({bool showTips = true}) async { + if (_currentWorkMode == WorkMode.custom) { + setState(() { + _saveBoxOpen = true; // 显示保存按钮 + _isWorkAreaCompleted = true; // 标记为完成,允许保存 + gcjPathPoints = List.from(_markedPoints); // outer直接使用打点坐标 + gcjOuterPoints = List.from(_markedPoints); + typedPathList = []; // 路径列表置空 + }); + + return; + } // 1. 校验必要条件 if (_currentAreaMode == AreaMode.work && _markedPoints.isEmpty) { if (showTips) { @@ -1391,6 +1407,8 @@ class _MapPageEnterpriseState extends State { if (cubitState.generatedPath is List) { setState(() { + _isWorkAreaCompleted = true; + _saveBoxOpen = true; final pathList = cubitState.generatedPath as List; typedPathList = pathList.whereType().toList(); debugPrint('✅ 过滤并转换后的路径点列表:typedPathList 长度=${typedPathList.length}'); @@ -1462,7 +1480,7 @@ class _MapPageEnterpriseState extends State { ), // 绘制outer边框(Polygon模式) - if (gcjOuterPoints.isNotEmpty) + if (gcjOuterPoints.isNotEmpty && _currentWorkMode == WorkMode.bow) PolygonLayer( polygons: [ Polygon( @@ -1474,15 +1492,29 @@ class _MapPageEnterpriseState extends State { ), ], ), + if (gcjPathPoints.isNotEmpty && _currentWorkMode == WorkMode.custom) + PolylineLayer( + polylines: [ + Polyline( + points: gcjPathPoints, // 转换后的GCJ02坐标 + color: Colors.green, // 内部填充色(透明) + strokeWidth: 3.0, // 折线宽度 + isDotted: false, // 非虚线(Line模式) + borderColor: Colors.white, // 可选:添加白色描边,提升辨识度 + borderStrokeWidth: 0.5, + ), + ], + ), /// 中心标与历史打点的虚线连线 - PolylineLayer( - polylines: [ - for (int i = 0; i < _markedPoints.length - 1; i++) - Polyline(points: [_markedPoints[i], _markedPoints[i + 1]], color: Colors.orange.withOpacity(0.5), strokeWidth: 1.5), - ], - ), - if (_markedPoints.isNotEmpty) + if (!_isWorkAreaCompleted) + PolylineLayer( + polylines: [ + for (int i = 0; i < _markedPoints.length - 1; i++) + Polyline(points: [_markedPoints[i], _markedPoints[i + 1]], color: Colors.orange.withOpacity(0.5), strokeWidth: 1.5), + ], + ), + if (_markedPoints.isNotEmpty && !_isWorkAreaCompleted) PolylineLayer( polylines: [ Polyline(points: [_mapCenter, _markedPoints.last], color: Colors.blue.withOpacity(0.5), strokeWidth: 1.5), @@ -1504,7 +1536,7 @@ class _MapPageEnterpriseState extends State { ), ], ), - if (_currentWorkMode == WorkMode.bow && _markedPoints.isNotEmpty) + if (_currentWorkMode == WorkMode.bow && _markedPoints.isNotEmpty && !_isWorkAreaCompleted) PolygonLayer( polygons: [ Polygon( @@ -1784,6 +1816,7 @@ class _MapPageEnterpriseState extends State { child: BottomOperationPanel( initialRobotMode: RobotMode.point, initialAreaMode: AreaMode.work, + initialWorkMode: _currentWorkMode!, onComplete: () async { debugPrint( '操作完成回调:当前机器人模式=$_currentRobotMode,当前区域模式=$_currentAreaMode,当前作业模式:$_currentWorkMode,作业区域点:$_markedPoints,作业行距=$_workDistance,航线方向角=$_angle', diff --git a/lib/features/home/presentation/widgets/startpoint_area.dart b/lib/features/home/presentation/widgets/startpoint_area.dart index 9095cf0f..0f590fa8 100644 --- a/lib/features/home/presentation/widgets/startpoint_area.dart +++ b/lib/features/home/presentation/widgets/startpoint_area.dart @@ -9,6 +9,7 @@ class BottomOperationPanel extends StatefulWidget { final AreaMode initialAreaMode; // 新增:外部控制初始选中的标签(默认地块) final String initialSelectedTab; + final WorkMode initialWorkMode; // 回调函数:向外部传递事件 final VoidCallback onComplete; // 完成按钮点击回调 final ValueChanged? onRobotModeChanged; // 机器人模式变更回调 @@ -29,6 +30,7 @@ class BottomOperationPanel extends StatefulWidget { this.initialRobotMode = RobotMode.point, this.initialAreaMode = AreaMode.work, this.initialSelectedTab = '地块', // 默认选中地块 + this.initialWorkMode = WorkMode.bow, required this.onComplete, // 完成按钮必须传 this.onRobotModeChanged, this.onAreaModeChanged, @@ -166,19 +168,20 @@ class _BottomOperationPanelState extends State { child: const Icon(Icons.add, color: Colors.white, size: 32), ), ), - DropdownButton( - value: _areaMode, - items: const [ - DropdownMenuItem(value: AreaMode.work, child: Text("作业区域")), - DropdownMenuItem(value: AreaMode.obstacle, child: Text("障碍区域")), - ], - onChanged: (v) { - if (v != null) { - setState(() => _areaMode = v); - widget.onAreaModeChanged?.call(v); - } - }, - ), + if (widget.initialWorkMode == WorkMode.bow) + DropdownButton( + value: _areaMode, + items: const [ + DropdownMenuItem(value: AreaMode.work, child: Text("作业区域")), + DropdownMenuItem(value: AreaMode.obstacle, child: Text("障碍区域")), + ], + onChanged: (v) { + if (v != null) { + setState(() => _areaMode = v); + widget.onAreaModeChanged?.call(v); + } + }, + ), ], ), const SizedBox(height: 16),