decoration.magnetic-meridians.js (3222B)
1 import L from 'leaflet'; 2 import {getDeclination} from '~/lib/magnetic-declination'; 3 import {PrintStaticLayer} from './decorations'; 4 5 function radians(degrees) { 6 return degrees * Math.PI / 180; 7 } 8 9 function movePoint(p, angle, dist) { 10 angle = radians(angle); 11 return L.point(p.x + Math.sin(angle) * dist, p.y - Math.cos(angle) * dist); 12 } 13 14 class MagneticMeridians extends PrintStaticLayer { 15 lineThicknessMm = 0.2; 16 lineIntervalMm = 50; 17 samplingIntervalMm = 15; 18 color = '#66c2ff'; 19 overlaySolid = false; 20 21 _makeCanvasToLatLngTransformer(printOptions) { 22 const projectedBounds = printOptions.pixelBounds; 23 const scale = projectedBounds.getSize().unscaleBy(printOptions.destPixelSize); 24 const origin = projectedBounds.min; 25 return function(pixel) { 26 return L.CRS.EPSG3857.pointToLatLng(pixel.scaleBy(scale).add(origin), printOptions.zoom); 27 }; 28 } 29 30 _drawRaster(canvas, printOptions) { 31 const toLatLng = this._makeCanvasToLatLngTransformer(printOptions); 32 const ctx = canvas.getContext('2d'); 33 ctx.beginPath(); 34 ctx.strokeStyle = this.color; 35 ctx.lineWidth = this.lineThicknessMm / 25.4 * printOptions.resolution; 36 const intervalPx = this.lineIntervalMm / 25.4 * printOptions.resolution; 37 const samplingPx = this.samplingIntervalMm / 25.4 * printOptions.resolution; 38 const pageDiagonal = Math.sqrt( 39 printOptions.destPixelSize.x * printOptions.destPixelSize.x + 40 printOptions.destPixelSize.y * printOptions.destPixelSize.y 41 ); 42 const maxSegments = pageDiagonal / 2 / samplingPx; 43 44 function drawLine(p, directionDown) { 45 ctx.moveTo(p.x, p.y); 46 47 for (let i = 0; i <= maxSegments; i++) { 48 let latLng = toLatLng(p); 49 let declination = getDeclination(latLng.lat, latLng.lng); 50 if (declination === null) { 51 break; 52 } 53 if (directionDown) { 54 declination += 180; 55 } 56 p = movePoint(p, declination, samplingPx); 57 ctx.lineTo(p.x, p.y); 58 } 59 } 60 61 const center = printOptions.destPixelSize.divideBy(2); 62 const maxLines = pageDiagonal / 2 / intervalPx; 63 64 drawLine(center); 65 drawLine(center, true); 66 67 let p = center; 68 for (let i = 0; i <= maxLines; i++) { 69 let latLng = toLatLng(p); 70 let declination = getDeclination(latLng.lat, latLng.lng); 71 if (declination === null) { 72 declination = 0; 73 } 74 p = movePoint(p, declination + 90, intervalPx); 75 drawLine(p); 76 drawLine(p, true); 77 } 78 p = center; 79 for (let i = 0; i <= maxLines; i++) { 80 let latLng = toLatLng(p); 81 let declination = getDeclination(latLng.lat, latLng.lng); 82 if (declination === null) { 83 declination = 0; 84 } 85 p = movePoint(p, declination - 90, intervalPx); 86 drawLine(p); 87 drawLine(p, true); 88 } 89 90 ctx.stroke(); 91 } 92 } 93 94 export {MagneticMeridians};