地图打点
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user