public AimGraphic(IGraphic graphic, aim_dotnet.ImageAnnotation imageAnnotation, int shapeIdentifier) : base(graphic) { _imageAnnotation = imageAnnotation; _shapeIdentifier = shapeIdentifier; _graphic = graphic; }
internal Aim3ObjectReference(aim_dotnet.Annotation aimAnnotation) { AimAnnotation = aimAnnotation; }
private static string GetImageSOPInstanceUID(aim_dotnet.IGeometricShape geoShape) { if (geoShape.SpatialCoordinateCollection != null && geoShape.SpatialCoordinateCollection.Count > 0 && geoShape.SpatialCoordinateCollection[0].CoordinateType == aim_dotnet.SpatialCoordinateType.SPATIAL_COORD_2D) { var twoDSpatialCoord = geoShape.SpatialCoordinateCollection[0] as aim_dotnet.TwoDimensionSpatialCoordinate; if (twoDSpatialCoord != null) return twoDSpatialCoord.ImageReferenceUID; } return string.Empty; }
private static PointF AsPointF(aim_dotnet.ISpatialCoordinate spatialCoord) { Platform.CheckTrue(spatialCoord != null, "Spatial Coordinate Exists"); Platform.CheckTrue(spatialCoord.CoordinateType == aim_dotnet.SpatialCoordinateType.SPATIAL_COORD_2D, "SpatialCoordinate is 2D"); var twoDCoord = spatialCoord as aim_dotnet.TwoDimensionSpatialCoordinate; if (twoDCoord == null) throw new ArgumentException("Spatial coordinate is not 2D"); return new PointF((float)twoDCoord.X, (float)twoDCoord.Y); }
public static bool WriteXmlAnnotationToFile(aim_dotnet.Annotation annotation, string filePathName) { var xmlModel = new aim_dotnet.XmlModel(); try { xmlModel.WriteAnnotationToFile(annotation, filePathName); return true; } catch (Exception ex) { Platform.Log(LogLevel.Error, ex, "Failed to save annotation to file \"{0}\"", filePathName); } finally { xmlModel = null; } return false; }
public static string GetAimHtml(aim_dotnet.Annotation annotation) { if (annotation == null) return GetEmptyHtml(); switch (annotation.AnnotationKind) { case aim_dotnet.AnnotationKind.AK_ImageAnnotation: return GetImageAnnotationHtml(annotation as aim_dotnet.ImageAnnotation); case aim_dotnet.AnnotationKind.AK_AnnotationOfAnnotation: return GetAnnotationOfAnnotationHtml(annotation as aim_dotnet.AnnotationOfAnnotation); } Debug.Assert(false, "Uknown Annotation Type"); Platform.Log(LogLevel.Error, "Annotation Display Formatting (HTML): unknown annotation type"); return "Unknown Annotation Type"; }
private static string OperatorToString(aim_dotnet.ComparisonOperatorIdentifier operatorIdentifier, bool capFirst) { switch(operatorIdentifier) { case aim_dotnet.ComparisonOperatorIdentifier.Equal: return capFirst ? "Equal to" : "equal to"; case aim_dotnet.ComparisonOperatorIdentifier.NotEqual: return capFirst ? "Not equal to" : "not equal to"; case aim_dotnet.ComparisonOperatorIdentifier.LessThan: return capFirst ? "Less than" : "less than"; case aim_dotnet.ComparisonOperatorIdentifier.LessThanEqual: return capFirst ? "Less than or equal" : "less than or equal"; case aim_dotnet.ComparisonOperatorIdentifier.GreaterThan: return capFirst ? "Greater than" : "greater than"; case aim_dotnet.ComparisonOperatorIdentifier.GreaterThanEqual: return capFirst ? "Greater than or equal" : "greater than or equal"; case aim_dotnet.ComparisonOperatorIdentifier.None: return capFirst ? "None" : "none"; case aim_dotnet.ComparisonOperatorIdentifier.InvalidComparisonOperator: return capFirst ? "Invalid" : "invalid"; } return string.Empty; }
private static string GetAnnotationOfAnnotationHtml(aim_dotnet.AnnotationOfAnnotation annotationOfAnnotation) { throw new NotImplementedException(); }
public static bool AimDotNetNonQuantifiableEqualsTemplateTreeNonQuantifiable(aim_dotnet.NonQuantifiable a, TemplateTree.StandardCodedTerm b) { return String.Equals(a.CodeValue, b.CodeValue) && String.Equals(a.CodeMeaning, b.CodeMeaning) && StringEquals(a.CodingSchemeVersion, b.CodingSchemeVersion) && String.Equals(a.CodingSchemeDesignator, b.CodingSchemeDesignator); }
public static bool AimDotNetIntervalEqualsTemplateTreeInterval(aim_dotnet.Interval a, TemplateTree.Interval b) { return a.MinValue == b.MinValue && a.MaxValue == b.MaxValue && a.MinOperator == ToAimComparisonOperator(b.MinOperator) && a.MaxOperator == ToAimComparisonOperator(b.MaxOperator) && a.UcumString == b.UcumString; }
// Retrieves SOP Instance UID and Referenced Frame Number from the coordinate private static void SetMarkupImageReference(TemplateTree.IMarkup markup, aim_dotnet.ISpatialCoordinate spatialCoordinate) { if (spatialCoordinate.CoordinateType == aim_dotnet.SpatialCoordinateType.SPATIAL_COORD_2D) { var twoDSpatialCoord = spatialCoordinate as aim_dotnet.TwoDimensionSpatialCoordinate; if (twoDSpatialCoord != null) { Debug.Assert(twoDSpatialCoord.ReferencedFrameNumber > 0, "Referenced Frame Number must be positive"); markup.PresentationImageUid = twoDSpatialCoord.ImageReferenceUID; markup.FrameNumber = twoDSpatialCoord.ReferencedFrameNumber; } } else { Debug.Assert(false, "Setting image references is not implemented for 3D"); } }
public static TemplateTree.StandardCodeSequence ToStandardCodeSequence(aim_dotnet.Inference inference) { return inference == null ? null : new TemplateTree.StandardCodeSequence(inference.CodeValue, inference.CodeMeaning, inference.CodingSchemeDesignator, inference.CodingSchemeVersion); }
public static TemplateTree.StandardCodeSequence ToStandardCodeSequence(aim_dotnet.ImagingObservationCharacteristic imagingObservationCharacteristic) { return imagingObservationCharacteristic == null ? null : new TemplateTree.StandardCodeSequence(imagingObservationCharacteristic.CodeValue, imagingObservationCharacteristic.CodeMeaning, imagingObservationCharacteristic.CodingSchemeDesignator, imagingObservationCharacteristic.CodingSchemeVersion); }
public static TemplateTree.StandardCodeSequence ToStandardCodeSequence(aim_dotnet.AnatomicEntityCharacteristic anatomicEntityCharacteristic) { return anatomicEntityCharacteristic == null ? null : new TemplateTree.StandardCodeSequence(anatomicEntityCharacteristic.CodeValue, anatomicEntityCharacteristic.CodeMeaning, anatomicEntityCharacteristic.CodingSchemeDesignator, anatomicEntityCharacteristic.CodingSchemeVersion); }
internal DataProvider(aim_dotnet.Annotation annotation) { Platform.CheckForNullReference(annotation, "Annotation"); _annotation = annotation; }
public static bool AimDotNetNumericalEqualsTemplateTreeNumerical(aim_dotnet.Numerical a, TemplateTree.Numerical b) { return a.Value == b.Value && a.UcumString == b.UcumString && a.Operator == ToAimComparisonOperator(b.Operator); }
private static string CombineOperatorAndValue(aim_dotnet.ComparisonOperatorIdentifier operatorIdentifier, string aValue, bool capFirst) { aValue = aValue.Trim(); if (operatorIdentifier == aim_dotnet.ComparisonOperatorIdentifier.None || operatorIdentifier == aim_dotnet.ComparisonOperatorIdentifier.InvalidComparisonOperator) return string.IsNullOrEmpty(aValue) ? "" : aValue; if (string.IsNullOrEmpty(aValue)) return OperatorToString(operatorIdentifier, capFirst); return string.Format("{0} {1}", OperatorToString(operatorIdentifier, capFirst), aValue); }
public static bool AimDotNetScaleEqualsTemplateTreeScaleLevel(aim_dotnet.Scale a, TemplateTree.ScaleLevel b) { return a.Value == b.Value; }
private static string GetImageAnnotationHtml(aim_dotnet.ImageAnnotation imageAnnotation) { var sb = new StringBuilder(); var htmlFormatter = new AimHtmlFormatter(); var ctrlColor = Color.FromKnownColor(KnownColor.Control); sb.Append(HtmlDocHeader); sb.AppendFormat("<body style=\"background-color: #{0}{1}{2};\" onload=\"setupPaths(['{3}', '{4}'])\">", ctrlColor.R.ToString("X2"), ctrlColor.G.ToString("X2"), ctrlColor.B.ToString("X2"), MinusImagePathName, PlusImagePathName); sb.Append("<div id=\"main_content\">"); sb.Append(htmlFormatter.GetAnatomicEntitiesHtml(imageAnnotation.AnatomyEntityCollection)); sb.Append(htmlFormatter.GetImagingObservationHtml(imageAnnotation.ImagingObservationCollection)); sb.Append("</div>"); sb.Append("</body>"); sb.Append("</html>"); return sb.ToString(); }
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; }
private string GetCharacteristicQuantificationHtml(aim_dotnet.ICharacteristicQuantification characteristicQuantification) { if (characteristicQuantification == null) return ""; switch (characteristicQuantification.QuantificationType) { case aim_dotnet.CharacteristicQuantificationType.Numerical: var numerical = (aim_dotnet.Numerical) characteristicQuantification; return numerical.Operator == aim_dotnet.ComparisonOperatorIdentifier.InvalidComparisonOperator || numerical.Operator == aim_dotnet.ComparisonOperatorIdentifier.None ? string.Format("{0} {1}", numerical.Value, numerical.UcumString) : string.Format("{0} {1} {2}", OperatorToString(numerical.Operator, true), numerical.Value, numerical.UcumString); case aim_dotnet.CharacteristicQuantificationType.Quantile: var quantile = (aim_dotnet.Quantile) characteristicQuantification; return string.Format("Quantile [{0}]", quantile.Bin); case aim_dotnet.CharacteristicQuantificationType.NonQuantifiable: var nonQuantifiable = (aim_dotnet.NonQuantifiable) characteristicQuantification; return nonQuantifiable.CodeMeaning ?? ""; case aim_dotnet.CharacteristicQuantificationType.Scale: var scale = (aim_dotnet.Scale) characteristicQuantification; return scale.Value ?? ""; case aim_dotnet.CharacteristicQuantificationType.Interval: var interval = (aim_dotnet.Interval) characteristicQuantification; { var left = CombineOperatorAndValue(interval.MinOperator, interval.MinValue == double.MinValue ? "" : interval.MinValue.ToString(), true); var right = CombineOperatorAndValue(interval.MaxOperator, interval.MaxValue == double.MaxValue ? "" : interval.MaxValue.ToString(), string.IsNullOrEmpty(left)); var sb = new StringBuilder(); sb.Append(left); if (!string.IsNullOrEmpty(left) && !string.IsNullOrEmpty(right)) sb.Append(" and "); sb.Append(right); return sb.ToString(); } default: Debug.Assert(false, "Unknown characteristic quantification type"); break; } return ""; }
// ==================================================================== // // Read and display annotation back // // ==================================================================== public static bool ReadGraphicsFromAnnotation(aim_dotnet.Annotation annotation, IPresentationImage presentationImage) { bool hasNewRoiGraphic = false; IOverlayGraphicsProvider graphicsProvider = presentationImage as IOverlayGraphicsProvider; //IApplicationGraphicsProvider graphicsProvider = presentationImage as IApplicationGraphicsProvider; IImageSopProvider currentImageSOP = presentationImage as IImageSopProvider; if (graphicsProvider == null || currentImageSOP == null) return false; if (annotation is aim_dotnet.ImageAnnotation) { aim_dotnet.ImageAnnotation imgAnnotation = annotation as aim_dotnet.ImageAnnotation; if (imgAnnotation.GeometricShapeCollection != null) { foreach (aim_dotnet.IGeometricShape geoShape in imgAnnotation.GeometricShapeCollection) { // Check if the image is the one on which the annotation was originally drawn if (GetImageSOPInstanceUID(geoShape) != currentImageSOP.ImageSop.SopInstanceUid) break; // Prevent from adding the same annotation again bool isAlreadyDisplayed = false; foreach (IGraphic graphic in graphicsProvider.OverlayGraphics) { AimGraphic aimGraphic = graphic as AimGraphic; isAlreadyDisplayed = aimGraphic != null && aimGraphic.AimAnnotation.UniqueIdentifier == imgAnnotation.UniqueIdentifier && aimGraphic.ShapeIdentifier == geoShape.ShapeIdetifier; if (isAlreadyDisplayed) break; } if (isAlreadyDisplayed) continue; //hasNewRoiGraphic = AddRoiGraphic(geoShape, graphicsProvider) || hasNewRoiGraphic; RoiGraphic roiGraphic = GeoShapeToRoiGraphic(geoShape); if (roiGraphic != null) { AimGraphic aimGraphic = new AimGraphic(roiGraphic, imgAnnotation, geoShape.ShapeIdetifier); if (!String.IsNullOrEmpty(imgAnnotation.Name)) roiGraphic.Name = imgAnnotation.Name; aimGraphic.Color = Color.SlateBlue; graphicsProvider.OverlayGraphics.Add(aimGraphic); } hasNewRoiGraphic |= roiGraphic == null; } } } return hasNewRoiGraphic; }
// ==================================================================== // // Read and display annotation back // // ==================================================================== public static bool ReadGraphicsFromAnnotation(aim_dotnet.Annotation annotation, IPresentationImage presentationImage) { var hasNewRoiGraphic = false; var graphicsProvider = presentationImage as IOverlayGraphicsProvider; var currentImageSOP = presentationImage as IImageSopProvider; if (graphicsProvider == null || currentImageSOP == null) return false; if (annotation is aim_dotnet.ImageAnnotation) { var imgAnnotation = annotation as aim_dotnet.ImageAnnotation; if (imgAnnotation.GeometricShapeCollection != null) { foreach (var geoShape in imgAnnotation.GeometricShapeCollection) { if (GetImageSOPInstanceUID(geoShape) != currentImageSOP.ImageSop.SopInstanceUid) continue; var isAlreadyDisplayed = false; foreach (var graphic in graphicsProvider.OverlayGraphics) { var aimGraphic = graphic as AimGraphic; isAlreadyDisplayed = aimGraphic != null && aimGraphic.AimAnnotation.UniqueIdentifier == imgAnnotation.UniqueIdentifier && aimGraphic.ShapeIdentifier == geoShape.ShapeIdetifier; if (isAlreadyDisplayed) break; } if (isAlreadyDisplayed) continue; var geoGraphic = GeoShapeToGraphic(geoShape, string.IsNullOrEmpty(imgAnnotation.Name) ? string.Empty : imgAnnotation.Name); if (geoGraphic != null) { var aimGraphic = new AimGraphic(geoGraphic, imgAnnotation, geoShape.ShapeIdetifier); aimGraphic.Color = AimSettings.Default.GetAimGraphicColorForUser(aimGraphic.UserLoginName); graphicsProvider.OverlayGraphics.Add(aimGraphic); } hasNewRoiGraphic |= geoGraphic != null; } } if (imgAnnotation.TextAnnotationCollection != null) { foreach (var textAnnotation in imgAnnotation.TextAnnotationCollection) { if (textAnnotation.ConnectorPoints == null) continue; if (GetImageSOPInstanceUID(textAnnotation.ConnectorPoints) != currentImageSOP.ImageSop.SopInstanceUid) continue; var isAlreadyDisplayed = false; foreach (var graphic in graphicsProvider.OverlayGraphics) { var aimGraphic = graphic as AimGraphic; isAlreadyDisplayed = aimGraphic != null && aimGraphic.AimAnnotation.UniqueIdentifier == imgAnnotation.UniqueIdentifier && aimGraphic.ShapeIdentifier == textAnnotation.ConnectorPoints.ShapeIdetifier; if (isAlreadyDisplayed) break; } if (isAlreadyDisplayed) continue; var textGraphic = TextAnnotationToGraphic(textAnnotation, string.IsNullOrEmpty(imgAnnotation.Name) ? string.Empty : imgAnnotation.Name); if (textGraphic != null) { var aimGraphic = new AimGraphic(textGraphic, imgAnnotation, textAnnotation.ConnectorPoints.ShapeIdetifier); aimGraphic.Color = Color.SlateBlue; graphicsProvider.OverlayGraphics.Add(aimGraphic); } hasNewRoiGraphic |= textGraphic != null; } } } return hasNewRoiGraphic; }
private static RoiGraphic GeoShapeToRoiGraphic(aim_dotnet.IGeometricShape geoShape) { RoiGraphic roiGraphic = null; if (geoShape.SpatialCoordinateCollection == null || geoShape.SpatialCoordinateCollection.Count == 0) return null; if (geoShape is aim_dotnet.Circle) { // Ellipse aim_dotnet.Circle shapeCircle = geoShape as aim_dotnet.Circle; PointF centerPt = AsPointF(shapeCircle.Center); PointF radiusPt = AsPointF(shapeCircle.RadiusPoint); double radiusLength = Vector.Distance(centerPt, radiusPt); roiGraphic = RoiGraphic.CreateEllipse(); BoundableGraphic boundableGraphic = roiGraphic.Subject as BoundableGraphic; if (boundableGraphic != null) { roiGraphic.Suspend(); // prevent callout location calculation untill all points are set boundableGraphic.TopLeft = new PointF((float) (centerPt.X - radiusLength), (float) (centerPt.Y - radiusLength)); boundableGraphic.BottomRight = new PointF((float) (centerPt.X + radiusLength), (float) (centerPt.Y + radiusLength)); roiGraphic.Resume(true); // Force callout location calculation } } else if (geoShape is aim_dotnet.Ellipse) { // Ellipse aim_dotnet.Ellipse shapeEllipse = geoShape as aim_dotnet.Ellipse; PointF firstMajorAxisPt = AsPointF(shapeEllipse.EllipseCollection[0]); PointF secondMajorAxisPt = AsPointF(shapeEllipse.EllipseCollection[1]); PointF firstMinorAxisPt = AsPointF(shapeEllipse.EllipseCollection[2]); PointF secondMinorAxisPt = AsPointF(shapeEllipse.EllipseCollection[3]); roiGraphic = RoiGraphic.CreateEllipse(); BoundableGraphic boundableGraphic = roiGraphic.Subject as BoundableGraphic; if (boundableGraphic != null) { roiGraphic.Suspend(); // prevent callout location calculation untill all points are set boundableGraphic.TopLeft = new PointF(firstMajorAxisPt.X, firstMinorAxisPt.Y); boundableGraphic.BottomRight = new PointF(secondMajorAxisPt.X, secondMinorAxisPt.Y); roiGraphic.Resume(true); // Force callout location calculation } } else if (geoShape is aim_dotnet.Point) { throw new NotImplementedException("Reading Point shape is not implemented"); } else if (geoShape is aim_dotnet.MultiPoint) { // How this case works: // If we have 2 points, it's a line // If we have 3 points, it's a protractor // All others - unknown unclosed object (not supported) aim_dotnet.MultiPoint shapeMultiPoint = geoShape as aim_dotnet.MultiPoint; switch (shapeMultiPoint.SpatialCoordinateCollection.Count) { case 2: { // Line VerticesControlGraphic interactiveGraphic = new VerticesControlGraphic(new MoveControlGraphic(new PolylineGraphic())); PointF firstPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[0]); PointF secondPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[1]); interactiveGraphic.Subject.Points.Add(firstPt); interactiveGraphic.Subject.Points.Add(secondPt); roiGraphic = CreateRoiGraphic(interactiveGraphic, null); roiGraphic.Resume(true); // Force callout location calculation } break; case 3: { // Protractor VerticesControlGraphic interactiveGraphic = new VerticesControlGraphic(new MoveControlGraphic(new ProtractorGraphic())); PointF firstPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[0]); PointF secondPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[1]); PointF thirdPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[2]); interactiveGraphic.Subject.Points.Add(firstPt); interactiveGraphic.Subject.Points.Add(secondPt); interactiveGraphic.Subject.Points.Add(thirdPt); roiGraphic = CreateRoiGraphic(interactiveGraphic, new ProtractorRoiCalloutLocationStrategy()); roiGraphic.Resume(true); // Force callout location calculation } break; default: throw new NotImplementedException("Reading non-linear or non-triangular MultiPoint shape is not implemented"); } } else if (geoShape is aim_dotnet.Polyline) { aim_dotnet.Polyline shapePolyline = geoShape as aim_dotnet.Polyline; bool isRectangle = false; // true - if we have CC's rectangle coordinates // Check if this is a non-rotated rectangle if (shapePolyline.SpatialCoordinateCollection.Count == 4) { PointF twoDPoint1 = AsPointF(shapePolyline.SpatialCoordinateCollection[0]); PointF twoDPoint2 = AsPointF(shapePolyline.SpatialCoordinateCollection[1]); PointF twoDPoint3 = AsPointF(shapePolyline.SpatialCoordinateCollection[2]); PointF twoDPoint4 = AsPointF(shapePolyline.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)) { isRectangle = true; roiGraphic = RoiGraphic.CreateRectangle(); BoundableGraphic boundableGraphic = roiGraphic.Subject as BoundableGraphic; if (boundableGraphic != null) { roiGraphic.Suspend(); // prevent callout location calculation untill all points are set // Assume that the points are in order and start at the top left corner. boundableGraphic.TopLeft = twoDPoint1; boundableGraphic.BottomRight = twoDPoint3; roiGraphic.Resume(true); // Force callout location calculation } } } // It's a CC's polygon if it's not a rectangle if (!isRectangle) { roiGraphic = RoiGraphic.CreatePolygon(); PolylineGraphic polylineGraphic = roiGraphic.Subject as PolylineGraphic; if (polylineGraphic != null) { roiGraphic.Suspend(); for (int i = 0; i < shapePolyline.SpatialCoordinateCollection.Count; i++) { PointF twoDPoint = AsPointF(shapePolyline.SpatialCoordinateCollection[i]); polylineGraphic.Points.Add(twoDPoint); } // We deal with closed polygons only if (polylineGraphic.Points.Count > 0) polylineGraphic.Points.Add(polylineGraphic.Points[0]); roiGraphic.Resume(true); // Force callout location calculation } } } else throw new Exception("Unknown shape type encountered: " + geoShape.GetType().FullName); return roiGraphic; }
private static bool AddDicomImageReference(aim_dotnet.ImageAnnotation imageAnnotation, IImageSopProvider image) { Platform.CheckForNullReference(imageAnnotation, "ImageAnnotation"); if (imageAnnotation.ImageReferenceCollection == null) imageAnnotation.ImageReferenceCollection = new List<aim_dotnet.ImageReference>(); var imageReferences = imageAnnotation.ImageReferenceCollection; aim_dotnet.ImageStudy aimImageStudy = null; foreach (var imgRef in imageReferences) { var dicomImgRef = imgRef as aim_dotnet.DICOMImageReference; if (dicomImgRef != null) { if (dicomImgRef.Study.InstanceUID == image.ImageSop.StudyInstanceUid && dicomImgRef.Study.Series.InstanceUID == image.ImageSop.SeriesInstanceUid) aimImageStudy = dicomImgRef.Study; } } if (aimImageStudy == null) { aimImageStudy = CreateStudy(image); aimImageStudy.Series = CreateSeries(image); aimImageStudy.Series.ImageCollection = new List<aim_dotnet.Image>(); var dicomImgRef = new aim_dotnet.DICOMImageReference(); dicomImgRef.Study = aimImageStudy; imageReferences.Add(dicomImgRef); } foreach (var existingImage in aimImageStudy.Series.ImageCollection) { if (existingImage.SopInstanceUID == image.ImageSop.SopInstanceUid) return false; } var aimImage = CreateImage(image); aimImageStudy.Series.ImageCollection.Add(aimImage); return true; }
internal string WriteXmlAnnotationToString(aim_dotnet.Annotation annotation) { try { return Model.WriteAnnotationToXmlString(annotation); } catch (Exception ex) { Platform.Log(LogLevel.Error, ex, "Failed to convert annotation to xml."); } return null; }
private static IGraphic GeoShapeToGraphic(aim_dotnet.IGeometricShape geoShape, string shapeLabel) { if (geoShape.SpatialCoordinateCollection == null || geoShape.SpatialCoordinateCollection.Count == 0) return null; IGraphic graphic = null; if (geoShape is aim_dotnet.Circle) { // Ellipse var shapeCircle = geoShape as aim_dotnet.Circle; var centerPt = AsPointF(shapeCircle.Center); var radiusPt = AsPointF(shapeCircle.RadiusPoint); var radiusLength = Vector.Distance(centerPt, radiusPt); RoiGraphic roiGraphic = AimRoiGraphic.CreateEllipse(); var boundableGraphic = roiGraphic.Subject as BoundableGraphic; if (boundableGraphic != null) { roiGraphic.Suspend(); roiGraphic.Name = shapeLabel; boundableGraphic.TopLeft = new PointF((float) (centerPt.X - radiusLength), (float) (centerPt.Y - radiusLength)); boundableGraphic.BottomRight = new PointF((float) (centerPt.X + radiusLength), (float) (centerPt.Y + radiusLength)); roiGraphic.Resume(true); } graphic = roiGraphic; } else if (geoShape is aim_dotnet.Ellipse) { // Ellipse var shapeEllipse = geoShape as aim_dotnet.Ellipse; var firstMajorAxisPt = AsPointF(shapeEllipse.EllipseCollection[0]); var secondMajorAxisPt = AsPointF(shapeEllipse.EllipseCollection[1]); var firstMinorAxisPt = AsPointF(shapeEllipse.EllipseCollection[2]); var secondMinorAxisPt = AsPointF(shapeEllipse.EllipseCollection[3]); RoiGraphic roiGraphic = AimRoiGraphic.CreateEllipse(); var boundableGraphic = roiGraphic.Subject as BoundableGraphic; if (boundableGraphic != null) { roiGraphic.Suspend(); roiGraphic.Name = shapeLabel; boundableGraphic.TopLeft = new PointF(firstMajorAxisPt.X, firstMinorAxisPt.Y); boundableGraphic.BottomRight = new PointF(secondMajorAxisPt.X, secondMinorAxisPt.Y); roiGraphic.Resume(true); } graphic = roiGraphic; } else if (geoShape is aim_dotnet.Point) { var shapePoint = geoShape as aim_dotnet.Point; var callout = new CalloutGraphic(shapeLabel); callout.LineStyle = LineStyle.Solid; callout.ShowArrowhead = true; callout.AnchorPoint = AsPointF(shapePoint.Center); callout.TextLocation = callout.AnchorPoint - new SizeF(30, 30); var statefulGraphic = new StandardStatefulGraphic(callout); statefulGraphic.State = statefulGraphic.CreateInactiveState(); graphic = statefulGraphic; } else if (geoShape is aim_dotnet.MultiPoint) { // How this case works: // If we have 2 points, it's a line // If we have 3 points, it's a protractor // All others - unknown unclosed object (not supported) var shapeMultiPoint = geoShape as aim_dotnet.MultiPoint; switch (shapeMultiPoint.SpatialCoordinateCollection.Count) { case 2: { // Line var interactiveGraphic = new VerticesControlGraphic(new MoveControlGraphic(new PolylineGraphic())); var firstPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[0]); var secondPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[1]); interactiveGraphic.Subject.Points.Add(firstPt); interactiveGraphic.Subject.Points.Add(secondPt); var roiGraphic = CreateRoiGraphic(interactiveGraphic, null); roiGraphic.Name = shapeLabel; roiGraphic.Resume(true); graphic = roiGraphic; } break; case 3: { // Protractor var interactiveGraphic = new VerticesControlGraphic(new MoveControlGraphic(new ProtractorGraphic())); var firstPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[0]); var secondPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[1]); var thirdPt = AsPointF(shapeMultiPoint.SpatialCoordinateCollection[2]); interactiveGraphic.Subject.Points.Add(firstPt); interactiveGraphic.Subject.Points.Add(secondPt); interactiveGraphic.Subject.Points.Add(thirdPt); var roiGraphic = CreateRoiGraphic(interactiveGraphic, new ProtractorRoiCalloutLocationStrategy()); roiGraphic.Name = shapeLabel; roiGraphic.Resume(true); graphic = roiGraphic; } break; default: throw new NotImplementedException("Reading non-linear or non-triangular MultiPoint shape is not implemented"); } } else if (geoShape is aim_dotnet.Polyline) { var shapePolyline = geoShape as aim_dotnet.Polyline; var isRectangle = false; if (shapePolyline.SpatialCoordinateCollection.Count == 4) { var twoDPoint1 = AsPointF(shapePolyline.SpatialCoordinateCollection[0]); var twoDPoint2 = AsPointF(shapePolyline.SpatialCoordinateCollection[1]); var twoDPoint3 = AsPointF(shapePolyline.SpatialCoordinateCollection[2]); var twoDPoint4 = AsPointF(shapePolyline.SpatialCoordinateCollection[3]); 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)) { isRectangle = true; RoiGraphic roiGraphic = AimRoiGraphic.CreateRectangle(); var boundableGraphic = roiGraphic.Subject as BoundableGraphic; if (boundableGraphic != null) { roiGraphic.Suspend(); roiGraphic.Name = shapeLabel; boundableGraphic.TopLeft = twoDPoint1; boundableGraphic.BottomRight = twoDPoint3; roiGraphic.Resume(true); } graphic = roiGraphic; } } if (!isRectangle) { RoiGraphic roiGraphic = AimRoiGraphic.CreatePolygon(); var polylineGraphic = roiGraphic.Subject as PolylineGraphic; if (polylineGraphic != null) { roiGraphic.Suspend(); for (var i = 0; i < shapePolyline.SpatialCoordinateCollection.Count; i++) { var twoDPoint = AsPointF(shapePolyline.SpatialCoordinateCollection[i]); polylineGraphic.Points.Add(twoDPoint); } // We deal with closed polygons only if (polylineGraphic.Points.Count > 0) polylineGraphic.Points.Add(polylineGraphic.Points[0]); roiGraphic.Name = shapeLabel; roiGraphic.Resume(true); } graphic = roiGraphic; } } else throw new Exception("Unknown shape type encountered: " + geoShape.GetType().FullName); return graphic; }
private string ToolTipTextFromAimAnnotation(aim_dotnet.Annotation annotation) { var toolTipText = String.Empty; toolTipText += annotation.Name + "\n"; toolTipText += annotation.DateTime.ToString() + "\n"; toolTipText += annotation.CodeValue + "\n"; toolTipText += annotation.CodeMeaning += "\n"; toolTipText += annotation.Comment; return toolTipText; }
private static IGraphic TextAnnotationToGraphic(aim_dotnet.TextAnnotation textAnnotation, string shapeLabel) { Platform.CheckForNullReference(textAnnotation.ConnectorPoints, "ConnectorPoints"); Platform.CheckForNullReference(textAnnotation.ConnectorPoints.SpatialCoordinateCollection, "SpatialCoordinateCollection"); Platform.CheckArgumentRange(textAnnotation.ConnectorPoints.SpatialCoordinateCollection.Count, 1, 2, "SpatialCoordinateCollection"); if (textAnnotation.ConnectorPoints == null || textAnnotation.ConnectorPoints.SpatialCoordinateCollection == null) return null; var graphicText = shapeLabel.Trim(); graphicText = string.IsNullOrEmpty(graphicText) ? textAnnotation.Text.Trim() : string.Format("{0}:\r\n{1}", graphicText, textAnnotation.Text.Trim()); switch (textAnnotation.ConnectorPoints.SpatialCoordinateCollection.Count) { case 1: { var textPrimitive = new InvariantTextPrimitive(graphicText); textPrimitive.Location = AsPointF(textAnnotation.ConnectorPoints.SpatialCoordinateCollection[0]); var statefulGraphic = new StandardStatefulGraphic(textPrimitive); statefulGraphic.State = statefulGraphic.CreateInactiveState(); return statefulGraphic; } break; case 2: { var callout = new CalloutGraphic(graphicText); callout.LineStyle = LineStyle.Solid; callout.ShowArrowhead = true; callout.AnchorPoint = AsPointF(textAnnotation.ConnectorPoints.SpatialCoordinateCollection[0]); callout.TextLocation = AsPointF(textAnnotation.ConnectorPoints.SpatialCoordinateCollection[1]); var statefulGraphic = new StandardStatefulGraphic(callout); statefulGraphic.State = statefulGraphic.CreateInactiveState(); return statefulGraphic; } break; default: break; } return null; }
private static string GetImageAnnotationHtml(aim_dotnet.ImageAnnotation imageAnnotation) { StringBuilder sb = new StringBuilder(); AimHtmlFormatter htmlFormatter = new AimHtmlFormatter(); Color ctrlColor = Color.FromKnownColor(KnownColor.Control); Color fontColor = Color.FromKnownColor(KnownColor.WindowText); sb.Append(HtmlDocHeader); sb.AppendFormat("<body style=\"background-color: #{0}{1}{2};\" onload=\"setupPaths(['{3}', '{4}'])\">", ctrlColor.R.ToString("X2"), ctrlColor.G.ToString("X2"), ctrlColor.B.ToString("X2"), MinusImagePathName, PlusImagePathName); sb.Append("<div id=\"main_content\">"); sb.AppendFormat("<div><b>Name: {0}</b></div>", imageAnnotation.Name); sb.AppendFormat("<div>Number of Markups: {0}</div>", imageAnnotation.GeometricShapeCollection == null ? 0 : imageAnnotation.GeometricShapeCollection.Count(geoShape => geoShape != null)); if (imageAnnotation.User != null) sb.AppendFormat("<div>Created by: {0}</div>", imageAnnotation.User.Name); sb.Append(htmlFormatter.GetAnatomicEntitiesHtml(imageAnnotation.AnatomyEntityCollection)); sb.Append(htmlFormatter.GetImagingObservationHtml(imageAnnotation.ImagingObservationCollection)); // TODO - append other sections sb.Append("</div>"); sb.Append("</body>"); sb.Append("</html>"); return sb.ToString(); }