nakarte

Source code of https://map.sikmir.ru (fork)
git clone git://git.sikmir.ru/nakarte
Log | Files | Refs | LICENSE

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};