Mercurial > gemma
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 |