guanxinyi před 9 měsíci
rodič
revize
21f539411c

+ 45 - 1
lib/process/calcuators/urm_calcuators/urm_ellipse_den_measure.dart

@@ -1,6 +1,10 @@
 import 'package:fis_common/logger/logger.dart';
+import 'package:fis_jsonrpc/rpc.dart';
+import 'package:fis_measure/interfaces/process/items/terms.dart';
 import 'package:fis_measure/process/calcuators/urm_calcuators/urm_ellipse_measure.dart';
 import 'package:fis_measure/process/workspace/urm/application.dart';
+import 'package:vid/us/vid_us_unit.dart';
+import 'dart:math' as math;
 
 class URMEllipseDenMeasureCal extends URMEllipseMeasureCal {
   URMEllipseDenMeasureCal(super.ref);
@@ -14,11 +18,51 @@ class URMEllipseDenMeasureCal extends URMEllipseMeasureCal {
     try {
       if (ref.feature == null) return;
       if (ref.application is! URMApplication) return;
+      final URMApplication urmApplication = ref.application as URMApplication;
 
-      // TODO 规划入参,坐标系转换,调用接口,处理返回结果
+      URMMeasureProcessResult? outResult =
+          await urmApplication.getURMMeasureResult(
+        urmMeasureType: URMMeasureType.URMDenMeasure,
+        rOIType: URMROIType.URMEllipse,
+        srcDPoints: param!.srcDPoints,
+      );
+      var result = outResult?.denMeasureResult;
+
+      if (result != null) {
+        final feature = ref.feature!;
+
+        for (var output in ref.meta.outputs) {
+          if (output.name == MeasureTerms.URMDenROI) {
+            output.unit = VidUsUnit.percent;
+            feature.updateFloatValue(output, result.roiDen * 100, output.unit);
+          } else if (output.name == MeasureTerms.URMDenFractalDim) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, result.roiFractalDim, output.unit);
+          } else if (output.name == MeasureTerms.URMDenMax) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, result.maxDensity, output.unit);
+          } else if (output.name == MeasureTerms.URMDenMin) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, result.minDensity, output.unit);
+          } else if (output.name == MeasureTerms.URMDenMean) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, result.meanDensity, output.unit);
+          } else if (output.name == MeasureTerms.URMDenStd) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(
+                output, math.sqrt(result.varianceDensity), output.unit);
+          } else if (output.name == MeasureTerms.Area) {
+            output.unit = VidUsUnit.cm2;
+            feature.updateFloatValue(output, result.roiArea, output.unit);
+          }
+        }
+      } else {
+        throw Exception("URM Measure API error");
+      }
     } catch (e) {
       logger.e('URM Measure error: $e');
       return;
     }
+    ref.application.updateRenderReady.emit(this, null);
   }
 }

+ 59 - 1
lib/process/calcuators/urm_calcuators/urm_ellipse_den_vel_measure.dart

@@ -1,6 +1,10 @@
 import 'package:fis_common/logger/logger.dart';
+import 'package:fis_jsonrpc/rpc.dart';
+import 'package:fis_measure/interfaces/process/items/terms.dart';
 import 'package:fis_measure/process/calcuators/urm_calcuators/urm_ellipse_measure.dart';
 import 'package:fis_measure/process/workspace/urm/application.dart';
