forked from MapComplete/MapComplete
Feature(clustering): fix count update on filters, fix hiding when zoomed out to much
This commit is contained in:
parent
0048c091d0
commit
63e9d20255
5 changed files with 26 additions and 21 deletions
|
@ -1,12 +1,13 @@
|
||||||
import { Store, UIEventSource } from "../../UIEventSource"
|
import { Store, UIEventSource } from "../../UIEventSource"
|
||||||
import FilteredLayer from "../../../Models/FilteredLayer"
|
import FilteredLayer from "../../../Models/FilteredLayer"
|
||||||
import { FeatureSource } from "../FeatureSource"
|
import { FeatureSource } from "../FeatureSource"
|
||||||
import { Feature } from "geojson"
|
import { Feature, Geometry } from "geojson"
|
||||||
import { GlobalFilter } from "../../../Models/GlobalFilter"
|
import { GlobalFilter } from "../../../Models/GlobalFilter"
|
||||||
|
import { OsmTags } from "../../../Models/OsmFeature"
|
||||||
|
|
||||||
export default class FilteringFeatureSource implements FeatureSource {
|
export default class FilteringFeatureSource<T extends Feature = Feature<Geometry, OsmTags>> implements FeatureSource<T> {
|
||||||
public features: UIEventSource<Feature[]> = new UIEventSource([])
|
public readonly features: UIEventSource<T[]> = new UIEventSource([])
|
||||||
private readonly upstream: FeatureSource
|
private readonly upstream: FeatureSource<T>
|
||||||
private readonly _fetchStore?: (id: string) => Store<Record<string, string>>
|
private readonly _fetchStore?: (id: string) => Store<Record<string, string>>
|
||||||
private readonly _globalFilters?: Store<GlobalFilter[]>
|
private readonly _globalFilters?: Store<GlobalFilter[]>
|
||||||
private readonly _alreadyRegistered = new Set<Store<any>>()
|
private readonly _alreadyRegistered = new Set<Store<any>>()
|
||||||
|
@ -18,7 +19,7 @@ export default class FilteringFeatureSource implements FeatureSource {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
layer: FilteredLayer,
|
layer: FilteredLayer,
|
||||||
upstream: FeatureSource,
|
upstream: FeatureSource<T>,
|
||||||
fetchStore?: (id: string) => Store<Record<string, string>>,
|
fetchStore?: (id: string) => Store<Record<string, string>>,
|
||||||
globalFilters?: Store<GlobalFilter[]>,
|
globalFilters?: Store<GlobalFilter[]>,
|
||||||
metataggingUpdated?: Store<any>,
|
metataggingUpdated?: Store<any>,
|
||||||
|
@ -40,7 +41,7 @@ export default class FilteringFeatureSource implements FeatureSource {
|
||||||
})
|
})
|
||||||
|
|
||||||
layer.appliedFilters.forEach((value) =>
|
layer.appliedFilters.forEach((value) =>
|
||||||
value.addCallback((_) => {
|
value.addCallback(() => {
|
||||||
this.update()
|
this.update()
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -68,7 +69,7 @@ export default class FilteringFeatureSource implements FeatureSource {
|
||||||
|
|
||||||
private update() {
|
private update() {
|
||||||
const layer = this._layer
|
const layer = this._layer
|
||||||
const features: Feature[] = this.upstream.features.data ?? []
|
const features: T[] = this.upstream.features.data ?? []
|
||||||
const includedFeatureIds = new Set<string>()
|
const includedFeatureIds = new Set<string>()
|
||||||
const globalFilters = this._globalFilters?.data?.map((f) => f)
|
const globalFilters = this._globalFilters?.data?.map((f) => f)
|
||||||
const zoomlevel = this._zoomlevel?.data
|
const zoomlevel = this._zoomlevel?.data
|
||||||
|
@ -121,10 +122,9 @@ export default class FilteringFeatureSource implements FeatureSource {
|
||||||
}
|
}
|
||||||
this._alreadyRegistered.add(src)
|
this._alreadyRegistered.add(src)
|
||||||
|
|
||||||
const self = this
|
|
||||||
// Add a callback as a changed tag might change the filter
|
// Add a callback as a changed tag might change the filter
|
||||||
src.addCallbackAndRunD((_) => {
|
src.addCallbackAndRunD(() => {
|
||||||
self._is_dirty.setData(true)
|
this._is_dirty.setData(true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@ export class IfVisibleFeatureSource<T extends Feature> implements FeatureSource<
|
||||||
let dirty = false
|
let dirty = false
|
||||||
upstream.features.addCallbackAndRun(features => {
|
upstream.features.addCallbackAndRun(features => {
|
||||||
if (!visible.data) {
|
if (!visible.data) {
|
||||||
console.log(">>> not writing data as not visible")
|
|
||||||
dirty = true
|
dirty = true
|
||||||
|
this._features.set([])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this._features.set(features)
|
this._features.set(features)
|
||||||
|
|
|
@ -140,13 +140,14 @@ export class ClusterGrouping implements FeatureSource<Feature<Point, { total_met
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const features: Feature<Point, { total_metric: string, id: string }>[] = []
|
const features: Feature<Point, { total_metric: string, id: string }>[] = []
|
||||||
|
const now = new Date().getTime() + ""
|
||||||
for (const tileId of countPerTile.keys()) {
|
for (const tileId of countPerTile.keys()) {
|
||||||
const coordinates = Tiles.centerPointOf(tileId)
|
const coordinates = Tiles.centerPointOf(tileId)
|
||||||
features.push({
|
features.push({
|
||||||
type: "Feature",
|
type: "Feature",
|
||||||
properties: {
|
properties: {
|
||||||
total_metric: "" + countPerTile.get(tileId),
|
total_metric: "" + countPerTile.get(tileId),
|
||||||
id: "clustered_all_" + tileId
|
id: "clustered_all_" + tileId + "_" + now // We add the date to force a fresh ID every time, this makes sure values are updated
|
||||||
},
|
},
|
||||||
geometry: {
|
geometry: {
|
||||||
type: "Point",
|
type: "Point",
|
||||||
|
|
|
@ -79,12 +79,12 @@ export class PointRenderingLayer {
|
||||||
}
|
}
|
||||||
allowed_location_codes.forEach((code) => {
|
allowed_location_codes.forEach((code) => {
|
||||||
const marker = this._allMarkers.get(<OsmId>selected.properties.id)
|
const marker = this._allMarkers.get(<OsmId>selected.properties.id)
|
||||||
.get(code)
|
?.get(code)
|
||||||
?.getElement()
|
?.getElement()
|
||||||
if (marker === undefined) {
|
if (marker === undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
marker?.classList?.add("selected")
|
marker.classList?.add("selected")
|
||||||
this._markedAsSelected.push(marker)
|
this._markedAsSelected.push(marker)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -388,20 +388,26 @@ export default class ShowDataLayer {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the data, unless they are clustered.
|
||||||
|
* This method does _not_ add the clusters themselves to the map,
|
||||||
|
* this should be done independently. In a themeViewGui, this is done by the 'addSpecialLayers'
|
||||||
|
* @see ClusterGrouping
|
||||||
|
* @param mlmap
|
||||||
|
* @param state
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
public static showLayerClustered(mlmap: Store<MlMap>,
|
public static showLayerClustered(mlmap: Store<MlMap>,
|
||||||
state: { mapProperties: { zoom: UIEventSource<number> } },
|
state: { mapProperties: { zoom: UIEventSource<number> } },
|
||||||
options: ShowDataLayerOptions & { layer: LayerConfig }
|
options: ShowDataLayerOptions & { layer: LayerConfig }
|
||||||
) {
|
) {
|
||||||
options.preprocessPoints = feats => {
|
options.preprocessPoints = feats =>
|
||||||
const clustering = new ClusteringFeatureSource(feats, state.mapProperties.zoom.map(z => z + 2),
|
new ClusteringFeatureSource(feats, state.mapProperties.zoom.map(z => z + 2),
|
||||||
options.layer.id,
|
options.layer.id,
|
||||||
{
|
{
|
||||||
cutoff: 7,
|
cutoff: 7,
|
||||||
showSummaryAt: "tilecenter"
|
showSummaryAt: "tilecenter"
|
||||||
})
|
})
|
||||||
|
|
||||||
return clustering
|
|
||||||
}
|
|
||||||
new ShowDataLayer(mlmap, options)
|
new ShowDataLayer(mlmap, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,8 +423,6 @@ export default class ShowDataLayer {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public destruct() {}
|
|
||||||
|
|
||||||
private static zoomToCurrentFeatures(map: MlMap, features: Feature[]) {
|
private static zoomToCurrentFeatures(map: MlMap, features: Feature[]) {
|
||||||
if (!features || !map || features.length == 0) {
|
if (!features || !map || features.length == 0) {
|
||||||
return
|
return
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue