机器打点逻辑 初始化
This commit is contained in:
@@ -87,9 +87,10 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
WorkStatus _workStatus = WorkStatus.idle;
|
||||
bool isStartWork = false; //是否开始作业
|
||||
|
||||
LatLng? _currentLatLng;
|
||||
LatLng? _currentLatLng; //gc格式
|
||||
LatLng? _currentWgsLatLng;
|
||||
|
||||
StreamSubscription<Position>? _positionSub;
|
||||
bool _hasMovedOnce = false;
|
||||
bool _isPanelOpen = false; // 控制面板显示/隐藏
|
||||
bool _directionBoxOpen = false; //航线面板显示/隐藏
|
||||
bool _saveBoxOpen = false; //保存按钮显示/隐藏
|
||||
@@ -111,14 +112,18 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
List<PlotPoint>? gctracePoint = [];
|
||||
|
||||
// ========== 核心新增状态 ==========
|
||||
final List<LatLng> _markedPoints = []; // 存储所有打点坐标
|
||||
final List<LatLng> _markedPoints = []; // 存储所有s十字准星打点坐标
|
||||
List<LatLng> _robotModeWgsPoints = []; // Robot模式下从设备获取的wgs打点
|
||||
List<LatLng> _robotModeObsWgsPoints = []; // Robot模式下从设备获取的wgs打点 障碍物
|
||||
|
||||
LatLng _mapCenter = const LatLng(39.9042, 116.4074);
|
||||
double _headingAngle = 0.0; // 当前机器航向角(单位:度)
|
||||
List<LatLng>? _currentTracePoints; //收到机器的点坐标
|
||||
List typedPathList = <work_area_model.DeviceAddPathPointModel>[]; // 存储生成路径的坐标列表(已转换为LatLng)
|
||||
|
||||
// ========== 障碍物模式核心状态 ==========
|
||||
List<List<LatLng>> _obstacleHoles = []; // 存储多组障碍物打点(嵌套数组:每组是一个空洞)
|
||||
|
||||
List<List<LatLng>> _obstacleWgsHoles = []; // 存储多组障碍物打点(嵌套数组:每组是一个空洞)
|
||||
List<LatLng> _currentObstaclePoints = []; // 当前正在绘制的障碍物打点
|
||||
bool _isObstacleEditing = false; // 是否处于障碍物编辑状态
|
||||
|
||||
@@ -524,69 +529,62 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
setState(() {
|
||||
// 1. 作业区域模式
|
||||
if (_currentAreaMode == AreaMode.work) {
|
||||
if (_markedPoints.isNotEmpty) {
|
||||
if (_currentRobotMode == RobotMode.robot && _robotModeWgsPoints.isNotEmpty && _markedPoints.isNotEmpty) {
|
||||
// Robot模式撤回
|
||||
_robotModeWgsPoints.removeLast();
|
||||
_markedPoints.removeLast();
|
||||
// 作业点撤回后,若路径已生成,重新生成路径(保持同步)
|
||||
if (_isWorkAreaCompleted && _markedPoints.length >= 3) {
|
||||
_generatePath(showTips: false);
|
||||
}
|
||||
ToastUtils.showInfo(context, '已撤回作业区域最后一个点,剩余${_markedPoints.length}个点');
|
||||
//ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('已撤回作业区域最后一个点,剩余${_markedPoints.length}个点')));
|
||||
ToastUtils.showInfo(context, '已撤回Robot模式最后一个点,剩余${_robotModeWgsPoints.length}个点');
|
||||
} else {
|
||||
ToastUtils.showInfo(context, '暂无作业区域点可撤回');
|
||||
//ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('暂无作业区域点可撤回')));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 空洞模式(完成后优先撤回已完成的空洞)
|
||||
// 2. 空洞模式(逻辑不变,Robot模式下障碍物打点和Point模式一致)
|
||||
if (_currentAreaMode == AreaMode.obstacle) {
|
||||
if (_currentObstaclePoints.isNotEmpty) {
|
||||
_currentObstaclePoints.removeLast();
|
||||
// 如果当前空洞的点撤空了,退出编辑状态
|
||||
_robotModeObsWgsPoints.removeLast();
|
||||
if (_currentObstaclePoints.isEmpty) {
|
||||
_isObstacleEditing = false;
|
||||
}
|
||||
ToastUtils.showInfo(context, '已撤回当前空洞最后一个点,剩余${_currentObstaclePoints.length}个点');
|
||||
|
||||
//ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('已撤回当前空洞最后1个点,剩余${_currentObstaclePoints.length}个点')));
|
||||
return; // 撤完点就结束,不执行后面的逻辑
|
||||
return;
|
||||
}
|
||||
|
||||
// 第二步:当前空洞无点可撤 → 再撤回「上一个完整空洞」
|
||||
if (_obstacleHoles.isNotEmpty) {
|
||||
_obstacleHoles.removeLast();
|
||||
// 撤完空洞后重新生成路径(排除该空洞)
|
||||
if (_isWorkAreaCompleted) {
|
||||
_generatePath(showTips: false);
|
||||
}
|
||||
ToastUtils.showInfo(context, '已撤回上一个完整空洞,剩余${_obstacleHoles.length}个空洞');
|
||||
|
||||
//ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('已撤回上一个完整空洞,剩余${_obstacleHoles.length}个空洞')));
|
||||
return;
|
||||
}
|
||||
|
||||
// 第三步:无任何可撤内容
|
||||
ToastUtils.showInfo(context, '暂无空洞可撤回');
|
||||
//ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('暂无空洞可撤回')));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 兼容原有调用(可保留,也可直接用上面的_unifiedUndo)
|
||||
void _undoLastPoint() => _undoAction();
|
||||
void _undoObstaclePoint() => _undoAction();
|
||||
|
||||
// ========== 统一删除方法(适配完成后状态) ==========
|
||||
void _deleteAllAction() {
|
||||
setState(() {
|
||||
// 1. 作业区域模式:清空作业点 + 重置路径
|
||||
if (_currentAreaMode == AreaMode.work) {
|
||||
if (_markedPoints.isEmpty) {
|
||||
ToastUtils.showInfo(context, '暂无作业区域点可删除');
|
||||
|
||||
//ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('暂无作业区域点可删除')));
|
||||
return;
|
||||
if (_currentRobotMode == RobotMode.robot) {
|
||||
_robotModeWgsPoints.clear();
|
||||
_markedPoints.clear();
|
||||
ToastUtils.showSuccess(context, '已清空所有作业点');
|
||||
} else {
|
||||
// 原有Point模式清空
|
||||
if (_markedPoints.isEmpty) {
|
||||
ToastUtils.showInfo(context, '暂无作业区域点可删除');
|
||||
return;
|
||||
}
|
||||
_markedPoints.clear();
|
||||
}
|
||||
_markedPoints.clear();
|
||||
gcjPathPoints.clear();
|
||||
@@ -606,6 +604,7 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
}
|
||||
_obstacleHoles.clear();
|
||||
_currentObstaclePoints.clear();
|
||||
_robotModeObsWgsPoints.clear();
|
||||
_isObstacleEditing = false;
|
||||
// 清空后重新生成路径(无空洞)
|
||||
if (_isWorkAreaCompleted) {
|
||||
@@ -616,10 +615,6 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
});
|
||||
}
|
||||
|
||||
// 兼容原有调用
|
||||
void _deleteAllPoints() => _deleteAllAction();
|
||||
void _clearAllObstacles() => _deleteAllAction();
|
||||
|
||||
// ========== 核心:清空所有打点和轨迹 ==========
|
||||
//void _deleteAllPoints() {
|
||||
// if (_markedPoints.isNotEmpty) {
|
||||
@@ -670,8 +665,9 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
// 清空打点和轨迹数据
|
||||
_markedPoints.clear();
|
||||
gcjPathPoints.clear();
|
||||
_robotModeWgsPoints.clear();
|
||||
_robotModeObsWgsPoints.clear();
|
||||
gcjOuterPoints.clear();
|
||||
_currentTracePoints = null;
|
||||
_isWorkAreaCompleted = false;
|
||||
_saveBoxOpen = false;
|
||||
|
||||
@@ -698,7 +694,6 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
_workDistance = 0.0;
|
||||
_angle = 0.0;
|
||||
_mapCenter = const LatLng(39.9042, 116.4074);
|
||||
_hasMovedOnce = false;
|
||||
_currentLatLng = null;
|
||||
});
|
||||
|
||||
@@ -741,29 +736,13 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
}
|
||||
}
|
||||
|
||||
/// ===============================
|
||||
/// 更新位置
|
||||
/// ===============================
|
||||
void _updateLocation(LatLng latLng, {bool moveMap = false}) {
|
||||
setState(() {
|
||||
_currentLatLng = latLng;
|
||||
});
|
||||
|
||||
if (moveMap) {
|
||||
//_hasMovedOnce = true;
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_hasMovedOnce = true;
|
||||
_mapController.move(latLng, 17);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// 手动回到当前位置
|
||||
void _moveToCurrentLocation() {
|
||||
if (_currentLatLng == null) return;
|
||||
_mapController.move(_currentLatLng!, 17);
|
||||
}
|
||||
|
||||
// ========== 障碍物模式:完成当前障碍物绘制 ==========
|
||||
// ========== 障碍物模式:完成当前障碍物绘制 ==========
|
||||
void _completeObstacle() {
|
||||
if (_currentObstaclePoints.length < 3) {
|
||||
@@ -772,13 +751,20 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_obstacleHoles.add(List.from(_currentObstaclePoints)); // 保存当前障碍物组
|
||||
// 保存当前障碍物组(Robot模式下直接用WGS84坐标)
|
||||
if (_currentRobotMode == RobotMode.robot && _robotModeObsWgsPoints.isNotEmpty) {
|
||||
final gcjPoints = _robotModeObsWgsPoints.map((wgs) => wgs84ToGcj02(wgs.latitude, wgs.longitude)).toList();
|
||||
_obstacleHoles.add(gcjPoints);
|
||||
_obstacleWgsHoles.add(List.from(_robotModeObsWgsPoints));
|
||||
} else {
|
||||
_obstacleHoles.add(List.from(_currentObstaclePoints));
|
||||
}
|
||||
_currentObstaclePoints.clear(); // 清空当前绘制的障碍物点
|
||||
_robotModeObsWgsPoints.clear(); // 清空Robot模式下的障碍物WGS84坐标
|
||||
_isObstacleEditing = false; // 退出编辑状态
|
||||
});
|
||||
|
||||
debugPrint('完成障碍物绘制,当前障碍物组数:${_obstacleHoles.length}');
|
||||
|
||||
ToastUtils.showSuccess(context, '已添加第${_obstacleHoles.length}个障碍物区域');
|
||||
}
|
||||
|
||||
@@ -813,14 +799,34 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
if (_currentAreaMode == AreaMode.work) {
|
||||
_markedPoints.add(_mapCenter);
|
||||
debugPrint('新增作业区域打点:第${_markedPoints.length}个点,经纬度:${_mapCenter.latitude}, ${_mapCenter.longitude}');
|
||||
if (_currentRobotMode == RobotMode.point) {
|
||||
if (_currentAreaMode == AreaMode.work) {
|
||||
_markedPoints.add(_mapCenter);
|
||||
debugPrint('新增作业区域打点:第${_markedPoints.length}个点,经纬度:${_mapCenter.latitude}, ${_mapCenter.longitude}');
|
||||
} else {
|
||||
// 障碍物模式:添加到当前障碍物打点
|
||||
_currentObstaclePoints.add(_mapCenter);
|
||||
_isObstacleEditing = true; // 标记进入障碍物编辑状态
|
||||
debugPrint('新增障碍物打点:第${_currentObstaclePoints.length}个点,经纬度:${_mapCenter.latitude}, ${_mapCenter.longitude}');
|
||||
}
|
||||
} else {
|
||||
// 障碍物模式:添加到当前障碍物打点
|
||||
_currentObstaclePoints.add(_mapCenter);
|
||||
_isObstacleEditing = true; // 标记进入障碍物编辑状态
|
||||
debugPrint('新增障碍物打点:第${_currentObstaclePoints.length}个点,经纬度:${_mapCenter.latitude}, ${_mapCenter.longitude}');
|
||||
if (_currentLatLng == null || !_isValidLatLng(_currentLatLng!.latitude, _currentLatLng!.longitude)) {
|
||||
ToastUtils.showError(context, '设备坐标无效,无法添加打点!');
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Robot模式-作业区域打点
|
||||
if (_currentAreaMode == AreaMode.work) {
|
||||
_markedPoints.add(_currentLatLng!); // 从设备实时坐标取最后一个值
|
||||
_robotModeWgsPoints.add(_currentWgsLatLng!);
|
||||
debugPrint('Robot模式新增作业打点:第${_markedPoints.length}个点,经纬度:${_currentLatLng!.latitude}, ${_currentLatLng!.longitude}');
|
||||
} else {
|
||||
// 3. Robot模式-障碍物打点
|
||||
_currentObstaclePoints.add(_currentLatLng!);
|
||||
_robotModeObsWgsPoints.add(_currentWgsLatLng!);
|
||||
_isObstacleEditing = true;
|
||||
debugPrint('Robot模式新增障碍物打点:第${_currentObstaclePoints.length}个点,经纬度:${_currentLatLng!.latitude}, ${_currentLatLng!.longitude}');
|
||||
}
|
||||
}
|
||||
});
|
||||
debugPrint('$_markedPoints,新增打点:第${_markedPoints.length}个点,经纬度:${_mapCenter.latitude.toStringAsFixed(20)}, ${_mapCenter.longitude.toStringAsFixed(20)}');
|
||||
@@ -899,7 +905,6 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
setState(() {
|
||||
gcjPathPoints = [];
|
||||
gcjOuterPoints = [];
|
||||
_currentTracePoints = null;
|
||||
});
|
||||
|
||||
await context.read<DevicesCubit>().loadSelectedPath(plot.plotName);
|
||||
@@ -1180,6 +1185,7 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
'120.81992468426961', // 经度
|
||||
'32.04532826114155',
|
||||
);
|
||||
_currentWgsLatLng = LatLng(lat, lng);
|
||||
|
||||
_currentLatLng = gcjPoint; // ✅ 状态变量在setState内更新
|
||||
return FlutterMap(
|
||||
@@ -1300,18 +1306,6 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
}).toList(),
|
||||
),
|
||||
//开始作业之后
|
||||
if (gctracePoint!.isNotEmpty && isStartWork)
|
||||
PolylineLayer(
|
||||
polylines: [
|
||||
for (int i = 0; i < gctracePoint!.length - 1; i++)
|
||||
Polyline(
|
||||
points: [gctracePoint![i], gctracePoint![i + 1]],
|
||||
color: Colors.white,
|
||||
strokeWidth: 1.5,
|
||||
isDotted: true, // 虚线区分作业区域
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// 2. 正在绘制的障碍物打点连线(红色虚线)
|
||||
if (_isObstacleEditing && _currentObstaclePoints.isNotEmpty)
|
||||
@@ -1429,6 +1423,18 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
if (gctracePoint!.isNotEmpty && isStartWork)
|
||||
PolylineLayer(
|
||||
polylines: [
|
||||
for (int i = 0; i < gctracePoint!.length - 1; i++)
|
||||
Polyline(
|
||||
points: [gctracePoint![i], gctracePoint![i + 1]],
|
||||
color: Colors.white,
|
||||
strokeWidth: 1.5,
|
||||
isDotted: true, // 虚线区分作业区域
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -1778,14 +1784,13 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
gcjOuterPoints = List.from(_markedPoints);
|
||||
typedPathList = []; // 路径列表置空
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 校验必要条件
|
||||
if (_currentAreaMode == AreaMode.work && _markedPoints.isEmpty) {
|
||||
if (showTips) {
|
||||
ToastUtils.showError(context, '请先添加作业区域打点!');
|
||||
//ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('请先添加作业区域打点!'), backgroundColor: Colors.red));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1798,54 +1803,97 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
if (_currentWorkMode == null) {
|
||||
if (showTips) {
|
||||
ToastUtils.showError(context, '请先选择作业模式!');
|
||||
//ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('请先选择作业模式!'), backgroundColor: Colors.red));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 2. 转换页面数据为 generatePath 所需的参数格式
|
||||
// 2.1 参考点(取作业区域第一个打点)
|
||||
final firstPoint = _markedPoints.first;
|
||||
final wgs84FirstPoint = gcj02ToWgs84(firstPoint.latitude, firstPoint.longitude);
|
||||
final referencePoint = work_area_model.ReferencePoint(lat: wgs84FirstPoint.latitude, lon: wgs84FirstPoint.longitude);
|
||||
// 2.1 参考点(区分Robot/Point模式)
|
||||
LatLng firstPointWgs; // 最终传给接口的WGS84格式参考点
|
||||
if (_currentRobotMode == RobotMode.robot && _robotModeWgsPoints.isNotEmpty) {
|
||||
// Robot模式:直接使用原始WGS84坐标(无需转换)
|
||||
firstPointWgs = _robotModeWgsPoints.first;
|
||||
} else {
|
||||
// Point模式:先取十字准星的GCJ02坐标 → 转换为WGS84
|
||||
if (_markedPoints.isEmpty) return;
|
||||
LatLng firstPointGcj = _markedPoints.first;
|
||||
firstPointWgs = gcj02ToWgs84(firstPointGcj.latitude, firstPointGcj.longitude);
|
||||
}
|
||||
// 参考点使用转换后的WGS84坐标
|
||||
final referencePoint = work_area_model.ReferencePoint(lat: firstPointWgs.latitude, lon: firstPointWgs.longitude);
|
||||
|
||||
// 2.2 航向角
|
||||
final heading = _angle == -1 ? -1 : _angle.toInt();
|
||||
|
||||
// 2.3 外边界(作业区域)
|
||||
final outerBoundary = work_area_model.OuterBoundary(
|
||||
position: _markedPoints.map((latLng) {
|
||||
// 2.3 外边界(作业区域)- 核心区分Robot/Point模式
|
||||
List<work_area_model.Position> outerPositions = [];
|
||||
if (_currentRobotMode == RobotMode.robot && _robotModeWgsPoints.isNotEmpty) {
|
||||
// Robot模式:直接使用原始WGS84坐标,跳过GCJ02→WGS84转换
|
||||
outerPositions = _robotModeWgsPoints.map((latLng) {
|
||||
return work_area_model.Position(lat: latLng.latitude, lon: latLng.longitude);
|
||||
}).toList();
|
||||
} else {
|
||||
// Point模式:十字准星的GCJ02坐标 → 转换为WGS84
|
||||
outerPositions = _markedPoints.map((latLng) {
|
||||
final wgs84Point = gcj02ToWgs84(latLng.latitude, latLng.longitude);
|
||||
return work_area_model.Position(lat: wgs84Point.latitude, lon: wgs84Point.longitude);
|
||||
}).toList(),
|
||||
sideWidth: _workDistance,
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
final outerBoundary = work_area_model.OuterBoundary(position: outerPositions, sideWidth: _workDistance);
|
||||
|
||||
// 2.4 障碍物处理(同样区分Robot/Point模式)
|
||||
work_area_model.HoleBoundary? holeBoundary;
|
||||
|
||||
if (_obstacleHoles.isNotEmpty) {
|
||||
// 1. 构造二维 Position 数组
|
||||
List<List<work_area_model.Position>> positionList = [];
|
||||
|
||||
for (var holePoints in _obstacleHoles) {
|
||||
List<work_area_model.Position> innerPositionList = holePoints.map((latLng) {
|
||||
final wgs84Point = gcj02ToWgs84(latLng.latitude, latLng.longitude);
|
||||
return work_area_model.Position(lat: wgs84Point.latitude, lon: wgs84Point.longitude);
|
||||
}).toList();
|
||||
if (_currentRobotMode == RobotMode.robot && _robotModeObsWgsPoints.isNotEmpty) {
|
||||
for (var holePoints in _obstacleWgsHoles) {
|
||||
List<work_area_model.Position> innerPositionList = [];
|
||||
|
||||
positionList.add(innerPositionList);
|
||||
innerPositionList = holePoints.map((latLng) {
|
||||
return work_area_model.Position(lat: latLng.latitude, lon: latLng.longitude);
|
||||
}).toList();
|
||||
positionList.add(innerPositionList);
|
||||
}
|
||||
} else {
|
||||
for (var holePoints in _obstacleHoles) {
|
||||
List<work_area_model.Position> innerPositionList = [];
|
||||
|
||||
// Point模式:GCJ02→WGS84转换
|
||||
innerPositionList = holePoints.map((latLng) {
|
||||
final wgs84Point = gcj02ToWgs84(latLng.latitude, latLng.longitude);
|
||||
return work_area_model.Position(lat: wgs84Point.latitude, lon: wgs84Point.longitude);
|
||||
}).toList();
|
||||
positionList.add(innerPositionList);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 创建 HoleBoundary 对象(无外层 Map)
|
||||
for (var holePoints in _obstacleHoles) {
|
||||
List<work_area_model.Position> innerPositionList = [];
|
||||
|
||||
if (_currentRobotMode == RobotMode.robot && _robotModeObsWgsPoints.isNotEmpty) {
|
||||
// Robot模式:使用障碍物原始WGS84坐标
|
||||
innerPositionList = holePoints.map((latLng) {
|
||||
return work_area_model.Position(lat: latLng.latitude, lon: latLng.longitude);
|
||||
}).toList();
|
||||
} else {
|
||||
// Point模式:GCJ02→WGS84转换
|
||||
innerPositionList = holePoints.map((latLng) {
|
||||
final wgs84Point = gcj02ToWgs84(latLng.latitude, latLng.longitude);
|
||||
return work_area_model.Position(lat: wgs84Point.latitude, lon: wgs84Point.longitude);
|
||||
}).toList();
|
||||
}
|
||||
positionList.add(innerPositionList);
|
||||
}
|
||||
holeBoundary = work_area_model.HoleBoundary(position: positionList, sideWidth: 0.0);
|
||||
}
|
||||
|
||||
// 🔥 第二步:构造符合方法参数要求的 Map<String, HoleBoundary>
|
||||
// 用一个临时 Map 来满足类型要求,后续在 Cubit 中取值即可
|
||||
Map<String, work_area_model.HoleBoundary> holes = {};
|
||||
if (holeBoundary != null) {
|
||||
holes = {'tempKey': holeBoundary}; // 键名任意,仅为满足类型要求
|
||||
holes = {'tempKey': holeBoundary};
|
||||
}
|
||||
final workType = _currentWorkMode == WorkMode.bow ? 0 : 2;
|
||||
|
||||
@@ -1854,7 +1902,7 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
reference: referencePoint,
|
||||
heading: heading,
|
||||
outer: outerBoundary,
|
||||
holes: holes.isNotEmpty ? holes : {}, // 无障碍物时传空对象
|
||||
holes: holes.isNotEmpty ? holes : {},
|
||||
workType: workType,
|
||||
);
|
||||
|
||||
@@ -1865,7 +1913,6 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
if (cubitState.errorMessage != null) {
|
||||
if (showTips) {
|
||||
ToastUtils.showError(context, '路径生成失败:${cubitState.errorMessage}');
|
||||
//ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('路径生成失败:${cubitState.errorMessage}'), backgroundColor: Colors.red));
|
||||
}
|
||||
} else if (cubitState.generatedPath != null) {
|
||||
if (showTips) {
|
||||
@@ -1880,8 +1927,8 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
final pathList = cubitState.generatedPath as List;
|
||||
typedPathList = pathList.whereType<work_area_model.DeviceAddPathPointModel>().toList();
|
||||
debugPrint('✅ 过滤并转换后的路径点列表:typedPathList 长度=${typedPathList.length}');
|
||||
//打印
|
||||
|
||||
// 路径点转换为GCJ02(无论哪种模式,最终地图显示都需要GCJ02)
|
||||
gcjPathPoints = typedPathList.map((point) {
|
||||
double wgs84Lat = point.latitude;
|
||||
double wgs84Lon = point.longitude;
|
||||
@@ -1889,8 +1936,8 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
return LatLng(gcjPoint.latitude, gcjPoint.longitude);
|
||||
}).toList();
|
||||
|
||||
// 外边界保持原有逻辑
|
||||
gcjOuterPoints = List.from(_markedPoints);
|
||||
//_markedPoints.clear();
|
||||
});
|
||||
moveMapToPointsCenter(gcjPathPoints);
|
||||
}
|
||||
@@ -1899,7 +1946,6 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
debugPrint('路径生成异常:$e');
|
||||
if (showTips) {
|
||||
ToastUtils.showError(context, '路径生成异常:${e.toString().substring(0, 50)}');
|
||||
//ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('路径生成异常:${e.toString().substring(0, 50)}'), backgroundColor: Colors.red));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1912,13 +1958,12 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
final userState = context.watch<AppUserCubit>().state;
|
||||
final deviceId = context.watch<DevicesCubit>().state.selectedDevice?.deviceName;
|
||||
|
||||
if (deviceId != null && userState.user?.token != null) {
|
||||
if (deviceId != null && userState.user != null && userState.user!.token != null) {
|
||||
_videoStreamUrl = "webrtc://${TCPConsts.TCP_IP}/live/livestream/$deviceId?token=${userState.user!.token}";
|
||||
} else {
|
||||
_videoStreamUrl = ''; // 无设备/用户信息时置空
|
||||
_videoStreamUrl = '';
|
||||
print("设备未选中或用户未登录,无法生成视频流地址");
|
||||
}
|
||||
|
||||
return BlocBuilder<DeviceStatusBloc, DeviceStatusState>(
|
||||
builder: (context, state) {
|
||||
// 初始化默认值
|
||||
|
||||
Reference in New Issue
Block a user