Testing clustering with a proxy.

This commit is contained in:
vdv committed 2023-01-19 21:08:06 +01:00
1 parent 420d75520c
commit 6f359b2e80
2 files changed
+185 -32

No files matched your search

+142
View File
@@ -0,0 +1,142 @@
import { cloneDeep } from 'lodash';
import { Feature } from 'ol';
import { equals, Extent } from 'ol/extent';
import { fromLonLat, Projection } from 'ol/proj';
import VectorTileSource from 'ol/source/VectorTile.js';
const CLUSTER_PROPS = '[cluster props]';
type FeatureFilter = (
feature: Feature,
resolution: number | undefined
) => boolean;
const passAllFeatureFilter = (feature: Feature, resolution?: number) => true;
interface Props {
extent: Extent | null;
resolution?: number;
extentProjected: Extent | null;
featuresSent: boolean;
featureFilter: FeatureFilter;
}
interface Options {
featureFilter?: FeatureFilter;
}
const initialProps = {
extent: null,
extentProjected: null,
featuresSent: false,
featureFilter: passAllFeatureFilter,
};
const getProps = (vectorTileSource: VectorTileSource) =>
vectorTileSource.get(CLUSTER_PROPS) as Props;
const setProps = (vectorTileSource: VectorTileSource, props: Props) =>
vectorTileSource.set(CLUSTER_PROPS, props);
const overloads = {
init: (target: VectorTileSource) => {
return (options?: Options) => {
let props = cloneDeep(initialProps);
if (options) {
props = { ...props, ...options };
}
setProps(target, props);
};
},
loadFeatures: (target: VectorTileSource) => {
return (extent: Extent, resolution: number, projection: Projection) => {
let props = getProps(target);
props.resolution = resolution;
if (props.extent === null || !equals(props.extent, extent)) {
props.extent = extent;
if (target.getProjection() != null) {
props.extentProjected = fromLonLat(
extent.slice(0, 2),
target.getProjection()
).concat(fromLonLat(extent.slice(2), props.projection));
}
}
if (!props.featuresSent) {
target.dispatchEvent('change');
}
props.featuresSent = false;
setProps(target, props);
console.log({
caller: 'clusterableVectorTileSourceProxy',
overload: 'loadFeatures',
extent,
resolution,
projection,
target: target,
props,
});
};
},
getFeatures: (target: VectorTileSource) => {
return () => {
let props = getProps(target);
const result = (
props.extentProjected !== null
? target.getFeaturesInExtent(props.extentProjected)
: []
).filter((feature) => props.featureFilter(feature, props.resolution));
//console.trace();
props.featuresSent = true;
setProps(target, props);
console.log({
caller: 'clusterableVectorTileSourceProxy',
overload: 'getFeatures',
result,
props,
target,
});
return result;
};
},
addEventListener: (target: VectorTileSource) => {
return (type: string, listener: any) => {
console.log({
caller: 'clusterableVectorTileSourceProxy',
overload: 'addEventListener',
type,
listener,
target,
});
target.addEventListener(type, listener);
if (type === 'change') {
target.addEventListener('tileloadend', listener);
}
};
},
};
const clusterableVectorTileSourceProxy = (vectorTileSource: VectorTileSource) =>
new Proxy(vectorTileSource, {
get: (target, prop, receiver) => {
let result;
if (prop in overloads) {
result = overloads[prop as keyof typeof overloads](target);
} else {
result = Reflect.get(target, prop, receiver);
}
// console.log({
// caller: 'clusterableVectorTileSourceProxy',
// trap: 'get',
// target,
// prop,
// receiver,
// result,
// });
return result;
},
});
export default clusterableVectorTileSourceProxy;