# HG changeset patch # User Thomas Junk # Date 1563359305 -7200 # Node ID 7316b7e8246f605cd1b1eb9f26e343fe46ed145c # Parent 4eaa6bca367a1026a819ecff813f734606ce7a8f improve PDFTool diff -r 4eaa6bca367a -r 7316b7e8246f client/src/components/Pdftool.vue --- a/client/src/components/Pdftool.vue Wed Jul 17 10:47:11 2019 +0200 +++ b/client/src/components/Pdftool.vue Wed Jul 17 12:28:25 2019 +0200 @@ -169,7 +169,7 @@ readyToGenerate: true, // if the user is allowed to press the button rendercompleteListener: null, mapSize: null, - mapExtent: null + resolution: null }; }, computed: { @@ -209,12 +209,6 @@ close() { this.$store.commit("application/showPdfTool", false); }, - millimeter2pixels(length, dpi) { - return (dpi * length) / 25.4; - }, - pixel2millimeter(pixels, dpi) { - return (pixels * 25.4) / dpi; - }, // When a template is chosen from the dropdown, its propoerties are // applied to the rest of the form. applyTemplateToForm() { @@ -293,7 +287,7 @@ // Calculate the extent for the current view state and the passed size. // The size is the pixel dimensions of the box into which the calculated // extent should fit. - this.mapExtent = map.getView().calculateExtent(this.mapSize); + this.resolution = map.getView().getResolution(); this.pdf.doc = new jsPDF(this.form.format, "mm", this.form.paperSize); // set a callback for after the next complete rendering of the map @@ -315,191 +309,147 @@ 1000 * pixelsPerMapMillimeter * metersPerPixel ); console.log("scaleDenominator = ", scaleDenominator); - const width80DPI = this.millimeter2pixels(this.pdf.width, 80); - const height80DPI = this.millimeter2pixels(this.pdf.height, 80); - const currentHeight = this.millimeter2pixels( - this.pdf.height, - this.form.resolution - ); - const currentWidth = this.millimeter2pixels( + var snapshot = canvas.toDataURL("image/jpeg"); + this.pdf.doc.addImage( + snapshot, + "JPEG", + 0, + 0, this.pdf.width, - this.form.resolution + this.pdf.height ); - //const scaleFactor = this.form.resolution / 80; - var snapshot = canvas.toDataURL("image/jpeg"); - const offscreen = document.createElement("canvas"); - offscreen.width = currentWidth; - offscreen.height = currentHeight; - const image = new Image(); - image.src = snapshot; - image.onload = () => { - offscreen - .getContext("2d") - .drawImage( - image, - (currentWidth - width80DPI) / 2, - (currentHeight - height80DPI) / 2, - width80DPI, - height80DPI, - 0, - 0, - currentWidth, - currentHeight - ); - const data = offscreen.toDataURL("image/jpeg"); - this.pdf.doc.addImage( - data, - "JPEG", - 0, - 0, - this.pdf.width, - this.pdf.height - ); - if (this.templateData) { - this.pdf.doc.setFont("linbiolinum", "normal"); - let defaultFontSize = 11, - defaultRounding = 2, - defaultTextColor = "black", - defaultBgColor = "white", - defaultPadding = 3, - defaultOffset = { x: 0, y: 0 }, - defaultBorderColor = "white", - defaultWidth = 100; - this.templateData.elements.forEach(e => { - switch (e.type) { - case "text": { - this.addText( - e.position, - e.offset || defaultOffset, - e.width || defaultWidth, - e.fontSize || defaultFontSize, - e.color || defaultTextColor, - e.text - ); - break; - } - case "box": { - this.addBox( - e.position, - e.offset || defaultOffset, - e.width, - e.height, - // handling the case when the rectangle not rounded (rounding = 0) - e.rounding === 0 || e.rounding - ? e.rounding - : defaultRounding, - e.color || defaultBgColor, - e.brcolor || defaultBorderColor - ); - break; - } - case "textbox": { - this.addTextBox( - e.position, - e.offset || defaultOffset, - e.width, - e.height, - e.rounding === 0 || e.rounding - ? e.rounding - : defaultRounding, - e.padding || defaultPadding, - e.fontSize || defaultFontSize, - e.color || defaultTextColor, - e.background || defaultBgColor, - e.text, - e.brcolor || defaultBorderColor - ); - break; - } - case "image": { - this.addImage( - e.url, - e.format, - e.position, - e.offset || defaultOffset, - e.width, - e.height - ); - break; - } - case "bottleneck": { - this.addBottleneckInfo( - e.position, - e.offset || defaultOffset, - e.rounding === 0 || e.rounding - ? e.rounding - : defaultRounding, - e.color || defaultTextColor, - e.brcolor || defaultBorderColor - ); - break; - } - case "legend": { - this.addLegend( - e.position, - e.offset || defaultOffset, - e.rounding === 0 || e.rounding - ? e.rounding - : defaultRounding, - e.brcolor || defaultBorderColor - ); - break; - } - case "scalebar": { - this.addScaleBar( - scaleDenominator, - e.position, - e.offset || defaultOffset, - e.rounding === 0 || e.rounding - ? e.rounding - : defaultRounding, - e.brcolor || defaultBorderColor - ); - break; - } - case "scale": { - this.addScale( - scaleDenominator, - e.position, - e.width, - e.offset || defaultOffset, - e.fontSize || defaultFontSize, - e.color || defaultTextColor - ); - break; - } - case "northarrow": { - this.addNorthArrow( - e.position, - e.offset || defaultOffset, - e.size - ); - break; - } + if (this.templateData) { + this.pdf.doc.setFont("linbiolinum", "normal"); + let defaultFontSize = 11, + defaultRounding = 2, + defaultTextColor = "black", + defaultBgColor = "white", + defaultPadding = 3, + defaultOffset = { x: 0, y: 0 }, + defaultBorderColor = "white", + defaultWidth = 100; + this.templateData.elements.forEach(e => { + switch (e.type) { + case "text": { + this.addText( + e.position, + e.offset || defaultOffset, + e.width || defaultWidth, + e.fontSize || defaultFontSize, + e.color || defaultTextColor, + e.text + ); + break; + } + case "box": { + this.addBox( + e.position, + e.offset || defaultOffset, + e.width, + e.height, + // handling the case when the rectangle not rounded (rounding = 0) + e.rounding === 0 || e.rounding ? e.rounding : defaultRounding, + e.color || defaultBgColor, + e.brcolor || defaultBorderColor + ); + break; + } + case "textbox": { + this.addTextBox( + e.position, + e.offset || defaultOffset, + e.width, + e.height, + e.rounding === 0 || e.rounding ? e.rounding : defaultRounding, + e.padding || defaultPadding, + e.fontSize || defaultFontSize, + e.color || defaultTextColor, + e.background || defaultBgColor, + e.text, + e.brcolor || defaultBorderColor + ); + break; } - }); - - this.pdf.doc.save(this.filename); - } - - // reset to original size - map.setSize(this.mapSize); - map.getView().fit(this.mapExtent, { - size: this.mapSize, - // necessary to get to the previous zoom level in all cases - // details see https://github.com/openlayers/openlayers/issues/9235 - constrainResolution: false + case "image": { + this.addImage( + e.url, + e.format, + e.position, + e.offset || defaultOffset, + e.width, + e.height + ); + break; + } + case "bottleneck": { + this.addBottleneckInfo( + e.position, + e.offset || defaultOffset, + e.rounding === 0 || e.rounding ? e.rounding : defaultRounding, + e.color || defaultTextColor, + e.brcolor || defaultBorderColor + ); + break; + } + case "legend": { + this.addLegend( + e.position, + e.offset || defaultOffset, + e.rounding === 0 || e.rounding ? e.rounding : defaultRounding, + e.brcolor || defaultBorderColor + ); + break; + } + case "scalebar": { + this.addScaleBar( + scaleDenominator, + e.position, + e.offset || defaultOffset, + e.rounding === 0 || e.rounding ? e.rounding : defaultRounding, + e.brcolor || defaultBorderColor + ); + break; + } + case "scale": { + this.addScale( + scaleDenominator, + e.position, + e.width, + e.offset || defaultOffset, + e.fontSize || defaultFontSize, + e.color || defaultTextColor + ); + break; + } + case "northarrow": { + this.addNorthArrow( + e.position, + e.offset || defaultOffset, + e.size + ); + break; + } + } }); - // as we are done: re-enable button - this.readyToGenerate = true; - }; + this.pdf.doc.save(this.filename); + } + + // reset to original size + map.setSize(this.mapSize); + map.getView().setResolution(this.resolution); + + // as we are done: re-enable button + this.readyToGenerate = true; }); // trigger rendering + const size = map.getSize(); + const [width, height] = mapSizeForPrint; map.setSize(mapSizeForPrint); - map.getView().fit(this.mapExtent, { size: mapSizeForPrint }); + const scaling = Math.min(width / size[0], height / size[1]); + map.getView().setResolution(this.resolution / scaling); }, cancel() { this.openLayersMap().un( @@ -509,7 +459,7 @@ this.openLayersMap().setSize(this.mapSize); this.openLayersMap() .getView() - .fit(this.mapExtent, { size: this.mapSize }); + .fit(this.resolution, { size: this.mapSize }); this.readyToGenerate = true; }, // add the used map scale and papersize