forked from MapComplete/MapComplete
Feature: second iteration of clustering
This commit is contained in:
parent
8360ab9a8b
commit
5bc8f11d24
3 changed files with 25 additions and 5 deletions
|
@ -8,7 +8,8 @@ import { Utils } from "../../../Utils"
|
|||
import { TagsFilter } from "../../Tags/TagsFilter"
|
||||
import { BBox } from "../../BBox"
|
||||
import { OsmTags } from "../../../Models/OsmFeature"
|
||||
;("use strict")
|
||||
|
||||
("use strict")
|
||||
|
||||
/**
|
||||
* A wrapper around the 'Overpass'-object.
|
||||
|
@ -138,7 +139,6 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource {
|
|||
return undefined
|
||||
}
|
||||
this.runningQuery.setData(true)
|
||||
console.trace("Overpass feature source: querying geojson")
|
||||
data = (await overpass.queryGeoJson(bounds))[0]
|
||||
} catch (e) {
|
||||
this.retries.data++
|
||||
|
|
|
@ -15,12 +15,15 @@ export interface ClusteringOptions {
|
|||
* drop those features and emit a summary tile instead
|
||||
*/
|
||||
cutoff?: 20 | number
|
||||
|
||||
showSummaryAt?: "tilecenter" | "average"
|
||||
}
|
||||
|
||||
export class ClusteringFeatureSource<T extends Feature<Point> = Feature<Point>> implements FeatureSource<T> {
|
||||
|
||||
public readonly summaryPoints: FeatureSource
|
||||
private readonly id: string
|
||||
private readonly showSummaryAt: "tilecenter" | "average"
|
||||
features: Store<T[]>
|
||||
|
||||
/**
|
||||
|
@ -35,6 +38,7 @@ export class ClusteringFeatureSource<T extends Feature<Point> = Feature<Point>>
|
|||
id: string,
|
||||
options?: ClusteringOptions) {
|
||||
this.id = id
|
||||
this.showSummaryAt = options?.showSummaryAt ?? "average"
|
||||
const clusterCutoff = options?.dontClusterAboveZoom ?? 17
|
||||
const doCluster = options?.dontClusterAboveZoom === undefined ? new ImmutableStore(true) : currentZoomlevel.map(zoom => zoom <= clusterCutoff)
|
||||
const cutoff = options?.cutoff ?? 20
|
||||
|
@ -42,6 +46,7 @@ export class ClusteringFeatureSource<T extends Feature<Point> = Feature<Point>>
|
|||
currentZoomlevel = currentZoomlevel.stabilized(500)
|
||||
this.summaryPoints = new StaticFeatureSource(summaryPoints)
|
||||
this.features = (upstream.features.map(features => {
|
||||
console.log(">>> Updating features in clusters ", this.id, ":", features)
|
||||
if (!doCluster.data) {
|
||||
summaryPoints.set([])
|
||||
return features
|
||||
|
@ -69,8 +74,23 @@ export class ClusteringFeatureSource<T extends Feature<Point> = Feature<Point>>
|
|||
|
||||
|
||||
private createSummaryFeature(features: Feature<Point>[], tileId: number): Feature<Point> {
|
||||
|
||||
let lon: number
|
||||
let lat: number
|
||||
const [z, x, y] = Tiles.tile_from_index(tileId)
|
||||
const [lon, lat] = Tiles.centerPointOf(z, x, y)
|
||||
if (this.showSummaryAt === "tilecenter") {
|
||||
[lon, lat] = Tiles.centerPointOf(z, x, y)
|
||||
} else {
|
||||
let lonSum = 0
|
||||
let latSum = 0
|
||||
for (const feature of features) {
|
||||
const [lon, lat] = feature.geometry.coordinates
|
||||
lonSum += lon
|
||||
latSum += lat
|
||||
}
|
||||
lon = lonSum / features.length
|
||||
lat = latSum / features.length
|
||||
}
|
||||
return <Feature<Point>>{
|
||||
type: "Feature",
|
||||
geometry: {
|
||||
|
|
|
@ -351,7 +351,6 @@ export default class ShowDataLayer {
|
|||
drawLines?: true | boolean
|
||||
}
|
||||
) {
|
||||
console.trace("Creating a data layer for", options.layer.id)
|
||||
this._options = options
|
||||
this.onDestroy.push(map.addCallbackAndRunD((map) => this.initDrawFeatures(map)))
|
||||
}
|
||||
|
@ -397,7 +396,8 @@ export default class ShowDataLayer {
|
|||
const clustering = new ClusteringFeatureSource(feats, state.mapProperties.zoom.map(z => z + 2),
|
||||
options.layer.id,
|
||||
{
|
||||
cutoff: 5
|
||||
cutoff: 2,
|
||||
showSummaryAt: "tilecenter"
|
||||
})
|
||||
new ShowDataLayer(mlmap, {
|
||||
features: clustering.summaryPoints,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue