import ol_control_Control from 'ol/control/Control.js' import ol_ext_element from '../util/element.js' /** Bookmark positions on ol maps. * * @constructor * @extends {ol_control_Control} * @fires add * @fires remove * @fires select * @param {} options Geobookmark's options * @param {string} options.className default ol-bookmark * @param {string | undefined} options.title Title to use for the button tooltip, default "Geobookmarks" * @param {string} options.placeholder input placeholder, default Add a new geomark... * @param {string} [options.deleteTitle='Suppr.'] title for delete buttons * @param {bool} options.editable enable modification, default true * @param {string} options.namespace a namespace to save the boolmark (if more than one on a page), default ol * @param {Array} options.marks a list of default bookmarks: * @see [Geobookmark example](../../examples/control/map.control.geobookmark.html) * @example var bm = new GeoBookmark ({ marks: { "Paris": {pos:ol.proj.transform([2.351828, 48.856578], 'EPSG:4326', 'EPSG:3857'), zoom:11, permanent: true }, "London": {pos:ol.proj.transform([-0.1275,51.507222], 'EPSG:4326', 'EPSG:3857'), zoom:12} } }); */ var ol_control_GeoBookmark = class olcontrolGeoBookmark extends ol_control_Control { constructor(options) { options = options || {}; var element = document.createElement('div'); // Init super({ element: element, target: options.target }); if (options.target) { element.className = options.className || "ol-bookmark"; } else { element.className = (options.className || "ol-bookmark") + " ol-unselectable ol-control ol-collapsed"; element.addEventListener("mouseleave", function () { if (input !== document.activeElement) { this.element.classList.add('ol-collapsed') } }.bind(this)); // Show bookmarks on click this.button = ol_ext_element.create('BUTTON', { type: 'button', title: options.title || 'Geobookmarks', click: function () { var show = !this.element.classList.contains('ol-collapsed'); this.element.classList.toggle('ol-collapsed') if (show) { this.setBookmarks(); } }.bind(this) }); element.appendChild(this.button); } // The menu var menu = document.createElement('div'); element.appendChild(menu); var ul = document.createElement('ul'); menu.appendChild(ul); var input = document.createElement('input'); input.setAttribute('placeholder', options.placeholder || "Add a new geomark..."); input.addEventListener('keydown', function (e) { e.stopPropagation(); if (e.keyCode === 13) { e.preventDefault(); var title = input.value; if (title) { this.addBookmark(title); input.value = ''; this.dispatchEvent({ type: "add", name: title }); } this.element.classList.add('ol-collapsed') } }.bind(this)); input.addEventListener('blur', function () { this.element.classList.add('ol-collapsed') }.bind(this)); menu.appendChild(input); this.on("propertychange", function (e) { if (e.key === 'editable') { element.className = element.className.replace(" ol-editable", ""); if (this.get('editable')) { element.className += " ol-editable"; } } // console.log(e); }.bind(this)); this.set("namespace", options.namespace || 'ol'); this.set("editable", options.editable !== false); this.set('deleteTitle', options.deleteTitle || 'Suppr.'); // Set default bmark var bmark = {}; try { if (localStorage[this.get('namespace') + "@bookmark"]) { bmark = JSON.parse(localStorage[this.get('namespace') + "@bookmark"]); } } catch (e) { console.warn('Failed to access localStorage...'); } if (options.marks) { for (var i in options.marks) { bmark[i] = options.marks[i]; } } this.setBookmarks(bmark); } /** Set bookmarks * @param {} bmark a list of bookmarks, default retreave in the localstorage * @example bm.setBookmarks({ "Paris": {pos:_ol_proj_.transform([2.351828, 48.856578], 'EPSG:4326', 'EPSG:3857'), zoom:11, permanent: true }, "London": {pos:_ol_proj_.transform([-0.1275,51.507222], 'EPSG:4326', 'EPSG:3857'), zoom:12} }); */ setBookmarks(bmark) { if (!bmark) { bmark = {}; try { bmark = JSON.parse(localStorage[this.get('namespace') + "@bookmark"] || "{}"); } catch (e) { console.warn('Failed to access localStorage...'); } } var modify = this.get("editable"); var ul = this.element.querySelector("ul"); var self = this; ul.innerHTML = ''; for (var b in bmark) { var li = document.createElement('li'); li.textContent = b; li.setAttribute('data-bookmark', JSON.stringify(bmark[b])); li.setAttribute('data-name', b); li.addEventListener('click', function (e) { var bm = JSON.parse(e.target.getAttribute("data-bookmark")); this.getMap().getView().setCenter(bm.pos); this.getMap().getView().setZoom(bm.zoom); this.getMap().getView().setRotation(bm.rot || 0); this.element.classList.add('ol-collapsed') this.dispatchEvent({ type: 'select', name: e.target.getAttribute("data-name"), bookmark: bm }); }.bind(this)); ul.appendChild(li); if (modify && !bmark[b].permanent) { var button = document.createElement('button'); button.setAttribute('data-name', b); button.setAttribute('type', 'button'); button.setAttribute('title', this.get('deleteTitle') || 'Suppr.'); button.addEventListener('click', function (e) { self.removeBookmark(this.getAttribute("data-name")); self.dispatchEvent({ type: "remove", name: this.getAttribute("data-name") }); e.stopPropagation(); }); li.appendChild(button); } } try { localStorage[this.get('namespace') + "@bookmark"] = JSON.stringify(bmark); } catch (e) { console.warn('Failed to access localStorage...'); } } /** Get Geo bookmarks * @return {any} a list of bookmarks : { BM1:{pos:ol.coordinates, zoom: integer}, BM2:{pos:ol.coordinates, zoom: integer} } */ getBookmarks() { var bm = {}; try { bm = JSON.parse(localStorage[this.get('namespace') + "@bookmark"] || "{}"); } catch (e) { console.warn('Failed to access localStorage...'); } return bm; } /** Remove a Geo bookmark * @param {string} name */ removeBookmark(name) { if (!name) { return; } var bmark = this.getBookmarks(); delete bmark[name]; this.setBookmarks(bmark); } /** Add a new Geo bookmark (replace existing one if any) * @param {string} name name of the bookmark (display in the menu) * @param {*} options * @param {ol.coordinate} position default current position * @param {number} zoom default current map zoom * @param {number} rotation default current map rotation * @param {bool} permanent prevent from deletion, default false */ addBookmark(name, position, zoom, permanent) { if (!name) return; var options = position; var rot; if (options && options.position) { zoom = options.zoom; permanent = options.permanent; rot = options.rotation; position = options.position; } else { rot = this.getMap().getView().getRotation(); } var bmark = this.getBookmarks(); // Don't override permanent bookmark if (bmark[name] && bmark[name].permanent) return; // Create or override bmark[name] = { pos: position || this.getMap().getView().getCenter(), zoom: zoom || this.getMap().getView().getZoom(), permanent: !!permanent }; if (rot) { bmark[name].rot = rot; } this.setBookmarks(bmark); } } export default ol_control_GeoBookmark