/* * μlogger * * Copyright(C) 2019 Bartek Fabiszewski (www.fabiszewski.net) * * This is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ import * as gmApi from './mapapi/api_gmaps.js'; import * as olApi from './mapapi/api_openlayers.js'; import { config, lang } from './constants.js'; import uEvent from './event.js'; import { uLogger } from './ulogger.js'; import uUtils from './utils.js'; /** * @typedef {Object} uMap.api * @memberOf uMap * @type {Object} * @property {string} name * @property {function(uBinder, HTMLElement)} init * @property {function} cleanup * @property {function(uTrack, boolean)} displayTrack * @property {function} clearMap * @property {function(number)} animateMarker * @property {function} getBounds * @property {function} zoomToExtent * @property {function} zoomToBounds * @property {function} updateSize */ /** * @class uMap * @property {number} loadTime * @property {?Array} savedBounds * @property {?(gmApi|olApi)} api * @property {?HTMLElement} mapElement */ export default class uMap { /** * @param {uBinder} binder */ constructor(binder) { binder.addEventListener(uEvent.API_CHANGE, this); binder.addEventListener(uEvent.CHART_CLICKED, this); binder.addEventListener(uEvent.TRACK_READY, this); binder.addEventListener(uEvent.UI_READY, this); this.loadTime = 0; this.savedBounds = null; this.api = null; this.mapElement = null; this.lastTrackId = null; this._binder = binder; this.track = null; } /** * Dynamic change of map api * @param {string=} apiName API name */ loadMapAPI(apiName) { if (apiName) { config.mapapi = apiName; try { this.savedBounds = this.api.getBounds(); } catch (e) { this.savedBounds = null; } this.api.cleanup(); } if (config.mapapi === 'gmaps') { this.api = gmApi; } else { this.api = olApi; } this.waitAndInit(); } /** * Try to initialize map engine */ waitAndInit() { // wait till main api loads if (this.loadTime > 10000) { this.loadTime = 0; alert(uUtils.sprintf(lang.strings['apifailure'], config.mapapi)); return; } try { this.api.init(this._binder, this.mapElement); } catch (e) { setTimeout(() => { this.loadTime += 50; this.waitAndInit(); }, 50); return; } this.loadTime = 0; if (this.savedBounds) { this.api.zoomToBounds(this.savedBounds); } uLogger.trackList.onChange(); // save current api as default uUtils.setCookie('api', config.mapapi, 30); } /** * * @param {uEvent} event * @param {*=} args */ handleEvent(event, args) { if (event.type === uEvent.TRACK_READY) { /** @type {uTrack} */ const track = args; this.api.clearMap(); const onlyReload = track.id !== this.lastTrackId; this.api.displayTrack(track, onlyReload); this.lastTrackId = track.id; } else if (event.type === uEvent.UI_READY) { /** @type {uUI} */ const ui = args; this.mapElement = ui.map; this.loadMapAPI(); } else if (event.type === uEvent.API_CHANGE) { /** @type {string} */ const api = args; this.loadMapAPI(api); } else if (event.type === uEvent.CHART_CLICKED) { /** @type {number} */ const id = args; this.api.animateMarker(id); } } }