+import 'package:vid/us/vid_us_unit.dart';
+import 'dart:math' as math;
 
 class URMEllipseDenVelMeasureCal extends URMEllipseMeasureCal {
   URMEllipseDenVelMeasureCal(super.ref);
@@ -14,11 +18,65 @@ class URMEllipseDenVelMeasureCal extends URMEllipseMeasureCal {
     try {
       if (ref.feature == null) return;
       if (ref.application is! URMApplication) return;
+      final URMApplication urmApplication = ref.application as URMApplication;
 
-      // TODO 规划入参,坐标系转换,调用接口,处理返回结果
+      URMMeasureProcessResult? outResult =
+          await urmApplication.getURMMeasureResult(
+        urmMeasureType: URMMeasureType.URMDenVelMeasure,
+        rOIType: URMROIType.URMEllipse,
+        srcDPoints: param!.srcDPoints,
+      );
+      var result = outResult?.denMeasureResult;
+      var velResult = outResult?.velMeasureResult;
+
+      if (result != null && velResult != null) {
+        final feature = ref.feature!;
+
+        for (var output in ref.meta.outputs) {
+          if (output.name == MeasureTerms.URMDenROI) {
+            output.unit = VidUsUnit.percent;
+            feature.updateFloatValue(output, result.roiDen * 100, output.unit);
+          } else if (output.name == MeasureTerms.URMDenFractalDim) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, result.roiFractalDim, output.unit);
+          } else if (output.name == MeasureTerms.URMDenMax) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, result.maxDensity, output.unit);
+          } else if (output.name == MeasureTerms.URMDenMin) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, result.minDensity, output.unit);
+          } else if (output.name == MeasureTerms.URMDenMean) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, result.meanDensity, output.unit);
+          } else if (output.name == MeasureTerms.URMDenStd) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(
+                output, math.sqrt(result.varianceDensity), output.unit);
+          } else if (output.name == MeasureTerms.URMVelMax) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, velResult.maxVel, output.unit);
+          } else if (output.name == MeasureTerms.URMVelMin) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, velResult.minVel, output.unit);
+          } else if (output.name == MeasureTerms.URMVelMean) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, velResult.meanVel, output.unit);
+          } else if (output.name == MeasureTerms.URMVelStd) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(
+                output, math.sqrt(velResult.varianceVel), output.unit);
+          } else if (output.name == MeasureTerms.Area) {
+            output.unit = VidUsUnit.cm2;
+            feature.updateFloatValue(output, result.roiArea, output.unit);
+          }
+        }
+      } else {
+        throw Exception("URM Measure API error");
+      }
     } catch (e) {
       logger.e('URM Measure error: $e');
       return;
     }
+    ref.application.updateRenderReady.emit(this, null);
   }
 }

+ 26 - 1
lib/process/calcuators/urm_calcuators/urm_ellipse_density.dart

@@ -1,6 +1,9 @@
 import 'package:fis_common/logger/logger.dart';
+import 'package:fis_jsonrpc/rpc.dart';
+import 'package:fis_measure/interfaces/process/items/terms.dart';
 import 'package:fis_measure/process/calcuators/urm_calcuators/urm_ellipse_measure.dart';
 import 'package:fis_measure/process/workspace/urm/application.dart';
+import 'package:vid/us/vid_us_unit.dart';
 
 class URMEllipseDensityCal extends URMEllipseMeasureCal {
   URMEllipseDensityCal(super.ref);
@@ -14,11 +17,33 @@ class URMEllipseDensityCal extends URMEllipseMeasureCal {
     try {
       if (ref.feature == null) return;
       if (ref.application is! URMApplication) return;
+      final URMApplication urmApplication = ref.application as URMApplication;
 
-      // TODO 规划入参,坐标系转换,调用接口,处理返回结果
+      URMMeasureProcessResult? outResult =
+          await urmApplication.getURMMeasureResult(
+        urmMeasureType: URMMeasureType.URMDen,
+        rOIType: URMROIType.URMEllipse,
+        srcDPoints: param!.srcDPoints,
+      );
+      var result = outResult?.denMeasureResult;
+      var velResult = outResult?.velMeasureResult;
+
+      if (result != null && velResult != null) {
+        final feature = ref.feature!;
+
+        for (var output in ref.meta.outputs) {
+          if (output.name == MeasureTerms.URMDenROI) {
+            output.unit = VidUsUnit.percent;
+            feature.updateFloatValue(output, result.roiDen * 100, output.unit);
+          }
+        }
+      } else {
+        throw Exception("URM Measure API error");
+      }
     } catch (e) {
       logger.e('URM Measure error: $e');
       return;
     }
+    ref.application.updateRenderReady.emit(this, null);
   }
 }

+ 26 - 1
lib/process/calcuators/urm_calcuators/urm_ellipse_fractal_dim.dart

