//字体 import 'package:bottom_picker/resources/arrays.dart'; import 'package:cpnav/controllers/gnss_Controller.dart'; import 'package:cpnav/pages/aim_point/aimPointer.dart'; import 'package:cpnav/pages/aim_point/aimpoint_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/scheduler.dart'; import 'package:flutter/widgets.dart'; import 'package:get/get.dart'; import 'package:scence_map/controllers/controller.dart'; import 'package:scence_map/record_entity.dart'; import 'package:scence_map/scence_map.dart'; import 'package:syncfusion_flutter_sliders/sliders.dart'; import 'iconContainer.dart'; import "controller.dart"; // import '../login_in/connect/bluetooth_page.dart'; // import '../login_in/connect/config.dart'; // import '../login_in/connect/connect_type.dart'; // import '../login_in/getx/blue_tooth.dart'; // import '../setting/antenna_setting.dart'; // import '../setting/person_details.dart'; // import '../setting/wifi_page.dart'; // import '../setting/xy_change.dart'; ScenceMapController mapcontroller = Get.put(ScenceMapController()); class PassTrack extends StatefulWidget { final String date; final controller; const PassTrack({super.key, required this.date, this.controller}); @override State createState() => _PasstrackState(); } class _PasstrackState extends State { final GlobalKey> _popupMenuKey = GlobalKey>(); final controller = Get.put(PassTrackController("TEST", "pile_cm")); final sightcontroller = Get.find(); String str = "播放"; int sWidth = 0; int bits = -1; int speed = 50; List speedList = [1, 2, 10, 20, 50, 100, 200, 500]; int maxLength = 200; SfRangeValues _rangevalues = const SfRangeValues(0.0, 200.0); @override initState() { super.initState(); SchedulerBinding.instance.addPostFrameCallback((_) async { // sWidth = sqrt(screen.width * screen.width + screen.height * screen.height) // .ceil(); // // scenceMapController.scale = passTrackPlugin.passTrack_getScale() * 1.0; // fileHandle.date = widget.date; // await fileHandle.init(); // //在帧绘制完成后执行数据渲染 // // await initPlatformState(); // if (fileHandle.pointData.isNotEmpty) { // DecodeDataObj obj = fileHandle.pointData[0].obj!; // scenceMapController.centerXY = Offset(obj.y / 20, obj.x / 20); // } // for (var item in fileHandle.deviceList) { // if (item["point"] != null) { // bits = item["bits"]; // break; // } // } // // passTrackPlugin.map_setCenterDevice(bits); // setState(() { // if (fileHandle.pointData.isNotEmpty) { // maxLength = fileHandle.pointData.length; // // _value = maxLength; // _rangevalues = SfRangeValues(0.0, maxLength.toDouble()); // } // }); }); } Future initPlatformState() async { // String platformVersion; // try { // platformVersion = await passTrackPlugin.getPlatformVersion() ?? // 'Unknown platform version'; // } on PlatformException { // platformVersion = 'Failed to get platform version.'; // } // await passTrackPlugin.create(sWidth, sWidth); // fileHandle.textureId = await passTrackPlugin.getTextureId() ?? -1; // print("textureId: ${fileHandle.textureId}"); // if (!mounted) return; // setState(() { // platformVersion = platformVersion; // }); } @override Widget build(BuildContext context) { final size = MediaQuery.of(context).size; var isPortrait = MediaQuery.of(context).orientation == Orientation.portrait; return OrientationBuilder(builder: (context, orientation) { return Stack( children: [ ScenceMapView( children: [], onUpdate: (Offset center, double scale, double rotation) { print("center:$center scale:$scale rotation:$rotation"); }, forGroundPainter: BorderPainter(controller), onUpdatePilePoint: (RecordEntity? selectedPilePoint, double scale, double rotation) { print( "selectedPilePoint:$selectedPilePoint scale:$scale rotation:$rotation"); controller.selectedPilePoint = selectedPilePoint; sightcontroller.selectedPilePoint = selectedPilePoint; }, ), Positioned( width: isPortrait ? size.width * .63 : size.width * .41, left: isPortrait ? 190 : 200, bottom: 30, child: Container( padding: const EdgeInsets.only(bottom: 5), child: SfRangeSlider( min: 0.0, max: maxLength, values: _rangevalues, showTicks: false, showLabels: false, enableTooltip: true, minorTicksPerInterval: 1, stepSize: 1, onChanged: (SfRangeValues values) { setState(() { _rangevalues = SfRangeValues(values.start.roundToDouble(), values.end.roundToDouble()); }); }, ), ), ), Positioned( left: isPortrait ? 190 : 200, bottom: 0, child: Row( children: [ const SizedBox(width: 18), SizedBox( width: 74, child: ElevatedButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all( str == "播放" ? Colors.blue : Colors.red, ), ), onPressed: () { setState(() { str = str == "播放" ? "暂停" : "播放"; }); }, child: Text( str, style: const TextStyle(fontSize: 12, color: Colors.black), ), ), ), const SizedBox(width: 5), GestureDetector( onTap: () { // 触发 PopupMenuButton 的点击事件 final dynamic state = _popupMenuKey.currentState; state.showButtonMenu(); }, child: Container( width: 70, height: 35, padding: const EdgeInsets.symmetric(horizontal: 6.0), decoration: BoxDecoration( color: const Color.fromARGB(255, 255, 255, 255), border: Border.all(color: Colors.black), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Text( "$speed X", style: const TextStyle( fontSize: 11, color: Colors.black), ), Container( width: 25, child: PopupMenuButton( key: _popupMenuKey, padding: const EdgeInsets.all(1.0), icon: const Icon(Icons.arrow_drop_up, color: Color.fromARGB(255, 47, 48, 47)), onSelected: (int value) { setState(() { speed = value; }); }, // style: ButtonStyle( // minimumSize: MaterialStateProperty.all( // Size(48, 48)), // 设置最小点击区域 // tapTargetSize: MaterialTapTargetSize // .shrinkWrap, // 设置点击区域大小 // ), itemBuilder: (BuildContext context) { return speedList.map((int speed) { return PopupMenuItem( height: 30, value: speed, child: Text("$speed X速度"), ); }).toList(); }, ), ), ], )), ), const SizedBox(width: 12), Column( children: [ const Text("此处遍数:0"), StreamBuilder( stream: Stream.periodic( const Duration(seconds: 1), (_) => DateTime.now()), builder: (context, snapshot) { if (snapshot.hasData) { final dateTime = snapshot.data!.toLocal(); final formattedDate = "${dateTime.year % 100}-${dateTime.month.toString().padLeft(2, '0')}-${dateTime.day.toString().padLeft(2, '0')}"; final formattedTime = "${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}:${dateTime.second.toString().padLeft(2, '0')}"; return Text( "$formattedDate $formattedTime", style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ); } else { return const Text( "加载中...", style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold), ); } }, ), ], ) ], ), ), IconContainer(), SightGview(), // CustomPaint( // painter: BorderPainter(controller), // ), ], ); }); } } // 自定义的 BorderPainter class BorderPainter extends CustomPainter { final PassTrackController controller; final GnssController gnsscontroller; // final SightController sight; BorderPainter(this.controller) : gnsscontroller = Get.find(), super(repaint: controller); @override void paint(Canvas canvas, Size size) { // 绘制边框 // canvas.scale(controller.dtScale); final paint = Paint() ..color = Colors.red ..strokeWidth = 3.0; if (controller.selectedPilePoint != null) { var offset = Offset( controller.selectedPilePoint!.x, controller.selectedPilePoint!.y); Offset screenPos = mapcontroller.xy2Screen0(offset); // 计算圆的直径 double circleDiameter = 2 * 0.3 / mapcontroller.pixel2MeterRatio; final rect = Rect.fromCenter( center: screenPos, width: circleDiameter + 4, height: circleDiameter + 4); // 定义角的长度 // double cornerLength = 10.0 ; double cornerLength = 12; // 确保 cornerLength 不小于最小值 if (mapcontroller.scale >= 2 && mapcontroller.scale < 5) { cornerLength = 1.0; } else if (mapcontroller.scale >= 5 && mapcontroller.scale < 10) { cornerLength = 0.01; } else if (mapcontroller.scale >= 10) { cornerLength = 0; } // 左上角 canvas.drawLine( rect.topLeft, rect.topLeft + Offset(cornerLength, 0), paint); canvas.drawLine( rect.topLeft, rect.topLeft + Offset(0, cornerLength), paint); // 右上角 canvas.drawLine( rect.topRight, rect.topRight + Offset(-cornerLength, 0), paint); canvas.drawLine( rect.topRight, rect.topRight + Offset(0, cornerLength), paint); // 左下角 canvas.drawLine( rect.bottomLeft, rect.bottomLeft + Offset(cornerLength, 0), paint); canvas.drawLine( rect.bottomLeft, rect.bottomLeft + Offset(0, -cornerLength), paint); // 右下角 canvas.drawLine( rect.bottomRight, rect.bottomRight + Offset(-cornerLength, 0), paint); canvas.drawLine( rect.bottomRight, rect.bottomRight + Offset(0, -cornerLength), paint); Offset center = Offset(gnsscontroller.device.x, gnsscontroller.device.y); Offset pilerCenter = mapcontroller.xy2Screen0(center); //绘制虚线 if (mapcontroller.deviceList.isNotEmpty) { Paint dashedPaint = Paint() ..color = Colors.red ..strokeWidth = 3.5; var offset = Offset( controller.selectedPilePoint!.x, controller.selectedPilePoint!.y); Offset screenPos = mapcontroller.xy2Screen0(offset); drawDashedLine(canvas, pilerCenter, screenPos, dashedPaint); } // // // // if (!controller.isCardVisible.value) { // if (controller.calculateDistance(pilerCenterPoint, offset) < 0.9) { // print("距离小于1m"); // controller.isCardVisible.value = !controller.isCardVisible.value; // } else { // print("距离大于1m"); // } // } else { // if (controller.calculateDistance(pilerCenterPoint, offset) > 1.1) { // print("距离大于1m"); // controller.isCardVisible.value = controller.isCardVisible.value; // } else { // print("距禽小于1m"); // } // } } } void drawDashedLine(Canvas canvas, Offset start, Offset end, Paint paint) { const double dashWidth = 10.0; const double dashSpace = 5.0; double distance = (end - start).distance; double dashCount = distance / (dashWidth + dashSpace).floor(); if (dashCount < 5000) { for (int i = 0; i < dashCount; ++i) { double startX = start.dx + (end.dx - start.dx) * (i * (dashWidth + dashSpace) / distance); double startY = start.dy + (end.dy - start.dy) * (i * (dashWidth + dashSpace) / distance); double endX = start.dx + (end.dx - start.dx) * ((i * (dashWidth + dashSpace) + dashWidth) / distance); double endY = start.dy + (end.dy - start.dy) * ((i * (dashWidth + dashSpace) + dashWidth) / distance); canvas.drawLine(Offset(startX, startY), Offset(endX, endY), paint); } } } @override bool shouldRepaint(covariant CustomPainter oldDelegate) { return true; } }