Skip to content

Commit

Permalink
Cache filter results
Browse files Browse the repository at this point in the history
  • Loading branch information
cdauth committed Mar 2, 2024
1 parent 0ef09d5 commit 8d857d4
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 28 deletions.
46 changes: 30 additions & 16 deletions leaflet/src/lines/lines-layer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ID, Line, LinePointsEvent, ObjectWithId, Point, Stroke, Width } from "facilmap-types";
import { FeatureGroup, latLng, type LayerOptions, Map, type PolylineOptions, type LatLngBounds } from "leaflet";
import { FeatureGroup, latLng, type LayerOptions, type Map as LeafletMap, type PolylineOptions, type LatLngBounds } from "leaflet";
import { type HighlightableLayerOptions, HighlightablePolyline } from "leaflet-highlightable-layers";
import { type BasicTrackPoints, disconnectSegmentsOutsideViewport, tooltipOptions, trackPointsToLatLngArray, fmToLeafletBbox } from "../utils/leaflet";
import { numberKeys, quoteHtml } from "facilmap-utils";
Expand All @@ -25,13 +25,14 @@ export default class LinesLayer extends FeatureGroup {
protected highlightedLinesIds = new Set<ID>();
protected hiddenLinesIds = new Set<ID>();
protected lastMapBounds?: LatLngBounds;
protected filterResults = new Map<ID, boolean>();

constructor(client: Client, options?: LinesLayerOptions) {
super([], options);
this.client = client;
}

onAdd(map: Map): this {
onAdd(map: LeafletMap): this {
super.onAdd(map);

this.client.on("line", this.handleLine);
Expand All @@ -41,13 +42,18 @@ export default class LinesLayer extends FeatureGroup {
map.on("moveend", this.handleMoveEnd);
map.on("fmFilter", this.handleFilter);

if (map._loaded)
this.handleMoveEnd();
if (map._loaded) {
this.lastMapBounds = this._map.getBounds();
}

for (const lineId of numberKeys(this.client.lines)) {
this.handleLine(this.client.lines[lineId]);
}

return this;
}

onRemove(map: Map): this {
onRemove(map: LeafletMap): this {
super.onRemove(map);

this.client.removeListener("line", this.handleLine);
Expand All @@ -60,11 +66,17 @@ export default class LinesLayer extends FeatureGroup {
return this;
}

protected recalculateFilter(line: Line): void {
this.filterResults.set(line.id, this._map.fmFilterFunc(line, this.client.types[line.typeId]));
}

protected shouldShowLine(line: Line): boolean {
return !this.hiddenLinesIds.has(line.id) && this._map.fmFilterFunc(line, this.client.types[line.typeId]);
return !this.hiddenLinesIds.has(line.id) && !!this.filterResults.get(line.id);
}

protected handleLine = (line: Line): void => {
this.recalculateFilter(line);

if(this.shouldShowLine(line))
this._addLine(line);
else
Expand All @@ -79,6 +91,7 @@ export default class LinesLayer extends FeatureGroup {

protected handleDeleteLine = (data: ObjectWithId): void => {
this._deleteLine(data);
this.filterResults.delete(data.id);
};

protected handleMoveEnd = (): void => {
Expand All @@ -87,8 +100,8 @@ export default class LinesLayer extends FeatureGroup {
Promise.resolve().then(() => {
const lastMapBounds = this.lastMapBounds;
const mapBounds = this.lastMapBounds = this._map.getBounds();
for(const i of numberKeys(this.client.lines)) {
const lineBounds = fmToLeafletBbox(this.client.lines[i]);
for(const lineId of numberKeys(this.client.lines)) {
const lineBounds = fmToLeafletBbox(this.client.lines[lineId]);
if (
(
// We do not have to do this for lines that are either completely outside or completely within the
Expand All @@ -98,21 +111,22 @@ export default class LinesLayer extends FeatureGroup {
(lastMapBounds.contains(lineBounds) && mapBounds.contains(lineBounds)) ||
(!lastMapBounds.intersects(lineBounds) && !mapBounds.intersects(lineBounds))
)
) && this.shouldShowLine(this.client.lines[i])
) && this.shouldShowLine(this.client.lines[lineId])
) {
this._addLine(this.client.lines[i]);
this._addLine(this.client.lines[lineId]);
}
}
});
};

protected handleFilter = (): void => {
for(const i of numberKeys(this.client.lines)) {
const show = this.shouldShowLine(this.client.lines[i]);
if(this.linesById[i] && !show)
this._deleteLine(this.client.lines[i]);
else if(!this.linesById[i] && show)
this._addLine(this.client.lines[i]);
for(const lineId of numberKeys(this.client.lines)) {
this.recalculateFilter(this.client.lines[lineId]);
const show = this.shouldShowLine(this.client.lines[lineId]);
if(this.linesById[lineId] && !show)
this._deleteLine(this.client.lines[lineId]);
else if(!this.linesById[lineId] && show)
this._addLine(this.client.lines[lineId]);
}
};

Expand Down
40 changes: 28 additions & 12 deletions leaflet/src/markers/markers-layer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type Client from "facilmap-client";
import type { ID, Marker, ObjectWithId } from "facilmap-types";
import { Map } from "leaflet";
import { Map as LeafletMap } from "leaflet";
import { tooltipOptions } from "../utils/leaflet";
import { numberKeys, quoteHtml } from "facilmap-utils";
import MarkerCluster, { type MarkerClusterOptions } from "./marker-cluster";
Expand All @@ -14,6 +14,7 @@ export default class MarkersLayer extends MarkerCluster {
declare options: MarkersLayerOptions;
protected markersById: Record<string, MarkerLayer> = {};
protected highlightedMarkerIds = new Set<ID>();
protected filterResults = new Map<ID, boolean>();

/** The position of these markers will not be touched until they are unlocked again. */
protected lockedMarkerIds = new Set<ID>();
Expand All @@ -22,18 +23,22 @@ export default class MarkersLayer extends MarkerCluster {
super(client, options);
}

onAdd(map: Map): this {
onAdd(map: LeafletMap): this {
super.onAdd(map);

this.client.on("marker", this.handleMarker);
this.client.on("deleteMarker", this.handleDeleteMarker);

for (const markerId of numberKeys(this.client.markers)) {
this.handleMarker(this.client.markers[markerId]);
}

map.on("fmFilter", this.handleFilter);

return this;
}

onRemove(map: Map): this {
onRemove(map: LeafletMap): this {
super.onRemove(map);

this.client.removeListener("marker", this.handleMarker);
Expand All @@ -44,25 +49,36 @@ export default class MarkersLayer extends MarkerCluster {
return this;
}

protected recalculateFilter(marker: Marker): void {
this.filterResults.set(marker.id, this._map.fmFilterFunc(marker, this.client.types[marker.typeId]));
}

protected shouldShowMarker(marker: Marker): boolean {
return !!this.filterResults.get(marker.id);
}

protected handleMarker = (marker: Marker): void => {
if(this._map.fmFilterFunc(marker, this.client.types[marker.typeId]))
this.recalculateFilter(marker);
if(this.shouldShowMarker(marker))
this._addMarker(marker);
else
this._deleteMarker(marker);
};

protected handleDeleteMarker = (data: ObjectWithId): void => {
this._deleteMarker(data);
this.filterResults.delete(data.id);
};

protected handleFilter = (): void => {
for(const i of numberKeys(this.client.markers)) {
if (!this.lockedMarkerIds.has(i)) {
const show = this._map.fmFilterFunc(this.client.markers[i], this.client.types[this.client.markers[i].typeId]);
if(this.markersById[i] && !show)
this._deleteMarker(this.client.markers[i]);
else if(!this.markersById[i] && show)
this._addMarker(this.client.markers[i]);
for(const markerId of numberKeys(this.client.markers)) {
if (!this.lockedMarkerIds.has(markerId)) {
this.recalculateFilter(this.client.markers[markerId]);
const show = this.shouldShowMarker(this.client.markers[markerId]);
if(this.markersById[markerId] && !show)
this._deleteMarker(this.client.markers[markerId]);
else if(!this.markersById[markerId] && show)
this._addMarker(this.client.markers[markerId]);
}
}
};
Expand Down Expand Up @@ -120,7 +136,7 @@ export default class MarkersLayer extends MarkerCluster {
unlockMarker(id: ID): void {
this.lockedMarkerIds.delete(id);

if (this._map.fmFilterFunc(this.client.markers[id], this.client.types[this.client.markers[id].typeId]))
if (this.shouldShowMarker(this.client.markers[id]))
this._addMarker(this.client.markers[id]);
else
this._deleteMarker(this.client.markers[id]);
Expand Down

0 comments on commit 8d857d4

Please sign in to comment.