@@ -1,6 +1,9 @@
 import 'package:fis_common/logger/logger.dart';
+import 'package:fis_jsonrpc/rpc.dart';
+import 'package:fis_measure/interfaces/process/items/terms.dart';
 import 'package:fis_measure/process/calcuators/urm_calcuators/urm_ellipse_measure.dart';
 import 'package:fis_measure/process/workspace/urm/application.dart';
+import 'package:vid/us/vid_us_unit.dart';
 
 class URMEllipseFractalDimCal extends URMEllipseMeasureCal {
   URMEllipseFractalDimCal(super.ref);
@@ -14,11 +17,33 @@ class URMEllipseFractalDimCal extends URMEllipseMeasureCal {
     try {
       if (ref.feature == null) return;
       if (ref.application is! URMApplication) return;
+      final URMApplication urmApplication = ref.application as URMApplication;
 
-      // TODO 规划入参,坐标系转换,调用接口,处理返回结果
+      URMMeasureProcessResult? outResult =
+          await urmApplication.getURMMeasureResult(
+        urmMeasureType: URMMeasureType.URMFracetalDim,
+        rOIType: URMROIType.URMEllipse,
+        srcDPoints: param!.srcDPoints,
+      );
+      var result = outResult?.denMeasureResult;
+      var velResult = outResult?.velMeasureResult;
+
+      if (result != null && velResult != null) {
+        final feature = ref.feature!;
+
+        for (var output in ref.meta.outputs) {
+          if (output.name == MeasureTerms.URMDenFractalDim) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, result.roiFractalDim, output.unit);
+          }
+        }
+      } else {
+        throw Exception("URM Measure API error");
+      }
     } catch (e) {
       logger.e('URM Measure error: $e');
       return;
     }
+    ref.application.updateRenderReady.emit(this, null);
   }
 }

+ 8 - 10
lib/process/calcuators/urm_calcuators/urm_ellipse_measure.dart

@@ -58,19 +58,17 @@ class URMEllipseMeasureCal extends Calculator<URMEllipseMeasure, double> {
       final URMApplication urmApplication = ref.application as URMApplication;
       urmResultSize = Size(urmApplication.resultWidth.toDouble(),
           urmApplication.resultHeight.toDouble());
-      final List<UrmPoint> points = ref.feature!.innerPoints
-          .map(
-            (e) => UrmPoint(
-              x: e.scale2Size(urmResultSize).x,
-              y: e.scale2Size(urmResultSize).y,
-            ),
-          )
-          .toList();
+
+      // 添加入参
+      List<UrmPoint> srcDPoints = [];
+      for (var point in ref.feature!.innerPoints) {
+        srcDPoints.add(urmApplication.localToView(point));
+      }
 
       param = URMSimpleMeasureParams(
         urmMeasureType: URMMeasureType.URMCurvature,
-        rOIType: URMROIType.URMRect,
-        srcDPoints: points,
+        rOIType: URMROIType.URMEllipse,
+        srcDPoints: srcDPoints,
       );
     } catch (e) {
       logger.e('URM handleURMSimpleMeasureParams error: $e');

+ 45 - 1
lib/process/calcuators/urm_calcuators/urm_ellipse_perfusion.dart

@@ -1,6 +1,14 @@
+import 'dart:convert';
+import 'dart:typed_data';
+
 import 'package:fis_common/logger/logger.dart';
+import 'package:fis_jsonrpc/rpc.dart';
+import 'package:fis_measure/interfaces/process/items/terms.dart';
 import 'package:fis_measure/process/calcuators/urm_calcuators/urm_ellipse_measure.dart';
+import 'package:fis_measure/process/primitives/urm_measure/urm_ellipse_measure.dart';
 import 'package:fis_measure/process/workspace/urm/application.dart';
+import 'package:vid/us/vid_us_unit.dart';
+import 'dart:ui' as ui;
 
 class URMEllipsePerfusionCal extends URMEllipseMeasureCal {
   URMEllipsePerfusionCal(super.ref);
@@ -14,11 +22,47 @@ class URMEllipsePerfusionCal extends URMEllipseMeasureCal {
     try {
       if (ref.feature == null) return;
       if (ref.application is! URMApplication) return;
+      final URMApplication urmApplication = ref.application as URMApplication;
+
+      URMMeasureProcessResult? outResult =
+          await urmApplication.getURMMeasureResult(
+        urmMeasureType: URMMeasureType.URMPerfusion,
+        rOIType: URMROIType.URMRect,
+        srcDPoints: param!.srcDPoints,
+      );
+
+      if (outResult != null) {
+        final feature = ref.feature!;
 
-      // TODO 规划入参,坐标系转换,调用接口,处理返回结果
+        for (var output in ref.meta.outputs) {
+          if (output.name == MeasureTerms.URMPerfusionIndex) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, outResult.resultData, output.unit);
+
+            if (feature is! EllipsePerfusionImageFeature) return;
+            if (outResult.perfusionImgBase64 != null) {
+              feature.perfusionImg =
+                  await loadImageFromBase64(outResult.perfusionImgBase64!);
+              feature.perfusionScaleDRect = urmApplication.viewToLocalRect(
+                outResult.perfusionScaleDRect!,
+              );
+            }
+          }
+        }
+      } else {
+        throw Exception("URM Measure API error");
+      }
     } catch (e) {
       logger.e('URM Measure error: $e');
       return;
     }
+    ref.application.updateRenderReady.emit(this, null);
+  }
+
+  Future<ui.Image> loadImageFromBase64(String base64String) async {
+    Uint8List bytes = base64Decode(base64String);
+    ui.Codec codec = await ui.instantiateImageCodec(bytes);
+    ui.FrameInfo frameInfo = await codec.getNextFrame();
+    return frameInfo.image;
   }
 }

