Merker set changes
- Use separate panes for each marker set - Set pane z-index based on marker set priority - Optimize zoom visibility checks
This commit is contained in:
parent
f7d1ef4cfc
commit
0eea500098
@ -52,10 +52,16 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setup() {
|
setup(props) {
|
||||||
const store = useStore(),
|
const store = useStore(),
|
||||||
markerSettings = computed(() => store.state.components.markers),
|
markerSettings = computed(() => store.state.components.markers),
|
||||||
layerGroup = new DynmapLayerGroup();
|
layerGroup = new DynmapLayerGroup({
|
||||||
|
id: props.markerSet.id,
|
||||||
|
minZoom: props.markerSet.minZoom,
|
||||||
|
maxZoom: props.markerSet.maxZoom,
|
||||||
|
showLabels: props.markerSet.showLabels || store.state.components.markers.showLabels,
|
||||||
|
priority: props.markerSet.priority,
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
markerSettings,
|
markerSettings,
|
||||||
|
@ -14,9 +14,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Layer, Map as LeafletMap, LayerGroup, LayerOptions, Util} from "leaflet";
|
import {Layer, Map as LeafletMap, LayerGroup, LayerOptions, Util, Marker, Path} from "leaflet";
|
||||||
|
|
||||||
export interface DynmapLayerGroupOptions extends LayerOptions {
|
export interface DynmapLayerGroupOptions extends LayerOptions {
|
||||||
|
id: string; //Added to the name of layer group panes
|
||||||
|
showLabels: boolean;
|
||||||
|
priority: number; //Added to the z-index of layer group panes
|
||||||
|
|
||||||
|
//Zoom limits for the whole group, can be overridden by layers
|
||||||
minZoom?: number;
|
minZoom?: number;
|
||||||
maxZoom?: number;
|
maxZoom?: number;
|
||||||
}
|
}
|
||||||
@ -24,33 +29,44 @@ export interface DynmapLayerGroupOptions extends LayerOptions {
|
|||||||
export default class DynmapLayerGroup extends LayerGroup {
|
export default class DynmapLayerGroup extends LayerGroup {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
options: DynmapLayerGroupOptions;
|
options: DynmapLayerGroupOptions;
|
||||||
_layerVisibility: Map<Layer, boolean>;
|
_zoomLimitedLayers: Set<Layer>; //Layers which are zoom limited and should be checked on zoom
|
||||||
_layers: any;
|
_layers: any;
|
||||||
|
_markerPane?: HTMLElement;
|
||||||
|
_vectorPane?: HTMLElement;
|
||||||
|
|
||||||
constructor(layers?: Layer[], options?: DynmapLayerGroupOptions) {
|
_zoomEndCallback = () => this._updateLayerVisibility();
|
||||||
super(layers, options);
|
|
||||||
|
constructor(options: DynmapLayerGroupOptions) {
|
||||||
|
super([], options);
|
||||||
Util.setOptions(this, options);
|
Util.setOptions(this, options);
|
||||||
|
|
||||||
this._layerVisibility = new Map();
|
this._zoomLimitedLayers = new Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
onAdd(map: LeafletMap) {
|
onAdd(map: LeafletMap) {
|
||||||
map.on('zoomend', this._handleZoomChange, this);
|
map.on('zoomend', this._zoomEndCallback, this);
|
||||||
this._handleZoomChange();
|
|
||||||
|
this._map = map;
|
||||||
|
this._markerPane = map.createPane(`${this.options.id}-markers`);
|
||||||
|
this._vectorPane = map.createPane(`${this.options.id}-vectors`);
|
||||||
|
|
||||||
|
this._markerPane.style.zIndex = (401 + this.options.priority).toString();
|
||||||
|
this._vectorPane.style.zIndex = (400 + this.options.priority).toString();
|
||||||
|
|
||||||
|
this._updateLayerVisibility(true);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
onRemove(map: LeafletMap) {
|
onRemove(map: LeafletMap) {
|
||||||
super.onRemove(map);
|
super.onRemove(map);
|
||||||
this._layerVisibility.clear();
|
map.off('zoomend', this._zoomEndCallback, this);
|
||||||
map.off('zoomend', this._handleZoomChange, this);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
clearLayers(): this {
|
clearLayers(): this {
|
||||||
this._layerVisibility.clear();
|
this._zoomLimitedLayers.clear();
|
||||||
return super.clearLayers();
|
return super.clearLayers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,53 +75,81 @@ export default class DynmapLayerGroup extends LayerGroup {
|
|||||||
|
|
||||||
this._layers[id] = layer;
|
this._layers[id] = layer;
|
||||||
|
|
||||||
|
if (layer instanceof Marker) {
|
||||||
|
layer.options.pane = `${this.options.id}-markers`;
|
||||||
|
} else if (layer instanceof Path) {
|
||||||
|
layer.options.pane = `${this.options.id}-vectors`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const zoomLimited = this._isLayerZoomLimited(layer);
|
||||||
|
|
||||||
|
if (zoomLimited) {
|
||||||
|
this._zoomLimitedLayers.add(layer);
|
||||||
|
}
|
||||||
|
|
||||||
if (this._map) {
|
if (this._map) {
|
||||||
const visible = this._isLayerVisible(layer, this._map.getZoom());
|
//If layer is zoom limited, only add to map if it should be visible
|
||||||
this._layerVisibility.set(layer, visible);
|
if (zoomLimited) {
|
||||||
|
if (this._isLayerVisible(layer, this._map.getZoom())) {
|
||||||
if(visible) {
|
|
||||||
this._map.addLayer(layer);
|
this._map.addLayer(layer);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this._layerVisibility.set(layer, false);
|
this._map.addLayer(layer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
removeLayer(layer: Layer): this {
|
removeLayer(layer: Layer): this {
|
||||||
this._layerVisibility.delete(layer);
|
this._zoomLimitedLayers.delete(layer);
|
||||||
return super.addLayer(layer);
|
return super.addLayer(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleZoomChange() {
|
_updateLayerVisibility(onAdd?: boolean) {
|
||||||
if(!this._map) {
|
if(!this._map) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const zoom = this._map.getZoom();
|
const zoom = this._map.getZoom();
|
||||||
|
|
||||||
//FIXME: Keep track of layers that actually have min/max zoom, to avoid pointless checking of every layer?
|
//The whole group is zoom limited
|
||||||
|
if(this._isZoomLimited()) {
|
||||||
|
const visible = zoom >= (this.options.minZoom || -Infinity) && zoom <= (this.options.maxZoom || Infinity);
|
||||||
|
|
||||||
this.eachLayer((layer) => {
|
this.eachLayer((layer) => {
|
||||||
const newVisibility = this._isLayerVisible(layer, zoom),
|
//Per marker zoom limits take precedence, if present
|
||||||
currentVisibility = this._layerVisibility.get(layer);
|
if(this._zoomLimitedLayers.has(layer)) {
|
||||||
|
this._isLayerVisible(layer, zoom) ? this._map.addLayer(layer) : this._map.removeLayer(layer);
|
||||||
if(newVisibility) {
|
} else { //Otherwise apply group zoom limit
|
||||||
if(!currentVisibility) {
|
visible ? this._map.addLayer(layer) : this._map.removeLayer(layer);
|
||||||
this._map.addLayer(layer);
|
|
||||||
}
|
}
|
||||||
} else if(currentVisibility) {
|
|
||||||
this._map.removeLayer(layer);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._layerVisibility.set(layer, newVisibility);
|
|
||||||
}, this);
|
}, this);
|
||||||
|
//Group isn't zoom limited, but some individual markers are
|
||||||
|
} else if(this._zoomLimitedLayers.size) {
|
||||||
|
this._zoomLimitedLayers.forEach((layer) => {
|
||||||
|
this._isLayerVisible(layer, zoom) ? this._map.addLayer(layer) : this._map.removeLayer(layer);
|
||||||
|
});
|
||||||
|
//Nothing is zoom limited, but we've just been added to the map
|
||||||
|
} else if(onAdd) {
|
||||||
|
this.eachLayer(this._map.addLayer, this._map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Returns if this layer group has zoom limits defined
|
||||||
|
_isZoomLimited() {
|
||||||
|
return this.options.maxZoom !== undefined || this.options.minZoom !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Returns if the given layer has its own zoom limits defined
|
||||||
|
_isLayerZoomLimited(layer: Layer) {
|
||||||
|
return ((layer as any).options && (layer as any).options.minZoom !== undefined)
|
||||||
|
&& ((layer as any).options && (layer as any).options.maxZoom !== undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
_isLayerVisible(layer: Layer, currentZoom: number) {
|
_isLayerVisible(layer: Layer, currentZoom: number) {
|
||||||
let minZoom = this.options.minZoom || -Infinity,
|
let minZoom = -Infinity,
|
||||||
maxZoom = this.options.maxZoom || Infinity;
|
maxZoom = Infinity;
|
||||||
|
|
||||||
if((layer as any).options && (layer as any).options.minZoom !== undefined) {
|
if((layer as any).options && (layer as any).options.minZoom !== undefined) {
|
||||||
minZoom = (layer as any).options.minZoom;
|
minZoom = (layer as any).options.minZoom;
|
||||||
|
Loading…
Reference in New Issue
Block a user