@mapsight/lib-ol 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -0
- package/dist/coordinate/add.d.ts +3 -0
- package/dist/coordinate/add.d.ts.map +1 -0
- package/dist/coordinate/add.js +8 -0
- package/dist/coordinate/add.js.map +1 -0
- package/dist/coordinate/addPixelPadding.d.ts +10 -0
- package/dist/coordinate/addPixelPadding.d.ts.map +1 -0
- package/dist/coordinate/addPixelPadding.js +13 -0
- package/dist/coordinate/addPixelPadding.js.map +1 -0
- package/dist/coordinate/fromPixel.d.ts +3 -0
- package/dist/coordinate/fromPixel.d.ts.map +1 -0
- package/dist/coordinate/fromPixel.js +8 -0
- package/dist/coordinate/fromPixel.js.map +1 -0
- package/dist/coordinate/scale.d.ts +3 -0
- package/dist/coordinate/scale.d.ts.map +1 -0
- package/dist/coordinate/scale.js +5 -0
- package/dist/coordinate/scale.js.map +1 -0
- package/dist/coordinate/toPixel.d.ts +3 -0
- package/dist/coordinate/toPixel.d.ts.map +1 -0
- package/dist/coordinate/toPixel.js +8 -0
- package/dist/coordinate/toPixel.js.map +1 -0
- package/dist/coordinates/equals.d.ts +3 -0
- package/dist/coordinates/equals.d.ts.map +1 -0
- package/dist/coordinates/equals.js +5 -0
- package/dist/coordinates/equals.js.map +1 -0
- package/dist/coordinates/middleCoordinate.d.ts +3 -0
- package/dist/coordinates/middleCoordinate.d.ts.map +1 -0
- package/dist/coordinates/middleCoordinate.js +5 -0
- package/dist/coordinates/middleCoordinate.js.map +1 -0
- package/dist/events/condition/clickOnFeature.d.ts +9 -0
- package/dist/events/condition/clickOnFeature.d.ts.map +1 -0
- package/dist/events/condition/clickOnFeature.js +10 -0
- package/dist/events/condition/clickOnFeature.js.map +1 -0
- package/dist/extent/getCentroid.d.ts +6 -0
- package/dist/extent/getCentroid.d.ts.map +1 -0
- package/dist/extent/getCentroid.js +9 -0
- package/dist/extent/getCentroid.js.map +1 -0
- package/dist/extent/isFiniteExtent.d.ts +3 -0
- package/dist/extent/isFiniteExtent.d.ts.map +1 -0
- package/dist/extent/isFiniteExtent.js +4 -0
- package/dist/extent/isFiniteExtent.js.map +1 -0
- package/dist/extents/combineExtents.d.ts +3 -0
- package/dist/extents/combineExtents.d.ts.map +1 -0
- package/dist/extents/combineExtents.js +9 -0
- package/dist/extents/combineExtents.js.map +1 -0
- package/dist/feature/animator.d.ts +9 -0
- package/dist/feature/animator.d.ts.map +1 -0
- package/dist/feature/animator.js +33 -0
- package/dist/feature/animator.js.map +1 -0
- package/dist/feature/cluster.d.ts +8 -0
- package/dist/feature/cluster.d.ts.map +1 -0
- package/dist/feature/cluster.js +50 -0
- package/dist/feature/cluster.js.map +1 -0
- package/dist/feature/detectFeatureHits.d.ts +11 -0
- package/dist/feature/detectFeatureHits.d.ts.map +1 -0
- package/dist/feature/detectFeatureHits.js +34 -0
- package/dist/feature/detectFeatureHits.js.map +1 -0
- package/dist/feature/ensureId.d.ts +3 -0
- package/dist/feature/ensureId.d.ts.map +1 -0
- package/dist/feature/ensureId.js +7 -0
- package/dist/feature/ensureId.js.map +1 -0
- package/dist/feature/getCentroid.d.ts +3 -0
- package/dist/feature/getCentroid.d.ts.map +1 -0
- package/dist/feature/getCentroid.js +13 -0
- package/dist/feature/getCentroid.js.map +1 -0
- package/dist/feature/getExtent.d.ts +3 -0
- package/dist/feature/getExtent.d.ts.map +1 -0
- package/dist/feature/getExtent.js +8 -0
- package/dist/feature/getExtent.js.map +1 -0
- package/dist/feature/getLayer.d.ts +4 -0
- package/dist/feature/getLayer.d.ts.map +1 -0
- package/dist/feature/getLayer.js +23 -0
- package/dist/feature/getLayer.js.map +1 -0
- package/dist/feature/getUid.d.ts +3 -0
- package/dist/feature/getUid.d.ts.map +1 -0
- package/dist/feature/getUid.js +5 -0
- package/dist/feature/getUid.js.map +1 -0
- package/dist/features/getCentroidForFeatures.d.ts +3 -0
- package/dist/features/getCentroidForFeatures.d.ts.map +1 -0
- package/dist/features/getCentroidForFeatures.js +7 -0
- package/dist/features/getCentroidForFeatures.js.map +1 -0
- package/dist/features/getExtentForFeatures.d.ts +3 -0
- package/dist/features/getExtentForFeatures.d.ts.map +1 -0
- package/dist/features/getExtentForFeatures.js +7 -0
- package/dist/features/getExtentForFeatures.js.map +1 -0
- package/dist/geometry/deriveGeometriesFromBase.d.ts +8 -0
- package/dist/geometry/deriveGeometriesFromBase.d.ts.map +1 -0
- package/dist/geometry/deriveGeometriesFromBase.js +69 -0
- package/dist/geometry/deriveGeometriesFromBase.js.map +1 -0
- package/dist/geometry/getDominantGeometryType.d.ts +4 -0
- package/dist/geometry/getDominantGeometryType.d.ts.map +1 -0
- package/dist/geometry/getDominantGeometryType.js +30 -0
- package/dist/geometry/getDominantGeometryType.js.map +1 -0
- package/dist/geometry/getLineStringSegmentVerticesWithRotation.d.ts +4 -0
- package/dist/geometry/getLineStringSegmentVerticesWithRotation.d.ts.map +1 -0
- package/dist/geometry/getLineStringSegmentVerticesWithRotation.js +28 -0
- package/dist/geometry/getLineStringSegmentVerticesWithRotation.js.map +1 -0
- package/dist/geometry/getPolygonRingSegmentVerticesWithRotation.d.ts +4 -0
- package/dist/geometry/getPolygonRingSegmentVerticesWithRotation.d.ts.map +1 -0
- package/dist/geometry/getPolygonRingSegmentVerticesWithRotation.js +49 -0
- package/dist/geometry/getPolygonRingSegmentVerticesWithRotation.js.map +1 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/map/animateDuringTransition.d.ts +4 -0
- package/dist/map/animateDuringTransition.d.ts.map +1 -0
- package/dist/map/animateDuringTransition.js +41 -0
- package/dist/map/animateDuringTransition.js.map +1 -0
- package/dist/map/canvasSizeFixer.d.ts +10 -0
- package/dist/map/canvasSizeFixer.d.ts.map +1 -0
- package/dist/map/canvasSizeFixer.js +35 -0
- package/dist/map/canvasSizeFixer.js.map +1 -0
- package/dist/map/containsExtentWithPadding.d.ts +5 -0
- package/dist/map/containsExtentWithPadding.d.ts.map +1 -0
- package/dist/map/containsExtentWithPadding.js +9 -0
- package/dist/map/containsExtentWithPadding.js.map +1 -0
- package/dist/map/fitToExtent.d.ts +10 -0
- package/dist/map/fitToExtent.d.ts.map +1 -0
- package/dist/map/fitToExtent.js +26 -0
- package/dist/map/fitToExtent.js.map +1 -0
- package/dist/map/fitToFeature.d.ts +17 -0
- package/dist/map/fitToFeature.d.ts.map +1 -0
- package/dist/map/fitToFeature.js +16 -0
- package/dist/map/fitToFeature.js.map +1 -0
- package/dist/map/fitToFeatures.d.ts +17 -0
- package/dist/map/fitToFeatures.d.ts.map +1 -0
- package/dist/map/fitToFeatures.js +11 -0
- package/dist/map/fitToFeatures.js.map +1 -0
- package/dist/map/getPaddedViewExtent.d.ts +5 -0
- package/dist/map/getPaddedViewExtent.d.ts.map +1 -0
- package/dist/map/getPaddedViewExtent.js +28 -0
- package/dist/map/getPaddedViewExtent.js.map +1 -0
- package/dist/map/getVisibleLayersFromFramestate.d.ts +5 -0
- package/dist/map/getVisibleLayersFromFramestate.d.ts.map +1 -0
- package/dist/map/getVisibleLayersFromFramestate.js +8 -0
- package/dist/map/getVisibleLayersFromFramestate.js.map +1 -0
- package/dist/map/updateSizeDuringTransition.d.ts +3 -0
- package/dist/map/updateSizeDuringTransition.d.ts.map +1 -0
- package/dist/map/updateSizeDuringTransition.js +7 -0
- package/dist/map/updateSizeDuringTransition.js.map +1 -0
- package/dist/map/updateSizeOnTransitionEnd.d.ts +3 -0
- package/dist/map/updateSizeOnTransitionEnd.d.ts.map +1 -0
- package/dist/map/updateSizeOnTransitionEnd.js +19 -0
- package/dist/map/updateSizeOnTransitionEnd.js.map +1 -0
- package/dist/points/findClosestPoint.d.ts +11 -0
- package/dist/points/findClosestPoint.d.ts.map +1 -0
- package/dist/points/findClosestPoint.js +32 -0
- package/dist/points/findClosestPoint.js.map +1 -0
- package/dist/points/spreadPointClusterInRadius.d.ts +14 -0
- package/dist/points/spreadPointClusterInRadius.d.ts.map +1 -0
- package/dist/points/spreadPointClusterInRadius.js +53 -0
- package/dist/points/spreadPointClusterInRadius.js.map +1 -0
- package/dist/style/bindStyleToGeometry.d.ts +4 -0
- package/dist/style/bindStyleToGeometry.d.ts.map +1 -0
- package/dist/style/bindStyleToGeometry.js +6 -0
- package/dist/style/bindStyleToGeometry.js.map +1 -0
- package/dist/style/createCachedStyleFunction.d.ts +45 -0
- package/dist/style/createCachedStyleFunction.d.ts.map +1 -0
- package/dist/style/createCachedStyleFunction.js +175 -0
- package/dist/style/createCachedStyleFunction.js.map +1 -0
- package/dist/style/declarationToGeometry.d.ts +3 -0
- package/dist/style/declarationToGeometry.d.ts.map +1 -0
- package/dist/style/declarationToGeometry.js +4 -0
- package/dist/style/declarationToGeometry.js.map +1 -0
- package/dist/style/declarationToStyle.d.ts +6 -0
- package/dist/style/declarationToStyle.d.ts.map +1 -0
- package/dist/style/declarationToStyle.js +167 -0
- package/dist/style/declarationToStyle.js.map +1 -0
- package/dist/style/styleFunction.d.ts +21 -0
- package/dist/style/styleFunction.d.ts.map +1 -0
- package/dist/style/styleFunction.js +13 -0
- package/dist/style/styleFunction.js.map +1 -0
- package/dist/tileGrid/getTileUrlsForExtent.d.ts +4 -0
- package/dist/tileGrid/getTileUrlsForExtent.d.ts.map +1 -0
- package/dist/tileGrid/getTileUrlsForExtent.js +23 -0
- package/dist/tileGrid/getTileUrlsForExtent.js.map +1 -0
- package/dist/view/centerOnFeature.d.ts +10 -0
- package/dist/view/centerOnFeature.d.ts.map +1 -0
- package/dist/view/centerOnFeature.js +12 -0
- package/dist/view/centerOnFeature.js.map +1 -0
- package/dist/view/centerOnFeatures.d.ts +8 -0
- package/dist/view/centerOnFeatures.d.ts.map +1 -0
- package/dist/view/centerOnFeatures.js +19 -0
- package/dist/view/centerOnFeatures.js.map +1 -0
- package/dist/view/getMinZoomFittingContentInView.d.ts +15 -0
- package/dist/view/getMinZoomFittingContentInView.d.ts.map +1 -0
- package/dist/view/getMinZoomFittingContentInView.js +29 -0
- package/dist/view/getMinZoomFittingContentInView.js.map +1 -0
- package/package.json +36 -0
- package/src/js/coordinate/add.ts +13 -0
- package/src/js/coordinate/addPixelPadding.ts +21 -0
- package/src/js/coordinate/fromPixel.ts +10 -0
- package/src/js/coordinate/scale.ts +7 -0
- package/src/js/coordinate/toPixel.ts +13 -0
- package/src/js/coordinates/equals.ts +6 -0
- package/src/js/coordinates/middleCoordinate.ts +7 -0
- package/src/js/events/condition/clickOnFeature.ts +13 -0
- package/src/js/extent/getCentroid.ts +14 -0
- package/src/js/extent/isFiniteExtent.ts +7 -0
- package/src/js/extents/combineExtents.ts +11 -0
- package/src/js/feature/animator.ts +91 -0
- package/src/js/feature/cluster.ts +86 -0
- package/src/js/feature/detectFeatureHits.ts +57 -0
- package/src/js/feature/ensureId.ts +9 -0
- package/src/js/feature/getCentroid.ts +18 -0
- package/src/js/feature/getExtent.ts +10 -0
- package/src/js/feature/getLayer.ts +39 -0
- package/src/js/feature/getUid.ts +6 -0
- package/src/js/features/getCentroidForFeatures.ts +10 -0
- package/src/js/features/getExtentForFeatures.ts +10 -0
- package/src/js/geometry/deriveGeometriesFromBase.ts +122 -0
- package/src/js/geometry/getDominantGeometryType.ts +40 -0
- package/src/js/geometry/getLineStringSegmentVerticesWithRotation.ts +48 -0
- package/src/js/geometry/getPolygonRingSegmentVerticesWithRotation.ts +90 -0
- package/src/js/index.ts +62 -0
- package/src/js/map/animateDuringTransition.ts +58 -0
- package/src/js/map/canvasSizeFixer.ts +46 -0
- package/src/js/map/containsExtentWithPadding.ts +17 -0
- package/src/js/map/fitToExtent.ts +45 -0
- package/src/js/map/fitToFeature.ts +29 -0
- package/src/js/map/fitToFeatures.ts +21 -0
- package/src/js/map/getPaddedViewExtent.ts +42 -0
- package/src/js/map/getVisibleLayersFromFramestate.ts +14 -0
- package/src/js/map/updateSizeDuringTransition.ts +9 -0
- package/src/js/map/updateSizeOnTransitionEnd.ts +28 -0
- package/src/js/points/findClosestPoint.ts +51 -0
- package/src/js/points/spreadPointClusterInRadius.ts +84 -0
- package/src/js/style/bindStyleToGeometry.ts +11 -0
- package/src/js/style/createCachedStyleFunction.ts +344 -0
- package/src/js/style/declarationToGeometry.ts +7 -0
- package/src/js/style/declarationToStyle.ts +277 -0
- package/src/js/style/styleFunction.ts +42 -0
- package/src/js/tileGrid/getTileUrlsForExtent.ts +41 -0
- package/src/js/view/centerOnFeature.ts +23 -0
- package/src/js/view/centerOnFeatures.ts +30 -0
- package/src/js/view/getMinZoomFittingContentInView.ts +50 -0
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
import type {Type as GeometryType} from "ol/geom/Geometry";
|
|
2
|
+
import type Geometry from "ol/geom/Geometry";
|
|
3
|
+
import type GeometryCollection from "ol/geom/GeometryCollection";
|
|
4
|
+
import LRUCache from "ol/structs/LRUCache";
|
|
5
|
+
import type Style from "ol/style/Style";
|
|
6
|
+
|
|
7
|
+
import {ensureNonNullable} from "@mapsight/lib-js/nonNullable";
|
|
8
|
+
|
|
9
|
+
import type {Derivation} from "../geometry/deriveGeometriesFromBase.ts";
|
|
10
|
+
import deriveGeometriesFromBase from "../geometry/deriveGeometriesFromBase.ts";
|
|
11
|
+
import type {GroupedRootStyleDeclaration} from "../index.ts";
|
|
12
|
+
import declarationToGeometry from "./declarationToGeometry.ts";
|
|
13
|
+
import declarationToStyle from "./declarationToStyle.ts";
|
|
14
|
+
import type {
|
|
15
|
+
MapsightStyleFunction,
|
|
16
|
+
MapsightStyleFunctionEnv,
|
|
17
|
+
MapsightStyleFunctionProps,
|
|
18
|
+
} from "./styleFunction.ts";
|
|
19
|
+
import {STYLE_ENV_FIELD_NAME, createPropsFilter} from "./styleFunction.ts";
|
|
20
|
+
|
|
21
|
+
const TYPE_GEOMETRY_COLLECTION: GeometryType = "GeometryCollection";
|
|
22
|
+
const DEFAULT_STYLE = "default";
|
|
23
|
+
const HASH_STRING_DELIMITER = "|";
|
|
24
|
+
|
|
25
|
+
const DEFAULT_ROOT_STYLE_TYPE = "style";
|
|
26
|
+
|
|
27
|
+
const DEFAULT_CACHE_LEVEL_1_SIZE = 100;
|
|
28
|
+
const DEFAULT_CACHE_LEVEL_2_SIZE = 100;
|
|
29
|
+
const DEFAULT_CACHE_LEVEL_3_SIZE = 100;
|
|
30
|
+
|
|
31
|
+
type CachedValue = {
|
|
32
|
+
style: Style | null;
|
|
33
|
+
geometryTypeOrDerivation: GeometryType | Derivation | null;
|
|
34
|
+
};
|
|
35
|
+
type CachedValues = Array<CachedValue>;
|
|
36
|
+
|
|
37
|
+
export type StyleFunctionMetrics = {
|
|
38
|
+
envHashMs: number;
|
|
39
|
+
propsHashMs: number;
|
|
40
|
+
level1Hits: number;
|
|
41
|
+
level1Misses: number;
|
|
42
|
+
level2Hits: number;
|
|
43
|
+
level2Misses: number;
|
|
44
|
+
declarationMs: number;
|
|
45
|
+
styleMaterializationMs: number;
|
|
46
|
+
inputStylesCount: number;
|
|
47
|
+
outputStylesCount: number;
|
|
48
|
+
geometryCollectionsTraversed: number;
|
|
49
|
+
totalMs: number;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export type StyleFunctionMetricsCollector = (
|
|
53
|
+
metrics: StyleFunctionMetrics,
|
|
54
|
+
) => void;
|
|
55
|
+
|
|
56
|
+
export type StyleFunctionOptions = {
|
|
57
|
+
constructorsMap: Record<string, unknown>;
|
|
58
|
+
metricsCollector?: StyleFunctionMetricsCollector;
|
|
59
|
+
declarationHashFunction: (
|
|
60
|
+
env: MapsightStyleFunctionEnv,
|
|
61
|
+
props: MapsightStyleFunctionProps,
|
|
62
|
+
envHash: string,
|
|
63
|
+
geometryType: GeometryType,
|
|
64
|
+
styleName: string,
|
|
65
|
+
) => string;
|
|
66
|
+
declarationFunction: (
|
|
67
|
+
env: MapsightStyleFunctionEnv,
|
|
68
|
+
props: MapsightStyleFunctionProps,
|
|
69
|
+
geometryType: GeometryType,
|
|
70
|
+
styleName: string,
|
|
71
|
+
) => unknown; // Using GroupedRootStyleDeclaration here breaks tsc, probably because the object is too big/complex
|
|
72
|
+
allowedProps?: Array<string> | false;
|
|
73
|
+
allowedStyles?: Array<string> | false;
|
|
74
|
+
cacheLevel1Size?: number;
|
|
75
|
+
cacheLevel2Size?: number;
|
|
76
|
+
cacheLevel3Size?: number;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Creates a cached mapsight style function for openlayers
|
|
81
|
+
*
|
|
82
|
+
* @param constructorsMap map of style constructors
|
|
83
|
+
* @param [metricsCollector] optional callback receiving per-invocation runtime metrics (hash timing, cache hit/miss, and declaration/style timings)
|
|
84
|
+
* @param declarationHashFunction style declaration hash function
|
|
85
|
+
* @param declarationFunction style declaration function
|
|
86
|
+
* @param [allowedProps=false] list of props allowed, false = all allowed
|
|
87
|
+
* @param [allowedStyles=false] list of styles allowed, false = all allowed
|
|
88
|
+
* @param [cacheLevel1Size=100] size of first level cache that caches feature geometry styles based on feature and environment state
|
|
89
|
+
* @param [cacheLevel2Size=100] size of second level cache that caches style objects based on the rules that apply and the environment state
|
|
90
|
+
* @param [cacheLevel3Size=100] size of third level cache that caches style objects based on the rules that apply and the environment state
|
|
91
|
+
*
|
|
92
|
+
* @returns style function
|
|
93
|
+
*/
|
|
94
|
+
export default function createCachedStyleFunction({
|
|
95
|
+
constructorsMap,
|
|
96
|
+
metricsCollector,
|
|
97
|
+
declarationHashFunction,
|
|
98
|
+
declarationFunction,
|
|
99
|
+
allowedProps = false,
|
|
100
|
+
allowedStyles = false,
|
|
101
|
+
cacheLevel1Size = DEFAULT_CACHE_LEVEL_1_SIZE,
|
|
102
|
+
cacheLevel2Size = DEFAULT_CACHE_LEVEL_2_SIZE,
|
|
103
|
+
cacheLevel3Size = DEFAULT_CACHE_LEVEL_3_SIZE,
|
|
104
|
+
}: StyleFunctionOptions) {
|
|
105
|
+
const hasMetricsCollector = typeof metricsCollector === "function";
|
|
106
|
+
const filterProps = createPropsFilter(allowedProps);
|
|
107
|
+
const createHash = (value: unknown) => JSON.stringify(value);
|
|
108
|
+
|
|
109
|
+
const cacheLevel1 = new LRUCache<CachedValues>(cacheLevel1Size); // the first level cache caches feature geometry styles based on feature and environment state
|
|
110
|
+
const cacheLevel2 = new LRUCache<CachedValues>(cacheLevel2Size); // the second level cache caches style objects based on the rules that apply and the environment state
|
|
111
|
+
const cacheLevel3 = new LRUCache<Style | null>(cacheLevel3Size); // the third level cache caches style objects based on the rules that apply and the environment state
|
|
112
|
+
|
|
113
|
+
function level1(
|
|
114
|
+
env: MapsightStyleFunctionEnv,
|
|
115
|
+
props: MapsightStyleFunctionProps,
|
|
116
|
+
envHash: string,
|
|
117
|
+
propsHash: string,
|
|
118
|
+
geometryType: GeometryType,
|
|
119
|
+
metrics?: StyleFunctionMetrics,
|
|
120
|
+
): CachedValues {
|
|
121
|
+
const cacheHashL1 =
|
|
122
|
+
envHash +
|
|
123
|
+
HASH_STRING_DELIMITER +
|
|
124
|
+
geometryType +
|
|
125
|
+
HASH_STRING_DELIMITER +
|
|
126
|
+
propsHash;
|
|
127
|
+
const hasLevel1 = cacheLevel1.containsKey(cacheHashL1);
|
|
128
|
+
if (metrics) {
|
|
129
|
+
if (hasLevel1) {
|
|
130
|
+
metrics.level1Hits += 1;
|
|
131
|
+
} else {
|
|
132
|
+
metrics.level1Misses += 1;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (!hasLevel1) {
|
|
137
|
+
cacheLevel1.set(
|
|
138
|
+
cacheHashL1,
|
|
139
|
+
level2(env, props, envHash, propsHash, geometryType, metrics),
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return cacheLevel1.get(cacheHashL1);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function level2(
|
|
147
|
+
env: MapsightStyleFunctionEnv,
|
|
148
|
+
props: MapsightStyleFunctionProps,
|
|
149
|
+
envHash: string,
|
|
150
|
+
propsHash: string,
|
|
151
|
+
geometryType: GeometryType,
|
|
152
|
+
metrics?: StyleFunctionMetrics,
|
|
153
|
+
): CachedValues {
|
|
154
|
+
let styleName: string = DEFAULT_STYLE;
|
|
155
|
+
|
|
156
|
+
const envStyle = env[STYLE_ENV_FIELD_NAME];
|
|
157
|
+
if (typeof envStyle === "string") {
|
|
158
|
+
if (allowedStyles === false) {
|
|
159
|
+
styleName = envStyle;
|
|
160
|
+
} else {
|
|
161
|
+
styleName =
|
|
162
|
+
allowedStyles.indexOf(envStyle) > -1
|
|
163
|
+
? envStyle
|
|
164
|
+
: DEFAULT_STYLE;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const cacheHashL2 = declarationHashFunction(
|
|
169
|
+
env,
|
|
170
|
+
props,
|
|
171
|
+
envHash,
|
|
172
|
+
geometryType,
|
|
173
|
+
styleName,
|
|
174
|
+
);
|
|
175
|
+
if (cacheLevel2.containsKey(cacheHashL2)) {
|
|
176
|
+
if (metrics) {
|
|
177
|
+
metrics.level2Hits += 1;
|
|
178
|
+
}
|
|
179
|
+
return cacheLevel2.get(cacheHashL2);
|
|
180
|
+
}
|
|
181
|
+
if (metrics) {
|
|
182
|
+
metrics.level2Misses += 1;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const declarationStart = metrics ? performance.now() : 0;
|
|
186
|
+
const declarations = declarationFunction(
|
|
187
|
+
env,
|
|
188
|
+
props,
|
|
189
|
+
geometryType,
|
|
190
|
+
styleName,
|
|
191
|
+
) as GroupedRootStyleDeclaration; // Having to cast here because of the tsc bug noted above
|
|
192
|
+
if (metrics) {
|
|
193
|
+
metrics.declarationMs += performance.now() - declarationStart;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const styleMaterializationStart = metrics ? performance.now() : 0;
|
|
197
|
+
const values: CachedValues = Object.keys(declarations).map((group) => ({
|
|
198
|
+
style: declarationToStyle(
|
|
199
|
+
constructorsMap,
|
|
200
|
+
ensureNonNullable(declarations[group]),
|
|
201
|
+
DEFAULT_ROOT_STYLE_TYPE,
|
|
202
|
+
group + "," + cacheHashL2,
|
|
203
|
+
cacheLevel3,
|
|
204
|
+
),
|
|
205
|
+
geometryTypeOrDerivation: declarationToGeometry(
|
|
206
|
+
declarations[group],
|
|
207
|
+
),
|
|
208
|
+
}));
|
|
209
|
+
if (metrics) {
|
|
210
|
+
metrics.styleMaterializationMs +=
|
|
211
|
+
performance.now() - styleMaterializationStart;
|
|
212
|
+
metrics.inputStylesCount += values.length;
|
|
213
|
+
}
|
|
214
|
+
cacheLevel2.set(cacheHashL2, values);
|
|
215
|
+
|
|
216
|
+
return values;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function styleGeometryOrGeometryCollectionCached(
|
|
220
|
+
env: MapsightStyleFunctionEnv,
|
|
221
|
+
props: MapsightStyleFunctionProps,
|
|
222
|
+
envHash: string,
|
|
223
|
+
propsHash: string,
|
|
224
|
+
geometryOrGeometryCollection?: Geometry,
|
|
225
|
+
metrics?: StyleFunctionMetrics,
|
|
226
|
+
i = 0,
|
|
227
|
+
): Array<Style> {
|
|
228
|
+
if (!geometryOrGeometryCollection) {
|
|
229
|
+
return [];
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const geometryType = geometryOrGeometryCollection.getType();
|
|
233
|
+
|
|
234
|
+
// recurse through collections
|
|
235
|
+
if (geometryType === TYPE_GEOMETRY_COLLECTION) {
|
|
236
|
+
if (metrics) {
|
|
237
|
+
metrics.geometryCollectionsTraversed += 1;
|
|
238
|
+
}
|
|
239
|
+
const collection =
|
|
240
|
+
geometryOrGeometryCollection as GeometryCollection;
|
|
241
|
+
|
|
242
|
+
return collection
|
|
243
|
+
.getGeometries()
|
|
244
|
+
.flatMap((geometry: Geometry) =>
|
|
245
|
+
styleGeometryOrGeometryCollectionCached(
|
|
246
|
+
env,
|
|
247
|
+
props,
|
|
248
|
+
envHash,
|
|
249
|
+
propsHash,
|
|
250
|
+
geometry,
|
|
251
|
+
metrics,
|
|
252
|
+
i + 1,
|
|
253
|
+
),
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return level1(env, props, envHash, propsHash, geometryType, metrics)
|
|
258
|
+
.filter(({style}) => style != null)
|
|
259
|
+
.flatMap(function bindStyleToBaseGeometry({
|
|
260
|
+
style: baseStyle,
|
|
261
|
+
geometryTypeOrDerivation: geometryDerivation,
|
|
262
|
+
}: CachedValue) {
|
|
263
|
+
if (baseStyle === null) {
|
|
264
|
+
return [];
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const derivedGeometries = deriveGeometriesFromBase(
|
|
268
|
+
geometryOrGeometryCollection,
|
|
269
|
+
geometryDerivation,
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
return derivedGeometries.map(
|
|
273
|
+
function bindDerivedGeometryToStyle(geometryWithMeta) {
|
|
274
|
+
const [geometry, meta] = geometryWithMeta;
|
|
275
|
+
const style = baseStyle.clone();
|
|
276
|
+
style.setGeometry(geometry);
|
|
277
|
+
|
|
278
|
+
const baseImageStyle = style.getImage();
|
|
279
|
+
if (meta?.rotation != null && baseImageStyle) {
|
|
280
|
+
const imageStyle = baseImageStyle.clone();
|
|
281
|
+
const baseRotation = imageStyle.getRotation();
|
|
282
|
+
imageStyle.setRotation(
|
|
283
|
+
baseRotation + meta.rotation,
|
|
284
|
+
);
|
|
285
|
+
style.setImage(imageStyle);
|
|
286
|
+
}
|
|
287
|
+
return style;
|
|
288
|
+
},
|
|
289
|
+
);
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const cachedStyleFunction: MapsightStyleFunction = (env = {}, feature) => {
|
|
294
|
+
const totalStart = hasMetricsCollector ? performance.now() : 0;
|
|
295
|
+
const metrics: StyleFunctionMetrics | undefined = hasMetricsCollector
|
|
296
|
+
? {
|
|
297
|
+
envHashMs: 0,
|
|
298
|
+
propsHashMs: 0,
|
|
299
|
+
level1Hits: 0,
|
|
300
|
+
level1Misses: 0,
|
|
301
|
+
level2Hits: 0,
|
|
302
|
+
level2Misses: 0,
|
|
303
|
+
declarationMs: 0,
|
|
304
|
+
styleMaterializationMs: 0,
|
|
305
|
+
inputStylesCount: 0,
|
|
306
|
+
outputStylesCount: 0,
|
|
307
|
+
geometryCollectionsTraversed: 0,
|
|
308
|
+
totalMs: 0,
|
|
309
|
+
}
|
|
310
|
+
: undefined;
|
|
311
|
+
|
|
312
|
+
// subset of feature properties that are relevant for styling (also used for caching decisions)
|
|
313
|
+
const filteredProps = filterProps(feature.getProperties());
|
|
314
|
+
const envHashStart = hasMetricsCollector ? performance.now() : 0;
|
|
315
|
+
const envHash = createHash(env);
|
|
316
|
+
if (metrics) {
|
|
317
|
+
metrics.envHashMs = performance.now() - envHashStart;
|
|
318
|
+
}
|
|
319
|
+
const propsHashStart = hasMetricsCollector ? performance.now() : 0;
|
|
320
|
+
const propsHash = createHash(filteredProps);
|
|
321
|
+
if (metrics) {
|
|
322
|
+
metrics.propsHashMs = performance.now() - propsHashStart;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const styles = styleGeometryOrGeometryCollectionCached(
|
|
326
|
+
env,
|
|
327
|
+
filteredProps,
|
|
328
|
+
envHash,
|
|
329
|
+
propsHash,
|
|
330
|
+
feature.getGeometry() as Geometry,
|
|
331
|
+
metrics,
|
|
332
|
+
);
|
|
333
|
+
|
|
334
|
+
if (metrics && metricsCollector) {
|
|
335
|
+
metrics.outputStylesCount = styles.length;
|
|
336
|
+
metrics.totalMs = performance.now() - totalStart;
|
|
337
|
+
metricsCollector(metrics);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return styles;
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
return cachedStyleFunction;
|
|
344
|
+
}
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import LRUCache from "ol/structs/LRUCache";
|
|
2
|
+
import type Image from "ol/style/Image";
|
|
3
|
+
import type Style from "ol/style/Style";
|
|
4
|
+
|
|
5
|
+
import type {
|
|
6
|
+
BoolishStyleValue,
|
|
7
|
+
NumberArrayStyleValue,
|
|
8
|
+
RootStyleDeclaration,
|
|
9
|
+
StyleDeclaration,
|
|
10
|
+
StyleLiteral,
|
|
11
|
+
StyleValues,
|
|
12
|
+
UnitStyleValue,
|
|
13
|
+
} from "../index";
|
|
14
|
+
|
|
15
|
+
const IMAGE_TYPES = ["image", "icon", "circle"];
|
|
16
|
+
const NONE_ABLE_PROPS = ["fill", "stroke"];
|
|
17
|
+
|
|
18
|
+
const unitFromAnchorValue = (a?: string | null) =>
|
|
19
|
+
a && typeof a === "string" && a.indexOf("px") > -1 ? "pixels" : "fraction";
|
|
20
|
+
const boolishValue = (a?: BoolishStyleValue) =>
|
|
21
|
+
a === true || a === 1 || a === "1" || a === "true";
|
|
22
|
+
const numberValue = (a?: string | number | null) =>
|
|
23
|
+
a ? parseFloat(String(a)) : 0;
|
|
24
|
+
const intValue = (a?: string | number | null) =>
|
|
25
|
+
a ? parseInt(String(a), 10) : 0;
|
|
26
|
+
const numberArrayValue = (a?: NumberArrayStyleValue) => {
|
|
27
|
+
let arr: Array<string | number> = [];
|
|
28
|
+
if (a) {
|
|
29
|
+
if (Array.isArray(a)) {
|
|
30
|
+
arr = a;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (typeof a === "string") {
|
|
34
|
+
arr = a.split(",");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return arr.map((b) => parseFloat(String(b).trim()));
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const HASH_STRING_DELIMITER = "|";
|
|
42
|
+
export const DEFAULT_CACHE_SIZE = 100;
|
|
43
|
+
|
|
44
|
+
let defaultCache: null | LRUCache<Style | null> = null;
|
|
45
|
+
|
|
46
|
+
function getDefaultCache() {
|
|
47
|
+
if (defaultCache === null) {
|
|
48
|
+
defaultCache = new LRUCache(DEFAULT_CACHE_SIZE);
|
|
49
|
+
}
|
|
50
|
+
return defaultCache;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function _declarationToStyle(
|
|
54
|
+
constructorsMap: Record<string, unknown>,
|
|
55
|
+
declaration: Readonly<RootStyleDeclaration | StyleDeclaration>,
|
|
56
|
+
type: string,
|
|
57
|
+
cache: LRUCache<Style | null>,
|
|
58
|
+
root = true,
|
|
59
|
+
): Style | null {
|
|
60
|
+
const style: StyleLiteral = {};
|
|
61
|
+
|
|
62
|
+
if (root) {
|
|
63
|
+
const rootDeclaration = declaration as Readonly<RootStyleDeclaration>;
|
|
64
|
+
|
|
65
|
+
if (rootDeclaration.display?.value === "none") {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// image is the base for icon, circle and regular shape. image only has image-type: *; any other options
|
|
70
|
+
// will be in either of the above. e.g. icon-src: ...;
|
|
71
|
+
if (rootDeclaration.image) {
|
|
72
|
+
const imageType = rootDeclaration.image.type.value;
|
|
73
|
+
if (imageType) {
|
|
74
|
+
if (rootDeclaration[imageType]) {
|
|
75
|
+
// FIXME: converting `Style` to `Image`
|
|
76
|
+
style.image = declarationToStyle(
|
|
77
|
+
constructorsMap,
|
|
78
|
+
rootDeclaration[
|
|
79
|
+
imageType
|
|
80
|
+
] as Readonly<StyleDeclaration>,
|
|
81
|
+
imageType,
|
|
82
|
+
undefined,
|
|
83
|
+
cache,
|
|
84
|
+
false,
|
|
85
|
+
) as Image | null;
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
console.error("Image type unknown", imageType, rootDeclaration);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
Object.keys(declaration).forEach((key) => {
|
|
94
|
+
if (IMAGE_TYPES.indexOf(key) > -1) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const values = declaration as Readonly<StyleValues>;
|
|
99
|
+
const declarationValue = values[key];
|
|
100
|
+
if (typeof declarationValue !== "object") {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const declarationValueValue =
|
|
105
|
+
"value" in declarationValue ? declarationValue.value : undefined;
|
|
106
|
+
|
|
107
|
+
if (declarationValueValue === undefined) {
|
|
108
|
+
if (key in constructorsMap) {
|
|
109
|
+
try {
|
|
110
|
+
style[key] = declarationToStyle(
|
|
111
|
+
constructorsMap,
|
|
112
|
+
declarationValue as Readonly<StyleDeclaration>,
|
|
113
|
+
key,
|
|
114
|
+
undefined,
|
|
115
|
+
cache,
|
|
116
|
+
false,
|
|
117
|
+
);
|
|
118
|
+
} catch (e) {
|
|
119
|
+
console.error("Style error", e);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (
|
|
127
|
+
declarationValueValue === "unset" ||
|
|
128
|
+
(declarationValueValue === "none" &&
|
|
129
|
+
NONE_ABLE_PROPS.indexOf(key) > -1)
|
|
130
|
+
) {
|
|
131
|
+
delete style[key];
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
switch (key) {
|
|
136
|
+
// booleans
|
|
137
|
+
case "snapToPixel":
|
|
138
|
+
style.snapToPixel = boolishValue(
|
|
139
|
+
declarationValueValue as BoolishStyleValue,
|
|
140
|
+
);
|
|
141
|
+
break;
|
|
142
|
+
|
|
143
|
+
case "rotateWithView":
|
|
144
|
+
style.rotateWithView = boolishValue(
|
|
145
|
+
declarationValueValue as BoolishStyleValue,
|
|
146
|
+
);
|
|
147
|
+
break;
|
|
148
|
+
|
|
149
|
+
// allow space separated double value (x and y)
|
|
150
|
+
//case 'size':
|
|
151
|
+
// style.size = declarationValueValue ? declarationValueValue.split(' ').map(part => parseFloat(part)) : style.size;
|
|
152
|
+
// break;
|
|
153
|
+
|
|
154
|
+
case "sizeX":
|
|
155
|
+
style.size = style.size || [0, 0];
|
|
156
|
+
style.size[0] = numberValue(declarationValueValue);
|
|
157
|
+
break;
|
|
158
|
+
|
|
159
|
+
case "sizeY":
|
|
160
|
+
style.size = style.size || [0, 0];
|
|
161
|
+
style.size[1] = numberValue(declarationValueValue);
|
|
162
|
+
break;
|
|
163
|
+
|
|
164
|
+
// allow space separated double value (x and y)
|
|
165
|
+
//case 'imgSize':
|
|
166
|
+
// style.imgSize = declarationValueValue ? declarationValueValue.split(' ').map(part => parseFloat(part)) : style.imgSize;
|
|
167
|
+
// break;
|
|
168
|
+
|
|
169
|
+
case "imgSizeX":
|
|
170
|
+
style.imgSize = style.imgSize || [0, 0];
|
|
171
|
+
style.imgSize[0] = numberValue(declarationValueValue);
|
|
172
|
+
break;
|
|
173
|
+
|
|
174
|
+
case "imgSizeY":
|
|
175
|
+
style.imgSize = style.imgSize || [0, 0];
|
|
176
|
+
style.imgSize[1] = numberValue(declarationValueValue);
|
|
177
|
+
break;
|
|
178
|
+
|
|
179
|
+
case "anchorX":
|
|
180
|
+
style.anchor = style.anchor || [0, 0];
|
|
181
|
+
style.anchor[0] = numberValue(declarationValueValue);
|
|
182
|
+
style.anchorXUnits = unitFromAnchorValue(
|
|
183
|
+
declarationValueValue as UnitStyleValue,
|
|
184
|
+
);
|
|
185
|
+
break;
|
|
186
|
+
|
|
187
|
+
case "anchorY":
|
|
188
|
+
style.anchor = style.anchor || [0, 0];
|
|
189
|
+
style.anchor[1] = numberValue(declarationValueValue);
|
|
190
|
+
style.anchorYUnits = unitFromAnchorValue(
|
|
191
|
+
declarationValueValue as UnitStyleValue,
|
|
192
|
+
);
|
|
193
|
+
break;
|
|
194
|
+
|
|
195
|
+
// can be directly (offsetX in ol.style.Text or offset array in ol.style.Icon)
|
|
196
|
+
case "offsetX":
|
|
197
|
+
style.offset = style.offset || [0, 0];
|
|
198
|
+
style.offsetX = style.offset[0] = numberValue(
|
|
199
|
+
declarationValueValue,
|
|
200
|
+
);
|
|
201
|
+
break;
|
|
202
|
+
|
|
203
|
+
// can be directly (offsetY in ol.style.Text or offset array in ol.style.Icon)
|
|
204
|
+
case "offsetY":
|
|
205
|
+
style.offset = style.offset || [0, 0];
|
|
206
|
+
style.offsetY = style.offset[1] = numberValue(
|
|
207
|
+
declarationValueValue,
|
|
208
|
+
);
|
|
209
|
+
break;
|
|
210
|
+
|
|
211
|
+
case "colorRed":
|
|
212
|
+
style.color = style.color || [0, 0, 0, 1];
|
|
213
|
+
style.color[0] = intValue(declarationValueValue);
|
|
214
|
+
break;
|
|
215
|
+
|
|
216
|
+
case "colorGreen":
|
|
217
|
+
style.color = style.color || [0, 0, 0, 1];
|
|
218
|
+
style.color[1] = intValue(declarationValueValue);
|
|
219
|
+
break;
|
|
220
|
+
|
|
221
|
+
case "colorBlue":
|
|
222
|
+
style.color = style.color || [0, 0, 0, 1];
|
|
223
|
+
style.color[2] = intValue(declarationValueValue);
|
|
224
|
+
break;
|
|
225
|
+
|
|
226
|
+
case "colorAlpha":
|
|
227
|
+
style.color = style.color || [0, 0, 0, 1];
|
|
228
|
+
style.color[3] = numberValue(declarationValueValue);
|
|
229
|
+
break;
|
|
230
|
+
|
|
231
|
+
case "lineDash":
|
|
232
|
+
style.lineDash = numberArrayValue(
|
|
233
|
+
declarationValueValue as NumberArrayStyleValue,
|
|
234
|
+
);
|
|
235
|
+
break;
|
|
236
|
+
|
|
237
|
+
default:
|
|
238
|
+
style[key] = declarationValueValue;
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
const StyleCtor = constructorsMap[type] as
|
|
243
|
+
| (new (style: StyleLiteral) => Style)
|
|
244
|
+
| undefined;
|
|
245
|
+
return StyleCtor ? new StyleCtor(style) : null;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export default function declarationToStyle<StyleKey extends string = string>(
|
|
249
|
+
constructorsMap: Record<StyleKey, unknown>,
|
|
250
|
+
declaration: Readonly<RootStyleDeclaration | StyleDeclaration>,
|
|
251
|
+
type: StyleKey,
|
|
252
|
+
hash?: string,
|
|
253
|
+
cache: LRUCache<Style | null> = getDefaultCache(),
|
|
254
|
+
root = true,
|
|
255
|
+
): null | Style {
|
|
256
|
+
if (!constructorsMap[type]) {
|
|
257
|
+
console.error("Style unknown", type, declaration);
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const cacheHash =
|
|
262
|
+
type + HASH_STRING_DELIMITER + (hash || JSON.stringify(declaration));
|
|
263
|
+
if (!cache.containsKey(cacheHash)) {
|
|
264
|
+
cache.set(
|
|
265
|
+
cacheHash,
|
|
266
|
+
_declarationToStyle(
|
|
267
|
+
constructorsMap,
|
|
268
|
+
declaration,
|
|
269
|
+
type,
|
|
270
|
+
cache,
|
|
271
|
+
root,
|
|
272
|
+
),
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return cache.get(cacheHash);
|
|
277
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type {FeatureLike} from "ol/Feature";
|
|
2
|
+
import type Style from "ol/style/Style";
|
|
3
|
+
|
|
4
|
+
import type {StyleFunctionOptions} from "./createCachedStyleFunction";
|
|
5
|
+
|
|
6
|
+
export const STYLE_ENV_FIELD_NAME = "style";
|
|
7
|
+
|
|
8
|
+
// TODO: I dont really like this (here). Can we find a better way of
|
|
9
|
+
// defining the style function props/env?
|
|
10
|
+
type StatePrimitive = string | number | boolean | null | undefined;
|
|
11
|
+
type StateObject = {[key: string]: StateValue};
|
|
12
|
+
type StateArray = StateValue[];
|
|
13
|
+
type StateValue = StatePrimitive | StateObject | StateArray;
|
|
14
|
+
|
|
15
|
+
export type MapsightStyleFunctionEnv = {
|
|
16
|
+
[k: string]: StateValue;
|
|
17
|
+
[STYLE_ENV_FIELD_NAME]?: string;
|
|
18
|
+
};
|
|
19
|
+
export type MapsightStyleFunctionProps = {
|
|
20
|
+
[k: string]: StateValue;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type MapsightStyleFunction = (
|
|
24
|
+
env: MapsightStyleFunctionEnv,
|
|
25
|
+
feature: FeatureLike,
|
|
26
|
+
) => Array<Style> | Style | undefined;
|
|
27
|
+
|
|
28
|
+
export const createPropsFilter = (
|
|
29
|
+
allowedProps: StyleFunctionOptions["allowedProps"] = [],
|
|
30
|
+
) =>
|
|
31
|
+
allowedProps === false
|
|
32
|
+
? (props: MapsightStyleFunctionProps) => props
|
|
33
|
+
: function filterProps(props: MapsightStyleFunctionProps) {
|
|
34
|
+
const filteredProps: MapsightStyleFunctionProps = {};
|
|
35
|
+
allowedProps
|
|
36
|
+
.filter((key) => props[key])
|
|
37
|
+
.forEach((key) => {
|
|
38
|
+
filteredProps[key] = props[key];
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
return filteredProps;
|
|
42
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type {Extent} from "ol/extent";
|
|
2
|
+
import type TileGrid from "ol/tilegrid/TileGrid";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
assertNonNullable,
|
|
6
|
+
ensureNonNullable,
|
|
7
|
+
} from "@mapsight/lib-js/nonNullable";
|
|
8
|
+
|
|
9
|
+
export default function getTileUrlsForExtent(
|
|
10
|
+
tileGrid: TileGrid,
|
|
11
|
+
extent: Extent,
|
|
12
|
+
) {
|
|
13
|
+
assertNonNullable(extent[0]);
|
|
14
|
+
assertNonNullable(extent[1]);
|
|
15
|
+
assertNonNullable(extent[2]);
|
|
16
|
+
assertNonNullable(extent[3]);
|
|
17
|
+
|
|
18
|
+
const tileUrls: Array<string> = [];
|
|
19
|
+
for (let z = 17; z <= 21; z++) {
|
|
20
|
+
const leftBottom = tileGrid.getTileCoordForCoordAndZ(
|
|
21
|
+
[extent[0], extent[1]],
|
|
22
|
+
z,
|
|
23
|
+
);
|
|
24
|
+
const left = ensureNonNullable(leftBottom[1]);
|
|
25
|
+
const bottom = -ensureNonNullable(leftBottom[2]);
|
|
26
|
+
|
|
27
|
+
const rightTop = tileGrid.getTileCoordForCoordAndZ(
|
|
28
|
+
[extent[2], extent[3]],
|
|
29
|
+
z,
|
|
30
|
+
);
|
|
31
|
+
const right = ensureNonNullable(rightTop[1]);
|
|
32
|
+
const top = -ensureNonNullable(rightTop[2]);
|
|
33
|
+
|
|
34
|
+
for (let x = left; x <= right; x += 1) {
|
|
35
|
+
for (let y = top; y <= bottom; y += 1) {
|
|
36
|
+
tileUrls.push(`${z}/${x}/${y}.png`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return tileUrls;
|
|
41
|
+
}
|