+ 41 - 1
lib/process/calcuators/urm_calcuators/urm_ellipse_vel_measure.dart

@@ -1,6 +1,11 @@
 import 'package:fis_common/logger/logger.dart';
+import 'package:fis_jsonrpc/rpc.dart';
+import 'package:fis_measure/interfaces/process/items/terms.dart';
 import 'package:fis_measure/process/calcuators/urm_calcuators/urm_ellipse_measure.dart';
 import 'package:fis_measure/process/workspace/urm/application.dart';
+import 'dart:math' as math;
+
+import 'package:vid/us/vid_us_unit.dart';
 
 class URMEllipseVelMeasureCal extends URMEllipseMeasureCal {
   URMEllipseVelMeasureCal(super.ref);
@@ -14,11 +19,46 @@ class URMEllipseVelMeasureCal extends URMEllipseMeasureCal {
     try {
       if (ref.feature == null) return;
       if (ref.application is! URMApplication) return;
+      final URMApplication urmApplication = ref.application as URMApplication;
+
+      URMMeasureProcessResult? outResult =
+          await urmApplication.getURMMeasureResult(
+        urmMeasureType: URMMeasureType.URMVelMeasure,
+        rOIType: URMROIType.URMEllipse,
+        srcDPoints: param!.srcDPoints,
+      );
+      var result = outResult?.denMeasureResult;
+      var velResult = outResult?.velMeasureResult;
+
+      if (result != null && velResult != null) {
+        final feature = ref.feature!;
 
-      // TODO 规划入参,坐标系转换,调用接口,处理返回结果
+        for (var output in ref.meta.outputs) {
+          if (output.name == MeasureTerms.URMVelMax) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, velResult.maxVel, output.unit);
+          } else if (output.name == MeasureTerms.URMVelMin) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, velResult.minVel, output.unit);
+          } else if (output.name == MeasureTerms.URMVelMean) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, velResult.meanVel, output.unit);
+          } else if (output.name == MeasureTerms.URMVelStd) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(
+                output, math.sqrt(velResult.varianceVel), output.unit);
+          } else if (output.name == MeasureTerms.Area) {
+            output.unit = VidUsUnit.cm2;
+            feature.updateFloatValue(output, result.roiArea, output.unit);
+          }
+        }
+      } else {
+        throw Exception("URM Measure API error");
+      }
     } catch (e) {
       logger.e('URM Measure error: $e');
       return;
     }
