public static AimTemplateTree AimAnnotationToAimTemplateTree(Aim4AnnotationInstance annotationInstance, AimTemplateTree template) { if (annotationInstance == null || annotationInstance.AimAnnotationEntity == null) return null; var annotation = annotationInstance.AimAnnotationEntity; if (annotation.ImagingPhysicalEntityCollection != null) { foreach (var imgPhysEnt in annotation.ImagingPhysicalEntityCollection) { if (IsNullCodeList(imgPhysEnt.TypeCode)) continue; AimTemplateTreeAnatomicEntityNode matchingTreeNode = FromImagingPhysicalEntity(imgPhysEnt, template); if (matchingTreeNode == null) return null; } } if (annotation.ImagingObservationEntityCollection != null) { foreach (var io in annotation.ImagingObservationEntityCollection) { if (IsNullCodeList(io.TypeCode)) continue; AimTemplateTreeImagingObservationNode matchingTreeNode = FromImagingObservationEntity(io, template); if (matchingTreeNode == null) return null; } } if (annotation.CalculationEntityCollection != 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.InferenceEntityCollection != null) { foreach (var inference in annotation.InferenceEntityCollection) { if (IsNullCodeList(inference.TypeCode)) continue; foreach (var inferenceNode in template.TemplateNodes.OfType<AimTemplateTreeInferenceNode>()) { AimTemplateTreeAllowedTerm matchingAllowedTerm = inferenceNode.AllowedTerms.FirstOrDefault(term => DoTheyMatch(term, inference.TypeCode)); if (matchingAllowedTerm != null) matchingAllowedTerm.Selected = true; } } } template.Markup.Clear(); if (annotation is aim4_dotnet.ImageAnnotation) { var imageAnnotation = (aim4_dotnet.ImageAnnotation)annotation; var annotationName = string.IsNullOrEmpty(imageAnnotation.Name) ? "" : imageAnnotation.Name; if (imageAnnotation.MarkupEntityCollection != null) { foreach (var markupEntity in imageAnnotation.MarkupEntityCollection) { if (markupEntity is aim4_dotnet.GeometricShapeEntity) { var markup = ToMarkup2D((aim4_dotnet.GeometricShapeEntity)markupEntity, annotationName); if (markup != null) template.Markup.Add(markup); } else if (markupEntity is aim4_dotnet.TextAnnotationEntity) { var textAnnotationEntity = (aim4_dotnet.TextAnnotationEntity) markupEntity; if (textAnnotationEntity.GeometricShapeEntity != null) { var calloutText = AimHelpers.FormatPointCalloutText(annotationName, textAnnotationEntity.Text); aim4_dotnet.TwoDimensionGeometricShapeEntity geoShapeEntity = null; if (textAnnotationEntity.GeometricShapeEntity is aim4_dotnet.TwoDimensionGeometricShapeEntity) { var twoDGeoShape = (aim4_dotnet.TwoDimensionGeometricShapeEntity) textAnnotationEntity.GeometricShapeEntity; switch (twoDGeoShape.TwoDimensionSpatialCoordinateCollection.Count) { case 1: { var markup = new MarkupPoint(); markup.Name = annotationName; markup.IncludeInAnnotation = twoDGeoShape.IncludeFlag; markup.Point = AsPointF(twoDGeoShape.TwoDimensionSpatialCoordinateCollection[0]); markup.CalloutText = calloutText; markup.CalloutLocation = new PointF(markup.Point.X, markup.Point.Y); SetMarkupImageReference(markup, twoDGeoShape); markup.UseCrosshair = AimSettings.Default.UseCrosshairsForTextCallouts; template.Markup.Add(markup); } break; case 2: { var markup = new MarkupPoint(); markup.Name = annotationName; markup.IncludeInAnnotation = twoDGeoShape.IncludeFlag; markup.Point = AsPointF(twoDGeoShape.TwoDimensionSpatialCoordinateCollection[0]); markup.CalloutText = calloutText; markup.CalloutLocation = AsPointF(twoDGeoShape.TwoDimensionSpatialCoordinateCollection[1]); SetMarkupImageReference(markup, twoDGeoShape); markup.UseCrosshair = AimSettings.Default.UseCrosshairsForTextCallouts; template.Markup.Add(markup); } break; default: Platform.Log(LogLevel.Error, "TextAnnotation has [{0}] Connector Points", twoDGeoShape.TwoDimensionSpatialCoordinateCollection.Count); break; } } else if (textAnnotationEntity.GeometricShapeEntity is aim4_dotnet.ThreeDimensionGeometricShapeEntity) { // TODO: implement 2D markup conversion! // TODO: convert to the 2D ImageReferenceUid and referencedFrameNumber! var threeDGeoShape = (aim4_dotnet.ThreeDimensionGeometricShapeEntity) textAnnotationEntity.GeometricShapeEntity; switch (threeDGeoShape.ThreeDimensionSpatialCoordinateCollection.Count) { case 1: throw new NotImplementedException(); break; case 2: throw new NotImplementedException(); break; default: Platform.Log(LogLevel.Error, "TextAnnotation has [{0}] 3D Connector Points", threeDGeoShape.ThreeDimensionSpatialCoordinateCollection.Count); break; } } } } else Debug.Assert(false, "Unexpected markup type"); } } } return template; }
public static IMarkup ToMarkup2D(aim4_dotnet.GeometricShapeEntity geometricShape, string markupText) { if (geometricShape == null) return null; if (geometricShape is aim4_dotnet.TwoDimensionPoint) { var point = (aim4_dotnet.TwoDimensionPoint)geometricShape; var markup = new MarkupPoint(); markup.Name = markupText; markup.IncludeInAnnotation = point.IncludeFlag; markup.Point = AsPointF(point.Center); markup.CalloutText = string.Empty; // markupText; markup.CalloutLocation = markup.Point - new SizeF(30, 30); SetMarkupImageReference(markup, point); return markup; } if (geometricShape is aim4_dotnet.TwoDimensionCircle) { var circle = (aim4_dotnet.TwoDimensionCircle)geometricShape; PointF centerPt = AsPointF(circle.Center); PointF radiusPt = AsPointF(circle.RadiusPoint); double radiusLength = Vector.Distance(centerPt, radiusPt); var markup = new MarkupEllipse(); markup.Name = markupText; markup.IncludeInAnnotation = circle.IncludeFlag; 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); return markup; } if (geometricShape is aim4_dotnet.TwoDimensionEllipse) { var ellipse = (aim4_dotnet.TwoDimensionEllipse)geometricShape; Debug.Assert(ellipse.TwoDimensionSpatialCoordinateCollection.Count == 4, "Ellipse must have four points"); var firstMajorAxisPt = AsPointF(ellipse.TwoDimensionSpatialCoordinateCollection[0]); var secondMajorAxisPt = AsPointF(ellipse.TwoDimensionSpatialCoordinateCollection[1]); var firstMinorAxisPt = AsPointF(ellipse.TwoDimensionSpatialCoordinateCollection[2]); var secondMinorAxisPt = AsPointF(ellipse.TwoDimensionSpatialCoordinateCollection[3]); var markup = new MarkupEllipse(); markup.Name = markupText; markup.IncludeInAnnotation = ellipse.IncludeFlag; 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); return markup; } if (geometricShape is aim4_dotnet.TwoDimensionPolyline) { var polyline = (aim4_dotnet.TwoDimensionPolyline)geometricShape; // Check if this is a non-rotated rectangle if (polyline.TwoDimensionSpatialCoordinateCollection.Count == 4) { PointF twoDPoint1 = AsPointF(polyline.TwoDimensionSpatialCoordinateCollection[0]); PointF twoDPoint2 = AsPointF(polyline.TwoDimensionSpatialCoordinateCollection[1]); PointF twoDPoint3 = AsPointF(polyline.TwoDimensionSpatialCoordinateCollection[2]); PointF twoDPoint4 = AsPointF(polyline.TwoDimensionSpatialCoordinateCollection[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 MarkupRectangle(); markupRectangle.TopLeft = twoDPoint1; markupRectangle.BottomRight = twoDPoint3; markupRectangle.Name = markupText; markupRectangle.IncludeInAnnotation = polyline.IncludeFlag; markupRectangle.CalloutLocation = markupRectangle.TopLeft - new SizeF(30, 30); SetMarkupImageReference(markupRectangle, polyline); return markupRectangle; } } var points = new List<PointF>(); foreach (var spatialCoordinate in polyline.TwoDimensionSpatialCoordinateCollection) if (spatialCoordinate != null) points.Add(AsPointF(spatialCoordinate)); var markup = new MarkupPolygonal(); markup.Vertices = points; markup.Name = markupText; markup.IncludeInAnnotation = polyline.IncludeFlag; markup.CalloutLocation = markup.Vertices[0] - new SizeF(30, 30); SetMarkupImageReference(markup, polyline); return markup; } if (geometricShape is aim4_dotnet.TwoDimensionMultiPoint) { var multiPoint = (aim4_dotnet.TwoDimensionMultiPoint)geometricShape; IMarkup markup; switch (multiPoint.TwoDimensionSpatialCoordinateCollection.Count) { case 2: { // Line var markupLinear = new MarkupLinear(); markupLinear.Vertices = new List<PointF>(2); markupLinear.Vertices.Add(AsPointF(multiPoint.TwoDimensionSpatialCoordinateCollection[0])); markupLinear.Vertices.Add(AsPointF(multiPoint.TwoDimensionSpatialCoordinateCollection[1])); markupLinear.CalloutLocation = markupLinear.Vertices[0] - new SizeF(30, 30); markup = markupLinear; } break; case 3: { // Protractor var markupProtractor = new MarkupProtractor(); markupProtractor.Points = new List<PointF>(3); markupProtractor.Points.Add(AsPointF(multiPoint.TwoDimensionSpatialCoordinateCollection[0])); markupProtractor.Points.Add(AsPointF(multiPoint.TwoDimensionSpatialCoordinateCollection[1])); markupProtractor.Points.Add(AsPointF(multiPoint.TwoDimensionSpatialCoordinateCollection[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.IncludeFlag; SetMarkupImageReference(markup, multiPoint); return markup; } // TODO - 3D GeoShapes Conversions throw new NotImplementedException(); return null; }