|
@@ -0,0 +1,132 @@
|
|
|
+import 'dart:convert';
|
|
|
+import 'dart:ui';
|
|
|
+
|
|
|
+import 'package:fis_measure/interfaces/date_types/point.dart';
|
|
|
+import 'package:fis_measure/interfaces/process/items/measure_terms.dart';
|
|
|
+import 'package:fis_measure/process/primitives/carotid_imt.dart';
|
|
|
+import 'package:fis_measure/utils/js_utils.dart';
|
|
|
+import 'package:vid/us/vid_us_unit.dart';
|
|
|
+
|
|
|
+import 'calculator.dart';
|
|
|
+
|
|
|
+class ShellCal extends Calculator<CarotidIMT, double> {
|
|
|
+ ShellCal(CarotidIMT ref) : super(ref);
|
|
|
+
|
|
|
+ @override
|
|
|
+ void calculate() {
|
|
|
+ if (ref.feature == null) return;
|
|
|
+ final p1 = ref.feature!.startPoint;
|
|
|
+ final p2 = ref.feature!.endPoint;
|
|
|
+ //左上顶点
|
|
|
+ final leftTopPoint =
|
|
|
+ DPoint(p1.x < p2.x ? p1.x : p2.x, p1.y < p2.y ? p1.y : p2.y);
|
|
|
+ //右下顶点
|
|
|
+ final rightBottomPoint =
|
|
|
+ DPoint(p1.x > p2.x ? p1.x : p2.x, p1.y > p2.y ? p1.y : p2.y);
|
|
|
+ final outputItem = createOutput(MeasureTerms.Distance, 0.0, VidUsUnit.cm);
|
|
|
+ //图片尺寸
|
|
|
+ final imageSize = ref.application.carotid2DSize;
|
|
|
+ //画布尺寸
|
|
|
+ final canavsSize = ref.application.displaySize;
|
|
|
+ //图像缩放比
|
|
|
+ final imageScale = ref.application.displayScaleRatio;
|
|
|
+ //标准画布尺寸
|
|
|
+ final stdCanavsSize =
|
|
|
+ Size(canavsSize.width / imageScale, canavsSize.height / imageScale);
|
|
|
+ final imageLeftTopPoint = DPoint(
|
|
|
+ (stdCanavsSize.width - imageSize.width) / 2,
|
|
|
+ (stdCanavsSize.height - imageSize.height) / 2);
|
|
|
+ final imageRightBottomPoint = DPoint(imageLeftTopPoint.x + imageSize.width,
|
|
|
+ imageLeftTopPoint.y + imageSize.height);
|
|
|
+ final rectLeftTopPoint = DPoint(stdCanavsSize.width * leftTopPoint.x,
|
|
|
+ stdCanavsSize.height * leftTopPoint.y);
|
|
|
+ final rectRightBottomPoint = DPoint(
|
|
|
+ stdCanavsSize.width * rightBottomPoint.x,
|
|
|
+ stdCanavsSize.height * rightBottomPoint.y);
|
|
|
+
|
|
|
+ /// 在图像外的点改到图像边缘上
|
|
|
+ if (rectLeftTopPoint.x < imageLeftTopPoint.x) {
|
|
|
+ rectLeftTopPoint.x = imageLeftTopPoint.x;
|
|
|
+ }
|
|
|
+ if (rectLeftTopPoint.x > imageRightBottomPoint.x) {
|
|
|
+ rectLeftTopPoint.x = imageRightBottomPoint.x;
|
|
|
+ }
|
|
|
+ if (rectLeftTopPoint.y < imageLeftTopPoint.y) {
|
|
|
+ rectLeftTopPoint.y = imageLeftTopPoint.y;
|
|
|
+ }
|
|
|
+ if (rectLeftTopPoint.y > imageRightBottomPoint.y) {
|
|
|
+ rectLeftTopPoint.y = imageRightBottomPoint.y;
|
|
|
+ }
|
|
|
+ if (rectRightBottomPoint.x > imageRightBottomPoint.x) {
|
|
|
+ rectRightBottomPoint.x = imageRightBottomPoint.x;
|
|
|
+ }
|
|
|
+ if (rectRightBottomPoint.x < imageLeftTopPoint.x) {
|
|
|
+ rectRightBottomPoint.x = imageLeftTopPoint.x;
|
|
|
+ }
|
|
|
+ if (rectRightBottomPoint.y > imageRightBottomPoint.y) {
|
|
|
+ rectRightBottomPoint.y = imageRightBottomPoint.y;
|
|
|
+ }
|
|
|
+ if (rectRightBottomPoint.y < imageLeftTopPoint.y) {
|
|
|
+ rectRightBottomPoint.y = imageLeftTopPoint.y;
|
|
|
+ }
|
|
|
+
|
|
|
+ final rectLeft = (rectLeftTopPoint.x - imageLeftTopPoint.x).round();
|
|
|
+ final rectTop = (rectLeftTopPoint.y - imageLeftTopPoint.y).round();
|
|
|
+ final rectWidth = (rectRightBottomPoint.x - rectLeftTopPoint.x).round();
|
|
|
+ final rectHeight = (rectRightBottomPoint.y - rectLeftTopPoint.y).round();
|
|
|
+ final params =
|
|
|
+ "{'MeasureItemType':'AntMeasureItem','IntimaRect':{'Left':$rectLeft,'Top':$rectTop,'Width':$rectWidth,'Height':$rectHeight}}";
|
|
|
+
|
|
|
+ String description = "IMT\n Measuring";
|
|
|
+
|
|
|
+ /// [Carotid] ✅在此处通知 Shell 计算,获取 description,touch/mouse finished 时绘制结果
|
|
|
+ try {
|
|
|
+ callShellMethod('getMeasureResult', [params]).callMethod(
|
|
|
+ 'then',
|
|
|
+ [
|
|
|
+ (result) {
|
|
|
+ // print("getMeasureResult: $result");
|
|
|
+ final res = jsonDecode(result);
|
|
|
+ // print("getMeasureResult: $res");
|
|
|
+ // print("getMeasureResult: ${res['ErrorCode']}");
|
|
|
+ if (res['ErrorCode'].toString() == "1000") {
|
|
|
+ description =
|
|
|
+ "Ant.CCA IMT\n Max: ${res['MaxThickness'].toStringAsFixed(2)}mm\n Min: ${res['MinThickness'].toStringAsFixed(2)}mm\n Avg: ${res['AverageThickness'].toStringAsFixed(2)}mm\n SD: ${res['SdThickness'].toStringAsFixed(2)}mm";
|
|
|
+ List<Offset> lowerPoints = [];
|
|
|
+ List<Offset> upperPoints = [];
|
|
|
+ for (var i = 0; i < res['PointLower'].length; i++) {
|
|
|
+ final xyStr = res['PointLower'][i].split(',');
|
|
|
+ lowerPoints.add(Offset(
|
|
|
+ (double.parse(xyStr[0]) + imageLeftTopPoint.x) * imageScale,
|
|
|
+ (double.parse(xyStr[1]) + imageLeftTopPoint.y) *
|
|
|
+ imageScale));
|
|
|
+ }
|
|
|
+ for (var i = 0; i < res['PointUpper'].length; i++) {
|
|
|
+ final xyStr = res['PointUpper'][i].split(',');
|
|
|
+ upperPoints.add(Offset(
|
|
|
+ (double.parse(xyStr[0]) + imageLeftTopPoint.x) * imageScale,
|
|
|
+ (double.parse(xyStr[1]) + imageLeftTopPoint.y) *
|
|
|
+ imageScale));
|
|
|
+ }
|
|
|
+ ref.feature!.offsetsList.add(lowerPoints);
|
|
|
+ ref.feature!.offsetsList.add(upperPoints);
|
|
|
+ } else {
|
|
|
+ description = "Ant.CCA IMT\n Measure failed";
|
|
|
+ }
|
|
|
+ outputs.add(outputItem);
|
|
|
+ outputs.last.updateDescription(description: description);
|
|
|
+
|
|
|
+ /// [Carotid] ✅在此处通知canvas 重绘结果
|
|
|
+
|
|
|
+ ref.application.updateRenderReady.emit(this, null);
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ );
|
|
|
+ } catch (e) {
|
|
|
+ outputs.add(outputItem);
|
|
|
+ outputs.last
|
|
|
+ .updateDescription(description: "Ant.CCA IMT\n Measure failed");
|
|
|
+ print(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|