@geospatial-sdk/openlayers 0.0.5-dev.54 → 0.0.5-dev.56
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/apply-context-diff.d.ts.map +1 -1
- package/dist/map/apply-context-diff.js +9 -1
- package/dist/map/create-map.d.ts +1 -1
- package/dist/map/create-map.d.ts.map +1 -1
- package/dist/map/create-map.js +73 -30
- package/dist/map/feature-hover.js +1 -1
- package/dist/map/handle-errors.d.ts +0 -7
- package/dist/map/handle-errors.d.ts.map +1 -1
- package/dist/map/handle-errors.js +10 -14
- package/dist/map/index.d.ts +2 -1
- package/dist/map/index.d.ts.map +1 -1
- package/dist/map/index.js +2 -1
- package/dist/map/layer-update.d.ts.map +1 -1
- package/dist/map/layer-update.js +1 -1
- package/dist/map/listen.d.ts.map +1 -1
- package/dist/map/listen.js +13 -26
- package/dist/map/register-events.d.ts +16 -2
- package/dist/map/register-events.d.ts.map +1 -1
- package/dist/map/register-events.js +172 -81
- package/lib/map/apply-context-diff.ts +16 -5
- package/lib/map/create-map.test.ts +172 -60
- package/lib/map/create-map.ts +100 -37
- package/lib/map/feature-hover.ts +1 -1
- package/lib/map/handle-errors.test.ts +13 -36
- package/lib/map/handle-errors.ts +10 -28
- package/lib/map/index.ts +2 -1
- package/lib/map/layer-update.ts +3 -2
- package/lib/map/listen.test.ts +977 -0
- package/lib/map/listen.ts +123 -0
- package/lib/map/register-events.ts +229 -109
- package/lib/map/resolved-map-state.ts +38 -0
- package/package.json +3 -3
- package/dist/map/feature-selection.d.ts +0 -8
- package/dist/map/feature-selection.d.ts.map +0 -1
- package/dist/map/feature-selection.js +0 -76
- package/dist/map/styles.d.ts +0 -16
- package/dist/map/styles.d.ts.map +0 -1
- package/dist/map/styles.js +0 -77
- package/dist/resolved-state/resolved-map-state.d.ts +0 -2
- package/dist/resolved-state/resolved-map-state.d.ts.map +0 -1
- package/dist/resolved-state/resolved-map-state.js +0 -1
- package/lib/map/register-events.test.ts +0 -259
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { FeaturesClickEventType, FeaturesHoverEventType,
|
|
1
|
+
import { FeaturesClickEventType, FeaturesHoverEventType, LayerCreationErrorEventType, LayerLoadingErrorEventType, MapLayerStateChangeEventType, MapStateChangeEventType, MapViewStateChangeEventType, SourceLoadErrorEvent, SourceLoadErrorType, } from "@geospatial-sdk/core";
|
|
2
|
+
import { readFeaturesAtPixel } from "./get-features.js";
|
|
2
3
|
import { equals } from "ol/extent.js";
|
|
3
|
-
import {
|
|
4
|
+
import { readMapViewState } from "./resolved-map-state.js";
|
|
4
5
|
import { GEOSPATIAL_SDK_PREFIX } from "./constants.js";
|
|
5
|
-
|
|
6
|
-
function registerFeatureClickEvent(map) {
|
|
6
|
+
export function registerFeatureClickEvent(map) {
|
|
7
7
|
if (map.get(FeaturesClickEventType))
|
|
8
8
|
return;
|
|
9
9
|
// Filter to only query clickable layers
|
|
@@ -12,99 +12,190 @@ function registerFeatureClickEvent(map) {
|
|
|
12
12
|
const featuresByLayer = await readFeaturesAtPixel(map, event, layerFilter);
|
|
13
13
|
const features = Array.from(featuresByLayer.values()).flat();
|
|
14
14
|
map.dispatchEvent({
|
|
15
|
-
type: FeaturesClickEventType
|
|
15
|
+
type: `${GEOSPATIAL_SDK_PREFIX}${FeaturesClickEventType}`,
|
|
16
16
|
features,
|
|
17
17
|
featuresByLayer,
|
|
18
18
|
});
|
|
19
19
|
});
|
|
20
20
|
map.set(FeaturesClickEventType, true);
|
|
21
21
|
}
|
|
22
|
-
function registerFeatureHoverEvent(map) {
|
|
22
|
+
export function registerFeatureHoverEvent(map) {
|
|
23
23
|
if (map.get(FeaturesHoverEventType))
|
|
24
24
|
return;
|
|
25
25
|
map.set(FeaturesHoverEventType, true);
|
|
26
26
|
}
|
|
27
|
-
function
|
|
28
|
-
if (map.get(
|
|
27
|
+
export function registerMapLayerStateChangeEvent(map) {
|
|
28
|
+
if (map.get(MapLayerStateChangeEventType))
|
|
29
29
|
return;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
map.set(MapLayerStateChangeEventType, true);
|
|
31
|
+
}
|
|
32
|
+
export function emitLayerCreationError(layer, error) {
|
|
33
|
+
layer.dispatchEvent({
|
|
34
|
+
type: `${GEOSPATIAL_SDK_PREFIX}${LayerCreationErrorEventType}`,
|
|
35
|
+
error,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
export function emitLayerLoadingStatusLoading(layer) {
|
|
39
|
+
layer.dispatchEvent({
|
|
40
|
+
type: `${GEOSPATIAL_SDK_PREFIX}layer-loading-status`,
|
|
41
|
+
layerState: { loading: true },
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
export function emitLayerLoadingStatusSuccess(layer) {
|
|
45
|
+
layer.dispatchEvent({
|
|
46
|
+
type: `${GEOSPATIAL_SDK_PREFIX}layer-loading-status`,
|
|
47
|
+
layerState: { loaded: true },
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
export function emitLayerLoadingError(layer, error, httpStatus) {
|
|
51
|
+
layer.dispatchEvent({
|
|
52
|
+
type: `${GEOSPATIAL_SDK_PREFIX}${LayerLoadingErrorEventType}`,
|
|
53
|
+
error,
|
|
54
|
+
...(httpStatus !== undefined ? { httpStatus } : {}),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
export function emitLayerDataInfo(layer, dataInfo) {
|
|
58
|
+
layer.dispatchEvent({
|
|
59
|
+
type: `${GEOSPATIAL_SDK_PREFIX}layer-data-info`,
|
|
60
|
+
layerState: dataInfo,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
export function propagateLayerStateChangeEventToMap(map, layer) {
|
|
64
|
+
let currentLayerState = {
|
|
65
|
+
created: true,
|
|
66
|
+
};
|
|
67
|
+
let currentLoadingStatus = {};
|
|
68
|
+
function updateStateAndEmit() {
|
|
69
|
+
if (!map.get(MapLayerStateChangeEventType)) {
|
|
35
70
|
return;
|
|
36
71
|
}
|
|
37
|
-
|
|
72
|
+
const layerIndex = map.getLayers().getArray().indexOf(layer);
|
|
38
73
|
map.dispatchEvent({
|
|
39
|
-
type:
|
|
40
|
-
|
|
74
|
+
type: `${GEOSPATIAL_SDK_PREFIX}${MapLayerStateChangeEventType}`,
|
|
75
|
+
layerState: {
|
|
76
|
+
...currentLayerState,
|
|
77
|
+
...currentLoadingStatus,
|
|
78
|
+
},
|
|
79
|
+
layerIndex,
|
|
41
80
|
});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
81
|
+
}
|
|
82
|
+
// on layer creation error update layer state and redispatch on map
|
|
83
|
+
layer.on(`${GEOSPATIAL_SDK_PREFIX}${LayerCreationErrorEventType}`, (event) => {
|
|
84
|
+
currentLayerState = {
|
|
85
|
+
creationError: true,
|
|
86
|
+
creationErrorMessage: event.error.message,
|
|
87
|
+
};
|
|
88
|
+
updateStateAndEmit();
|
|
89
|
+
if (map.get(LayerCreationErrorEventType)) {
|
|
90
|
+
map.dispatchEvent(event);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
// on layer loading error update layer state and redispatch on map
|
|
94
|
+
layer.on(`${GEOSPATIAL_SDK_PREFIX}${LayerLoadingErrorEventType}`, (event) => {
|
|
95
|
+
currentLoadingStatus = {
|
|
96
|
+
loadingError: true,
|
|
97
|
+
loadingErrorMessage: event.error.message,
|
|
98
|
+
...(event.httpStatus !== undefined && {
|
|
99
|
+
loadingErrorHttpStatus: event.httpStatus,
|
|
100
|
+
}),
|
|
101
|
+
};
|
|
102
|
+
updateStateAndEmit();
|
|
103
|
+
if (map.get(LayerLoadingErrorEventType)) {
|
|
104
|
+
map.dispatchEvent(event);
|
|
105
|
+
}
|
|
106
|
+
// deprecated event
|
|
107
|
+
if (map.get(SourceLoadErrorType)) {
|
|
108
|
+
const sourceLoadEvent = new SourceLoadErrorEvent(event.error);
|
|
109
|
+
if (event.httpStatus) {
|
|
110
|
+
sourceLoadEvent.httpStatus = event.httpStatus;
|
|
111
|
+
}
|
|
112
|
+
map.dispatchEvent(sourceLoadEvent);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
// When new information about a layer state is available, add it to the previous state & emit
|
|
116
|
+
layer.on(`${GEOSPATIAL_SDK_PREFIX}layer-data-info`, (event) => {
|
|
117
|
+
currentLayerState = {
|
|
118
|
+
...currentLayerState,
|
|
119
|
+
...event.layerState,
|
|
120
|
+
};
|
|
121
|
+
updateStateAndEmit();
|
|
122
|
+
});
|
|
123
|
+
// loading state can change over time
|
|
124
|
+
layer.on(`${GEOSPATIAL_SDK_PREFIX}layer-loading-status`, (event) => {
|
|
125
|
+
currentLoadingStatus = event.layerState;
|
|
126
|
+
updateStateAndEmit();
|
|
127
|
+
});
|
|
48
128
|
}
|
|
49
|
-
export function
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
map.on("click", (event) => {
|
|
67
|
-
const coordinate = toLonLat(event.coordinate, map.getView().getProjection());
|
|
68
|
-
callback({
|
|
69
|
-
type: "map-click",
|
|
70
|
-
coordinate,
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
break;
|
|
74
|
-
case MapExtentChangeEventType:
|
|
75
|
-
registerMapExtentChangeEvent(map);
|
|
76
|
-
// see comment above
|
|
77
|
-
map.on(eventType, (event) => {
|
|
78
|
-
callback(event);
|
|
79
|
-
});
|
|
80
|
-
break;
|
|
81
|
-
case SourceLoadErrorType: {
|
|
82
|
-
const errorCallback = (event) => {
|
|
83
|
-
callback(event);
|
|
84
|
-
};
|
|
85
|
-
//attach event listener to all existing layers
|
|
86
|
-
map.getLayers().forEach((layer) => {
|
|
87
|
-
if (layer) {
|
|
88
|
-
layer.on(SourceLoadErrorType, errorCallback);
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
//attach event listener when layer is added
|
|
92
|
-
map.getLayers().on("add", (event) => {
|
|
93
|
-
const layer = event.element;
|
|
94
|
-
if (layer) {
|
|
95
|
-
layer.on(SourceLoadErrorType, errorCallback);
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
//remove event listener when layer is removed
|
|
99
|
-
map.getLayers().on("remove", (event) => {
|
|
100
|
-
const layer = event.element;
|
|
101
|
-
if (layer) {
|
|
102
|
-
layer.un(SourceLoadErrorType, errorCallback);
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
break;
|
|
129
|
+
export function registerMapStateChangeEvent(map) {
|
|
130
|
+
if (map.get(MapStateChangeEventType))
|
|
131
|
+
return;
|
|
132
|
+
// the global map state requires both view and layers state
|
|
133
|
+
registerMapLayerStateChangeEvent(map);
|
|
134
|
+
registerMapViewStateChangeEvent(map);
|
|
135
|
+
let currentState = {
|
|
136
|
+
layers: [],
|
|
137
|
+
view: null,
|
|
138
|
+
};
|
|
139
|
+
function emitState() {
|
|
140
|
+
// we're making sure to have the right amount of layers in the state and to fill empty slots with null
|
|
141
|
+
currentState.layers.length = map.getLayers().getLength();
|
|
142
|
+
for (let i = 0; i < currentState.layers.length; i++) {
|
|
143
|
+
if (!currentState.layers[i]) {
|
|
144
|
+
currentState.layers[i] = null;
|
|
145
|
+
}
|
|
106
146
|
}
|
|
107
|
-
|
|
108
|
-
|
|
147
|
+
map.dispatchEvent({
|
|
148
|
+
type: `${GEOSPATIAL_SDK_PREFIX}${MapStateChangeEventType}`,
|
|
149
|
+
mapState: currentState,
|
|
150
|
+
});
|
|
109
151
|
}
|
|
152
|
+
// collect view and layer states to re-emit them as a global state
|
|
153
|
+
map.on(`${GEOSPATIAL_SDK_PREFIX}${MapLayerStateChangeEventType}`, (event) => {
|
|
154
|
+
const layers = [...currentState.layers];
|
|
155
|
+
layers[event.layerIndex] = event.layerState;
|
|
156
|
+
currentState = { ...currentState, layers };
|
|
157
|
+
emitState();
|
|
158
|
+
});
|
|
159
|
+
map.on(`${GEOSPATIAL_SDK_PREFIX}${MapViewStateChangeEventType}`, (event) => {
|
|
160
|
+
currentState = { ...currentState, view: event.viewState };
|
|
161
|
+
emitState();
|
|
162
|
+
});
|
|
163
|
+
map.set(MapStateChangeEventType, true);
|
|
164
|
+
}
|
|
165
|
+
export function registerLayerCreationErrorEvent(map) {
|
|
166
|
+
if (map.get(LayerCreationErrorEventType))
|
|
167
|
+
return;
|
|
168
|
+
map.set(LayerCreationErrorEventType, true);
|
|
169
|
+
}
|
|
170
|
+
export function registerLayerLoadingErrorEvent(map) {
|
|
171
|
+
if (map.get(LayerLoadingErrorEventType))
|
|
172
|
+
return;
|
|
173
|
+
map.set(LayerLoadingErrorEventType, true);
|
|
174
|
+
}
|
|
175
|
+
// DEPRECATED EVENTS
|
|
176
|
+
export function registerMapViewStateChangeEvent(map) {
|
|
177
|
+
if (map.get(MapViewStateChangeEventType))
|
|
178
|
+
return;
|
|
179
|
+
let lastExtent = null;
|
|
180
|
+
const handleViewChange = () => {
|
|
181
|
+
const viewState = readMapViewState(map);
|
|
182
|
+
if (lastExtent && equals(lastExtent, viewState.extent)) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
lastExtent = viewState.extent;
|
|
186
|
+
map.dispatchEvent({
|
|
187
|
+
type: `${GEOSPATIAL_SDK_PREFIX}${MapViewStateChangeEventType}`,
|
|
188
|
+
viewState,
|
|
189
|
+
});
|
|
190
|
+
};
|
|
191
|
+
map.getView().on("change:center", handleViewChange);
|
|
192
|
+
map.getView().on("change:resolution", handleViewChange);
|
|
193
|
+
map.getView().on("change:rotation", handleViewChange);
|
|
194
|
+
map.on("change:size", handleViewChange);
|
|
195
|
+
map.set(MapViewStateChangeEventType, true);
|
|
196
|
+
}
|
|
197
|
+
export function registerSourceLoadErrorEvent(map) {
|
|
198
|
+
if (map.get(SourceLoadErrorType))
|
|
199
|
+
return;
|
|
200
|
+
map.set(SourceLoadErrorType, true);
|
|
110
201
|
}
|
|
@@ -4,6 +4,7 @@ import { createLayer, createView, updateLayerInMap } from "./create-map.js";
|
|
|
4
4
|
import { fromLonLat, transformExtent } from "ol/proj.js";
|
|
5
5
|
import GeoJSON from "ol/format/GeoJSON.js";
|
|
6
6
|
import SimpleGeometry from "ol/geom/SimpleGeometry.js";
|
|
7
|
+
import { propagateLayerStateChangeEventToMap } from "./register-events.js";
|
|
7
8
|
|
|
8
9
|
const GEOJSON = new GeoJSON();
|
|
9
10
|
|
|
@@ -35,12 +36,16 @@ export async function applyContextDiffToMap(
|
|
|
35
36
|
);
|
|
36
37
|
|
|
37
38
|
newLayers.forEach((layer, index) => {
|
|
39
|
+
if (!layer) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
38
42
|
const position = contextDiff.layersAdded[index].position;
|
|
39
43
|
if (position >= layers.getLength()) {
|
|
40
44
|
layers.push(layer);
|
|
41
45
|
} else {
|
|
42
46
|
layers.insertAt(position, layer);
|
|
43
47
|
}
|
|
48
|
+
propagateLayerStateChangeEventToMap(map, layer);
|
|
44
49
|
});
|
|
45
50
|
|
|
46
51
|
// move reordered layers (sorted by ascending new position)
|
|
@@ -59,12 +64,15 @@ export async function applyContextDiffToMap(
|
|
|
59
64
|
}
|
|
60
65
|
|
|
61
66
|
// update or recreate changed layers
|
|
67
|
+
const updatePromises = [];
|
|
62
68
|
for (const layerChanged of contextDiff.layersChanged) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
69
|
+
updatePromises.push(
|
|
70
|
+
updateLayerInMap(
|
|
71
|
+
map,
|
|
72
|
+
layerChanged.layer,
|
|
73
|
+
layerChanged.position,
|
|
74
|
+
layerChanged.previousLayer,
|
|
75
|
+
),
|
|
68
76
|
);
|
|
69
77
|
}
|
|
70
78
|
|
|
@@ -107,5 +115,8 @@ export async function applyContextDiffToMap(
|
|
|
107
115
|
}
|
|
108
116
|
}
|
|
109
117
|
|
|
118
|
+
// wait for all layers to have been updated
|
|
119
|
+
await Promise.all(updatePromises);
|
|
120
|
+
|
|
110
121
|
return map;
|
|
111
122
|
}
|