+    ref.application.updateRenderReady.emit(this, null);
   }
 }

+ 45 - 2
lib/process/calcuators/urm_calcuators/urm_shell_den_measure.dart

@@ -1,9 +1,12 @@
 import 'package:fis_common/logger/logger.dart';
+import 'package:fis_jsonrpc/rpc.dart';
+import 'package:fis_measure/interfaces/process/items/terms.dart';
 import 'package:fis_measure/process/calcuators/urm_calcuators/urm_shell_measure.dart';
 import 'package:fis_measure/process/primitives/urm_measure/urm_shell_measure.dart';
-
+import 'dart:math' as math;
 // import 'package:fis_measure/process/primitives/urm_straightline.dart';
 import 'package:fis_measure/process/workspace/urm/application.dart';
+import 'package:vid/us/vid_us_unit.dart';
 
 class URMShellDenMeasureCal extends URMShellMeasureCal {
   URMShellDenMeasureCal(URMShellMeasure ref) : super(ref);
@@ -16,11 +19,51 @@ class URMShellDenMeasureCal extends URMShellMeasureCal {
     try {
       if (ref.feature == null) return;
       if (ref.application is! URMApplication) return;
+      final URMApplication urmApplication = ref.application as URMApplication;
+
+      URMMeasureProcessResult? outResult =
+          await urmApplication.getURMMeasureResult(
+        urmMeasureType: URMMeasureType.URMDenMeasure,
+        rOIType: URMROIType.URMShell,
+        srcDPoints: param!.srcDPoints,
+      );
+      var result = outResult?.denMeasureResult;
+
+      if (result != null) {
+        final feature = ref.feature!;
 
-      // TODO 规划入参,坐标系转换,调用接口,处理返回结果
+        for (var output in ref.meta.outputs) {
+          if (output.name == MeasureTerms.URMDenROI) {
+            output.unit = VidUsUnit.percent;
+            feature.updateFloatValue(output, result.roiDen * 100, output.unit);
+          } else if (output.name == MeasureTerms.URMDenFractalDim) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, result.roiFractalDim, output.unit);
+          } else if (output.name == MeasureTerms.URMDenMax) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, result.maxDensity, output.unit);
+          } else if (output.name == MeasureTerms.URMDenMin) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, result.minDensity, output.unit);
+          } else if (output.name == MeasureTerms.URMDenMean) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, result.meanDensity, output.unit);
+          } else if (output.name == MeasureTerms.URMDenStd) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(
+                output, math.sqrt(result.varianceDensity), output.unit);
+          } else if (output.name == MeasureTerms.Area) {
+            output.unit = VidUsUnit.cm2;
+            feature.updateFloatValue(output, result.roiArea, output.unit);
+          }
+        }
+      } else {
+        throw Exception("URM Measure API error");
+      }
     } catch (e) {
       logger.e('URM Measure error: $e');
       return;
     }
+    ref.application.updateRenderReady.emit(this, null);
   }
 }

+ 63 - 1
lib/process/calcuators/urm_calcuators/urm_shell_den_vel_measure.dart

@@ -1,9 +1,12 @@
 import 'package:fis_common/logger/logger.dart';
+import 'package:fis_jsonrpc/rpc.dart';
+import 'package:fis_measure/interfaces/process/items/terms.dart';
 import 'package:fis_measure/process/calcuators/urm_calcuators/urm_shell_measure.dart';
 import 'package:fis_measure/process/primitives/urm_measure/urm_shell_measure.dart';
 
 // import 'package:fis_measure/process/primitives/urm_straightline.dart';
 import 'package:fis_measure/process/workspace/urm/application.dart';
