ProjectMirador / mirador

An open-source, web-based 'multi-up' viewer that supports zoom-pan-rotate functionality, ability to display/compare simple images, and images with annotations.
https://projectmirador.org
Apache License 2.0
549 stars 258 forks source link

Loading Annotations #2971

Closed pixelomo closed 3 years ago

pixelomo commented 4 years ago

I'm trying to load annotations, fetchAnnotations gets them successfully from my manifest and the sidebar displays the number of annotations. An element with the annotations list is created for each but no text is displayed and the annotations do not show over my image.

Checking your demo https://mirador-dev.netlify.com/__tests__/integration/mirador/

each of your annotations “on” value includes a “selector” which specifies a value for x/y coordinates and width/height:

        "on": {
                "@type": "oa:SpecificResource",
                "full": "https://iiif.harvardartmuseums.org/manifests/object/299843/canvas/canvas-47174892",
                "selector": {
                    "@type": "oa:FragmentSelector",
                    "value": "xywh=697,707,720,833"
                },
                "within": {
                    "@id": "https://iiif.harvardartmuseums.org/manifests/object/299843",
                    "@type": "sc:Manifest"
                }
            },

whereas my “on” value just includes a link:

"on" : [ "https://iiif.europeana.eu/image/GPNNPGBENPQFFOB7PHRRSCK4GJFXZCJ7YFLGCZCJ5QMNJOWVVRJA/presentation_images/c5927d61-022b-11e6-a696-fa163e2dd531/node-3/image/BNL/La_clef_du_cabinet_des_princes_de_l'Europe/1704/09/01/00159/full/full/0/default.jpg#xywh=301,199,644,80" 
]

though this does include xywh data maybe it’s not the right data format Mirador is expecting?

Do I also need to provide annotation text within my resource value?

pixelomo commented 4 years ago

@mejackreed is there any chance you could help me with this?

mejackreed commented 4 years ago

This seems like it could work. OpenAnnotations in Presentation v2 are being parsed in AnnotationResource here: https://github.com/ProjectMirador/mirador/blob/master/src/lib/AnnotationResource.js. I think a few different things are going on which are causing the annotations not to display properly in Mirador.

Using https://iiif.europeana.eu/presentation/9200301/BibliographicResource_3000126341271/manifest and https://iiif.europeana.eu/presentation/9200301/BibliographicResource_3000126341271/annopage/1 as an example.

  1. Mirador checks the annotation's target to make sure that it is a canvas that is being displayed here: https://github.com/ProjectMirador/mirador/blob/master/src/components/OpenSeadragonViewer.js#L189 .
{
    "@id" : "https://data.europeana.eu/annotation/9200301/BibliographicResource_3000126341271/19ca3fa588e68b276f37a5846f02933a",
    "@type" : "oa:Annotation",
    "motivation" : "sc:painting",
    "dcType" : "Word",
    "resource" : {
      "@id" : "https://www.europeana.eu/api/fulltext/9200301/BibliographicResource_3000126341271/1d090a766b78ac9845599ff91cb6b9cf#char=0,3"
    },
    "on" : [ "https://iiif.europeana.eu/image/I26SNFNBBHFUYIFVUOSC7DHZTGD4TLYBH2PZPA2G6ILQDGN44VMQ/presentation_images/6e4bc210-021b-11e6-a696-fa163e2dd531/node-4/image/NLF/Uusi_Aura/1910/11/08/259_1/19101108_259_1-0001/full/full/0/default.jpg#xywh=18,198,74,33" ]
}

The on property here references the image, but not the canvas. The canvasId is https://iiif.europeana.eu/presentation/9200301/BibliographicResource_3000126341271/canvas/p1. I'm not sure if this is correct or expected, or what the "right" thing to do here is.

  1. No content is being displayed in the list, because we expect a body of the resource with chars to be present already. This is perhaps naive and could be enhanced but I do not think we would want to try and dereference all of the annotations. Screen Shot 2020-04-16 at 7 01 30 AM

