I've found a leaflet extension that hides map markers if they are outside of the current view map bounds.
import L from 'leaflet';
L.Marker.MyMarker= L.Marker.extend({}).addInitHook(function (this: ILazyMarker) {
this.on(
'add',
function (this: ILazyMarker) {
this._updateIconVisibility = function (this: ILazyMarker) {
var map = this._map,
isVisible = map.getBounds().contains(this.getLatLng()),
wasVisible = this._wasVisible,
icon = this._icon,
iconParent = this._iconParent,
shadow = this._shadow,
shadowParent = this._shadowParent;
// remember parent of icon
if (!iconParent) {
iconParent = this._iconParent = icon.parentNode;
}
if (shadow && !shadowParent) {
shadowParent = this._shadowParent = shadow.parentNode;
}
// add/remove from DOM on change
if (iconParent != null && isVisible != wasVisible) {
if (isVisible) {
iconParent.appendChild(icon);
if (shadowParent != null && shadow) {
shadowParent.appendChild(shadow);
}
} else {
iconParent.removeChild(icon);
if (shadowParent != null && shadow) {
shadowParent.removeChild(shadow);
}
}
this._wasVisible = isVisible;
}
};
// on map size change, remove/add icon from/to DOM
this._map.on('resize moveend zoomend', this._updateIconVisibility, this);
this._updateIconVisibility();
},
this,
);
});
This works fine, but I'd rather use a Typescript class for consistency within my project. Here's my attempt to convert this:
import L from 'leaflet';
export default class MyMarker extends L.Marker {
_wasVisible!: boolean;
_icon!: any;
_shadowParent!: any;
_iconParent!: any;
constructor(latlng: L.LatLngExpression, options?: L.MarkerOptions) {
super(latlng, options);
}
onAdd(): this {
this._map.on('resize moveend zoomend', this._updateIconVisibility, this);
this._updateIconVisibility();
return this;
}
_updateIconVisibility() {
var map = this._map,
isVisible = map.getBounds().contains(this.getLatLng()),
wasVisible = this._wasVisible,
icon = this._icon,
iconParent = this._iconParent,
shadow = this._shadow,
shadowParent = this._shadowParent;
// remember parent of icon
if (!iconParent) {
iconParent = this._iconParent = icon.parentNode;
}
if (shadow && !shadowParent) {
shadowParent = this._shadowParent = shadow.parentNode;
}
// add/remove from DOM on change
if (iconParent != null && isVisible != wasVisible) {
if (isVisible) {
iconParent.appendChild(icon);
if (shadowParent != null && shadow) {
shadowParent.appendChild(shadow);
}
} else {
iconParent.removeChild(icon);
if (shadowParent != null && shadow) {
shadowParent.removeChild(shadow);
}
}
this._wasVisible = isVisible;
}
}
}
When I try to use the class-based marker, I get this error for each marker I am adding and the map will not render:
TypeError: Cannot read property 'parentNode' of undefined
at MyMarker._updateIconVisibility (leaflet-my-marker.ts:78)
at MyMarker.onAdd (leaflet-my-marker.ts:63)
at MyMarker._layerAdd (leaflet-src.js:6567)
at NewClass.whenReady (leaflet-src.js:4428)
at NewClass.addLayer (leaflet-src.js:6629)
at NewClass.addLayer (leaflet-src.js:6780)
at VueComponent.addLayer (LLayerGroup.js:164)
at VueComponent.FirecamMarker.mounted (MyMarker.vue?6277:99)
at invokeWithErrorHandling (vue.runtime.esm.js:1854)
at callHook (vue.runtime.esm.js:4219)
question from:
https://stackoverflow.com/questions/65852126/convert-leaflet-marker-extension-to-typescript 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…