+import 'package:vid/us/vid_us_unit.dart';
 
 class URMShellDenVelMeasureCal extends URMShellMeasureCal {
   URMShellDenVelMeasureCal(URMShellMeasure ref) : super(ref);
@@ -16,11 +19,70 @@ class URMShellDenVelMeasureCal extends URMShellMeasureCal {
     try {
       if (ref.feature == null) return;
       if (ref.application is! URMApplication) return;
+      final URMApplication urmApplication = ref.application as URMApplication;
 
-      // TODO 规划入参,坐标系转换,调用接口,处理返回结果
+      URMMeasureProcessResult? outresult =
+          await urmApplication.getURMMeasureResult(
+        urmMeasureType: URMMeasureType.URMDenVelMeasure,
+        rOIType: URMROIType.URMShell,
+        srcDPoints: param!.srcDPoints,
+      );
+      if (outresult == null) {
+        return;
+      }
+      URMDenMeasureResult? denresult = outresult.denMeasureResult;
+      URMVelMeasureResult? velresult = outresult.velMeasureResult;
+      if (denresult != null && velresult != null) {
+        final feature = ref.feature!;
+
+        for (var output in ref.meta.outputs) {
+          if (output.name == MeasureTerms.URMDenROI) {
+            output.unit = VidUsUnit.percent;
+            feature.updateFloatValue(
+                output, denresult.roiDen * 100, output.unit);
+          } else if (output.name == MeasureTerms.URMDenFractalDim) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(
+                output, denresult.roiFractalDim, output.unit);
+          } else if (output.name == MeasureTerms.URMDenMax) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, denresult.maxDensity, output.unit);
+          } else if (output.name == MeasureTerms.URMDenMin) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(output, denresult.minDensity, output.unit);
+          } else if (output.name == MeasureTerms.URMDenMean) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(
+                output, denresult.meanDensity, output.unit);
+          } else if (output.name == MeasureTerms.URMDenStd) {
+            output.unit = VidUsUnit.None;
+            feature.updateFloatValue(
+                output, denresult.varianceDensity, output.unit);
+          } else if (output.name == MeasureTerms.URMVelMax) {
+            output.unit = VidUsUnit.mms;
+            feature.updateFloatValue(output, velresult.maxVel, output.unit);
+          } else if (output.name == MeasureTerms.URMVelMin) {
+            output.unit = VidUsUnit.mms;
+            feature.updateFloatValue(output, velresult.minVel, output.unit);
+          } else if (output.name == MeasureTerms.URMVelMean) {
+            output.unit = VidUsUnit.mms;
+            feature.updateFloatValue(output, velresult.meanVel, output.unit);
+          } else if (output.name == MeasureTerms.URMVelStd) {
+            output.unit = VidUsUnit.mms;
+            feature.updateFloatValue(
+                output, velresult.varianceVel, output.unit);
+          } else if (output.name == MeasureTerms.Area) {
+            output.unit = VidUsUnit.cm2;
+            feature.updateFloatValue(output, velresult.roiArea, output.unit);
+          }
+        }
+      } else {
+        throw Exception("URM Measure API error");
+      }
     } catch (e) {
       logger.e('URM Measure error: $e');
       return;
     }
+    ref.application.updateRenderReady.emit(this, null);
   }
 }

+ 19 - 1
lib/process/calcuators/urm_calcuators/urm_shell_density_measure.dart

@@ -1,9 +1,11 @@
 import 'package:fis_common/logger/logger.dart';
+import 'package:fis_jsonrpc/rpc.dart';
 import 'package:fis_measure/process/calcuators/urm_calcuators/urm_shell_measure.dart';
 import 'package:fis_measure/process/primitives/urm_measure/urm_shell_measure.dart';
 
 // import 'package:fis_measure/process/primitives/urm_straightline.dart';
 import 'package:fis_measure/process/workspace/urm/application.dart';
