ADN Open CIS
Сообщество программистов Autodesk в СНГ

31/07/2020

Forge Viewer: Markup-ы PDF документов


Ранее в ForgeViewer-е был единственный компонент LeafletLoader для отображения PDF документов, затем появился показывали новый способ загрузки PDF в Forge Viewer c помощью нового компонента PDFLoader, мы писали об этом в статье https://forge.autodesk.com/blog/fast-pdf-viewingmarkup-inside-forge-viewer.

Какой из загрузчиков будет использоваться зависит от разрешения, заданного в самом PDF документе, или, если быть точнее, в зависимости от значения totalRasterPixels в манифесте документа, преобразованного сервисом. Также можно повлиять на то, какой именно загрузчик будет использоваться для отображения документа можно с помощью свойств LMV_RASTER_PDF и LMV_VECTOR_PDF.

Вы можете посмотреть, какой именно загрузчик был использован при отображении PDF с помощью инструментов разработчика в браузере:

Код - JavaScript: [Выделить]
  1. NOP_VIEWER.model.loader
  2. // значением будет либо
  3. // LeafletLoader со свойством 'isLeafletLoader = true' или
  4. // PDFLoader со свойством 'isPdfLoader = true'

При этом вероятной проблемой для Вас может стать то, что пользователь мог создавать markup-ы в документе, загруженным с помощью LeafletLoader-а, а потом пытаться просмотреть эти же самые пометки, но при этом для отображения документа использовался PDFLoader. ВPDF документе, загруженном LeafletLoader-ом, используется нормализованная система координат, в то время как PDFLoader использует систему координат страницы самого PDF документа, поэтому Вы, скорее всего столкнетесь с тем, что при смене загрузчиков позиция и масштаб markup-ов будут некорректными, как на картинке в начале статьи.

Помочь решить эту проблему может функция Autodesk.Viewing.PDFUtils.leafletToPdfWorld(), которая возвращает преобразование позиции и масштаба, необходимое для корректного отображения markup-ов. Зная это преобразование, самым простым решением может быть отредактировать SVG, добавив атрибут «transform».

Итак, давайте проверим, как это работает. В инструментах разработчика браузера, в консоли:

1) Перед загрузкой документа установим:

Код - JavaScript: [Выделить]
  1. window.LMV_RASTER_PDF = true

2) Проверим, что после загрузки PDF используется LeafletLoader

Код - JavaScript: [Выделить]
  1. NOP_VIEWER.model.loader

3) Перейдем в режим редактирования markup-ов:

Код - JavaScript: [Выделить]
  1. let markupExtension = await NOP_VIEWER.loadExtension('Autodesk.Viewing.MarkupsCore')
  2. markupExtension.enterEditMode();
  3. var arrow = new Autodesk.Viewing.Extensions.Markups.Core.EditModeArrow(markupExtension)
  4. markupExtension.changeEditMode(arrow)

4) Нарисуем несколько стрелочек, постараемся запомнить их расположение :-)

5) Сохраним в SVG созданные markup-ы:

Код - JavaScript: [Выделить]
  1. var markupGeneratedForLeaflet = markupExtension.generateData()

6) Переключимся на PDFLoader:

Код - JavaScript: [Выделить]
  1. window.LMV_RASTER_PDF = false

7) Заново загрузим PDF документ

8) Загрузим сохраненные markup-ы с коррекцией их положения и масштаба:

Код - JavaScript: [Выделить]
  1. let markupExtension = await NOP_VIEWER.loadExtension('Autodesk.Viewing.MarkupsCore')
  2. markupExtension.show()
  3. markupExtension.loadMarkups(markupGeneratedForLeaflet, "layerName")
  4. if (NOP_VIEWER.model.loader.isPdfLoader) {
  5.   let origin = Autodesk.Viewing.PDFUtils.leafletToPdfWorld(NOP_VIEWER, new THREE.Vector3(0,0,0))
  6.   let one = Autodesk.Viewing.PDFUtils.leafletToPdfWorld(NOP_VIEWER, new THREE.Vector3(1,1,1))
  7.   let svg = markupExtension.svg
  8.   svg.firstChild.setAttribute("transform", `translate(${origin.x}, ${origin.y}) scale(${one.x - origin.x}, ${one.y - origin.y})`)
  9. }

Если Вы столкнулись с противоположной проблемой, когда данные SVG Ваших markup-ов были созданы в документе, загруженном PDFLoader-ом, а Вы хотите их корректно отобразить с использованием LeafletLoader-а, на шаге 8, Вы можете воспользоваться следующим кодом:

Код - JavaScript: [Выделить]
  1. let markupExtension = await NOP_VIEWER.loadExtension('Autodesk.Viewing.MarkupsCore')
  2. markupExtension.show()
  3. markupExtension.loadMarkups(markupGeneratedForPdf, "layerName")
  4. if (NOP_VIEWER.model.loader.isLeafletLoader) {
  5.   let origin = Autodesk.Viewing.PDFUtils.leafletToPdfWorld(NOP_VIEWER, new THREE.Vector3(0,0,0))
  6.   let one = Autodesk.Viewing.PDFUtils.leafletToPdfWorld(NOP_VIEWER, new THREE.Vector3(1,1,1))
  7.   let svg = markupExtension.svg
  8.   svg.firstChild.setAttribute("transform", `scale(${1 / (one.x - origin.x)}, ${1 / (one.y - origin.y)}) translate(${-origin.x}, ${-origin.y})`)
  9. }

 

Источник: https://forge.autodesk.com/blog/markups-leafletloader-vs-pdfloader

Автор перевода: Александр Игнатович
Опубликовано 31.07.2020