comparison client/src/components/Pdftool.vue @ 1884:59ef76d83de7 dev-pdf-generation

client: pdf-gen: make scalebar dynamic * Add calculations so that the bar scale will have the right text labels for the distance in meters. * Use print selected print resolution and add 80 dpi as additional value. * (cleanup) Remove unused and unneeded function this.addImage(). * Use better variable names for the different "resolutions".
author Bernhard Reiter <bernhard@intevation.de>
date Wed, 16 Jan 2019 22:19:50 +0100
parents 76a6d334e681
children 20fe31b4dd5d
comparison
equal deleted inserted replaced
1883:76a6d334e681 1884:59ef76d83de7
20 <select v-model="form.format" class="form-control d-block w-100"> 20 <select v-model="form.format" class="form-control d-block w-100">
21 <option value="landscape"><translate>landscape</translate></option> 21 <option value="landscape"><translate>landscape</translate></option>
22 <option value="portrait"><translate>portrait</translate></option> 22 <option value="portrait"><translate>portrait</translate></option>
23 </select> 23 </select>
24 <select v-model="form.resolution" class="form-control d-block w-100"> 24 <select v-model="form.resolution" class="form-control d-block w-100">
25 <option value="80">80 dpi</option>
25 <option value="120">120 dpi</option> 26 <option value="120">120 dpi</option>
26 <option value="200">200 dpi</option> 27 <option value="200">200 dpi</option>
27 </select> 28 </select>
28 <select v-model="form.paperSize" class="form-control d-block w-100"> 29 <select v-model="form.paperSize" class="form-control d-block w-100">
29 <option value="a3"><translate>ISO A3</translate></option> 30 <option value="a3"><translate>ISO A3</translate></option>
108 download() { 109 download() {
109 // FUTURE: disable button while working on it 110 // FUTURE: disable button while working on it
110 console.log( 111 console.log(
111 "will generate pdf with", 112 "will generate pdf with",
112 this.form.paperSize, 113 this.form.paperSize,
113 this.form.format 114 this.form.format,
115 this.form.resolution
114 ); 116 );
115 var width, height; 117 var width, height;
116 118
117 if (this.form.format !== "portrait") { 119 if (this.form.format !== "portrait") {
118 // landscape, default 120 // landscape, default
122 // switch width and height 124 // switch width and height
123 width = paperSizes[this.form.paperSize][1]; 125 width = paperSizes[this.form.paperSize][1];
124 height = paperSizes[this.form.paperSize][0]; 126 height = paperSizes[this.form.paperSize][0];
125 } 127 }
126 128
127 let resolution = 120; // Dots per inch. An inch is 25.4 mm.
128
129 // FUTURE: consider margins 129 // FUTURE: consider margins
130 console.log(width, height); 130 console.log(width, height);
131
132 // dots per mm = dots per inch / (25.4 mm/inch)
133 var pixelsPerMapMillimeter = this.form.resolution / 25.4;
134 var mapSizeForPrint = [
135 // in pixel
136 Math.round(width * pixelsPerMapMillimeter),
137 Math.round(height * pixelsPerMapMillimeter)
138 ];
131 139
132 // generate PDF and open it 140 // generate PDF and open it
133 // our units are milimeters; width 0 x height 0 is left upper corner 141 // our units are milimeters; width 0 x height 0 is left upper corner
134 142
135 // Step 1 prepare and save current map extend 143 // Step 1 prepare and save current map extend
153 var self = this; 161 var self = this;
154 162
155 // set a callback for after the next complete rendering of the map 163 // set a callback for after the next complete rendering of the map
156 map.once("rendercomplete", function(event) { 164 map.once("rendercomplete", function(event) {
157 let canvas = event.context.canvas; 165 let canvas = event.context.canvas;
158 console.log("rendered", canvas); 166 let view = map.getView();
167 let metersPerPixel = // meters (reality) per pixel (map)
168 view.getResolution() * view.getProjection().getMetersPerUnit();
169 console.log("metersPerPixel = ", metersPerPixel);
170
159 var data = canvas.toDataURL("image/png"); 171 var data = canvas.toDataURL("image/png");
160 pdf.addImage(data, "PNG", 0, 0, width, height); 172 pdf.addImage(data, "PNG", 0, 0, width, height);
161 self.addRoundedBox( 173 self.addRoundedBox(
162 pdf, 174 pdf,
163 width - scalebarSize * 5.5, 175 width - scalebarSize * 5.5,
167 ); 179 );
168 self.addScalebar( 180 self.addScalebar(
169 pdf, 181 pdf,
170 width - scalebarSize * 5, 182 width - scalebarSize * 5,
171 height - scalebarSize / 2, 183 height - scalebarSize / 2,
172 scalebarSize 184 scalebarSize,
185 scalebarSize * pixelsPerMapMillimeter * metersPerPixel
173 ); 186 );
174 //self.addText(pdf, 150, 20, 10, "black", 70, "some text"); 187 //self.addText(pdf, 150, 20, 10, "black", 70, "some text");
175 self.addNorthArrow(pdf, 15, 8, northarrowSize); 188 self.addNorthArrow(pdf, 15, 8, northarrowSize);
176 pdf.save("map.pdf"); 189 pdf.save("map.pdf");
177 // reset to original size 190 // reset to original size
180 193
181 // FUTURE: re-enable button when done 194 // FUTURE: re-enable button when done
182 }); 195 });
183 196
184 // trigger rendering 197 // trigger rendering
185 var mapSizeForPrint = [
186 Math.round((width * resolution) / 25.4),
187 Math.round((height * resolution) / 25.4)
188 ];
189 map.setSize(mapSizeForPrint); 198 map.setSize(mapSizeForPrint);
190 map.getView().fit(mapExtent, { size: mapSizeForPrint }); 199 map.getView().fit(mapExtent, { size: mapSizeForPrint });
191 200
192 // TODO: replace this src with an API reponse after actually generating PDFs 201 // TODO: replace this src with an API reponse after actually generating PDFs
193 /* 202 /*
213 // using jsPDF units 222 // using jsPDF units
214 doc.setDrawColor(255, 255, 255); 223 doc.setDrawColor(255, 255, 255);
215 doc.setFillColor(255, 255, 255); 224 doc.setFillColor(255, 255, 255);
216 doc.roundedRect(x, y, w, h, 3, 3, "FD"); 225 doc.roundedRect(x, y, w, h, 3, 3, "FD");
217 }, 226 },
218 addScalebar(doc, x, y, size) { 227 addScalebar(doc, x, y, size, realLength) {
228 // realLength as number in meters (reality)
219 doc.setDrawColor(0, 0, 0); 229 doc.setDrawColor(0, 0, 0);
220 doc.setFillColor(0, 0, 0); 230 doc.setFillColor(0, 0, 0);
221 doc.rect(x, y, size, 1, "FD"); 231 doc.rect(x, y, size, 1, "FD");
222 doc.setFillColor(255, 255, 255); 232 doc.setFillColor(255, 255, 255);
223 doc.setDrawColor(0, 0, 0); 233 doc.setDrawColor(0, 0, 0);
225 doc.setFillColor(0, 0, 0); 235 doc.setFillColor(0, 0, 0);
226 doc.setDrawColor(0, 0, 0); 236 doc.setDrawColor(0, 0, 0);
227 doc.rect(x + size * 2, y, size * 2, 1, "FD"); 237 doc.rect(x + size * 2, y, size * 2, 1, "FD");
228 doc.setFontSize(5); 238 doc.setFontSize(5);
229 doc.text(x, y + 3, "0"); 239 doc.text(x, y + 3, "0");
230 doc.text(x + size, y + 3, "50"); 240 doc.text(x + size, y + 3, Math.round(realLength).toString());
231 doc.text(x + size * 2, y + 3, "100"); 241 doc.text(x + size * 2, y + 3, Math.round(realLength * 2).toString());
232 doc.text(x + size * 4, y + 3, "200 m"); 242 doc.text(
243 x + size * 4,
244 y + 3,
245 Math.round(realLength * 4).toString() + " m"
246 );
233 }, 247 },
234 248
235 addNorthArrow(doc, x1, y1, size) { 249 addNorthArrow(doc, x1, y1, size) {
236 var y2 = y1 + size * 3; 250 var y2 = y1 + size * 3;
237 var x3 = x1 - size * 2; 251 var x3 = x1 - size * 2;
255 doc.setFontSize(size * 3); 269 doc.setFontSize(size * 3);
256 doc.setTextColor(0, 0, 0); 270 doc.setTextColor(0, 0, 0);
257 doc.setFontStyle("normal"); 271 doc.setFontStyle("normal");
258 doc.text(size < 3 ? x1 - 0.5 : x1 - 1.3, y3 + 1, "N"); 272 doc.text(size < 3 ? x1 - 0.5 : x1 - 1.3, y3 + 1, "N");
259 }, 273 },
260
261 //export an image to PDF
262 addImage(doc, img, type, x, y, width, hight) {
263 doc.addImage(img, type, x, y, width, hight);
264 },
265
266 // add some text at specific coordinates and determine how many wrolds in single line 274 // add some text at specific coordinates and determine how many wrolds in single line
267 addText(doc, postitionX, positionY, size, color, lineWidth, text) { 275 addText(doc, postitionX, positionY, size, color, lineWidth, text) {
268 // split the incoming string to an array, each element is a string of words in a single line 276 // split the incoming string to an array, each element is a string of words in a single line
269 var textLines = doc.splitTextToSize(text, lineWidth); 277 var textLines = doc.splitTextToSize(text, lineWidth);
270 // get the longest line to fit the white backround to it 278 // get the longest line to fit the white backround to it