+import 'package:vid/us/vid_us_unit.dart';
 
 class URMShellDensityMeasureCal extends URMShellMeasureCal {
   URMShellDensityMeasureCal(URMShellMeasure ref) : super(ref);
@@ -16,11 +18,27 @@ class URMShellDensityMeasureCal extends URMShellMeasureCal {
     try {
       if (ref.feature == null) return;
       if (ref.application is! URMApplication) return;
+      final URMApplication urmApplication = ref.application as URMApplication;
 
-      // TODO 规划入参,坐标系转换,调用接口,处理返回结果
+      URMMeasureProcessResult? outresult =
+          await urmApplication.getURMMeasureResult(
+        urmMeasureType: URMMeasureType.URMDen,
+        rOIType: URMROIType.URMShell,
+        srcDPoints: param!.srcDPoints,
+      );
+      if (outresult == null) {
+        return;
+      }
+      final feature = ref.feature!;
+
+      final first = ref.meta.outputs.first;
+      first.unit = VidUsUnit.percent;
+
+      feature.updateFloatValue(first, outresult.resultData * 100, first.unit);
     } catch (e) {
       logger.e('URM Measure error: $e');
       return;
     }
+    ref.application.updateRenderReady.emit(this, null);
   }
 }

+ 8 - 13
lib/process/calcuators/urm_calcuators/urm_shell_measure.dart

