forked from MapComplete/MapComplete
Add initial clustering per tile, very broken
This commit is contained in:
parent
2b78c4b53f
commit
c5e9448720
88 changed files with 1080 additions and 651 deletions
|
@ -1,5 +1,5 @@
|
|||
import FilteredLayer from "../../../Models/FilteredLayer";
|
||||
import {FeatureSourceForLayer} from "../FeatureSource";
|
||||
import {FeatureSourceForLayer, Tiled} from "../FeatureSource";
|
||||
import {UIEventSource} from "../../UIEventSource";
|
||||
import Loc from "../../../Models/Loc";
|
||||
import DynamicTileSource from "./DynamicTileSource";
|
||||
|
@ -8,7 +8,7 @@ import GeoJsonSource from "../Sources/GeoJsonSource";
|
|||
|
||||
export default class DynamicGeoJsonTileSource extends DynamicTileSource {
|
||||
constructor(layer: FilteredLayer,
|
||||
registerLayer: (layer: FeatureSourceForLayer) => void,
|
||||
registerLayer: (layer: FeatureSourceForLayer & Tiled) => void,
|
||||
state: {
|
||||
locationControl: UIEventSource<Loc>
|
||||
leafletMap: any
|
||||
|
|
|
@ -6,6 +6,7 @@ import {Utils} from "../../../Utils";
|
|||
import {UIEventSource} from "../../UIEventSource";
|
||||
import Loc from "../../../Models/Loc";
|
||||
import TileHierarchy from "./TileHierarchy";
|
||||
import {Tiles} from "../../../Models/TileRange";
|
||||
|
||||
/***
|
||||
* A tiled source which dynamically loads the required tiles at a fixed zoom level
|
||||
|
@ -46,9 +47,9 @@ export default class DynamicTileSource implements TileHierarchy<FeatureSourceFor
|
|||
// We'll retry later
|
||||
return undefined
|
||||
}
|
||||
const tileRange = Utils.TileRangeBetween(zoomlevel, bounds.getNorth(), bounds.getEast(), bounds.getSouth(), bounds.getWest())
|
||||
const tileRange = Tiles.TileRangeBetween(zoomlevel, bounds.getNorth(), bounds.getEast(), bounds.getSouth(), bounds.getWest())
|
||||
|
||||
const needed = Utils.MapRange(tileRange, (x, y) => Utils.tile_index(zoomlevel, x, y)).filter(i => !self._loadedTiles.has(i))
|
||||
const needed = Tiles.MapRange(tileRange, (x, y) => Tiles.tile_index(zoomlevel, x, y)).filter(i => !self._loadedTiles.has(i))
|
||||
if (needed.length === 0) {
|
||||
return undefined
|
||||
}
|
||||
|
@ -63,7 +64,7 @@ export default class DynamicTileSource implements TileHierarchy<FeatureSourceFor
|
|||
}
|
||||
for (const neededIndex of neededIndexes) {
|
||||
self._loadedTiles.add(neededIndex)
|
||||
const src = constructTile( Utils.tile_from_index(neededIndex))
|
||||
const src = constructTile(Tiles.tile_from_index(neededIndex))
|
||||
if(src !== undefined){
|
||||
self.loadedTiles.set(neededIndex, src)
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import FilteredLayer from "../../../Models/FilteredLayer";
|
|||
import {Utils} from "../../../Utils";
|
||||
import {BBox} from "../../GeoOperations";
|
||||
import FeatureSourceMerger from "../Sources/FeatureSourceMerger";
|
||||
import {Tiles} from "../../../Models/TileRange";
|
||||
|
||||
export class TileHierarchyMerger implements TileHierarchy<FeatureSourceForLayer & Tiled> {
|
||||
public readonly loadedTiles: Map<number, FeatureSourceForLayer & Tiled> = new Map<number, FeatureSourceForLayer & Tiled>();
|
||||
|
@ -13,7 +14,7 @@ export class TileHierarchyMerger implements TileHierarchy<FeatureSourceForLayer
|
|||
public readonly layer: FilteredLayer;
|
||||
private _handleTile: (src: FeatureSourceForLayer & IndexedFeatureSource, index: number) => void;
|
||||
|
||||
constructor(layer: FilteredLayer, handleTile: (src: FeatureSourceForLayer & IndexedFeatureSource, index: number) => void) {
|
||||
constructor(layer: FilteredLayer, handleTile: (src: FeatureSourceForLayer & IndexedFeatureSource & Tiled, index: number) => void) {
|
||||
this.layer = layer;
|
||||
this._handleTile = handleTile;
|
||||
}
|
||||
|
@ -37,7 +38,7 @@ export class TileHierarchyMerger implements TileHierarchy<FeatureSourceForLayer
|
|||
// We have to setup
|
||||
const sources = new UIEventSource<FeatureSource[]>([src])
|
||||
this.sources.set(index, sources)
|
||||
const merger = new FeatureSourceMerger(this.layer, index, BBox.fromTile(...Utils.tile_from_index(index)), sources)
|
||||
const merger = new FeatureSourceMerger(this.layer, index, BBox.fromTile(...Tiles.tile_from_index(index)), sources)
|
||||
this.loadedTiles.set(index, merger)
|
||||
this._handleTile(merger, index)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import {Utils} from "../../../Utils";
|
|||
import {BBox} from "../../GeoOperations";
|
||||
import FilteredLayer from "../../../Models/FilteredLayer";
|
||||
import TileHierarchy from "./TileHierarchy";
|
||||
import {feature} from "@turf/turf";
|
||||
import {Tiles} from "../../../Models/TileRange";
|
||||
|
||||
/**
|
||||
* Contains all features in a tiled fashion.
|
||||
|
@ -41,12 +41,12 @@ export default class TiledFeatureSource implements Tiled, IndexedFeatureSource,
|
|||
this.x = x;
|
||||
this.y = y;
|
||||
this.bbox = BBox.fromTile(z, x, y)
|
||||
this.tileIndex = Utils.tile_index(z, x, y)
|
||||
this.tileIndex = Tiles.tile_index(z, x, y)
|
||||
this.name = `TiledFeatureSource(${z},${x},${y})`
|
||||
this.parent = parent;
|
||||
this.layer = options.layer
|
||||
options = options ?? {}
|
||||
this.maxFeatureCount = options?.maxFeatureCount ?? 500;
|
||||
this.maxFeatureCount = options?.maxFeatureCount ?? 250;
|
||||
this.maxzoom = options.maxZoomLevel ?? 18
|
||||
this.options = options;
|
||||
if (parent === undefined) {
|
||||
|
@ -61,7 +61,7 @@ export default class TiledFeatureSource implements Tiled, IndexedFeatureSource,
|
|||
} else {
|
||||
this.root = this.parent.root;
|
||||
this.loadedTiles = this.root.loadedTiles;
|
||||
const i = Utils.tile_index(z, x, y)
|
||||
const i = Tiles.tile_index(z, x, y)
|
||||
this.root.loadedTiles.set(i, this)
|
||||
}
|
||||
this.features = new UIEventSource<any[]>([])
|
||||
|
@ -143,9 +143,7 @@ export default class TiledFeatureSource implements Tiled, IndexedFeatureSource,
|
|||
|
||||
for (const feature of features) {
|
||||
const bbox = BBox.get(feature.feature)
|
||||
if (this.options.minZoomLevel === undefined) {
|
||||
|
||||
|
||||
if (this.options.dontEnforceMinZoom || this.options.minZoomLevel === undefined) {
|
||||
if (bbox.isContainedIn(this.upper_left.bbox)) {
|
||||
ulf.push(feature)
|
||||
} else if (bbox.isContainedIn(this.upper_right.bbox)) {
|
||||
|
@ -186,6 +184,11 @@ export interface TiledFeatureSourceOptions {
|
|||
readonly maxFeatureCount?: number,
|
||||
readonly maxZoomLevel?: number,
|
||||
readonly minZoomLevel?: number,
|
||||
/**
|
||||
* IF minZoomLevel is set, and if a feature runs through a tile boundary, it would normally be duplicated.
|
||||
* Setting 'dontEnforceMinZoomLevel' will still allow bigger zoom levels for those features
|
||||
*/
|
||||
readonly dontEnforceMinZoom?: boolean,
|
||||
readonly registerTile?: (tile: TiledFeatureSource & Tiled) => void,
|
||||
readonly layer?: FilteredLayer
|
||||
}
|
|
@ -6,6 +6,7 @@ import TileHierarchy from "./TileHierarchy";
|
|||
import {Utils} from "../../../Utils";
|
||||
import SaveTileToLocalStorageActor from "../Actors/SaveTileToLocalStorageActor";
|
||||
import {BBox} from "../../GeoOperations";
|
||||
import {Tiles} from "../../../Models/TileRange";
|
||||
|
||||
export default class TiledFromLocalStorageSource implements TileHierarchy<FeatureSourceForLayer & Tiled> {
|
||||
public loadedTiles: Map<number, FeatureSourceForLayer & Tiled> = new Map<number, FeatureSourceForLayer & Tiled>();
|
||||
|
@ -17,6 +18,7 @@ export default class TiledFromLocalStorageSource implements TileHierarchy<Featur
|
|||
leafletMap: any
|
||||
}) {
|
||||
|
||||
const undefinedTiles = new Set<number>()
|
||||
const prefix = SaveTileToLocalStorageActor.storageKey + "-" + layer.layerDef.id + "-"
|
||||
// @ts-ignore
|
||||
const indexes: number[] = Object.keys(localStorage)
|
||||
|
@ -27,7 +29,7 @@ export default class TiledFromLocalStorageSource implements TileHierarchy<Featur
|
|||
return Number(key.substring(prefix.length));
|
||||
})
|
||||
|
||||
console.log("Layer", layer.layerDef.id, "has following tiles in available in localstorage", indexes.map(i => Utils.tile_from_index(i).join("/")).join(", "))
|
||||
console.log("Layer", layer.layerDef.id, "has following tiles in available in localstorage", indexes.map(i => Tiles.tile_from_index(i).join("/")).join(", "))
|
||||
|
||||
const zLevels = indexes.map(i => i % 100)
|
||||
const indexesSet = new Set(indexes)
|
||||
|
@ -57,9 +59,9 @@ export default class TiledFromLocalStorageSource implements TileHierarchy<Featur
|
|||
const needed = []
|
||||
for (let z = minZoom; z <= maxZoom; z++) {
|
||||
|
||||
const tileRange = Utils.TileRangeBetween(z, bounds.getNorth(), bounds.getEast(), bounds.getSouth(), bounds.getWest())
|
||||
const neededZ = Utils.MapRange(tileRange, (x, y) => Utils.tile_index(z, x, y))
|
||||
.filter(i => !self.loadedTiles.has(i) && indexesSet.has(i))
|
||||
const tileRange = Tiles.TileRangeBetween(z, bounds.getNorth(), bounds.getEast(), bounds.getSouth(), bounds.getWest())
|
||||
const neededZ = Tiles.MapRange(tileRange, (x, y) => Tiles.tile_index(z, x, y))
|
||||
.filter(i => !self.loadedTiles.has(i) && !undefinedTiles.has(i) && indexesSet.has(i))
|
||||
needed.push(...neededZ)
|
||||
}
|
||||
|
||||
|
@ -84,12 +86,13 @@ export default class TiledFromLocalStorageSource implements TileHierarchy<Featur
|
|||
features: new UIEventSource<{ feature: any; freshness: Date }[]>(features),
|
||||
name: "FromLocalStorage(" + key + ")",
|
||||
tileIndex: neededIndex,
|
||||
bbox: BBox.fromTile(...Utils.tile_from_index(neededIndex))
|
||||
bbox: BBox.fromTileIndex(neededIndex)
|
||||
}
|
||||
handleFeatureSource(src, neededIndex)
|
||||
self.loadedTiles.set(neededIndex, src)
|
||||
} catch (e) {
|
||||
console.error("Could not load data tile from local storage due to", e)
|
||||
undefinedTiles.add(neededIndex)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue