diff --git a/imagetagger/imagetagger/annotations/static/annotations/js/boundingboxes.js b/imagetagger/imagetagger/annotations/static/annotations/js/boundingboxes.js index 9747d234..640a67fc 100644 --- a/imagetagger/imagetagger/annotations/static/annotations/js/boundingboxes.js +++ b/imagetagger/imagetagger/annotations/static/annotations/js/boundingboxes.js @@ -18,6 +18,18 @@ class BoundingBoxes { this.clear(); calculateImageScale(); color = color || globals.stdColor; + let colors = []; + if (color.constructor === Array) { + colors = color; + if (color.length != annotations.length) { + console.log('wrong number of colors'); + return; + } + } else { + for (let i = 0; i < annotations.length; i++) { + colors.push(color); + } + } if (annotations.length === 0 || !globals.drawAnnotations) { return; @@ -29,6 +41,7 @@ class BoundingBoxes { for (var a in annotations) { var annotation = annotations[a]; + let color = colors[a]; if (annotation.annotation_type.id !== this.annotationTypeId) { continue; } diff --git a/imagetagger/imagetagger/annotations/static/annotations/js/canvas.js b/imagetagger/imagetagger/annotations/static/annotations/js/canvas.js index c9cd25dc..92e5dfe8 100644 --- a/imagetagger/imagetagger/annotations/static/annotations/js/canvas.js +++ b/imagetagger/imagetagger/annotations/static/annotations/js/canvas.js @@ -427,10 +427,26 @@ class Canvas { drawExistingAnnotations(annotations, color) { this.clear(); color = color || globals.stdColor; + let colors = []; + if (color.constructor === Array) { + colors = color; + if (color.length != annotations.length) { + console.log('wrong number of colors'); + return; + } + } else { + for (let i = 0; i < annotations.length; i++) { + colors.push(color); + } + } if (!globals.drawAnnotations) { return; } - for (let annotation of annotations) { + for (let i in annotations) { + let annotation = annotations[i]; + let color = colors[i]; + console.log(annotation); + console.log(color); if (annotation.annotation_type.id !== this.annotationTypeId) { continue; } diff --git a/imagetagger/imagetagger/annotations/static/annotations/js/verification.js b/imagetagger/imagetagger/annotations/static/annotations/js/verification.js index 8869c111..fdd7e61f 100644 --- a/imagetagger/imagetagger/annotations/static/annotations/js/verification.js +++ b/imagetagger/imagetagger/annotations/static/annotations/js/verification.js @@ -28,6 +28,7 @@ function calculateImageScale() { let gImageId; let gImageSet; let gImageSetId; + let gCurrentAnnotations; let gImageCache = {}; let gAnnotationId; // the selected annotation let tool; @@ -92,16 +93,18 @@ function calculateImageScale() { }) } - function loadSingleAnnotation(id, fromHistory) { + function loadImageAnnotations(annotation, fromHistory) { let params = { - annotation_id: id, + image_id: annotation.image.id, + annotation_type_id: annotation.annotation_type, }; - $.ajax(API_ANNOTATIONS_BASE_URL + 'annotation/loadone/?' + $.param(params), { + $.ajax(API_ANNOTATIONS_BASE_URL + 'annotation/loadmultiple/?' + $.param(params), { type: 'GET', headers: gHeaders, dataType: 'json', success: function (data) { - continueLoadAnnotationView(data.annotation, fromHistory); + gCurrentAnnotations = data.annotation; + continueLoadAnnotationView(annotation.id, fromHistory); }, error: function () { displayFeedback($('#feedback_connection_error')) @@ -130,7 +133,7 @@ function calculateImageScale() { if (state) { strState = 'accept'; } - let annotation = gAnnotationList.filter(function(e) { + let annotation = gCurrentAnnotations.filter(function(e) { return e.id === id; })[0]; annotation.verified_by_user = true; @@ -324,11 +327,9 @@ function calculateImageScale() { annotationIndex += offset; if (annotationIndex < 0) { displayFeedback($('#feedback_last_annotation')); - drawAnnotation(gAnnotationList[0]); return; } else if (annotationIndex >= annotationIndexList.length) { displayFeedback($('#feedback_last_annotation')); - drawAnnotation(gAnnotationList[gAnnotationList.length - 1]); return; } @@ -343,19 +344,22 @@ function calculateImageScale() { */ function loadAnnotationView(annotationId, fromHistory) { gAnnotationId = annotationId; - let annotationNotInList = gAnnotationList.filter(function (e) { + let annotation = gAnnotationList.filter(function (e) { return e.id === annotationId; - }).length === 0; - if (annotationNotInList) { + })[0]; + if (!annotation) { console.log( 'skipping request to load annotation ' + annotationId + ' as it is not in current annotation list.'); return; } - loadSingleAnnotation(annotationId, fromHistory); + loadImageAnnotations(annotation, fromHistory); } - function continueLoadAnnotationView(annotation, fromHistory) { + function continueLoadAnnotationView(annotation_id, fromHistory) { + let annotation = gCurrentAnnotations.filter(function (e) { + return e.id === annotation_id; + })[0]; if (annotation.verified_by_user) { displayFeedback($('#feedback_already_verified')); } @@ -396,18 +400,20 @@ function calculateImageScale() { $('#blurred_label').hide() } $('#blurred').prop('checked', annotation.blurred); - drawAnnotation(annotation); + drawAnnotations(gCurrentAnnotations, annotation.id); } /** - * Draw the annotation that should be verified + * Draw the annotations that should be verified * - * @param annotation + * @param annotations list of all annotation to draw + * @param current id of the current annotation */ - function drawAnnotation(annotation) { + function drawAnnotations(annotations, current) { if (tool) { tool.clear(); } + let annotation = annotations[0]; if (!tool || tool.annotationTypeId !== annotation.annotation_type.id || (tool.vector_type === 5 && tool.node_count !== annotation.annotation_type.node_count)) { switch (annotation.annotation_type.vector_type) { @@ -425,18 +431,25 @@ function calculateImageScale() { break; } } - let color = '#FF0000'; - if (annotation.concealed) { - if (annotation.blurred) { - color = '#5CB85C'; - } else { - color = '#F0AD4E'; + colors = []; + for (let annotation of annotations) { + let color = '#FF0000'; + if (annotation.concealed) { + if (annotation.blurred) { + color = '#5CB85C'; + } else { + color = '#F0AD4E'; + } } + else if (annotation.blurred) { + color = '#5BC0DE' + } + if (annotation.id !== current) { + color += '60'; // some transparency + } + colors.push(color); } - else if (annotation.blurred) { - color = '#5BC0DE' - } - tool.drawExistingAnnotations([annotation], color); + tool.drawExistingAnnotations(annotations, colors); } /** @@ -515,7 +528,7 @@ function calculateImageScale() { } function handleConcealedChange() { - let annotation = gAnnotationList.filter(function(e) { + let annotation = gCurrentAnnotations.filter(function(e) { return e.id === gAnnotationId; })[0]; annotation.concealed = $('#concealed').is(':checked'); @@ -524,12 +537,12 @@ function calculateImageScale() { } else { $('#concealed_label').hide() } - drawAnnotation(annotation); + drawAnnotations(gCurrentAnnotations, annotation.id); apiBlurredConcealed(); } function handleBlurredChange() { - let annotation = gAnnotationList.filter(function(e) { + let annotation = gCurrentAnnotations.filter(function(e) { return e.id === gAnnotationId; })[0]; annotation.blurred = $('#blurred').is(':checked'); @@ -538,12 +551,12 @@ function calculateImageScale() { } else { $('#blurred_label').hide() } - drawAnnotation(annotation); + drawAnnotations(gCurrentAnnotations, annotation.id); apiBlurredConcealed(); } function apiBlurredConcealed() { - let annotation = gAnnotationList.filter(function(e) { + let annotation = gCurrentAnnotations.filter(function(e) { return e.id === gAnnotationId; })[0]; let data = { diff --git a/imagetagger/imagetagger/annotations/urls.py b/imagetagger/imagetagger/annotations/urls.py index 54aa1e33..b61599b9 100644 --- a/imagetagger/imagetagger/annotations/urls.py +++ b/imagetagger/imagetagger/annotations/urls.py @@ -26,6 +26,7 @@ url(r'^api/annotation/loadsetannotationtypes/$', views.load_set_annotation_types, name='load_set_annotation_types'), # loads annotations of an image url(r'^api/annotation/loadfilteredset/$', views.load_filtered_set_annotations, name='load_filtered_set_annotations'), # loads filtered annotations of an image url(r'^api/annotation/loadone/$', views.load_annotation, name='load_annotation'), + url(r'^api/annotation/loadmultiple/$', views.load_multiple_annotations, name='load_multiple_annotations'), url(r'^api/annotation/verify/$', views.api_verify_annotation, name='verify_annotation'), url(r'^api/annotation/update/$', views.update_annotation, name='update_annotations'), url(r'^api/annotation/blurred_concealed/$', views.api_blurred_concealed_annotation, name='blurred_concealed_annotation'), diff --git a/imagetagger/imagetagger/annotations/views.py b/imagetagger/imagetagger/annotations/views.py index a965f3d2..c98d31a1 100644 --- a/imagetagger/imagetagger/annotations/views.py +++ b/imagetagger/imagetagger/annotations/views.py @@ -729,7 +729,7 @@ def load_filtered_set_annotations(request) -> Response: images = Image.objects.filter(image_set=imageset) annotations = Annotation.objects.filter(image__in=images, - annotation_type__active=True).order_by('image_id').select_related() + annotation_type__active=True).order_by('image__name', 'id').select_related() if annotation_type_id > -1: annotations = annotations.filter(annotation_type__id=annotation_type_id) if verified: @@ -769,6 +769,32 @@ def load_annotation(request) -> Response: }, status=HTTP_200_OK) +@login_required +@api_view(['GET']) +def load_multiple_annotations(request) -> Response: + try: + image_id = int(request.query_params['image_id']) + annotation_type_id = int(request.query_params['annotation_type_id']) + except (KeyError, TypeError, ValueError): + raise ParseError + + annotations = Annotation.objects.filter(image_id=image_id, annotation_type_id=annotation_type_id) + + if not Image.objects.get(id=image_id).image_set.has_perm('read', request.user): + return Response({ + 'detail': 'permission for reading this image set missing.', + }, status=HTTP_403_FORBIDDEN) + + serializer = AnnotationSerializer(annotations, + context={ + 'request': request, + }, + many=True) + return Response({ + 'annotation': serializer.data, + }, status=HTTP_200_OK) + + @login_required @api_view(['POST']) def update_annotation(request) -> Response: diff --git a/imagetagger/imagetagger/images/views.py b/imagetagger/imagetagger/images/views.py index 962613d2..a6965567 100644 --- a/imagetagger/imagetagger/images/views.py +++ b/imagetagger/imagetagger/images/views.py @@ -415,7 +415,7 @@ def view_imageset(request, image_set_id): all_annotation_types = AnnotationType.objects.filter(active=True) annotations = Annotation.objects.filter( image__in=images, - annotation_type__active=True).order_by("id") + annotation_type__active=True).order_by('image__name', 'id') annotation_types = AnnotationType.objects.filter(annotation__image__image_set=imageset, active=True).distinct()\ .annotate(count=Count('annotation'), in_image_count=Count('annotation', filter=Q(annotation__vector__isnull=False)),