//字体 import 'dart:developer'; import 'package:cpnav/controllers/gnss_controller.dart'; import 'package:cpnav/main.dart'; import 'package:cpnav/pages/aim_point/aimpoint_page.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; import 'package:scence_map/controllers/controller.dart'; import 'package:scence_map/record_entity.dart'; import 'package:scence_map/scence_map.dart'; import '../../service/pile/device_type.dart'; import '../aim_point/aimpoint_controller.dart'; import '../dataAndDevice/real_data.dart'; import '../dataAndDevice/real_device.dart'; import '../real/real_data_card.dart'; import "controller.dart"; ScenceMapController mapcontroller = Get.put(ScenceMapController()); class PassTackAndDevice extends StatelessWidget { final RecordEntity? currentPoint; PassTackAndDevice({this.currentPoint}); final controller = Get.put(PassTrackController()); @override Widget build(BuildContext context) { if (controller.isDeviceShow.value) { return Row( children: [ Expanded( flex: 2, child: RealDeviceView(), ), Expanded( flex: 5, child: PassTrack(currentPoint: currentPoint), ), Expanded(flex: 2, child: RealDataContainer()), ], ); } else { return Row( children: [ Expanded( flex: 7, child: PassTrack(currentPoint: currentPoint), ), Expanded(flex: 2, child: RealDataContainer()), ], ); } } } // ignore: must_be_immutable class PassTrack extends GetView { // final GlobalKey> _popupMenuKey = // GlobalKey>(); RecordEntity? currentPoint; @override final controller = Get.put(PassTrackController()); // String str = "播放"; // int sWidth = 0; // int bits = -1; // int speed = 50; // List speedList = [1, 2, 10, 20, 50, 100, 200, 500]; // int maxLength = 200; // final _rangevalues = const SfRangeValues(0.0, 200.0); PassTrack({super.key, this.currentPoint}); @override Widget build(BuildContext context) { if (currentPoint == null) { controller.date.value = DateFormat('yyyy-MM-dd').format(DateTime.now()); } else { controller.date.value = DateFormat('yyyy-MM-dd').format(currentPoint!.startTime); } controller.currentPoint = currentPoint; controller.loadData(); return Obx(() { controller.updateCount.value; CustomPainter? forGroundPainter = appcontroller.currentIndex.value == 1 ? BorderPainter( controller, ) : null; return OrientationBuilder(builder: (context, orientation) { final size = MediaQuery.of(context).size; return Stack( children: [ ScenceMapView( onUpdate: (Offset center, double scale, double rotation) { log("center:$center scale:$scale rotation:$rotation"); }, forGroundPainter: forGroundPainter, onUpdatePilePoint: (RecordEntity? selectedPilePoint, double scale, double rotation) { log("selectedPilePoint:$selectedPilePoint scale:$scale rotation:$rotation"); controller.selectedPilePoint.value = selectedPilePoint; aimcontroller.selectedPilePoint = selectedPilePoint; controller.updateCount.value++; }, children: const [], ), SightGview(size: size), const RealDataShow(), ], ); }); }); } } // 自定义的 BorderPainter class BorderPainter extends CustomPainter { final PassTrackController controller; final GnssController gnsscontroller; 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; RecordEntity? selectedPilePoint = controller.selectedPilePoint.value; if (selectedPilePoint != null) { var offset = Offset(selectedPilePoint.x, 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; } paint.style = PaintingStyle.stroke; canvas.drawRect(rect, paint); Offset center = Offset(gnsscontroller.device.x.value, gnsscontroller.device.y.value); Offset pilerCenter = mapcontroller.xy2Screen0(center); //绘制虚线 if (mapcontroller.deviceList.isNotEmpty) { Paint dashedPaint = Paint() ..color = Colors.red ..strokeWidth = 3.5; var offset = Offset(selectedPilePoint.x, selectedPilePoint.y); Offset screenPos = mapcontroller.xy2Screen0(offset); drawDashedLine(canvas, pilerCenter, screenPos, dashedPaint); } } } 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; } }