Happy to help out where I can work through these issues with you. Also if possible, it would be great if you could join the Mirador Community Call where we could discuss. https://iiif.io/community/groups/#iiif-call-calendar

rwd commented 4 years ago

@mejackreed many thanks for the pointers in your comment which have helped us get something working, albeit in a hacky workaround manner (for now).

Evidently there are some issues with the data coming from our IIIF APIs, some incorrect according to the IIIF specifications (as with targets referencing images and not canvases) and other more idiosyncratic compared to typical implementations (as with the referenced and not embedded annotation text), which I would not expect Mirador to cope with off-the-shelf.

What we have done is fork the repository and make changes to the annotation state action as can be seen at https://github.com/ProjectMirador/mirador/compare/master...europeana:v3.0.0-beta.9.2#diff-334468ec953c2251c99a904e9c5fa6ee

(Disclaimer: I am not especially familiar with the architecture of React applications, so expect that this may well not the right place to put such functions. Any recommendations on improvements are welcome.)

In essence this work added a series of post-fetch processors to mutate the response before dispatching it to the state, which:

  1. Filter the annotation resources to those having a specific dcType property. That is not related to this issue but rather to the one of performance noted in #2915. Our full text annotations are given at different granularities in the same annotation pages, which is of little use in the stock Mirador annotation UI, so filtering to one granularity both improves UX and reduces the rendering overhead.
  2. Rewrite the annotation targets to reference the relevant canvases instead of referencing images.
  3. Dereference the resource URIs to populate the chars property of the resources.

I would prefer not to have modified the state action in the Mirador core code to achieve this, but my impression was that some of those workarounds need to happen early, before the data is committed to the state and then utilised by various selectors, normalised into the various annotation classes, and finally made available to plugins. But, it works: we have line-level annotations, and performance is not too bad. Example: https://iiif-annotations-portaljs-dev.eanadev.org/en/item/9200301/BibliographicResource_3000126341271.

The issues encountered with our own data and its exposition have been reported back to the relevant team, but in the meantime we will likely need to proceed using and maintaining this fork.

Some further observations arising out of my work on this:

  1. It would alleviate the need to modify the core code if plugins, or even the Mirador configuration settings, were able to supply post-fetch processors.
  2. Regarding the filtering of annotations, this is comparable to that supported by the annotations.filteredMotivations setting, which makes me wonder if that could be extended or adapted to support arbitrary installation-specific filtering, something like:
        annotations: {
          filtered: {
            motivations: ['oa:commenting', 'sc:painting', 'commenting'],
            dcType: ['Line']
          }
        }
  3. Regarding the dereferencing of the referenced resources, in our use case these in fact all refer to the same document, but with a #char= fragment query to indicate which characters pertain to each annotation. The dereferencing processor detects this to ensure that it is only requested once, not hundreds or thousands of times. Is this something that would be of value as a contribution to the core code? The caveat here is that the target of those references in our case is in a Europeana-specific format of type "FullTextResource", but the dereferencing in general may be more widely applicable were the target of a more common type.
  4. I have also noted the work on #2946, and the new mirador-annotations repository which I would be interested to hear if you think may have any relevance to the issues we are working on.
mejackreed commented 4 years ago

Thanks for the follow up @rwd. I'll try to follow up on an approach that might address these issues.

  1. Understood. I wonder if an alternative would be a configuration option to just not fetch annotations. That way adopters with non-standard annotations could fetch them with a plugin as they are needed. A few plugins exist already that do this.

  2. Is dcType something from OA or Web Annotation? I think it might be difficult for us to support non standard annos in this way.

  3. I think the fragment dereferencing performance improvements could definitively be contributed up to core. However the processing might want to be handled via a plugin.

  4. The adapter approach implemented might be relevant here as a mechanism for processing and adding to the store https://github.com/ProjectMirador/mirador-annotations/blob/master/src/AnnototAdapter.js

Maybe its worth talking through some of this on a Mirador call?