in pathology/viewer/src/components/image-viewer-side-nav/image-viewer-side-nav.component.ts [753:852]
createOrUpdateAnnotation() {
const slideInfo = this.getSlideInfo();
if (!slideInfo) return;
const sopInstanceUid = slideInfo.levelMap[0].properties[0].instanceUid;
if (!sopInstanceUid) {
return;
}
const annotations: SideNavLayer[] = [...this.sideNavDrawLayers];
const annotationGroups =
annotations
.filter((annotation) => {
return annotation.annotatorId === this.currentUser;
})
.map((annotation, index) => {
const annotationKey = getFeatureAnnotationKey(annotation.feature);
annotationKey.notes = annotationKey?.notes?.trim() ?? '';
const coordinates =
((((annotation.feature as Feature<Polygon>).getGeometry())
?.getCoordinates() ??
[])[0] as Coordinate[]);
// Set label to be the first 3 words of the comment otherwise ROI.
const annotationLabel = (annotationKey.notes ?? '')
.split(' ')
.slice(0, 3)
.join(' ')
.substring(0, 15) ||
'ROI';
const annotationGroup: AnnotationGroup = {
idNumber: index + 1,
annotationGroupUid: '',
annotationGroupLabel: annotationLabel,
annotationGroupDescription: annotationKey.notes ?? '',
annotationGroupGenerationType: 'MANUAL',
annotationPropertyCategoryCodeSequence: [],
graphicType: 'POLYGON',
pointCoordinatesData: coordinates,
longPrimitivePointIndexList: [1], // DICOM indices are 1 based
};
return annotationGroup;
});
const seriesId = this.selectedSplitViewSlideDescriptor?.id as string;
const slidePath = parseDICOMwebUrl(seriesId).path;
if (!slidePath.studyUID || !slidePath.seriesUID) return;
const referencedSeries: ReferencedSeries =
this.annotationInstances
.find(
(annotationInstance) =>
annotationInstance.annotatorId === this.currentUser &&
annotationInstance.referencedSeries.seriesInstanceUid ===
slidePath.seriesUID)
?.referencedSeries ??
// If not found, create an ReferencedSeries based on slideInfo.
{
seriesInstanceUid: slidePath.seriesUID,
referencedImage: {
sopClassUid: slideInfo.sopClassUid,
sopInstanceUid: slideInfo.levelMap[0].properties[0].instanceUid,
dicomModel: slideInfo.levelMap[0].dicomModel,
pixelSize: {
width: slideInfo.levelMap[0].pixelWidth,
height: slideInfo.levelMap[0].pixelHeight
},
}
} as ReferencedSeries;
const dicomAnnotation: DicomAnnotation = {
instance: {
path: {
studyUID: slidePath.studyUID,
},
annotatorId: this.currentUser,
referencedSeries,
},
annotationCoordinateType: '2D',
annotationGroupSequence: annotationGroups,
};
this.imageViewerPageStore
.createOrModifyDicomAnnotation(
this.getSelectedSlideId(),
dicomAnnotation,
)
.pipe(
catchError((error) => {
this.snackBar.open('Failed to write annotation', 'Dismiss', {
duration: 3000,
});
// Remove recently added feature.
this.handleRecentFeature();
return error;
}),
)
.subscribe();
}