import { UiElement } from '../../ui/UiElement.js';
/**
* Dropdown button to switch the map projection.
*
* @extends UiElement
* @memberof vef.map.tools
*/
class ProjectionSwitcher extends UiElement {
/**
* Constructs a new ProjectionSwitcher instance.
*
* @param {Map} map - The map object.
* @param {string} [position="top-left"] - The position of the switcher on the map.
* @param {Object} [baseLayers] - The base layers for different projections.
* @param {Object} [projections] - The available projections.
*/
constructor(map, position, baseLayers, projections) {
super();
this.map = map;
this.position = position || "top-left";
this.baseLayers = baseLayers;
this.class = ["vef-tool", "tool-dropdown"];
this.html = `
<i class="fas fa-globe-europe"></i>
<div class="tool-dropdown-content"></div>
`;
this.getElement().title = "Projection Switcher";
this.setClass(this.class);
this.setHtml(this.html);
this.setProjections_(projections || {
"EPSG:4326": '<i class="vef vef-globe"></i><span>Global</span>',
"EPSG:3995": '<i class="vef vef-globe-north"></i><span>Arctic</span>',
"EPSG:3031": '<i class="vef vef-globe-south"></i><span>Antarctic</span>',
});
this.initEvents_();
this.map.on("projection_change", () => this.update());
this.map.on("baselayer_change", () => this.update());
this.map.addTool(this, this.position);
this.update();
}
/**
* Sets the available projections.
*
* @private
* @param {Object} projections - The available projections.
*/
setProjections_(projections) {
const list = this.query(".tool-dropdown-content");
for (let code in projections) {
list.insertAdjacentHTML("beforeend", `
<button data-crs="${code}">${projections[code]}</button>
`);
}
}
/**
* Initializes the event listeners for the switcher buttons.
*
* @private
*/
initEvents_() {
const buttons = this.queryAll(".tool-dropdown-content button");
for (let i = 0; i < buttons.length; ++i) {
buttons[i].addEventListener("click", e => {
const key = this.map.options.baseLayer;
const crs = e.currentTarget.dataset.crs;
if (crs in this.baseLayers[key]) {
this.map.setBaseLayer(this.baseLayers[key][crs], crs);
}
});
}
}
/**
* Updates the state of the switcher buttons based on the current map state.
*/
update() {
const key = this.map.options.baseLayer;
const crs = this.map.options.crs;
const buttons = this.queryAll(".tool-dropdown-content button");
for (let i = 0; i < buttons.length; ++i) {
buttons[i].classList.remove("active");
if (!(buttons[i].dataset.crs in this.baseLayers[key])) {
buttons[i].disabled = true;
buttons[i].title = "Projection is unsupported by the active baselayer.";
} else if (buttons[i].dataset.crs == crs) {
buttons[i].disabled = true;
buttons[i].classList.add("active");
buttons[i].title = "Projection is already selected.";
} else {
buttons[i].disabled = false;
buttons[i].title = "";
}
}
}
}
export { ProjectionSwitcher };