mapillary-coverage-layer.js (6113B)
1 import L from 'leaflet'; 2 import {MapillaryLoader} from './mapillary-loader'; 3 4 const MapillaryCoverage = L.GridLayer.extend({ 5 options: { 6 tileSize: 1024, 7 updateWhenIdle: true, 8 color: '#00cfb1' 9 }, 10 11 initialize: function(options) { 12 L.GridLayer.prototype.initialize.call(this, options); 13 this.loader = new MapillaryLoader(this.options.url, 12); 14 }, 15 16 onAdd: function(map) { 17 L.GridLayer.prototype.onAdd.call(this, map); 18 this.on('tileunload', this.onTileUnload, this); 19 }, 20 21 onRemove: function(map) { 22 L.GridLayer.prototype.onRemove.call(this, map); 23 this.off('tileunload', this.onTileUnload, this); 24 }, 25 26 onTileUnload: function(e) { 27 const tile = e.tile; 28 tile._abortLoading(); 29 delete tile._tileData; 30 delete tile._adjustment; 31 }, 32 33 drawOverview: function(canvas) { 34 const 35 tileData = canvas._tileData; 36 if (!tileData['mapillary-sequence-overview']) { 37 return; 38 } 39 let {multiplier, offsetX, offsetY} = canvas._adjustment; 40 const canvasCtx = canvas.getContext('2d'); 41 canvasCtx.fillStyle = this.options.color; 42 for (let feature of tileData['mapillary-sequence-overview']) { 43 if (feature.geometry.type !== 'Point') { 44 throw new Error(`Invalid sequence overview geometry type "${feature.geometry.type}"`); 45 } 46 canvasCtx.beginPath(); 47 let x = feature.geometry.coordinates[0] * multiplier - offsetX; 48 let y = feature.geometry.coordinates[1] * multiplier - offsetY; 49 canvasCtx.arc(x, y, 5, 0, 2 * Math.PI); 50 canvasCtx.fill(); 51 } 52 }, 53 54 drawSequences: function(canvas, lineWidth) { 55 let 56 tileData = canvas._tileData, 57 adjustment = canvas._adjustment; 58 59 if (!tileData['mapillary-sequences']) { 60 return; 61 } 62 const canvasCtx = canvas.getContext('2d'); 63 canvasCtx.beginPath(); 64 canvasCtx.strokeStyle = this.options.color; 65 canvasCtx.lineWidth = lineWidth; 66 // canvasCtx.lineWidth = thinLines ? 1 : 1; 67 canvasCtx.lineCap = "round"; 68 canvasCtx.lineJoin = "bevel"; 69 for (let feature of tileData['mapillary-sequences']) { 70 if (feature.geometry.type !== 'MultiLineString') { 71 throw new Error(`Invalid sequence geometry type "${feature.geometry.type}"`); 72 } 73 let {multiplier, offsetX, offsetY} = adjustment; 74 75 let lines = feature.geometry.coordinates; 76 for (let lineI = 0; lineI < lines.length; lineI++) { 77 let line = lines[lineI]; 78 if (!line.length) { 79 continue; 80 } 81 let x = line[0][0] * multiplier - offsetX; 82 let y = line[0][1] * multiplier - offsetY; 83 canvasCtx.moveTo(x, y); 84 if (line.length === 1) { 85 canvasCtx.lineTo(x, y); 86 } 87 for (let pointI = 0; pointI < line.length; pointI++) { 88 let x = line[pointI][0] * multiplier - offsetX; 89 let y = line[pointI][1] * multiplier - offsetY; 90 canvasCtx.lineTo(x, y); 91 } 92 } 93 } 94 canvasCtx.stroke(); 95 }, 96 97 drawImages: function(canvas) { 98 let 99 tileData = canvas._tileData, 100 adjustment = canvas._adjustment; 101 if (!tileData['mapillary-images']) { 102 return; 103 } 104 let {multiplier, offsetX, offsetY} = adjustment; 105 const canvasCtx = canvas.getContext('2d'); 106 canvasCtx.beginPath(); 107 canvasCtx.fillStyle = this.options.color; 108 for (let feature of tileData['mapillary-images']) { 109 if (feature.geometry.type !== 'Point') { 110 throw new Error(`Invalid image geometry type "${feature.geometry.type}"`); 111 } 112 canvasCtx.beginPath(); 113 let x = feature.geometry.coordinates[0] * multiplier - offsetX; 114 let y = feature.geometry.coordinates[1] * multiplier - offsetY; 115 canvasCtx.arc(x, y, 4, 0, 2 * Math.PI); 116 canvasCtx.fill(); 117 } 118 }, 119 120 drawTile: function(canvas, coords) { 121 if (!this._map) { 122 return; 123 } 124 if (!canvas._tileData) { 125 return; 126 } 127 if (coords.z < 6 + 2) { 128 this.drawOverview(canvas); 129 } else if (coords.z < 14 + 2) { 130 let width = coords.z < 14 ? 10 : 5; 131 this.drawSequences(canvas, width); 132 } else { 133 this.drawSequences(canvas, 2); 134 this.drawImages(canvas); 135 } 136 }, 137 138 createTile: function(coords, done) { 139 const canvas = L.DomUtil.create('canvas', 'leaflet-tile'); 140 canvas.width = this.options.tileSize; 141 canvas.height = this.options.tileSize; 142 let {dataPromise, abortLoading} = this.loader.requestTileData(coords); 143 dataPromise.then((data) => { 144 if (!data.error) { 145 canvas._tileData = data.tileData; 146 canvas._adjustment = data.adjustment || {multiplier: 1, offsetX: 0, offsetY: 0}; 147 setTimeout(() => { 148 this.drawTile(canvas, coords); 149 done(null, canvas); 150 }, 1); 151 } 152 }); 153 canvas._abortLoading = abortLoading; 154 return canvas; 155 }, 156 157 } 158 ); 159 160 export {MapillaryCoverage};