Adding measurement annotations programatically

Product:
Webviewer

Product Version:
10.2.3

Please give a brief summary of your issue:
I can’t figure out how to programatically add measurement annotations

Please describe your issue and provide steps to reproduce it:
I am trying to add measurement annotations to the currently opened document. I can add non-measurement annotations just fine, e.g. using

    const annotation = new Core.Annotations.PolygonAnnotation({
        PageNumber: 1
        StrokeColor: new Core.Annotations.Color(255, 0, 0, 1),
      });

    annotation.addPathPoint(1600.1, 300.1);
    annotation.addPathPoint(1700.1, 300.1);
    annotation.addPathPoint(1700.1, 400.1);
    annotation.addPathPoint(1600.1, 400.1);
    annotation.addPathPoint(1600.1, 300.1);

    annotationManager.addAnnotation(annotation);
    annotationManager.redrawAnnotation(annotation);

This creates an annotation with ToolName equal to AnnotationCreatePolygon, the same as if I would use the PolygonCreateTool or Shapes/Polygon in the UI. What I can’t figure out is how to create this annotation the same way the AnnotationCreateAreaMeasurement tool does it. I searched through the guides and the API documentation, but I found nothing. Is there a way to create the same polygon as a measurement annotation?

Please provide a link to a minimal sample where the issue is reproducible:
N/A

Thanks in advance,
David

1 Like

Hi DavidM,

Please find the solution below. Please use with caution and test thoroughly before using this in production as it’s not yet officially supported.

Regards,
Maggie V.

1 Like

Hello maggie,

thanks for your quick reply. Unfortunately, the workaround doesn’t really work. While the annotations now contain measurement information, the display is wrong. When I create only one annotation, it works fine. When multiple annotations are created, the annotations themselves appear (and have the correct information in the annotation objects), but all but one annotation have no content, and one of them (it seems sort of random which one) contains all the contents of all annotations. The reason seems to be that their captionRect is the same (if I export the annotations, I can see this in the trn-custom-data element, and there in trn-measurement-caption-options.captionRect. The appearance element also seems to be involved, but I couldn’t find the interesting parts in that, so I’m not sure it really has anything to do with it).

I have attached a screenshot

where you can see the left annotation containing all contents; the middle
annotation is selected, and while the bounds are displayed correctly, the blue content dot is inside the left annotation. I also cannot move these wrongly placed captions, but I can move the one of the left annotation.

Is there any more I can do to get this working?

Cheers,
David

For completeness, here is the code of the createPolygonAnnotation method I am calling three times:

  const createPolygonAnnotation = (
    annotationManager: Core.AnnotationManager,
    pageNumber: number,
    coordinates: CoordinateGroup
  ) => {
    const annotation: Core.Annotations.PolygonAnnotation =
      new webViewer.Core.Annotations.PolygonAnnotation({
        PageNumber: pageNumber,
        StrokeColor: new webViewer.Core.Annotations.Color(255, 0, 0, 1),
      });
    (annotation as any).IT = 'PolygonDimension';
    (annotation as any).Measure = {
      scale: '1 in = 1 in',
      axis: [
        {
          factor: 0.0138889,
          unit: 'in',
          decimalSymbol: '.',
          thousandsSymbol: ',',
          display: 'D',
          precision: 100,
          unitPrefix: '',
          unitSuffix: '',
          unitPosition: 'S',
        },
      ],
      distance: [
        {
          factor: 1,
          unit: 'in',
          decimalSymbol: '.',
          thousandsSymbol: ',',
          display: 'D',
          precision: 100,
          unitPrefix: '',
          unitSuffix: '',
          unitPosition: 'S',
        },
      ],
      area: [
        {
          factor: 1,
          unit: 'sq in',
          decimalSymbol: '.',
          thousandsSymbol: ',',
          display: 'D',
          precision: 100,
          unitPrefix: '',
          unitSuffix: '',
          unitPosition: 'S',
        },
      ],
    };
    coordinates.forEach((coord) => {
      annotation.addPathPoint(coord[0], coord[1]);
    });

    annotationManager.addAnnotation(annotation);
    annotationManager.redrawAnnotation(annotation);
    return annotation;
  };
1 Like

Hi DavidM,

I believe this could help as the annotation is missing the property caption.

annot.measurementCaptionOptions = {
  isEnabled: true,
  captionStyle: {
    "fontFamily": "sans-serif",
    "color": "rgba(228,66,52,1)",
    "staticSize": "0pt",
    "maximumSize": "0pt"
  },
  // can be "estimated" based on the shape coordinates
  captionRect: new instance.Core.Math.Rect(x1, y1, x2, y2),
};

However, I’d like to reiterate that this is not a foolproof solution as measurement annotations are a special kind of annotations and can be tricky to manipulate.

Regards,
Maggie V.

1 Like

Hello @maggiev ,

this now works somewhat. Still not perfect, but good enough for now (it’s just a proof of concept at the moment). Thanks a lot!

As a last question, is it planned to implement actual support for programmatic creation of measurements in the somewhat near future?

Cheers,
David

1 Like

Hi DavidM,

Glad to hear that it worked!

We don’t currently have creating measurement annotations programmatically on our roadmap but, we will add it to the backlog for our product team to review for feasibility and viability.

In the meantime, to get notified for the next official SDK release you can join our channel https://community.apryse.com/t/about-the-announcements-category/3750

Regards,
Maggie V.

1 Like