UNPKG

@senx/discovery-plugin-marauder

Version:

Discovery plugin - Marauder's map

1,012 lines (1,011 loc) 44.6 kB
import { h } from "@stencil/core"; import domtoimage from "dom-to-image"; import Leaflet from "leaflet"; import UPNG from "../utils/UPNG"; import { CanvasLayer } from "leaflet-canvas-layer"; import { ColorLib, DataModel, GTSLib, Logger, MapLib, Param, Utils } from "@senx/discovery-widgets"; export class DiscoveryMarauder { constructor() { this.defOptions = Object.assign(Object.assign({}, new Param()), { timeMode: 'date', map: { tiles: [], animate: false }, input: { showTicks: true } }); this.divider = 1000; this.initial = false; this.ticks = 0; this.bucketspan = 0.0; this.gts = 0; this.lllat = 0.0; this.lllon = 0.0; this.urlat = 0.0; this.urlon = 0.0; this.latstep = 0.0; this.lonstep = 0.0; this.done = true; this.selectionSize = 50; this.tileLayerGroup = Leaflet.featureGroup(); this.running = null; this.scheduled = false; this.delay = 10; this.MARKERS = true; this.trackMarkers = false; this.tracks = true; this.markerSize = 5; this.markerRadius = this.markerSize / 2.0; this.markerOffset = (this.markerSize - 1) / 2; this.trackMarkerColor = '#00897B'; this.markerColor = undefined; this.trackMarkerSize = 4; this.trackMarkerRadius = this.trackMarkerSize / 2.0; this.trackMarkerOffset = (this.trackMarkerSize - 1) / 2; this.bgTransparentThreshold = 250; this.transparentThreshold = 240; this.extraTicks = 50; this.step = 1; this.particles = null; // [ 0 ]; this.histcanvas = null; this.trackOpacity = 0.05; this.trackWidth = 2; this.squareMarkers = false; this.squareTrackMarkers = false; this.resetOnZoom = true; this.sliderMin = '0'; this.sliderMax = '0'; this.drawn = false; this.endDate = 0; this.startDate = 0; this.tileLayers = []; this.result = undefined; this.type = undefined; this.options = new Param(); this.width = undefined; this.height = undefined; this.debug = false; this.parsing = false; this.toDisplay = []; this.innerOptions = undefined; this.loading = true; this.currentTick = undefined; this.paused = true; this.selected = []; } updateRes(newValue, oldValue) { if (JSON.stringify(newValue) !== JSON.stringify(oldValue)) { this.result = GTSLib.getData(this.result); this.initial = true; setTimeout(() => { var _a; return this.drawMap((_a = this.result) !== null && _a !== void 0 ? _a : new DataModel(), true, true); }); } } optionsUpdate(newValue, oldValue) { this.LOG.debug(['optionsUpdate'], newValue, oldValue); if (JSON.stringify(newValue) !== JSON.stringify(oldValue)) { if (!!this.options && typeof this.options === 'string') { this.innerOptions = JSON.parse(this.options); } else { this.innerOptions = Object.assign({}, this.options); } this.applyInnerOptions(); setTimeout(() => this.drawMap(this.result || new DataModel(), true, true)); if (this.LOG) { this.LOG.debug(['optionsUpdate 2'], { options: this.innerOptions, newValue, oldValue }); } } } async resize() { const dims = Utils.getContentBounds(this.el.parentElement); this.width = dims.w; this.height = dims.h; if (this.map) { this.map.invalidateSize(); } } // noinspection JSUnusedLocalSymbols async export(type = 'png') { return await domtoimage.toPng(this.mapElement, { height: this.height, width: this.width }); } async handleKeyDown(ev) { this.LOG.debug(['handleKeydown'], ev); if (ev.key === 'Shift') { this.ctrlPressed = true; } } async handleKeyUp(ev) { this.LOG.debug(['handleKeyUp'], ev); if (ev.key === 'Shift') { this.ctrlPressed = false; } } applyInnerOptions() { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1; this.markerSize = (_b = (_a = this.innerOptions.extra) === null || _a === void 0 ? void 0 : _a.markerSize) !== null && _b !== void 0 ? _b : 5; this.trackMarkerColor = (_d = (_c = this.innerOptions.extra) === null || _c === void 0 ? void 0 : _c.trackMarkerColor) !== null && _d !== void 0 ? _d : '#00897B'; this.trackMarkerSize = (_f = (_e = this.innerOptions.extra) === null || _e === void 0 ? void 0 : _e.trackMarkerSize) !== null && _f !== void 0 ? _f : 4; this.bgTransparentThreshold = (_h = (_g = this.innerOptions.extra) === null || _g === void 0 ? void 0 : _g.bgTransparentThreshold) !== null && _h !== void 0 ? _h : 250; this.transparentThreshold = (_k = (_j = this.innerOptions.extra) === null || _j === void 0 ? void 0 : _j.transparentThreshold) !== null && _k !== void 0 ? _k : 240; this.extraTicks = (_m = (_l = this.innerOptions.extra) === null || _l === void 0 ? void 0 : _l.extraTicks) !== null && _m !== void 0 ? _m : 50; this.trackOpacity = (_p = (_o = this.innerOptions.extra) === null || _o === void 0 ? void 0 : _o.trackOpacity) !== null && _p !== void 0 ? _p : 0.05; this.trackWidth = (_r = (_q = this.innerOptions.extra) === null || _q === void 0 ? void 0 : _q.trackWidth) !== null && _r !== void 0 ? _r : 2; this.squareMarkers = (_t = (_s = this.innerOptions.extra) === null || _s === void 0 ? void 0 : _s.squareMarkers) !== null && _t !== void 0 ? _t : false; this.squareTrackMarkers = (_v = (_u = this.innerOptions.extra) === null || _u === void 0 ? void 0 : _u.squareTrackMarkers) !== null && _v !== void 0 ? _v : false; this.trackMarkers = (_x = (_w = this.innerOptions.extra) === null || _w === void 0 ? void 0 : _w.trackMarkers) !== null && _x !== void 0 ? _x : false; this.tracks = (_z = (_y = this.innerOptions.extra) === null || _y === void 0 ? void 0 : _y.tracks) !== null && _z !== void 0 ? _z : true; this.markerColor = (_1 = (_0 = this.innerOptions.extra) === null || _0 === void 0 ? void 0 : _0.markerColor) !== null && _1 !== void 0 ? _1 : undefined; } componentWillLoad() { var _a; this.parsing = true; this.LOG = new Logger(DiscoveryMarauder, this.debug); if (typeof this.options === 'string') { this.innerOptions = JSON.parse(this.options); } else { this.innerOptions = this.options; } this.applyInnerOptions(); this.result = GTSLib.getData(this.result); this.divider = GTSLib.getDivider((_a = this.innerOptions.timeUnit) !== null && _a !== void 0 ? _a : 'us'); this.LOG.debug(['componentWillLoad'], { type: this.type, options: this.innerOptions, toDisplay: this.toDisplay, }); const dims = Utils.getContentBounds(this.el.parentElement); this.width = dims.w; this.height = dims.h; this.parsing = false; } componentDidLoad() { var _a; this.height = Utils.getContentBounds(this.el.parentElement).h; this.setSliderPosition(0); this.drawMap((_a = this.result) !== null && _a !== void 0 ? _a : new DataModel()); } drawMap(data, isRefresh = false, optionUpdate = false) { var _a, _b, _c, _d, _e, _f, _g, _h, _j; let options = Utils.mergeDeep(this.defOptions, (_a = this.innerOptions) !== null && _a !== void 0 ? _a : {}); this.LOG.debug(['drawMap', 'this.options 2 '], Object.assign({}, data.globalParams)); options = Utils.mergeDeep(options, (_b = data.globalParams) !== null && _b !== void 0 ? _b : {}); this.innerOptions = Object.assign({}, options); this.applyInnerOptions(); if (!!this.map) { this.map.invalidateSize(true); } this.mapOpts = this.innerOptions.map || {}; let tilesPromise; if (this.mapOpts.mapType !== 'NONE') { const map = (_c = MapLib.mapTypes[this.mapOpts.mapType || 'DEFAULT']) !== null && _c !== void 0 ? _c : MapLib.mapTypes.DEFAULT; const mapOpts = { maxNativeZoom: (_d = this.mapOpts.maxNativeZoom) !== null && _d !== void 0 ? _d : 19, maxZoom: (_e = this.mapOpts.maxZoom) !== null && _e !== void 0 ? _e : 40, edgeBufferTiles: 5, }; if (map.attribution) { mapOpts.attribution = map.attribution; } if (map.subdomains) { mapOpts.subdomains = map.subdomains; } (_f = this.LOG) === null || _f === void 0 ? void 0 : _f.debug(['displayMap'], { isRefresh, optionUpdate }); if (!isRefresh || optionUpdate) { (_g = this.LOG) === null || _g === void 0 ? void 0 : _g.debug(['displayMap'], 'map', map); this.tileLayers.push(map.link); if (!!this.tilesLayer && this.tilesLayer._url !== map.link) { this.tileLayerGroup.removeLayer(this.tilesLayer); this.tilesLayer = undefined; } if (!this.tilesLayer) { this.tilesLayer = Leaflet.tileLayer(map.link, mapOpts); this.tilesLayer.addTo(this.tileLayerGroup); tilesPromise = new Promise(resolve => setTimeout(() => this.tilesLayer.on('load', () => resolve()))); } } } if (!!this.map) { this.map.invalidateSize(true); this.LOG.debug(['displayMap'], 'map exists'); if (!isRefresh || optionUpdate) { this.tileLayerGroup.clearLayers(); if (optionUpdate && !!this.tilesLayer) { this.tilesLayer.addTo(this.tileLayerGroup); } } } else { this.LOG.debug(['displayMap'], 'new map', this.tilesLayer); this.map = Leaflet.map(this.mapElement, { preferCanvas: true, zoomAnimation: true, maxBoundsViscocity: 1, worldCopyJump: true, maxBounds: new Leaflet.LatLngBounds(new Leaflet.latLng(-89.98155760646617, -180), new Leaflet.LatLng(89.99346179538875, 180)), maxZoom: (_h = this.mapOpts.maxZoom) !== null && _h !== void 0 ? _h : 19, // center: [this.lat, this.long], layers: [this.tileLayerGroup], boxZoom: false, trackResize: false }); if (this.tilesLayer) { this.tilesLayer.bringToBack(); // TODO: test it this.tilesLayer.addTo(this.tileLayerGroup); } this.map.on('movestart', () => { this.inMove = true; if (!this.inZoom) { this.previousPause = this.paused; } if (this.popup) { this.popup.removeFrom(this.map); this.popup = undefined; } this.emitPause(true); }); this.map.on('moveend', () => { this.emitPause(this.previousPause); this.selectedSquare = undefined; if (this.previousPause) { this.needRedraw = true; } if (this.selectedCenterLatLng) { this.inMove = true; } if (!!this.info && !!this.info.canvas) { this.info.canvas.getContext('2d').clearRect(0, 0, this.info.canvas.width, this.info.canvas.height); this.drawOnMap(this.info, false); } }); this.map.on('zoomstart', () => { this.inZoom = true; this.previousPause = this.paused; this.emitPause(true); }); this.map.on('zoomend', () => { if (this.popup) { this.popup.removeFrom(this.map); this.popup = undefined; } if (this.selectedCenterLatLng) { this.map.panTo(this.selectedCenterLatLng); } this.emitPause(this.previousPause); }); this.map.on('click', e => { if (this.popup) { this.popup.removeFrom(this.map); this.popup = undefined; } if (this.selectedSquare) { this.map.removeLayer(this.selectedSquare); this.selectedSquare = undefined; } if (this.ctrlPressed) { this.emitPause(true); this.selectedCenterLatLng = e.latlng; this.selectedCenter = this.map.latLngToLayerPoint(e.latlng); const bounds = [ this.map.layerPointToLatLng(Leaflet.point(this.selectedCenter.x - this.selectionSize, this.selectedCenter.y - this.selectionSize)), this.map.layerPointToLatLng(Leaflet.point(this.selectedCenter.x + this.selectionSize, this.selectedCenter.y + this.selectionSize)) ]; this.selectedSquare = Leaflet.rectangle(bounds, { color: 'blue', weight: 1 }).addTo(this.map); this.getDetails(); } }); const mapCanvasLayer = new CanvasLayer(); // If we do not inherit from L.CanvasLayer we can setup a delegate to receive events from L.CanvasLayer mapCanvasLayer.delegate(this); mapCanvasLayer.addTo(this.map); } ((_j = this.mapOpts.tiles) !== null && _j !== void 0 ? _j : []).forEach(t => { var _a, _b, _c, _d, _e, _f, _g, _h; (_a = this.LOG) === null || _a === void 0 ? void 0 : _a.debug(['displayMap'], t); const tile = { subdomains: 'abcd', maxNativeZoom: (_b = this.mapOpts.maxNativeZoom) !== null && _b !== void 0 ? _b : 19, maxZoom: (_c = this.mapOpts.maxZoom) !== null && _c !== void 0 ? _c : 19 }; if (typeof t === 'string') { tile.url = t; } else if (typeof t === 'object') { tile.url = t.url; tile.maxZoom = (_d = this.mapOpts.maxZoom) !== null && _d !== void 0 ? _d : 19; tile.maxNativeZoom = (_f = (_e = t.maxNativeZoom) !== null && _e !== void 0 ? _e : this.mapOpts.maxNativeZoom) !== null && _f !== void 0 ? _f : 19; } this.tileLayers.push(tile.url); const l = Leaflet.tileLayer(tile.url, { subdomains: 'abcd', maxNativeZoom: (_g = tile.maxNativeZoom) !== null && _g !== void 0 ? _g : 19, maxZoom: (_h = this.mapOpts.maxZoom) !== null && _h !== void 0 ? _h : 19, }); if (!this.tileLayerGroup.getLayers().find((l) => l._url === t.url)) { this.tileLayerGroup.addLayer(l); } }); if (!isRefresh || optionUpdate) { this.tileLayerGroup.getLayers().forEach((l) => { if (!this.tileLayers.includes(l._url)) { this.tileLayerGroup.removeLayer(l); } }); } Promise.all([tilesPromise]) .then(() => setTimeout(() => { if (this.initial) { this.draw.emit(); this.initial = false; } }, 500)); this.paused = false; this.initMap(data); } openModal() { this.modal.style.display = 'block'; } closeModal() { if (this.modal) { this.modal.style.display = 'none'; } } initMap(data) { var _a, _b, _c, _d, _e, _f, _g, _h, _j; this.currentTick = 0; this.setSliderPosition(this.currentTick); if (((_a = data.data) !== null && _a !== void 0 ? _a : []).length === 0) return; const result = data.data; this.loading = false; const decoded = atob(result[0].substring(22)); this.lat = result[1]; this.long = result[2]; this.map.setView({ lat: (_b = this.lat) !== null && _b !== void 0 ? _b : 0, lng: (_c = this.long) !== null && _c !== void 0 ? _c : 0 }, (_d = this.mapOpts.startZoom) !== null && _d !== void 0 ? _d : 10, { animate: true }); const buf = new ArrayBuffer(decoded.length); const bufView = new Uint8Array(buf); for (let i = 0, strLen = decoded.length; i < strLen; i++) { bufView[i] = decoded.charCodeAt(i); } const png = UPNG.decode(buf); // Extract parameters const json = png.tabs.iTXt[(_f = (_e = this.innerOptions.extra) === null || _e === void 0 ? void 0 : _e.metadata) !== null && _f !== void 0 ? _f : 'Discovery']; const params = JSON.parse(json); this.infos = params.infos; this.ticks = params.bucketcount; this.sliderMax = params.bucketcount; this.bucketspan = params.bucketspan; this.bucketcount = params.bucketcount; this.gts = params.gts; this.lastbucket = params.lastbucket; this.lonstep = params.lonstep; this.latstep = params.latstep; this.lllat = params.lllat; this.lllon = params.lllon; this.urlat = params.urlat; this.urlon = params.urlon; this.startDate = params.first; this.endDate = params.last; this.urlon = params.urlon; this.delay = (_h = (_g = this.innerOptions.map) === null || _g === void 0 ? void 0 : _g.delay) !== null && _h !== void 0 ? _h : 1000; this.sliderMin = '0'; this.sliderMax = this.bucketspan + ''; this.map.fitBounds([ [this.lllat, this.lllon], [this.urlat, this.urlon] ]); this.data = png.data; this.markers = new Array(this.gts); this.currentTick = 0; this.tick = 0; this.done = true; this.innerOptions.input = { min: this.startDate, max: this.endDate, value: this.startDate, progress: true, horizontal: true, showTicks: !((_j = this.innerOptions.input) === null || _j === void 0 ? void 0 : _j.showTicks) ? false : this.innerOptions.timeMode === 'date' }; this.emitPause(this.paused); } emitPause(b) { this.paused = b; if (!this.paused && this.selectedSquare) { this.map.removeLayer(this.selectedSquare); this.selectedSquare = undefined; } this.pausedEvent.emit(b); } getDetails() { this.selected = []; for (let particle = 0; particle < this.gts; particle++) { const positions = this.getPositions(particle, Math.max(this.tick - 1, 0)); if (!!positions && !!positions[2] && !isNaN(positions[2]) && !isNaN(positions[3])) { const p = this.map.latLngToLayerPoint([positions[2], positions[3]]); if (p.x > this.selectedCenter.x - this.selectionSize && p.x < this.selectedCenter.x + this.selectionSize && p.y > this.selectedCenter.y - this.selectionSize && p.y < this.selectedCenter.y + this.selectionSize) { this.selected.push({ index: particle, info: this.infos[particle] }); } } } this.openModal(); } // noinspection JSUnusedLocalSymbols onDrawLayer(info) { if (this.drawn || this.scheduled) { return; } info.canvas.getContext('2d').clearRect(0, 0, info.canvas.width, info.canvas.height); this.drawn = true; this.info = info; if (this.done) { this.done = false; if (!this.needRedraw) { this.running = this.doParticles(info); } else { this.drawOnMap(this.info, false); } } else { if (!this.inZoom && !this.inMove) { this.done = false; if (!this.needRedraw) { this.scheduled = true; this.running = this.running.then(() => { this.scheduled = false; this.done = false; this.running = this.doParticles(info); }); } else { this.drawOnMap(this.info, false); } } else { if (!!this.info) { if (this.selectedCenterLatLng) { this.drawOnMap(this.info, false); this.selectedCenter = this.map.latLngToLayerPoint(this.selectedCenterLatLng); const bounds = [ this.map.layerPointToLatLng(Leaflet.point(this.selectedCenter.x - this.selectionSize, this.selectedCenter.y - this.selectionSize)), this.map.layerPointToLatLng(Leaflet.point(this.selectedCenter.x + this.selectionSize, this.selectedCenter.y + this.selectionSize)) ]; this.selectedSquare = Leaflet.rectangle(bounds, { color: 'blue', weight: 1 }).addTo(this.map); if (!this.inMove || this.inZoom) { this.getAllDetails(); } } else { this.done = false; if (this.needRedraw) { this.drawOnMap(this.info, !this.needRedraw); } else { this.running = this.running.then(() => { this.scheduled = false; this.done = false; this.running = this.doParticles(info); }); } } } this.inMove = false; this.inZoom = false; } } this.needRedraw = false; } getPositions(gtsidx, tick) { let offset = ((gtsidx * this.ticks) + tick) * 4; if (!this.data) return; // ARGB let lat = ((this.data[offset + 3] << 8) | (this.data[offset] & 0xFF)) & 0xFFFF; let lon = ((this.data[offset + 1] << 8) | (this.data[offset + 2] & 0xFF)) & 0xFFFF; if (0 === lat && 0 === lon) { lat = NaN; lon = NaN; } else { lat = this.lllat + (lat * this.latstep); lon = this.lllon + (lon * this.lonstep); } if (tick < this.step) { return [NaN, NaN, lat, lon]; } else { // // Check if within the previous 'step' ticks one is absent, in which case // the function will return NaN/NaN as the previous position // let prevlat = null; let prevlon = null; if (this.step > 1) { for (let j = 1; j < this.step; j++) { offset = ((gtsidx * this.ticks) + tick - j) * 4; if (0 === this.data[offset] && 0 === this.data[offset + 1] && 0 === this.data[offset + 2] && 0 === this.data[offset + 3]) { prevlat = NaN; prevlon = NaN; break; } } } if (null === prevlat) { offset = ((gtsidx * this.ticks) + tick - this.step) * 4; prevlat = ((this.data[offset + 3] << 8) | (this.data[offset] & 0xFF)) & 0xFFFF; prevlon = ((this.data[offset + 1] << 8) | (this.data[offset + 2] & 0xFF)) & 0xFFFF; if (0 === prevlat && 0 === prevlon) { prevlat = NaN; prevlon = NaN; } else { prevlat = this.lllat + (prevlat * this.latstep); prevlon = this.lllon + (prevlon * this.lonstep); } } return [prevlat, prevlon, lat, lon]; } } drawOnMap(info, drawTraces = true) { var _a, _b, _c, _d, _e; if (!info) return; const canvas = info.canvas; const ctx = canvas.getContext('2d'); const histctx = this.histcanvas.getContext('2d'); if (this.tick < this.ticks) { (_a = this.markers) === null || _a === void 0 ? void 0 : _a.fill(null); histctx.fillStyle = this.trackMarkerColor; for (let particle = 0; particle < this.gts; particle++) { if (!!this.particles && !this.particles.includes(particle)) { continue; } const positions = this.getPositions(particle, this.tick); if (drawTraces) { histctx.strokeStyle = (_b = this.markerColor) !== null && _b !== void 0 ? _b : ColorLib.getColor(particle, this.innerOptions.scheme); // Draw line if the previous position is not NaN/NaN if (this.tracks && !!positions && !!positions[0] && !isNaN(positions[0]) && !isNaN(positions[1]) && !isNaN(positions[2]) && !isNaN(positions[3])) { histctx.beginPath(); histctx.lineWidth = this.trackWidth; let dot; dot = info.layer._map.latLngToContainerPoint([positions[0], positions[1]]); histctx.moveTo(dot.x, dot.y); dot = info.layer._map.latLngToContainerPoint([positions[2], positions[3]]); histctx.lineTo(dot.x, dot.y); histctx.stroke(); } } else { histctx.clearRect(0, 0, info.canvas.width, info.canvas.height); } // Draw marker at current location if (!!positions && !!positions[3] && !isNaN(positions[2]) && !isNaN(positions[3])) { let dot; dot = info.layer._map.latLngToContainerPoint([positions[2], positions[3]]); this.markers[particle] = dot; if (this.trackMarkers) { if (this.squareTrackMarkers || true) { histctx.fillRect(dot.x - this.trackMarkerOffset, dot.y - this.trackMarkerOffset, this.trackMarkerSize, this.trackMarkerSize); } else { // @ts-ignore histctx.fillStyle = (_c = this.markerColor) !== null && _c !== void 0 ? _c : ColorLib.getColor(particle, this.innerOptions.scheme); histctx.beginPath(); histctx.arc(dot.x, dot.y, this.trackMarkerRadius, 0, 2 * Math.PI); histctx.stroke(); } } } } } if (this.currentTick < this.ticks + this.extraTicks * this.step) { // Now clear the canvas and draw histcanvas with opacity 0.8 on it ctx.clearRect(0, 0, canvas.width, canvas.height); if (drawTraces) { ctx.drawImage(this.histcanvas, 0, 0); } // Copy the context onto histctx histctx.clearRect(0, 0, this.histcanvas.width, this.histcanvas.height); histctx.drawImage(canvas, 0, 0); const alpha = histctx.globalAlpha; // Will determine length of track histctx.globalAlpha = this.trackOpacity; histctx.fillStyle = 'white'; histctx.fillRect(0, 0, canvas.width, canvas.height); histctx.globalAlpha = alpha; // Now remove the pixels which are 'white' so they become transparent const imgdata = histctx.getImageData(0, 0, this.histcanvas.width, this.histcanvas.height); const pixels = imgdata.data; const size = pixels.length; for (let idx = 0; idx < size; idx += 4) { // Pixels which are close to white get their transparency set to full if (this.transparentThreshold < 256 && pixels[idx] >= this.transparentThreshold && pixels[idx + 1] >= this.transparentThreshold && pixels[idx + 2] >= this.transparentThreshold || (this.bgTransparentThreshold < 256 && pixels[idx] === pixels[idx + 1] && pixels[idx] === pixels[idx + 2] && pixels[idx] > this.bgTransparentThreshold)) { pixels[idx + 3] = 0; } } histctx.putImageData(imgdata, 0, 0); // Draw the current markers if (this.MARKERS && this.tick < this.ticks && !!this.markers) { for (let particle = 0; particle < this.gts; particle++) { const dot = this.markers[particle]; if (dot) { if (this.squareMarkers) { ctx.fillStyle = (_d = this.markerColor) !== null && _d !== void 0 ? _d : ColorLib.getColor(particle, this.innerOptions.scheme); ctx.fillRect(dot.x - this.markerOffset, dot.y - this.markerOffset, this.markerSize, this.markerSize); } else { ctx.fillStyle = (_e = this.markerColor) !== null && _e !== void 0 ? _e : ColorLib.getColor(particle, this.innerOptions.scheme); ctx.beginPath(); ctx.arc(dot.x, dot.y, this.markerRadius, 0, 2 * Math.PI); ctx.fill(); } } } } } } async doParticles(info) { const canvas = info.canvas; try { // Retrieve canvas const canvasWidth = canvas.width; const canvasHeight = canvas.height; const ctx = canvas.getContext('2d'); // Allocate canvas with history const oldcanvas = this.histcanvas; this.histcanvas = document.createElement('canvas'); this.histcanvas.width = canvasWidth; this.histcanvas.height = canvasHeight; this.histcanvas.bounds = info.bounds; const histctx = this.histcanvas.getContext('2d'); // Copy the current canvas to the new one if (!this.resetOnZoom && null != oldcanvas) { const NE = info.layer._map.latLngToContainerPoint(oldcanvas.bounds._northEast); const SW = info.layer._map.latLngToContainerPoint(oldcanvas.bounds._southWest); histctx.drawImage(oldcanvas, 0, 0, oldcanvas.width, oldcanvas.height, SW.x, NE.y, (NE.x - SW.x + 1), (SW.y - NE.y + 1)); } this.stopTick = this.ticks + (this.extraTicks * this.step); this.drawContext = { info, ctx, histctx, canvas }; this.drawIt(); } finally { this.done = true; } } drawIt() { if (!this.paused && this.tick < this.stopTick) { this.currentTick = this.tick; this.setSliderPosition(this.currentTick); const start = window.performance.now(); this.drawOnMap(this.drawContext.info); const end = window.performance.now(); const d = Math.max(1, this.delay - Math.round(end - start)); this.tick = this.tick + this.step; if (this.tick >= this.stopTick - this.extraTicks) { this.drawContext.ctx.clearRect(0, 0, this.drawContext.canvas.width, this.drawContext.canvas.height); this.drawContext.histctx.clearRect(0, 0, this.drawContext.canvas.width, this.drawContext.canvas.height); this.tick = 0; } if (d > 1) { setTimeout(() => this.drawIt(), d); } else { setTimeout(() => this.drawIt()); } } else { setTimeout(() => this.drawIt(), 500); } } getAllDetails() { } handleSelect(e) { const tick = Math.round((e.detail - this.startDate) / this.bucketspan / this.divider); if (this.tick !== tick + 1) { this.setSliderPosition(tick, true); } } setSliderPosition(pos, setTick = false) { if (setTick) { this.tick = pos; this.drawOnMap(this.info, true); } if (!!this.slider) { setTimeout(() => this.slider.setValue(this.startDate + pos * this.bucketspan * this.divider) .then(() => { })); } } togglePlayPause() { this.paused = !this.paused; this.emitPause(this.paused); } render() { return h("div", { key: '7f4827f12c6c98a7788f9778832750e40fd2ed70', class: "map-container", style: { width: this.width + 'px', height: this.height + 'px' } }, h("div", { key: '9cf72de03b10fde0e28af35b4b2be106504dcf4c', class: "modal", ref: (el) => this.modal = el }, h("div", { key: '2c506f1331b611131c26d024becb4049e5b5522a', class: "modal-content" }, h("span", { key: 'ed37d50a54b30e261ea466ae959f12726862ecd5', class: "close", onClick: () => this.closeModal() }, "\u00D7"), !!this.selected && this.selected.length > 0 ? h("table", null, h("thead", null, h("tr", null, h("th", null, "#"), Object.keys(this.selected[0].info).filter(k => !k.startsWith('.')).map(k => h("th", null, h("b", null, k))))), h("tbody", null, this.selected.map((s, i) => h("tr", { class: i % 2 === 0 ? 'odd' : 'even' }, h("td", null, s.index), Object.keys(s.info).filter(k => !k.startsWith('.')).map(k => h("td", null, s.info[k])))))) : '')), h("div", { key: '8d65e9a4ff7cf294e7944d89fe55b5c2f1576c70', class: "commands-wrapper" }, h("div", { key: '0922c92b40546dd1a9bf0bdb10581a0ef82b7136', class: "slider-wrapper" }, h("discovery-slider", { key: '0d1018ac11f26f4d86f90c6292eecea559a299c5', options: this.innerOptions, onValueChanged: e => this.handleSelect(e), onStartDrag: () => this.emitPause(true), debug: this.debug, progress: true, ref: el => this.slider = el })), h("button", { key: '36d12f0c09a1bb99fed1ca2e15a9abdb6a5bbf04', type: "button", class: { 'discovery-btn': true, 'paused': this.paused, 'play': !this.paused, }, onClick: () => this.togglePlayPause() })), h("div", { key: 'b59c891304d062def3510b89414ed4eca0dc395f', ref: (el) => this.mapElement = el, class: "map-wrapper" })); } static get is() { return "discovery-plugin-marauder"; } static get encapsulation() { return "shadow"; } static get originalStyleUrls() { return { "$": ["discovery-marauder.scss"] }; } static get styleUrls() { return { "$": ["discovery-marauder.css"] }; } static get properties() { return { "result": { "type": "string", "mutable": true, "complexType": { "original": "DataModel | string", "resolved": "DataModel | string", "references": { "DataModel": { "location": "import", "path": "@senx/discovery-widgets", "id": "node_modules::DataModel" } } }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "result", "reflect": false }, "type": { "type": "string", "mutable": false, "complexType": { "original": "ChartType", "resolved": "\"line\" | \"area\" | \"scatter\" | \"step-area\" | \"spline-area\" | \"spline\" | \"step\" | \"step-after\" | \"step-before\" | \"annotation\" | \"bar\" | \"bar-polar\" | \"display\" | \"image\" | \"map\" | \"gauge\" | \"linear-gauge\" | \"circle\" | \"compass\" | \"pie\" | \"doughnut\" | \"rose\" | \"tabular\" | \"svg\" | \"input:text\" | \"input:list\" | \"input:secret\" | \"input:autocomplete\" | \"input:chips\" | \"input:chips-autocomplete\" | \"input:slider\" | \"input:date\" | \"input:date-range\" | \"input:multi\" | \"input:multi-cb\" | \"button\" | \"button:radio\" | \"hidden\" | \"calendar\" | \"heatmap\" | \"profile\" | \"boxplot\" | \"dashboard\" | \"dashboard:flex\" | \"dashboard:scada\"", "references": { "ChartType": { "location": "import", "path": "@senx/discovery-widgets", "id": "node_modules::ChartType" } } }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "type", "reflect": false }, "options": { "type": "string", "mutable": false, "complexType": { "original": "Param | string", "resolved": "Param | string", "references": { "Param": { "location": "import", "path": "@senx/discovery-widgets", "id": "node_modules::Param" } } }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "options", "reflect": false, "defaultValue": "new Param()" }, "width": { "type": "number", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "width", "reflect": false }, "height": { "type": "number", "mutable": true, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "height", "reflect": false }, "debug": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "debug", "reflect": false, "defaultValue": "false" } }; } static get states() { return { "width": {}, "height": {}, "parsing": {}, "toDisplay": {}, "innerOptions": {}, "loading": {}, "currentTick": {}, "paused": {}, "selected": {} }; } static get events() { return [{ "method": "draw", "name": "draw", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "" }, "complexType": { "original": "void", "resolved": "void", "references": {} } }, { "method": "dataPointOver", "name": "dataPointOver", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "" }, "complexType": { "original": "any", "resolved": "any", "references": {} } }, { "method": "pausedEvent", "name": "pausedEvent", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "" }, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} } }]; } static get methods() { return { "resize": { "complexType": { "signature": "() => Promise<void>", "parameters": [], "references": { "Promise": { "location": "global", "id": "global::Promise" } }, "return": "Promise<void>" }, "docs": { "text": "", "tags": [] } }, "export": { "complexType": { "signature": "(type?: 'png' | 'svg') => Promise<any>", "parameters": [{ "name": "type", "type": "\"svg\" | \"png\"", "docs": "" }], "references": { "Promise": { "location": "global", "id": "global::Promise" } }, "return": "Promise<any>" }, "docs": { "text": "", "tags": [] } } }; } static get elementRef() { return "el"; } static get watchers() { return [{ "propName": "result", "methodName": "updateRes" }, { "propName": "options", "methodName": "optionsUpdate" }]; } static get listeners() { return [{ "name": "keydown", "method": "handleKeyDown", "target": "document", "capture": false, "passive": false }, { "name": "keyup", "method": "handleKeyUp", "target": "document", "capture": false, "passive": false }]; } } //# sourceMappingURL=discovery-marauder.js.map