@geospatial-sdk/openlayers 0.0.5-dev.52 → 0.0.5-dev.54
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/dist/map/feature-hover.d.ts +1 -1
- package/dist/map/feature-hover.d.ts.map +1 -1
- package/dist/map/feature-hover.js +18 -8
- package/dist/map/feature-selection.d.ts +8 -0
- package/dist/map/feature-selection.d.ts.map +1 -0
- package/dist/map/feature-selection.js +76 -0
- package/dist/map/get-features.d.ts +5 -5
- package/dist/map/get-features.d.ts.map +1 -1
- package/dist/map/get-features.js +8 -6
- package/dist/map/layer-update.d.ts.map +1 -1
- package/dist/map/layer-update.js +11 -3
- package/dist/map/listen.d.ts +4 -0
- package/dist/map/listen.d.ts.map +1 -0
- package/dist/map/listen.js +83 -0
- package/dist/map/register-events.d.ts +1 -1
- package/dist/map/register-events.d.ts.map +1 -1
- package/dist/map/register-events.js +5 -2
- package/dist/map/resolved-map-state.d.ts +8 -0
- package/dist/map/resolved-map-state.d.ts.map +1 -0
- package/dist/map/resolved-map-state.js +26 -0
- package/dist/map/styles.d.ts +16 -0
- package/dist/map/styles.d.ts.map +1 -0
- package/dist/map/styles.js +77 -0
- package/dist/resolved-state/resolved-map-state.d.ts +2 -0
- package/dist/resolved-state/resolved-map-state.d.ts.map +1 -0
- package/dist/resolved-state/resolved-map-state.js +1 -0
- package/lib/map/feature-hover.ts +28 -10
- package/lib/map/get-features.test.ts +2 -1
- package/lib/map/get-features.ts +15 -11
- package/lib/map/layer-update.test.ts +8 -3
- package/lib/map/layer-update.ts +15 -6
- package/lib/map/register-events.ts +11 -5
- package/package.json +3 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type OlMap from "ol/Map.js";
|
|
2
1
|
import VectorLayer from "ol/layer/Vector.js";
|
|
2
|
+
import type OlMap from "ol/Map.js";
|
|
3
3
|
import VectorSource from "ol/source/Vector.js";
|
|
4
4
|
export declare function initHoverLayer(map: OlMap): void;
|
|
5
5
|
export declare function getHoverLayer(map: OlMap): VectorLayer<VectorSource>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-hover.d.ts","sourceRoot":"","sources":["../../lib/map/feature-hover.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"feature-hover.d.ts","sourceRoot":"","sources":["../../lib/map/feature-hover.ts"],"names":[],"mappings":"AAQA,OAAO,WAAW,MAAM,oBAAoB,CAAC;AAC7C,OAAO,KAAK,KAAK,MAAM,WAAW,CAAC;AAEnC,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAO/C,wBAAgB,cAAc,CAAC,GAAG,EAAE,KAAK,QAoGxC;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,KAAK,GAAG,WAAW,CAAC,YAAY,CAAC,CAEnE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,KAAK,QAMzC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { GEOSPATIAL_SDK_PREFIX } from "./constants.js";
|
|
2
|
-
import VectorLayer from "ol/layer/Vector.js";
|
|
3
|
-
import VectorSource from "ol/source/Vector.js";
|
|
4
1
|
import { defaultHighlightStyle, FeaturesHoverEventType, } from "@geospatial-sdk/core";
|
|
5
2
|
import OlFeature from "ol/Feature.js";
|
|
3
|
+
import VectorLayer from "ol/layer/Vector.js";
|
|
6
4
|
import { unByKey } from "ol/Observable.js";
|
|
5
|
+
import VectorSource from "ol/source/Vector.js";
|
|
6
|
+
import { GEOSPATIAL_SDK_PREFIX } from "./constants.js";
|
|
7
7
|
import { readFeaturesAtPixel } from "./get-features.js";
|
|
8
8
|
const hoverLayerKey = `${GEOSPATIAL_SDK_PREFIX}hover-layer`;
|
|
9
9
|
const unsubscribeKey = `${GEOSPATIAL_SDK_PREFIX}hover-unsub`;
|
|
@@ -18,12 +18,16 @@ export function initHoverLayer(map) {
|
|
|
18
18
|
useSpatialIndex: false,
|
|
19
19
|
}),
|
|
20
20
|
style: defaultHighlightStyle,
|
|
21
|
+
properties: {
|
|
22
|
+
[`${GEOSPATIAL_SDK_PREFIX}hoverable`]: false,
|
|
23
|
+
[`${GEOSPATIAL_SDK_PREFIX}clickable`]: false,
|
|
24
|
+
},
|
|
21
25
|
});
|
|
22
26
|
map.set(hoverLayerKey, hoverLayer);
|
|
23
27
|
hoverLayer.setMap(map);
|
|
24
28
|
// store original cursor style in order to change it later
|
|
25
29
|
const originalCursorStyle = map.getTargetElement()?.style.cursor ?? "";
|
|
26
|
-
const layerFilter = (layer) => layer
|
|
30
|
+
const layerFilter = (layer) => layer.get(`${GEOSPATIAL_SDK_PREFIX}hoverable`);
|
|
27
31
|
const unKey = map.on("pointermove", async (event) => {
|
|
28
32
|
// skip hit detection if the view is moving as it can have an impact on performance
|
|
29
33
|
if (map.getView().getInteracting() || map.getView().getAnimating()) {
|
|
@@ -44,18 +48,24 @@ export function initHoverLayer(map) {
|
|
|
44
48
|
return;
|
|
45
49
|
}
|
|
46
50
|
// add hovered feature to the layer
|
|
47
|
-
|
|
48
|
-
map.forEachFeatureAtPixel(event.pixel, (feature) => {
|
|
51
|
+
const hoveredFeatureResult = [];
|
|
52
|
+
map.forEachFeatureAtPixel(event.pixel, (feature, layer) => {
|
|
49
53
|
if (feature instanceof OlFeature) {
|
|
50
|
-
|
|
54
|
+
hoveredFeatureResult.push({ feature, layer });
|
|
51
55
|
return true;
|
|
52
56
|
}
|
|
53
57
|
}, {
|
|
54
58
|
layerFilter,
|
|
55
59
|
});
|
|
56
|
-
if (
|
|
60
|
+
if (hoveredFeatureResult.length === 0) {
|
|
57
61
|
return;
|
|
58
62
|
}
|
|
63
|
+
const { feature: firstFeature, layer: sourceLayer } = hoveredFeatureResult[0];
|
|
64
|
+
// Get the hoverStyle from the source layer, fallback to defaultHighlightStyle
|
|
65
|
+
const hoverStyle = sourceLayer.get(`${GEOSPATIAL_SDK_PREFIX}hover-style`) ??
|
|
66
|
+
defaultHighlightStyle;
|
|
67
|
+
// Apply the hover style to the layer (FlatStyleLike works on layers, not features)
|
|
68
|
+
hoverLayer.setStyle(hoverStyle);
|
|
59
69
|
hoveredSource.addFeature(firstFeature);
|
|
60
70
|
// dispatch event if subscribed to
|
|
61
71
|
if (map.get(FeaturesHoverEventType)) {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type OlMap from "ol/Map.js";
|
|
2
|
+
import VectorLayer from "ol/layer/Vector.js";
|
|
3
|
+
import VectorSource from "ol/source/Vector.js";
|
|
4
|
+
export declare function initSelectionLayer(map: OlMap): void;
|
|
5
|
+
export declare function getSelectionLayer(map: OlMap): VectorLayer<VectorSource>;
|
|
6
|
+
export declare function clearSelectionLayer(map: OlMap): void;
|
|
7
|
+
export declare function clearSelection(map: OlMap): void;
|
|
8
|
+
//# sourceMappingURL=feature-selection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-selection.d.ts","sourceRoot":"","sources":["../../lib/map/feature-selection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,WAAW,CAAC;AACnC,OAAO,WAAW,MAAM,oBAAoB,CAAC;AAC7C,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAU/C,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,KAAK,QAqE5C;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,KAAK,GAAG,WAAW,CAAC,YAAY,CAAC,CAEvE;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,KAAK,QAM7C;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,KAAK,QAQxC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { GEOSPATIAL_SDK_PREFIX } from "./constants.js";
|
|
2
|
+
import VectorLayer from "ol/layer/Vector.js";
|
|
3
|
+
import VectorSource from "ol/source/Vector.js";
|
|
4
|
+
import { defaultHighlightStyle } from "@geospatial-sdk/core";
|
|
5
|
+
import OlFeature from "ol/Feature.js";
|
|
6
|
+
import { unByKey } from "ol/Observable.js";
|
|
7
|
+
const selectionLayerKey = `${GEOSPATIAL_SDK_PREFIX}selection-layer`;
|
|
8
|
+
const unsubscribeKey = `${GEOSPATIAL_SDK_PREFIX}selection-unsub`;
|
|
9
|
+
export function initSelectionLayer(map) {
|
|
10
|
+
if (map.get(selectionLayerKey)) {
|
|
11
|
+
clearSelectionLayer(map);
|
|
12
|
+
}
|
|
13
|
+
// create layer & add on top of everything else
|
|
14
|
+
const selectionLayer = new VectorLayer({
|
|
15
|
+
source: new VectorSource({
|
|
16
|
+
features: [],
|
|
17
|
+
useSpatialIndex: false,
|
|
18
|
+
}),
|
|
19
|
+
style: defaultHighlightStyle,
|
|
20
|
+
});
|
|
21
|
+
map.set(selectionLayerKey, selectionLayer);
|
|
22
|
+
selectionLayer.setMap(map);
|
|
23
|
+
const layerFilter = (layer) => layer !== selectionLayer &&
|
|
24
|
+
layer.get(`${GEOSPATIAL_SDK_PREFIX}enable-selection`);
|
|
25
|
+
const unKey = map.on("click", async (event) => {
|
|
26
|
+
const selectedSource = selectionLayer.getSource();
|
|
27
|
+
selectedSource.clear(true);
|
|
28
|
+
// Check if there's a feature at the clicked pixel
|
|
29
|
+
const hasFeature = map.hasFeatureAtPixel(event.pixel, {
|
|
30
|
+
layerFilter,
|
|
31
|
+
});
|
|
32
|
+
if (!hasFeature) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
// Find the selected feature and its source layer
|
|
36
|
+
const selectedFeatureResult = [];
|
|
37
|
+
map.forEachFeatureAtPixel(event.pixel, (feature, layer) => {
|
|
38
|
+
if (feature instanceof OlFeature) {
|
|
39
|
+
selectedFeatureResult.push({ feature, layer });
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
}, {
|
|
43
|
+
layerFilter,
|
|
44
|
+
});
|
|
45
|
+
if (selectedFeatureResult.length === 0) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const { feature: firstFeature, layer: sourceLayer } = selectedFeatureResult[0];
|
|
49
|
+
// Get the selectedStyle from the source layer, fallback to defaultHighlightStyle
|
|
50
|
+
const selectedStyle = sourceLayer.get(`${GEOSPATIAL_SDK_PREFIX}selected-style`) ??
|
|
51
|
+
defaultHighlightStyle;
|
|
52
|
+
// Apply the selected style to the layer (FlatStyleLike works on layers, not features)
|
|
53
|
+
selectionLayer.setStyle(selectedStyle);
|
|
54
|
+
selectedSource.addFeature(firstFeature);
|
|
55
|
+
});
|
|
56
|
+
map.set(unsubscribeKey, unKey);
|
|
57
|
+
}
|
|
58
|
+
export function getSelectionLayer(map) {
|
|
59
|
+
return map.get(selectionLayerKey);
|
|
60
|
+
}
|
|
61
|
+
export function clearSelectionLayer(map) {
|
|
62
|
+
const selectionLayer = getSelectionLayer(map);
|
|
63
|
+
selectionLayer.setMap(null);
|
|
64
|
+
selectionLayer.dispose();
|
|
65
|
+
map.set(selectionLayerKey, null);
|
|
66
|
+
unByKey(map.get(unsubscribeKey));
|
|
67
|
+
}
|
|
68
|
+
export function clearSelection(map) {
|
|
69
|
+
const selectionLayer = getSelectionLayer(map);
|
|
70
|
+
if (selectionLayer) {
|
|
71
|
+
const source = selectionLayer.getSource();
|
|
72
|
+
if (source) {
|
|
73
|
+
source.clear(true);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Pixel } from "ol/pixel.js";
|
|
3
|
-
import TileWMS from "ol/source/TileWMS.js";
|
|
4
|
-
import ImageWMS from "ol/source/ImageWMS.js";
|
|
1
|
+
import type { FeaturesByLayerIndex } from "@geospatial-sdk/core";
|
|
5
2
|
import { Coordinate } from "ol/coordinate.js";
|
|
6
3
|
import Layer from "ol/layer/Layer.js";
|
|
4
|
+
import OlMap from "ol/Map.js";
|
|
7
5
|
import type MapBrowserEvent from "ol/MapBrowserEvent.js";
|
|
8
|
-
import
|
|
6
|
+
import { Pixel } from "ol/pixel.js";
|
|
7
|
+
import ImageWMS from "ol/source/ImageWMS.js";
|
|
8
|
+
import TileWMS from "ol/source/TileWMS.js";
|
|
9
9
|
export declare function getFeaturesFromVectorSources(olMap: OlMap, pixel: Pixel, layerFilter?: (layer: Layer) => boolean): FeaturesByLayerIndex;
|
|
10
10
|
export declare function getGFIUrl(source: TileWMS | ImageWMS, map: OlMap, coordinate: Coordinate): string | null;
|
|
11
11
|
export declare function getFeaturesFromWmsSources(olMap: OlMap, coordinate: Coordinate, layerFilter?: (layer: Layer) => boolean): Promise<FeaturesByLayerIndex>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-features.d.ts","sourceRoot":"","sources":["../../lib/map/get-features.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"get-features.d.ts","sourceRoot":"","sources":["../../lib/map/get-features.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAGjE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,OAAO,KAAK,MAAM,mBAAmB,CAAC;AACtC,OAAO,KAAK,MAAM,WAAW,CAAC;AAC9B,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,QAAQ,MAAM,uBAAuB,CAAC;AAC7C,OAAO,OAAO,MAAM,sBAAsB,CAAC;AAI3C,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,EACZ,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,GACtC,oBAAoB,CAyBtB;AAED,wBAAgB,SAAS,CACvB,MAAM,EAAE,OAAO,GAAG,QAAQ,EAC1B,GAAG,EAAE,KAAK,EACV,UAAU,EAAE,UAAU,GACrB,MAAM,GAAG,IAAI,CAWf;AAED,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,UAAU,EACtB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,GACtC,OAAO,CAAC,oBAAoB,CAAC,CAsC/B;AAOD,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,KAAK,EACV,KAAK,EAAE,eAAe,CAAC,YAAY,CAAC,EACpC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,GACtC,OAAO,CAAC,oBAAoB,CAAC,CAS/B"}
|
package/dist/map/get-features.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import throttle from "lodash.throttle";
|
|
1
2
|
import GeoJSON from "ol/format/GeoJSON.js";
|
|
2
|
-
import TileWMS from "ol/source/TileWMS.js";
|
|
3
|
-
import ImageWMS from "ol/source/ImageWMS.js";
|
|
4
3
|
import Layer from "ol/layer/Layer.js";
|
|
5
|
-
import
|
|
4
|
+
import ImageWMS from "ol/source/ImageWMS.js";
|
|
5
|
+
import TileWMS from "ol/source/TileWMS.js";
|
|
6
6
|
const GEOJSON = new GeoJSON();
|
|
7
7
|
export function getFeaturesFromVectorSources(olMap, pixel, layerFilter) {
|
|
8
8
|
const result = new Map();
|
|
@@ -16,9 +16,11 @@ export function getFeaturesFromVectorSources(olMap, pixel, layerFilter) {
|
|
|
16
16
|
if (!result.has(layerIndex)) {
|
|
17
17
|
result.set(layerIndex, []);
|
|
18
18
|
}
|
|
19
|
-
result
|
|
20
|
-
.
|
|
21
|
-
|
|
19
|
+
result.get(layerIndex).push(GEOJSON.writeFeatureObject(feature, {
|
|
20
|
+
featureProjection: olMap.getView().getProjection(),
|
|
21
|
+
dataProjection: "EPSG:4326",
|
|
22
|
+
}));
|
|
23
|
+
return null;
|
|
22
24
|
}, { layerFilter });
|
|
23
25
|
return result;
|
|
24
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layer-update.d.ts","sourceRoot":"","sources":["../../lib/map/layer-update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAKhE,OAAO,KAAK,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"layer-update.d.ts","sourceRoot":"","sources":["../../lib/map/layer-update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAKhE,OAAO,KAAK,MAAM,mBAAmB,CAAC;AAsBtC;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,eAAe,GACxB,OAAO,CAIT;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,KAAK,EACd,kBAAkB,CAAC,EAAE,eAAe,QAiDrC"}
|
package/dist/map/layer-update.js
CHANGED
|
@@ -7,8 +7,10 @@ const UPDATABLE_PROPERTIES = [
|
|
|
7
7
|
"attributions",
|
|
8
8
|
"extras",
|
|
9
9
|
"version",
|
|
10
|
-
"
|
|
10
|
+
"hoverable",
|
|
11
|
+
"clickable",
|
|
11
12
|
"style",
|
|
13
|
+
"hoverStyle",
|
|
12
14
|
// TODO (when available) "zIndex"
|
|
13
15
|
];
|
|
14
16
|
/**
|
|
@@ -58,8 +60,14 @@ export function updateLayerProperties(layerModel, olLayer, previousLayerModel) {
|
|
|
58
60
|
if (shouldApplyProperty("label")) {
|
|
59
61
|
olLayer.set("label", layerModel.label);
|
|
60
62
|
}
|
|
61
|
-
if (shouldApplyProperty("
|
|
62
|
-
olLayer.set(`${GEOSPATIAL_SDK_PREFIX}
|
|
63
|
+
if (shouldApplyProperty("hoverable")) {
|
|
64
|
+
olLayer.set(`${GEOSPATIAL_SDK_PREFIX}hoverable`, layerModel.hoverable);
|
|
65
|
+
}
|
|
66
|
+
if (shouldApplyProperty("hoverStyle")) {
|
|
67
|
+
olLayer.set(`${GEOSPATIAL_SDK_PREFIX}hover-style`, layerModel.hoverStyle);
|
|
68
|
+
}
|
|
69
|
+
if (shouldApplyProperty("clickable")) {
|
|
70
|
+
olLayer.set(`${GEOSPATIAL_SDK_PREFIX}clickable`, layerModel.clickable);
|
|
63
71
|
}
|
|
64
72
|
if (shouldApplyProperty("style") &&
|
|
65
73
|
"setStyle" in olLayer) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listen.d.ts","sourceRoot":"","sources":["../../lib/map/listen.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,WAAW,CAAC;AAG5B,OAAO,EAKL,eAAe,EAShB,MAAM,sBAAsB,CAAC;AA8B9B,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,eAAe,EACpD,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,IAAI,QA+E9C"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { toLonLat } from "ol/proj.js";
|
|
2
|
+
import { FeaturesClickEventType, FeaturesHoverEventType, MapClickEventType, MapExtentChangeEventType, MapLayerStateChangeEventType, MapStateChangeEventType, MapViewStateChangeEventType, SourceLoadErrorType, } from "@geospatial-sdk/core";
|
|
3
|
+
import { GEOSPATIAL_SDK_PREFIX } from "./constants.js";
|
|
4
|
+
import { registerFeatureClickEvent, registerFeatureHoverEvent, registerMapLayerStateChangeEvent, registerMapViewStateChangeEvent, } from "./register-events.js";
|
|
5
|
+
function addEventListener(map, eventType, callback) {
|
|
6
|
+
map.on(`${GEOSPATIAL_SDK_PREFIX}${eventType}`, ({ target: _target, ...event }) =>
|
|
7
|
+
// we're excluding the `target` property and renaming the `type` here
|
|
8
|
+
callback({
|
|
9
|
+
...event,
|
|
10
|
+
type: eventType,
|
|
11
|
+
}));
|
|
12
|
+
}
|
|
13
|
+
export function listen(map, eventType, callback) {
|
|
14
|
+
switch (eventType) {
|
|
15
|
+
case FeaturesClickEventType:
|
|
16
|
+
registerFeatureClickEvent(map);
|
|
17
|
+
addEventListener(map, eventType, callback);
|
|
18
|
+
break;
|
|
19
|
+
case FeaturesHoverEventType:
|
|
20
|
+
registerFeatureHoverEvent(map);
|
|
21
|
+
addEventListener(map, eventType, callback);
|
|
22
|
+
break;
|
|
23
|
+
case MapClickEventType:
|
|
24
|
+
map.on("click", (event) => {
|
|
25
|
+
const coordinate = toLonLat(event.coordinate, map.getView().getProjection());
|
|
26
|
+
callback({
|
|
27
|
+
type: MapClickEventType,
|
|
28
|
+
coordinate,
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
break;
|
|
32
|
+
case MapViewStateChangeEventType:
|
|
33
|
+
registerMapViewStateChangeEvent(map);
|
|
34
|
+
addEventListener(map, eventType, callback);
|
|
35
|
+
break;
|
|
36
|
+
case MapLayerStateChangeEventType:
|
|
37
|
+
registerMapLayerStateChangeEvent(map);
|
|
38
|
+
addEventListener(map, eventType, callback);
|
|
39
|
+
break;
|
|
40
|
+
case MapStateChangeEventType:
|
|
41
|
+
// TODO: registerMapStateChangeEvent(map);
|
|
42
|
+
addEventListener(map, eventType, callback);
|
|
43
|
+
break;
|
|
44
|
+
/**
|
|
45
|
+
* DEPRECATED
|
|
46
|
+
*/
|
|
47
|
+
case MapExtentChangeEventType:
|
|
48
|
+
registerMapViewStateChangeEvent(map);
|
|
49
|
+
map.on(`${GEOSPATIAL_SDK_PREFIX}${MapViewStateChangeEventType}`, (event) => callback({
|
|
50
|
+
type: MapExtentChangeEventType,
|
|
51
|
+
extent: event.viewState.extent,
|
|
52
|
+
}));
|
|
53
|
+
break;
|
|
54
|
+
case SourceLoadErrorType: {
|
|
55
|
+
const errorCallback = (event) => {
|
|
56
|
+
callback(event);
|
|
57
|
+
};
|
|
58
|
+
//attach event listener to all existing layers
|
|
59
|
+
map.getLayers().forEach((layer) => {
|
|
60
|
+
if (layer) {
|
|
61
|
+
layer.on(SourceLoadErrorType, errorCallback);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
//attach event listener when layer is added
|
|
65
|
+
map.getLayers().on("add", (event) => {
|
|
66
|
+
const layer = event.element;
|
|
67
|
+
if (layer) {
|
|
68
|
+
layer.on(SourceLoadErrorType, errorCallback);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
//remove event listener when layer is removed
|
|
72
|
+
map.getLayers().on("remove", (event) => {
|
|
73
|
+
const layer = event.element;
|
|
74
|
+
if (layer) {
|
|
75
|
+
layer.un(SourceLoadErrorType, errorCallback);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
default:
|
|
81
|
+
throw new Error(`Unrecognized event type: ${eventType}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import Map from "ol/Map.js";
|
|
2
1
|
import { MapEventsByType } from "@geospatial-sdk/core";
|
|
2
|
+
import Map from "ol/Map.js";
|
|
3
3
|
export declare function listen<T extends keyof MapEventsByType>(map: Map, eventType: T, callback: (event: MapEventsByType[T]) => void): void;
|
|
4
4
|
//# sourceMappingURL=register-events.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-events.d.ts","sourceRoot":"","sources":["../../lib/map/register-events.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"register-events.d.ts","sourceRoot":"","sources":["../../lib/map/register-events.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,eAAe,EAGhB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,GAA4B,MAAM,WAAW,CAAC;AA+DrD,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,eAAe,EACpD,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,IAAI,QA0E9C"}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { FeaturesClickEventType, FeaturesHoverEventType, MapClickEventType, MapExtentChangeEventType, SourceLoadErrorType, } from "@geospatial-sdk/core";
|
|
2
|
-
import { toLonLat, transformExtent } from "ol/proj.js";
|
|
3
2
|
import { equals } from "ol/extent.js";
|
|
3
|
+
import { toLonLat, transformExtent } from "ol/proj.js";
|
|
4
|
+
import { GEOSPATIAL_SDK_PREFIX } from "./constants.js";
|
|
4
5
|
import { readFeaturesAtPixel } from "./get-features.js";
|
|
5
6
|
function registerFeatureClickEvent(map) {
|
|
6
7
|
if (map.get(FeaturesClickEventType))
|
|
7
8
|
return;
|
|
9
|
+
// Filter to only query clickable layers
|
|
10
|
+
const layerFilter = (layer) => layer.get(`${GEOSPATIAL_SDK_PREFIX}clickable`) !== false;
|
|
8
11
|
map.on("click", async (event) => {
|
|
9
|
-
const featuresByLayer = await readFeaturesAtPixel(map, event);
|
|
12
|
+
const featuresByLayer = await readFeaturesAtPixel(map, event, layerFilter);
|
|
10
13
|
const features = Array.from(featuresByLayer.values()).flat();
|
|
11
14
|
map.dispatchEvent({
|
|
12
15
|
type: FeaturesClickEventType,
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import Map from "ol/Map.js";
|
|
2
|
+
import { ResolvedMapViewState } from "@geospatial-sdk/core";
|
|
3
|
+
/**
|
|
4
|
+
* Reads the current view state of the map.
|
|
5
|
+
* @param map
|
|
6
|
+
*/
|
|
7
|
+
export declare function readMapViewState(map: Map): ResolvedMapViewState;
|
|
8
|
+
//# sourceMappingURL=resolved-map-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolved-map-state.d.ts","sourceRoot":"","sources":["../../lib/map/resolved-map-state.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,WAAW,CAAC;AAE5B,OAAO,EAAsB,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAOhF;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,GAAG,oBAAoB,CAwB/D"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { transform as transformCoordinate, transformExtent } from "ol/proj.js";
|
|
2
|
+
/**
|
|
3
|
+
* This magic value is generally used across OGC services as a reasonable approximation for most displays
|
|
4
|
+
*/
|
|
5
|
+
const PIXEL_SIZE_MM = 0.28;
|
|
6
|
+
/**
|
|
7
|
+
* Reads the current view state of the map.
|
|
8
|
+
* @param map
|
|
9
|
+
*/
|
|
10
|
+
export function readMapViewState(map) {
|
|
11
|
+
const view = map.getView();
|
|
12
|
+
const projection = view.getProjection();
|
|
13
|
+
const extent = transformExtent(view.calculateExtent(map.getSize()), projection, "EPSG:4326");
|
|
14
|
+
const center = transformCoordinate(view.getCenter() ?? [0, 0], projection, "EPSG:4326");
|
|
15
|
+
const resolution = view.getResolution() ?? 1;
|
|
16
|
+
const metersPerUnit = projection.getMetersPerUnit() ?? 1;
|
|
17
|
+
const scaleDenominator = metersPerUnit * resolution * (1000 / PIXEL_SIZE_MM);
|
|
18
|
+
const bearing = view.getRotation() * (180 / Math.PI) + 90; // by default, bearing is North
|
|
19
|
+
return {
|
|
20
|
+
center,
|
|
21
|
+
extent,
|
|
22
|
+
resolution,
|
|
23
|
+
scaleDenominator,
|
|
24
|
+
bearing,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Style } from "ol/style.js";
|
|
2
|
+
import { StyleFunction } from "ol/style/Style.js";
|
|
3
|
+
export interface CreateStyleOptions {
|
|
4
|
+
color: string;
|
|
5
|
+
isFocused?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface StyleByGeometryType {
|
|
8
|
+
line: Style | Style[];
|
|
9
|
+
polygon: Style | Style[];
|
|
10
|
+
point: Style | Style[];
|
|
11
|
+
}
|
|
12
|
+
export declare function createGeometryStyles(options: CreateStyleOptions): StyleByGeometryType;
|
|
13
|
+
export declare function createStyleFunction(styleByGeometryType: StyleByGeometryType): StyleFunction;
|
|
14
|
+
export declare const defaultStyle: StyleFunction;
|
|
15
|
+
export declare const defaultHighlightStyle: StyleFunction;
|
|
16
|
+
//# sourceMappingURL=styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../lib/map/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAIlD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,KAAK,GAAG,KAAK,EAAE,CAAC;IACtB,OAAO,EAAE,KAAK,GAAG,KAAK,EAAE,CAAC;IACzB,KAAK,EAAE,KAAK,GAAG,KAAK,EAAE,CAAC;CACxB;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,kBAAkB,GAC1B,mBAAmB,CA4CrB;AAED,wBAAgB,mBAAmB,CACjC,mBAAmB,EAAE,mBAAmB,GACvC,aAAa,CAmBf;AAMD,eAAO,MAAM,YAAY,eAIxB,CAAC;AAEF,eAAO,MAAM,qBAAqB,eAKjC,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Circle, Fill, Stroke, Style } from "ol/style.js";
|
|
2
|
+
import chroma from "chroma-js";
|
|
3
|
+
export function createGeometryStyles(options) {
|
|
4
|
+
const { color, isFocused } = options;
|
|
5
|
+
const zIndex = isFocused ? 10 : undefined;
|
|
6
|
+
return {
|
|
7
|
+
polygon: new Style({
|
|
8
|
+
fill: new Fill({
|
|
9
|
+
color: computeTransparentFillColor(color),
|
|
10
|
+
}),
|
|
11
|
+
stroke: new Stroke({
|
|
12
|
+
color: "white",
|
|
13
|
+
width: 2,
|
|
14
|
+
}),
|
|
15
|
+
zIndex,
|
|
16
|
+
}),
|
|
17
|
+
point: new Style({
|
|
18
|
+
image: new Circle({
|
|
19
|
+
fill: new Fill({
|
|
20
|
+
color,
|
|
21
|
+
}),
|
|
22
|
+
stroke: new Stroke({
|
|
23
|
+
color: "white",
|
|
24
|
+
width: isFocused ? 3 : 2,
|
|
25
|
+
}),
|
|
26
|
+
radius: isFocused ? 8 : 7,
|
|
27
|
+
}),
|
|
28
|
+
zIndex,
|
|
29
|
+
}),
|
|
30
|
+
line: [
|
|
31
|
+
new Style({
|
|
32
|
+
stroke: new Stroke({
|
|
33
|
+
color: "white",
|
|
34
|
+
width: isFocused ? 8 : 6,
|
|
35
|
+
}),
|
|
36
|
+
zIndex,
|
|
37
|
+
}),
|
|
38
|
+
new Style({
|
|
39
|
+
stroke: new Stroke({
|
|
40
|
+
color,
|
|
41
|
+
width: isFocused ? 3 : 2,
|
|
42
|
+
}),
|
|
43
|
+
zIndex,
|
|
44
|
+
}),
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export function createStyleFunction(styleByGeometryType) {
|
|
49
|
+
return (feature) => {
|
|
50
|
+
const geometryType = feature?.getGeometry()?.getType();
|
|
51
|
+
switch (geometryType) {
|
|
52
|
+
case "LinearRing":
|
|
53
|
+
case "LineString":
|
|
54
|
+
case "MultiLineString":
|
|
55
|
+
return styleByGeometryType.line;
|
|
56
|
+
case "Point":
|
|
57
|
+
case "MultiPoint":
|
|
58
|
+
return styleByGeometryType.point;
|
|
59
|
+
case "Circle":
|
|
60
|
+
case "Polygon":
|
|
61
|
+
case "MultiPolygon":
|
|
62
|
+
return styleByGeometryType.polygon;
|
|
63
|
+
default:
|
|
64
|
+
return styleByGeometryType.point;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function computeTransparentFillColor(color, alpha = 0.25) {
|
|
69
|
+
return chroma(color).alpha(alpha).css();
|
|
70
|
+
}
|
|
71
|
+
export const defaultStyle = createStyleFunction(createGeometryStyles({
|
|
72
|
+
color: "blue",
|
|
73
|
+
}));
|
|
74
|
+
export const defaultHighlightStyle = createStyleFunction(createGeometryStyles({
|
|
75
|
+
color: "red",
|
|
76
|
+
isFocused: true,
|
|
77
|
+
}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolved-map-state.d.ts","sourceRoot":"","sources":["../../lib/resolved-state/resolved-map-state.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/lib/map/feature-hover.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { GEOSPATIAL_SDK_PREFIX } from "./constants.js";
|
|
2
|
-
import type OlMap from "ol/Map.js";
|
|
3
|
-
import VectorLayer from "ol/layer/Vector.js";
|
|
4
|
-
import VectorSource from "ol/source/Vector.js";
|
|
5
1
|
import {
|
|
6
2
|
defaultHighlightStyle,
|
|
7
3
|
FeaturesHoverEventType,
|
|
8
4
|
} from "@geospatial-sdk/core";
|
|
9
|
-
import type BaseEvent from "ol/events/Event.js";
|
|
10
5
|
import { MapBrowserEvent } from "ol";
|
|
6
|
+
import type BaseEvent from "ol/events/Event.js";
|
|
11
7
|
import OlFeature from "ol/Feature.js";
|
|
12
8
|
import type BaseLayer from "ol/layer/Base.js";
|
|
9
|
+
import VectorLayer from "ol/layer/Vector.js";
|
|
10
|
+
import type OlMap from "ol/Map.js";
|
|
13
11
|
import { unByKey } from "ol/Observable.js";
|
|
12
|
+
import VectorSource from "ol/source/Vector.js";
|
|
13
|
+
import { GEOSPATIAL_SDK_PREFIX } from "./constants.js";
|
|
14
14
|
import { readFeaturesAtPixel } from "./get-features.js";
|
|
15
15
|
|
|
16
16
|
const hoverLayerKey = `${GEOSPATIAL_SDK_PREFIX}hover-layer`;
|
|
@@ -28,6 +28,10 @@ export function initHoverLayer(map: OlMap) {
|
|
|
28
28
|
useSpatialIndex: false,
|
|
29
29
|
}),
|
|
30
30
|
style: defaultHighlightStyle,
|
|
31
|
+
properties: {
|
|
32
|
+
[`${GEOSPATIAL_SDK_PREFIX}hoverable`]: false,
|
|
33
|
+
[`${GEOSPATIAL_SDK_PREFIX}clickable`]: false,
|
|
34
|
+
},
|
|
31
35
|
});
|
|
32
36
|
map.set(hoverLayerKey, hoverLayer);
|
|
33
37
|
hoverLayer.setMap(map);
|
|
@@ -36,7 +40,7 @@ export function initHoverLayer(map: OlMap) {
|
|
|
36
40
|
const originalCursorStyle = map.getTargetElement()?.style.cursor ?? "";
|
|
37
41
|
|
|
38
42
|
const layerFilter = (layer: BaseLayer) =>
|
|
39
|
-
layer
|
|
43
|
+
layer.get(`${GEOSPATIAL_SDK_PREFIX}hoverable`);
|
|
40
44
|
|
|
41
45
|
const unKey = map.on(
|
|
42
46
|
"pointermove",
|
|
@@ -63,12 +67,15 @@ export function initHoverLayer(map: OlMap) {
|
|
|
63
67
|
}
|
|
64
68
|
|
|
65
69
|
// add hovered feature to the layer
|
|
66
|
-
|
|
70
|
+
const hoveredFeatureResult: {
|
|
71
|
+
feature: OlFeature;
|
|
72
|
+
layer: BaseLayer;
|
|
73
|
+
}[] = [];
|
|
67
74
|
map.forEachFeatureAtPixel(
|
|
68
75
|
event.pixel,
|
|
69
|
-
(feature) => {
|
|
76
|
+
(feature, layer) => {
|
|
70
77
|
if (feature instanceof OlFeature) {
|
|
71
|
-
|
|
78
|
+
hoveredFeatureResult.push({ feature, layer });
|
|
72
79
|
return true;
|
|
73
80
|
}
|
|
74
81
|
},
|
|
@@ -76,9 +83,20 @@ export function initHoverLayer(map: OlMap) {
|
|
|
76
83
|
layerFilter,
|
|
77
84
|
},
|
|
78
85
|
);
|
|
79
|
-
if (
|
|
86
|
+
if (hoveredFeatureResult.length === 0) {
|
|
80
87
|
return;
|
|
81
88
|
}
|
|
89
|
+
|
|
90
|
+
const { feature: firstFeature, layer: sourceLayer } =
|
|
91
|
+
hoveredFeatureResult[0];
|
|
92
|
+
|
|
93
|
+
// Get the hoverStyle from the source layer, fallback to defaultHighlightStyle
|
|
94
|
+
const hoverStyle =
|
|
95
|
+
sourceLayer.get(`${GEOSPATIAL_SDK_PREFIX}hover-style`) ??
|
|
96
|
+
defaultHighlightStyle;
|
|
97
|
+
|
|
98
|
+
// Apply the hover style to the layer (FlatStyleLike works on layers, not features)
|
|
99
|
+
hoverLayer.setStyle(hoverStyle);
|
|
82
100
|
hoveredSource.addFeature(firstFeature);
|
|
83
101
|
|
|
84
102
|
// dispatch event if subscribed to
|
|
@@ -12,6 +12,7 @@ import VectorLayer from "ol/layer/Vector.js";
|
|
|
12
12
|
import VectorSource from "ol/source/Vector.js";
|
|
13
13
|
import View from "ol/View.js";
|
|
14
14
|
import { Collection, Object as BaseObject } from "ol";
|
|
15
|
+
import { toLonLat } from "ol/proj.js";
|
|
15
16
|
|
|
16
17
|
const gfiResult = {
|
|
17
18
|
type: "Feature",
|
|
@@ -86,7 +87,7 @@ describe("get features utils", () => {
|
|
|
86
87
|
[
|
|
87
88
|
{
|
|
88
89
|
geometry: {
|
|
89
|
-
coordinates: [100, 200],
|
|
90
|
+
coordinates: toLonLat([100, 200]),
|
|
90
91
|
type: "Point",
|
|
91
92
|
},
|
|
92
93
|
properties: null,
|
package/lib/map/get-features.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
import OlMap from "ol/Map.js";
|
|
3
|
-
import { Pixel } from "ol/pixel.js";
|
|
1
|
+
import type { FeaturesByLayerIndex } from "@geospatial-sdk/core";
|
|
4
2
|
import type { Feature, FeatureCollection } from "geojson";
|
|
5
|
-
import
|
|
6
|
-
import TileWMS from "ol/source/TileWMS.js";
|
|
7
|
-
import ImageWMS from "ol/source/ImageWMS.js";
|
|
3
|
+
import throttle from "lodash.throttle";
|
|
8
4
|
import { Coordinate } from "ol/coordinate.js";
|
|
5
|
+
import OlFeature from "ol/Feature.js";
|
|
6
|
+
import GeoJSON from "ol/format/GeoJSON.js";
|
|
9
7
|
import Layer from "ol/layer/Layer.js";
|
|
10
|
-
import
|
|
8
|
+
import OlMap from "ol/Map.js";
|
|
11
9
|
import type MapBrowserEvent from "ol/MapBrowserEvent.js";
|
|
12
|
-
import
|
|
10
|
+
import { Pixel } from "ol/pixel.js";
|
|
11
|
+
import ImageWMS from "ol/source/ImageWMS.js";
|
|
12
|
+
import TileWMS from "ol/source/TileWMS.js";
|
|
13
13
|
|
|
14
14
|
const GEOJSON = new GeoJSON();
|
|
15
15
|
|
|
@@ -31,9 +31,13 @@ export function getFeaturesFromVectorSources(
|
|
|
31
31
|
if (!result.has(layerIndex)) {
|
|
32
32
|
result.set(layerIndex, []);
|
|
33
33
|
}
|
|
34
|
-
result
|
|
35
|
-
.
|
|
36
|
-
|
|
34
|
+
result.get(layerIndex)!.push(
|
|
35
|
+
GEOJSON.writeFeatureObject(feature as OlFeature, {
|
|
36
|
+
featureProjection: olMap.getView().getProjection(),
|
|
37
|
+
dataProjection: "EPSG:4326",
|
|
38
|
+
}),
|
|
39
|
+
);
|
|
40
|
+
return null;
|
|
37
41
|
},
|
|
38
42
|
{ layerFilter },
|
|
39
43
|
);
|
|
@@ -116,7 +116,7 @@ describe("Layer update utils", () => {
|
|
|
116
116
|
expect(olLayer.set).toHaveBeenCalledWith("label", "Test Layer");
|
|
117
117
|
});
|
|
118
118
|
|
|
119
|
-
it("
|
|
119
|
+
it("enable interaction-related props without recreating them", async () => {
|
|
120
120
|
// mocking a vector layer
|
|
121
121
|
(olLayer as VectorLayer).setStyle = vi.fn();
|
|
122
122
|
|
|
@@ -125,7 +125,8 @@ describe("Layer update utils", () => {
|
|
|
125
125
|
style: {
|
|
126
126
|
"circle-fill-color": "blue",
|
|
127
127
|
},
|
|
128
|
-
|
|
128
|
+
hoverable: true,
|
|
129
|
+
clickable: false,
|
|
129
130
|
};
|
|
130
131
|
const prevLayerModel = SAMPLE_LAYER3;
|
|
131
132
|
updateLayerProperties(layerModel, olLayer, prevLayerModel);
|
|
@@ -133,9 +134,13 @@ describe("Layer update utils", () => {
|
|
|
133
134
|
layerModel.style,
|
|
134
135
|
);
|
|
135
136
|
expect(olLayer.set).toHaveBeenCalledWith(
|
|
136
|
-
"--geospatial-sdk-
|
|
137
|
+
"--geospatial-sdk-hoverable",
|
|
137
138
|
true,
|
|
138
139
|
);
|
|
140
|
+
expect(olLayer.set).toHaveBeenCalledWith(
|
|
141
|
+
"--geospatial-sdk-clickable",
|
|
142
|
+
false,
|
|
143
|
+
);
|
|
139
144
|
});
|
|
140
145
|
});
|
|
141
146
|
});
|
package/lib/map/layer-update.ts
CHANGED
|
@@ -4,8 +4,9 @@ import {
|
|
|
4
4
|
MapContextLayerVector,
|
|
5
5
|
} from "@geospatial-sdk/core/lib/model/map-context.js";
|
|
6
6
|
import Layer from "ol/layer/Layer.js";
|
|
7
|
-
import { GEOSPATIAL_SDK_PREFIX } from "./constants.js";
|
|
8
7
|
import VectorLayer from "ol/layer/Vector.js";
|
|
8
|
+
import type VectorSource from "ol/source/Vector.js";
|
|
9
|
+
import { GEOSPATIAL_SDK_PREFIX } from "./constants.js";
|
|
9
10
|
|
|
10
11
|
const UPDATABLE_PROPERTIES: (
|
|
11
12
|
| keyof MapContextBaseLayer
|
|
@@ -17,8 +18,10 @@ const UPDATABLE_PROPERTIES: (
|
|
|
17
18
|
"attributions",
|
|
18
19
|
"extras",
|
|
19
20
|
"version",
|
|
20
|
-
"
|
|
21
|
+
"hoverable",
|
|
22
|
+
"clickable",
|
|
21
23
|
"style",
|
|
24
|
+
"hoverStyle",
|
|
22
25
|
// TODO (when available) "zIndex"
|
|
23
26
|
];
|
|
24
27
|
|
|
@@ -79,17 +82,23 @@ export function updateLayerProperties(
|
|
|
79
82
|
if (shouldApplyProperty("label")) {
|
|
80
83
|
olLayer.set("label", layerModel.label);
|
|
81
84
|
}
|
|
82
|
-
if (shouldApplyProperty("
|
|
85
|
+
if (shouldApplyProperty("hoverable")) {
|
|
86
|
+
olLayer.set(`${GEOSPATIAL_SDK_PREFIX}hoverable`, layerModel.hoverable);
|
|
87
|
+
}
|
|
88
|
+
if (shouldApplyProperty("hoverStyle" as keyof MapContextLayer)) {
|
|
83
89
|
olLayer.set(
|
|
84
|
-
`${GEOSPATIAL_SDK_PREFIX}
|
|
85
|
-
(layerModel as MapContextLayerVector).
|
|
90
|
+
`${GEOSPATIAL_SDK_PREFIX}hover-style`,
|
|
91
|
+
(layerModel as MapContextLayerVector).hoverStyle,
|
|
86
92
|
);
|
|
87
93
|
}
|
|
94
|
+
if (shouldApplyProperty("clickable" as keyof MapContextLayer)) {
|
|
95
|
+
olLayer.set(`${GEOSPATIAL_SDK_PREFIX}clickable`, layerModel.clickable);
|
|
96
|
+
}
|
|
88
97
|
if (
|
|
89
98
|
shouldApplyProperty("style" as keyof MapContextLayer) &&
|
|
90
99
|
"setStyle" in olLayer
|
|
91
100
|
) {
|
|
92
|
-
(olLayer as VectorLayer).setStyle(
|
|
101
|
+
(olLayer as VectorLayer<VectorSource>).setStyle(
|
|
93
102
|
(layerModel as MapContextLayerVector).style,
|
|
94
103
|
);
|
|
95
104
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import Map, { MapObjectEventTypes } from "ol/Map.js";
|
|
2
1
|
import {
|
|
3
2
|
FeaturesClickEventType,
|
|
4
3
|
FeaturesHoverEventType,
|
|
@@ -7,18 +6,25 @@ import {
|
|
|
7
6
|
MapExtentChangeEventType,
|
|
8
7
|
SourceLoadErrorType,
|
|
9
8
|
} from "@geospatial-sdk/core";
|
|
10
|
-
import { toLonLat, transformExtent } from "ol/proj.js";
|
|
11
9
|
import BaseEvent from "ol/events/Event.js";
|
|
12
|
-
import Layer from "ol/layer/Layer.js";
|
|
13
|
-
import { BaseLayerObjectEventTypes } from "ol/layer/Base.js";
|
|
14
10
|
import { equals } from "ol/extent.js";
|
|
11
|
+
import type BaseLayer from "ol/layer/Base.js";
|
|
12
|
+
import { BaseLayerObjectEventTypes } from "ol/layer/Base.js";
|
|
13
|
+
import Layer from "ol/layer/Layer.js";
|
|
14
|
+
import Map, { MapObjectEventTypes } from "ol/Map.js";
|
|
15
|
+
import { toLonLat, transformExtent } from "ol/proj.js";
|
|
16
|
+
import { GEOSPATIAL_SDK_PREFIX } from "./constants.js";
|
|
15
17
|
import { readFeaturesAtPixel } from "./get-features.js";
|
|
16
18
|
|
|
17
19
|
function registerFeatureClickEvent(map: Map) {
|
|
18
20
|
if (map.get(FeaturesClickEventType)) return;
|
|
19
21
|
|
|
22
|
+
// Filter to only query clickable layers
|
|
23
|
+
const layerFilter = (layer: BaseLayer) =>
|
|
24
|
+
layer.get(`${GEOSPATIAL_SDK_PREFIX}clickable`) !== false;
|
|
25
|
+
|
|
20
26
|
map.on("click", async (event: any) => {
|
|
21
|
-
const featuresByLayer = await readFeaturesAtPixel(map, event);
|
|
27
|
+
const featuresByLayer = await readFeaturesAtPixel(map, event, layerFilter);
|
|
22
28
|
const features = Array.from(featuresByLayer.values()).flat();
|
|
23
29
|
map.dispatchEvent({
|
|
24
30
|
type: FeaturesClickEventType,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geospatial-sdk/openlayers",
|
|
3
|
-
"version": "0.0.5-dev.
|
|
3
|
+
"version": "0.0.5-dev.54+352b554",
|
|
4
4
|
"description": "OpenLayers-related utilities",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ol",
|
|
@@ -37,10 +37,9 @@
|
|
|
37
37
|
"ol": ">9.x"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@geospatial-sdk/core": "^0.0.5-dev.
|
|
41
|
-
"chroma-js": "^2.4.2",
|
|
40
|
+
"@geospatial-sdk/core": "^0.0.5-dev.54+352b554",
|
|
42
41
|
"lodash.throttle": "^4.1.1",
|
|
43
42
|
"ol-mapbox-style": "12.4.0"
|
|
44
43
|
},
|
|
45
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "352b554ec0ca6a27dee923a28b4b1bb4e3f12973"
|
|
46
45
|
}
|