import 'dart:math'; import 'package:fis_common/logger/logger.dart'; import 'package:fis_jsonrpc/rpc.dart'; import 'package:fis_measure/interfaces/date_types/point.dart'; import 'package:fis_measure/interfaces/process/urm/urm_data_processor.dart'; import 'package:fis_measure/process/workspace/rpc_bridge.dart'; import 'package:flutter/material.dart'; import 'package:vid/us/vid_us_probe.dart'; import '../application.dart'; import 'package:fis_measure/interfaces/process/workspace/point_info.dart'; /// URM 专业应用 class URMApplication extends Application { URMApplication( VidUsProbe probe, { required this.resultWidth, required this.resultHeight, required this.urmDataProcessor, this.onUpdateChart, this.onUpdateRimResult, }) : super(probe); IURMDataProcessor urmDataProcessor; int resultWidth; // 分析结果图像宽度 int resultHeight; // 分析结果图像高度 final ValueChanged? onUpdateChart; final ValueChanged? onUpdateRimResult; @override PointInfo createPointInfo(Offset offset, PointInfoType type) { double width = urmDataProcessor.showLeftRight ? displaySize.width / 2 : displaySize.width; if (isAnnotationWorking) { width = displaySize.width; } final height = displaySize.height; final x = offset.dx / width; final y = offset.dy / height; Rect zoomArea = urmDataProcessor.measureAreaInFullVisual; Offset percentOffset = Offset(x, y); if (!isAnnotationWorking) { percentOffset = pointPctOutRect(zoomArea, percentOffset); } final info = PointInfo.fromOffset(percentOffset, type); info.hostVisualArea = currentVisualArea; // 未切换区域则沿用当前区域 if (isAnnotationWorking) { activeAnnotationItem?.execute(info); } else { activeMeasureItem?.execute(info); if (type == PointInfoType.touchMove) { mobileTouchEvent.emit(this, offset); // 传出移动事件 } if (type == PointInfoType.touchUp) { mobileTouchEndEvent.emit(this, offset); // 传出触摸结束事件 } } return info; } @override double get displayScaleRatio { // return max( // 1, // min(displaySize.width / resultWidth, // displaySize.height / resultHeight)); return 1.0; } void loadURMVisuals() { loadVisuals(); } Future getURMMeasureResult({ required URMMeasureType urmMeasureType, required URMROIType rOIType, List? srcDPoints, double? cMlength, double shellWidth = 0, }) async { try { print("调接口获取测量值 getURMMeasureResult"); URMMeasureParams params = urmDataProcessor.getURMMeasureParams(); URMMeasureProcessResult result = await RPCBridge.ins.rpc.aIDiagnosis.uRMMeasureProcessAsync( URMMeasureProcessRequest( remedicalCode: params.remedicalCode, token: RPCBridge.ins.userToken, urmMeasureType: urmMeasureType, // 手动传入 rOIType: rOIType, // 手动传入 srcDPoints: srcDPoints, // 手动传入 cMlength: cMlength, // 手动传入 shellWidth: shellWidth, // 手动传入 phywidth: urmDataProcessor.fullVisualPhywidth * urmDataProcessor.urmScreenInFullVisual.width, // 手动计算 urmImageType: params.urmImageType, // 手动取值 urmBlend: params.urmBlend, // 手动取值 downsampleIndex: params.downsampleIndex, // 手动取值 intPowerDen: params.intPowerDen, // 手动取值 intPowerDir: params.intPowerDir, // 手动取值 sigmaGauss: params.sigmaGauss, // 手动取值 vessScale: params.vessScale, // 手动取值 velMaxScaler: params.velMaxScaler, // 手动取值 velMinScaler: params.velMinScaler, // 手动取值 iterations: params.iterations, // 手动取值 imgProcessVer: params.imgProcessVer, // 手动取值 zoomOn: params.zoomOn, // 手动取值 zoomRoix: params.zoomRoix, // 手动取值 zoomRoiy: params.zoomRoiy, // 手动取值 zoomRoiwidth: params.zoomRoiwidth, // 手动取值 zoomRoiheight: params.zoomRoiheight, // 手动取值 roix: params.roix, // 手动取值 roiy: params.roiy, // 手动取值 roiwidth: params.roiwidth, // 手动取值 roiheight: params.roiheight, // 手动取值 leftRight: params.leftRight, // 手动取值 upDown: params.upDown, // 手动取值 screenWidth: params.screenWidth, // 手动取值 screenHeight: params.screenHeight, // 手动取值 urmTraceDPoints: params.urmTraceDPoints, // 手动取值 ), ); return result; } catch (e) { logger.e("URM measure error($e)"); print("getURMMeasureResult error: $e"); return null; } } Offset pointPctOutRect(Rect r, Offset p) { double xPctInR = p.dx * r.width + r.left; double yPctInR = p.dy * r.height + r.top; return Offset(xPctInR, yPctInR); } Offset pointPctInRect(Rect r, Offset p) { double xPctOutR = (p.dx - r.left) / r.width; double yPctOutR = (p.dy - r.top) / r.height; return Offset(xPctOutR, yPctOutR); } // 本地完整图像内归一化坐标转视图(接口中 screenWidth、screenHeight 指代区域)内归一化坐标 UrmPoint localToView(DPoint point) { Rect urmScreen = urmDataProcessor.urmScreenInFullVisual; Offset percentOffset = Offset(point.x, point.y); percentOffset = pointPctInRect(urmScreen, percentOffset); return UrmPoint(x: percentOffset.dx, y: percentOffset.dy); } // 视图(接口中 screenWidth、screenHeight 指代区域)内归一化坐标转本地完整图像内归一化坐标 DPoint viewToLocal(UrmPoint point) { Rect urmScreen = urmDataProcessor.urmScreenInFullVisual; Offset percentOffset = Offset(point.x, point.y); percentOffset = pointPctOutRect(urmScreen, percentOffset); return DPoint(percentOffset.dx, percentOffset.dy); } // 视图(接口中 screenWidth、screenHeight 指代区域)内归一化矩形转本地完整图像内归一化矩形 Rect viewToLocalRect(DRect point) { DPoint p1 = viewToLocal(UrmPoint(x: point.left, y: point.top)); DPoint p2 = viewToLocal(UrmPoint(x: point.right, y: point.bottom)); return Rect.fromLTRB(p1.x, p1.y, p2.x, p2.y); } // 类型转换 List dPointsToUrmPoints(List? points) { if (points == null) return []; List urmPoints = []; for (var point in points) { urmPoints.add(localToView(point)); } return urmPoints; } // 类型转换 List urmPointsToDPoints(List? points) { if (points == null) return []; List urmPoints = []; for (var point in points) { urmPoints.add(viewToLocal(point)); } return urmPoints; } } class URMChartParams { final int featureId; final List> outerExterPoints; final List> line; final double cmlength; final int maxPointIndex; final int minPointIndex; URMChartParams({ required this.featureId, required this.outerExterPoints, required this.line, required this.cmlength, required this.maxPointIndex, required this.minPointIndex, }); } class URMSimpleMeasureParams { final URMMeasureType urmMeasureType; final URMROIType rOIType; final List? srcDPoints; final double? cMlength; double? shellWidth = 0; URMSimpleMeasureParams({ required this.urmMeasureType, required this.rOIType, this.srcDPoints, this.cMlength, this.shellWidth, }); } class URMRimMesureResult { final URMMeasureProcessResult result; final String measureType; URMRimMesureResult({ required this.result, required this.measureType, }); }