@@ -45,28 +45,23 @@ class URMShellMeasureCal extends Calculator<URMShellMeasure, double> {
   /// 处理获取到的URM参数
   void handleURMSimpleMeasureParams() {
     if (ref.feature == null) return;
-    Size urmResultSize = const Size(0, 0);
 
     try {
       if (ref.application is! URMApplication) {
         return;
       }
       final URMApplication urmApplication = ref.application as URMApplication;
-      urmResultSize = Size(urmApplication.resultWidth.toDouble(),
-          urmApplication.resultHeight.toDouble());
-      final List<UrmPoint> points = ref.feature!.innerPoints
-          .map(
-            (e) => UrmPoint(
-              x: e.scale2Size(urmResultSize).x,
-              y: e.scale2Size(urmResultSize).y,
-            ),
-          )
-          .toList();
+
+      // 添加入参
+      List<UrmPoint> srcDPoints = [];
+      for (var point in ref.feature!.innerPoints) {
+        srcDPoints.add(urmApplication.localToView(point));
+      }
 
       param = URMSimpleMeasureParams(
         urmMeasureType: URMMeasureType.URMCurvature,
-        rOIType: URMROIType.URMRect,
-        srcDPoints: points,
+        rOIType: URMROIType.URMShell,
+        srcDPoints: srcDPoints,
       );
     } catch (e) {
       logger.e('URM handleURMSimpleMeasureParams error: $e');

+ 107 - 0
lib/process/primitives/urm_measure/urm_ellipse_measure.dart

@@ -1,5 +1,9 @@
+import 'package:fis_jsonrpc/rpc.dart';
+import 'package:fis_measure/interfaces/date_types/point.dart';
+import 'package:fis_measure/interfaces/enums/items.dart';
 import 'package:fis_measure/interfaces/process/items/item.dart';
 import 'package:fis_measure/interfaces/process/items/item_metas.dart';
+import 'package:fis_measure/interfaces/process/workspace/point_info.dart';
 import 'package:fis_measure/process/calcuators/urm_calcuators/urm_ellipse_den_measure.dart';
 import 'package:fis_measure/process/calcuators/urm_calcuators/urm_ellipse_den_vel_measure.dart';
 import 'package:fis_measure/process/calcuators/urm_calcuators/urm_ellipse_density.dart';
@@ -8,10 +12,15 @@ import 'package:fis_measure/process/calcuators/urm_calcuators/urm_ellipse_hist.d
 import 'package:fis_measure/process/calcuators/urm_calcuators/urm_ellipse_perfusion.dart';
 import 'package:fis_measure/process/calcuators/urm_calcuators/urm_ellipse_vel_measure.dart';
 import 'package:fis_measure/process/primitives/ellipse.dart';
+import 'package:fis_measure/utils/prompt_box.dart';
+import 'package:flutter/material.dart';
+import 'dart:ui' as ui;
 
 class URMEllipseMeasure extends Ellipse {
   URMEllipseMeasure(super.meta, super.parent);
 
+  static bool needPerfusion = false;
+
   static URMEllipseMeasure createURMEllipseDenMeasure(ItemMeta meta,
       [IMeasureItem? parent]) {
     URMEllipseMeasure measureEllipse = URMEllipseMeasure(meta, parent);
@@ -70,10 +79,108 @@ class URMEllipseMeasure extends Ellipse {
 
   static URMEllipseMeasure createURMEllipsePerfusion(ItemMeta meta,
       [IMeasureItem? parent]) {
+    needPerfusion = true;
     URMEllipseMeasure measureEllipsePerfusion = URMEllipseMeasure(meta, parent);
     measureEllipsePerfusion.calculator = URMEllipsePerfusionCal(
       measureEllipsePerfusion,
     );
     return measureEllipsePerfusion;
   }
+
+  @override
+  bool onExecuteMouse(PointInfo args) {
+    if (state == ItemStates.finished) {
+      if (args.pointType == PointInfoType.mouseDown) {
+        state = ItemStates.waiting;
+      }
+    }
+
+    if (state == ItemStates.waiting) {
+      if (args.pointType == PointInfoType.mouseDown) {
+        handleMouseDownWhileWaiting(args);
+      }
+    } else if (state == ItemStates.running) {
+      if (feature == null) return false;
+      final f = feature! as EllipseFeature;
+      final activeIndex = f.activeIndex;
+
+      switch (args.pointType) {
+        case PointInfoType.mouseMove:
+          f.innerPoints[activeIndex] = args;
+          f.adjustPoints(args);
+          break;
+        case PointInfoType.mouseDown:
+          if (activeIndex == 1) {
+            if (f.xAxisEnd == f.xAxisStart) {
+              break;
+            }
+            f.adjustPoints(args);
+            f.activeIndex = 2;
+          } else if (activeIndex == 2) {
+            doFeatureFinish();
+          }
+          break;
+        default:
+          return false;
+      }
+
+      doCalculate();
+
+      return true;
+    }
+    return false;
+  }
+
+  @override
+  void handleMouseDownWhileWaiting(PointInfo args) {
+    if (needPerfusion) {
+      final point = args.toAreaLogicPoint();
+      feature = EllipsePerfusionImageFeature(this, point);
+    } else {
+      super.handleMouseDownWhileWaiting(args);
+    }
+    state = ItemStates.running;
+  }
+
+  bool waitingResult = false;
+
+  void handleFinish() async {
+    feature!.isActive = false;
+    PromptBox.loading("计算中...");
+    waitingResult = true;
+    await doCalculateAsync();
+    doFeatureFinish();
+    PromptBox.dismiss();
+    waitingResult = false;
+  }
+}
+
+class EllipsePerfusionImageFeature extends EllipseFeature {
+  EllipsePerfusionImageFeature(Ellipse refItem, DPoint point)
+      : super(refItem, point);
+
+  ui.Image? perfusionImg;
+  IntRect? perfusionPiexlRect;
+  Rect? perfusionScaleDRect;
+  @override
+  void paint(Canvas canvas, Size size) {
+    if (perfusionImg != null) {
+      Paint paint = Paint();
+
+      Rect src = Rect.fromLTWH(
+        0,
+        0,
+        perfusionImg!.width.toDouble(),
+        perfusionImg!.height.toDouble(),
+      );
+      Rect dst = Rect.fromLTWH(
+        perfusionScaleDRect!.left.toDouble() * size.width,
+        perfusionScaleDRect!.top.toDouble() * size.height,
+        perfusionScaleDRect!.width.toDouble() * size.width,
+        perfusionScaleDRect!.height.toDouble() * size.height,
+      );
+      canvas.drawImageRect(perfusionImg!, src, dst, paint);
+    }
+    super.paint(canvas, size);
+  }
 }

+ 1 - 1
lib/process/primitives/urm_measure/urm_trace_measure.dart

@@ -118,10 +118,10 @@ class URMTraceMeasure extends Trace {
   void handleMouseDownWhileWaiting(PointInfo args) {
     if (needPerfusion) {
       feature = TracePerfusionImageFeature(this);
-      state = ItemStates.running;
     } else {
       super.handleMouseDownWhileWaiting(args);
     }
+    state = ItemStates.running;
   }
 
   bool waitingResult = false;