public static TemplateTree.IMarkup ToMarkup(aim_dotnet.IGeometricShape geometricShape, string markupText) { if (geometricShape == null) return null; if (geometricShape is aim_dotnet.Point) { var point = (aim_dotnet.Point)geometricShape; var markup = new TemplateTree.MarkupPoint(); markup.Name = markupText; markup.IncludeInAnnotation = point.IsIncludeFlag; markup.Point = AimNativeConverter.AsPointF(point.Center); markup.CalloutText = string.Empty; // markupText; markup.CalloutLocation = markup.Point - new SizeF(30, 30); SetMarkupImageReference(markup, point.Center); return markup; } if (geometricShape is aim_dotnet.Circle) { var circle = (aim_dotnet.Circle)geometricShape; PointF centerPt = AimNativeConverter.AsPointF(circle.Center); PointF radiusPt = AimNativeConverter.AsPointF(circle.RadiusPoint); double radiusLength = Vector.Distance(centerPt, radiusPt); var markup = new TemplateTree.MarkupEllipse(); markup.Name = markupText; markup.IncludeInAnnotation = circle.IsIncludeFlag; markup.TopLeft = new PointF((float)(centerPt.X - radiusLength), (float)(centerPt.Y - radiusLength)); markup.BottomRight = new PointF((float)(centerPt.X + radiusLength), (float)(centerPt.Y + radiusLength)); markup.CalloutLocation = markup.TopLeft - new SizeF(30, 30); SetMarkupImageReference(markup, circle.Center); return markup; } if (geometricShape is aim_dotnet.Ellipse) { var ellipse = (aim_dotnet.Ellipse)geometricShape; Debug.Assert(ellipse.EllipseCollection.Count == 4, "Ellipse must have four points"); var firstMajorAxisPt = AimNativeConverter.AsPointF(ellipse.EllipseCollection[0]); var secondMajorAxisPt = AimNativeConverter.AsPointF(ellipse.EllipseCollection[1]); var firstMinorAxisPt = AimNativeConverter.AsPointF(ellipse.EllipseCollection[2]); var secondMinorAxisPt = AimNativeConverter.AsPointF(ellipse.EllipseCollection[3]); var markup = new TemplateTree.MarkupEllipse(); markup.Name = markupText; markup.IncludeInAnnotation = ellipse.IsIncludeFlag; markup.TopLeft = new PointF(firstMajorAxisPt.X, firstMinorAxisPt.Y); markup.BottomRight = new PointF(secondMajorAxisPt.X, secondMinorAxisPt.Y); markup.CalloutLocation = markup.TopLeft - new SizeF(30, 30); SetMarkupImageReference(markup, ellipse.EllipseCollection[0]); return markup; } if (geometricShape is aim_dotnet.Polyline) { var polyline = (aim_dotnet.Polyline)geometricShape; // Check if this is a non-rotated rectangle if (polyline.SpatialCoordinateCollection.Count == 4) { PointF twoDPoint1 = AimNativeConverter.AsPointF(polyline.SpatialCoordinateCollection[0]); PointF twoDPoint2 = AimNativeConverter.AsPointF(polyline.SpatialCoordinateCollection[1]); PointF twoDPoint3 = AimNativeConverter.AsPointF(polyline.SpatialCoordinateCollection[2]); PointF twoDPoint4 = AimNativeConverter.AsPointF(polyline.SpatialCoordinateCollection[3]); // If it's a rectangle with sides parallel to the axes if ((twoDPoint1.X == twoDPoint2.X && twoDPoint2.Y == twoDPoint3.Y && twoDPoint3.X == twoDPoint4.X && twoDPoint4.Y == twoDPoint1.Y) || (twoDPoint1.Y == twoDPoint2.Y && twoDPoint2.X == twoDPoint3.X && twoDPoint3.Y == twoDPoint4.Y && twoDPoint4.X == twoDPoint1.X)) { var markupRectangle = new TemplateTree.MarkupRectangle(); markupRectangle.TopLeft = twoDPoint1; markupRectangle.BottomRight = twoDPoint3; markupRectangle.Name = markupText; markupRectangle.IncludeInAnnotation = polyline.IsIncludeFlag; markupRectangle.CalloutLocation = markupRectangle.TopLeft - new SizeF(30, 30); SetMarkupImageReference(markupRectangle, polyline.SpatialCoordinateCollection[0]); return markupRectangle; } } var points = new List<PointF>(); foreach (var spatialCoordinate in polyline.SpatialCoordinateCollection) if (spatialCoordinate is aim_dotnet.TwoDimensionSpatialCoordinate) points.Add(AimNativeConverter.AsPointF(spatialCoordinate)); var markup = new TemplateTree.MarkupPolygonal(); markup.Vertices = points; markup.Name = markupText; markup.IncludeInAnnotation = polyline.IsIncludeFlag; markup.CalloutLocation = markup.Vertices[0] - new SizeF(30, 30); SetMarkupImageReference(markup, polyline.SpatialCoordinateCollection[0]); return markup; } if (geometricShape is aim_dotnet.MultiPoint) { var multiPoint = (aim_dotnet.MultiPoint)geometricShape; TemplateTree.IMarkup markup; switch (multiPoint.SpatialCoordinateCollection.Count) { case 2: { // Line var markupLinear = new TemplateTree.MarkupLinear(); markupLinear.Vertices = new List<PointF>(2); markupLinear.Vertices.Add(AimNativeConverter.AsPointF(multiPoint.SpatialCoordinateCollection[0])); markupLinear.Vertices.Add(AimNativeConverter.AsPointF(multiPoint.SpatialCoordinateCollection[1])); markupLinear.CalloutLocation = markupLinear.Vertices[0] - new SizeF(30, 30); markup = markupLinear; } break; case 3: { // Protractor var markupProtractor = new TemplateTree.MarkupProtractor(); markupProtractor.Points = new List<PointF>(3); markupProtractor.Points.Add(AimNativeConverter.AsPointF(multiPoint.SpatialCoordinateCollection[0])); markupProtractor.Points.Add(AimNativeConverter.AsPointF(multiPoint.SpatialCoordinateCollection[1])); markupProtractor.Points.Add(AimNativeConverter.AsPointF(multiPoint.SpatialCoordinateCollection[2])); markupProtractor.CalloutLocation = markupProtractor.Points[0] - new SizeF(30, 30); markup = markupProtractor; } break; default: throw new NotImplementedException("Reading non-linear or non-triangular MultiPoint shape is not implemented"); } markup.Name = markupText; markup.IncludeInAnnotation = multiPoint.IsIncludeFlag; SetMarkupImageReference(markup, multiPoint.SpatialCoordinateCollection[0]); return markup; } throw new NotImplementedException(); return null; }
public static TemplateTree.AimTemplateTree AimAnnotationToAimTemplateTree(Aim3AnnotationInstance annotationInstance, TemplateTree.AimTemplateTree template) { if (annotationInstance == null || annotationInstance.AimAnnotation == null) return null; var annotation = annotationInstance.AimAnnotation; if (annotation.AnatomyEntityCollection != null) { foreach (var ae in annotation.AnatomyEntityCollection) { if (IsNullCodeSequence(ToStandardCodeSequence(ae))) continue; TemplateTree.AimTemplateTreeAnatomicEntityNode matchingTreeNode = template.TemplateNodes.OfType<TemplateTree.AimTemplateTreeAnatomicEntityNode>().FirstOrDefault(treeAe => treeAe.Label == ae.Label); if (matchingTreeNode != null) { TemplateTree.AimTemplateTreeAllowedTerm matchingAllowedTerm = matchingTreeNode.AllowedTerms.FirstOrDefault(treeAe => ToStandardCodeSequence(treeAe).CodeValue == ae.CodeValue); if (matchingAllowedTerm != null) { matchingAllowedTerm.Selected = true; } else return null; if (matchingTreeNode.HasConfidence && ae.AnnotatorConfidence.HasValue) matchingTreeNode.ConfidenceValue = ae.AnnotatorConfidence.Value; } else return null; if (ae.AnatomicEntityCharacteristicCollection != null) { foreach (var aec in ae.AnatomicEntityCharacteristicCollection) { if (IsNullCodeSequence(ToStandardCodeSequence(aec))) continue; TemplateTree.AimTemplateTreeAnatomicEntityCharacteristicNode matchingAecTreeNode = matchingTreeNode.AnatomicEntityCharacteristicTreeNodes.FirstOrDefault(treeAec => treeAec.Label == aec.Label); if (matchingAecTreeNode != null) { TemplateTree.CharacteristicQuantificationAllowedTerm matchingAllowedTerm = matchingAecTreeNode.CharacteristicQuantificationAllowedTerms.FirstOrDefault(treeAec => ToStandardCodeSequence(treeAec).CodeValue == aec.CodeValue); if (matchingAllowedTerm != null) { matchingAllowedTerm.Selected = true; foreach (var quantification in matchingAllowedTerm.CharacteristicQuantifications) { if (ReadBackCharacteristicQuantificationFromAnnotation(aec.CharacteristicQuantificationCollection, quantification) == null) return null; } } else return null; if (matchingAecTreeNode.HasConfidence && aec.AnnotatorConfidence.HasValue) matchingAecTreeNode.ConfidenceValue = aec.AnnotatorConfidence.Value; } else return null; } } } } if (annotation.ImagingObservationCollection != null) { foreach (var io in annotation.ImagingObservationCollection) { if (IsNullCodeSequence(ToStandardCodeSequence(io))) continue; TemplateTree.AimTemplateTreeImagingObservationNode matchingTreeNode = template.TemplateNodes.OfType<TemplateTree.AimTemplateTreeImagingObservationNode>().FirstOrDefault( treeIo => treeIo.Label == io.Label); if (matchingTreeNode != null) { TemplateTree.AimTemplateTreeAllowedTerm matchingAllowedTerm = matchingTreeNode.AllowedTerms.FirstOrDefault( treeIo => ToStandardCodeSequence(treeIo).CodeValue == io.CodeValue); if (matchingAllowedTerm != null) { matchingAllowedTerm.Selected = true; } else return null; if (matchingTreeNode.HasConfidence && io.AnnotatorConfidence.HasValue) matchingTreeNode.ConfidenceValue = io.AnnotatorConfidence.Value; } else return null; if (io.ImagingObservationCharacteristicCollection != null) { foreach (var ioc in io.ImagingObservationCharacteristicCollection) { if (IsNullCodeSequence(ToStandardCodeSequence(ioc))) continue; TemplateTree.AimTemplateTreeImagingObservationCharacteristicNode matchingIocTreeNode = matchingTreeNode.ImagingObservationCharacteristicTreeNodes.FirstOrDefault( treeIoc => treeIoc.Label == ioc.Label); if (matchingIocTreeNode != null) { TemplateTree.CharacteristicQuantificationAllowedTerm matchingAllowedTerm = matchingIocTreeNode.CharacteristicQuantificationAllowedTerms.FirstOrDefault( treeIoc => ToStandardCodeSequence(treeIoc).CodeValue == ioc.CodeValue); if (matchingAllowedTerm != null) { matchingAllowedTerm.Selected = true; foreach (var quantification in matchingAllowedTerm.CharacteristicQuantifications) { if (ReadBackCharacteristicQuantificationFromAnnotation(ioc.CharacteristicQuantificationCollection, quantification) == null) return null; } } else return null; if (matchingIocTreeNode.HasConfidence && ioc.AnnotatorConfidence.HasValue) matchingIocTreeNode.ConfidenceValue = ioc.AnnotatorConfidence.Value; } else return null; } } } } if (annotation.CalculationCollection != null) { //foreach (var calc in annotation.CalculationCollection) //{ // AimTemplateTreeCalculationNode matchingTreeNode = // template.TemplateNodes.OfType<AimTemplateTreeCalculationNode>().FirstOrDefault( // treeCalc => treeCalc.Label == calc.Description); // if (matchingTreeNode != null) // { // AimTemplateTreeCalculationType matchingCalculationType = // matchingTreeNode.CalculationTypes.FirstOrDefault( // treeCalc => ToStandardCodeSequence(treeCalc).CodeValue == calc.CodeValue); // if (matchingCalculationType != null) // { // matchingTreeNode.SelectedCalculationType = matchingCalculationType; // } // else // return null; // //if (matchingTreeNode.HasConfidence && calc..HasValue) // // matchingTreeNode.ConfidenceValue = calc.AnnotatorConfidence.Value; // } // else // return null; //} } if (annotation.InferenceCollection != null) { foreach (var inference in annotation.InferenceCollection) { if (IsNullCodeSequence(ToStandardCodeSequence(inference))) continue; foreach (var inferenceNode in template.TemplateNodes.OfType<TemplateTree.AimTemplateTreeInferenceNode>()) { TemplateTree.AimTemplateTreeAllowedTerm matchingAllowedTerm = inferenceNode.AllowedTerms.FirstOrDefault( term => ToStandardCodeSequence(term).CodeValue == inference.CodeValue); if (matchingAllowedTerm != null) matchingAllowedTerm.Selected = true; } } } template.Markup.Clear(); if (annotation is aim_dotnet.ImageAnnotation) { var imageAnnotation = (aim_dotnet.ImageAnnotation)annotation; var annotationName = string.IsNullOrEmpty(imageAnnotation.Name) ? "" : imageAnnotation.Name; if (imageAnnotation.GeometricShapeCollection != null) { foreach (var geometricShape in imageAnnotation.GeometricShapeCollection) { var markup = ToMarkup(geometricShape, annotationName); if (markup != null) template.Markup.Add(markup); } } if (imageAnnotation.TextAnnotationCollection != null) { foreach (var textAnnotation in imageAnnotation.TextAnnotationCollection) { if (textAnnotation.ConnectorPoints != null && textAnnotation.ConnectorPoints.SpatialCoordinateCollection != null) { var calloutText = AimHelpers.FormatPointCalloutText(annotationName, textAnnotation.Text); switch (textAnnotation.ConnectorPoints.SpatialCoordinateCollection.Count) { case 1: { var markup = new TemplateTree.MarkupPoint(); markup.Name = annotationName; markup.IncludeInAnnotation = textAnnotation.ConnectorPoints.IsIncludeFlag; markup.Point = AimNativeConverter.AsPointF(textAnnotation.ConnectorPoints.SpatialCoordinateCollection[0]); markup.CalloutText = calloutText; markup.CalloutLocation = new PointF(markup.Point.X, markup.Point.Y); SetMarkupImageReference(markup, textAnnotation.ConnectorPoints.SpatialCoordinateCollection[0]); markup.UseCrosshair = AimSettings.Default.UseCrosshairsForTextCallouts; template.Markup.Add(markup); } break; case 2: { var markup = new TemplateTree.MarkupPoint(); markup.Name = annotationName; markup.IncludeInAnnotation = textAnnotation.ConnectorPoints.IsIncludeFlag; markup.Point = AimNativeConverter.AsPointF(textAnnotation.ConnectorPoints.SpatialCoordinateCollection[0]); markup.CalloutText = calloutText; markup.CalloutLocation = AimNativeConverter.AsPointF(textAnnotation.ConnectorPoints.SpatialCoordinateCollection[1]); SetMarkupImageReference(markup, textAnnotation.ConnectorPoints.SpatialCoordinateCollection[0]); markup.UseCrosshair = AimSettings.Default.UseCrosshairsForTextCallouts; template.Markup.Add(markup); } break; default: Platform.Log(LogLevel.Error, "TextAnnotation has [{0}] Connector Points", textAnnotation.ConnectorPoints.SpatialCoordinateCollection.Count); break; } } } } } return template; }