1 votos

OpenLayers generando PDFs del lado del cliente

Actualmente estoy trabajando en una solución para generar PDFs del lado del cliente a partir del contenido de OpenLayers. La experiencia está bien hasta ahora, pero estoy teniendo un poco de problemas.

El resumen es el siguiente:

  • Calcular la cantidad de píxeles necesarios para llenar un espacio determinado en el papel
  • Establecer temporalmente el map a una resolución determinada
  • leer el lienzo
  • hacer cosas de imprenta
  • restablecer el mapa a la resolución anterior

En código:

      var mapSizeForPrint = [
        // in pixel
        Math.round(this.pdf.width * pixelsPerMapMillimeter),
        Math.round(this.pdf.height * pixelsPerMapMillimeter)
      ];
      ...
      var map = this.openLayersMap();
      ...
      this.mapExtent = map.getView().calculateExtent(this.mapSize);
      ...
      this.rendercompleteListener = map.once("rendercomplete", event => {
       //Do printing magic
      }
      map.setSize(mapSizeForPrint);
      map.getView().fit(this.mapExtent, { size: mapSizeForPrint });

Si alguien está interesado en los detalles (sucios): el código completo está disponible como código abierto aquí

Eso funciona hasta cierto punto.

  • escalando a 80 DPI, obtengo un subconjunto esperado del mapa
  • escalando a 120 DPI, obtengo un subconjunto relativamente esperado del mapa
  • escalando a 200 DPI, obteniendo un resultado inesperado

application 80DPI 200DPI

Actualmente asumo, que obtengo el "mismo" conjunto de datos para cualquier resolución dada - es decir, el centro visible del 80DPI es "la misma" que la versión 200DPI sólo que no cabe en la pantalla; pero parece que no es el caso.

¿Alguien me da una pista en qué dirección mirar? Tal vez tengo algunas suposiciones falsas que actualmente no veo o no veo, cómo superar.

5voto

Bob Johnson Puntos 26

Es porque en OpenLayers 5 por defecto fit limita la resolución a un nivel de zoom entero. Esto se puede arreglar añadiendo constrainResolution: false a las opciones. Tenga en cuenta también que calculateExtent() y fit() no dan el resultado deseado cuando se gira la vista, por lo que podría reemplazarlos completamente estableciendo la resolución así en este ejemplo https://openlayers.org/en/latest/examples/export-pdf.html

    var extent = map.getView().calculateExtent(size);

    map.once('rendercomplete', function(event) {
      var canvas = event.context.canvas;
      var data = canvas.toDataURL('image/jpeg');
      var pdf = new jsPDF('landscape', undefined, format);
      pdf.addImage(data, 'JPEG', 0, 0, dim[0], dim[1]);
      pdf.save('map.pdf');
      // Reset original map size
      map.setSize(size);
      map.getView().fit(extent, {size: size});
      exportButton.disabled = false;
      document.body.style.cursor = 'auto';
    });

    // Set print size
    var printSize = [width, height];
    map.setSize(printSize);
    map.getView().fit(extent, {size: printSize});

se convierte en

    var viewResolution = map.getView().getResolution();

    map.once('rendercomplete', function(event) {
      var canvas = event.context.canvas;
      var data = canvas.toDataURL('image/jpeg');
      var pdf = new jsPDF('landscape', undefined, format);
      pdf.addImage(data, 'JPEG', 0, 0, dim[0], dim[1]);
      pdf.save('map.pdf');
      // Reset original map size
      map.setSize(size);
      map.getView().setResolution(viewResolution);
      exportButton.disabled = false;
      document.body.style.cursor = 'auto';
    });

    // Set print size
    var printSize = [width, height];
    map.setSize(printSize);
    var scaling = Math.min(width / size[0], height / size[1]);
    map.getView().setResolution(viewResolution / scaling);

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X