@masterportal/masterportalapi 2.19.2 → 2.20.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/CHANGELOG.md +18 -0
- package/example/config/services.json +42 -21
- package/example/index.js +111 -97
- package/jest.setup.js +15 -0
- package/package.json +3 -3
- package/src/index.js +2 -0
- package/src/layer/wfs.js +19 -0
- package/src/maps/interactions/drawInteractions.js +130 -0
- package/src/maps/ol/olMap.js +2 -2
- package/src/renderer/webgl.js +38 -77
- package/src/vectorStyle/createStyle.js +6 -11
- package/src/vectorStyle/styles/point/stylePoint.js +2 -2
- package/src/vectorStyle/styles/polygon/stylePolygon.js +2 -2
- package/src/vectorStyle/styles/style.js +8 -0
- package/src/vectorStyle/styles/styleCesium.js +2 -2
- package/src/vectorStyle/styles/styleLine.js +2 -2
- package/src/vectorStyle/styles/styleText.js +2 -2
- package/test/layer/wfs.test.js +52 -0
- package/test/maps/interactions/drawInteractions.test.js +50 -0
- package/test/renderer/webgl.test.js +0 -50
- package/test/vectorStyle/styles/point/stylePoint.test.js +7 -1
- package/test/vectorStyle/styles/polygon/stylePolygon.test.js +4 -1
- package/test/vectorStyle/styles/styleLine.test.js +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,11 +3,29 @@
|
|
|
3
3
|
|
|
4
4
|
The [Semantic Versioning](https://semver.org/spec/v2.0.0.html) is used.
|
|
5
5
|
|
|
6
|
+
## ## 2.20.0 - 2023-06-30
|
|
7
|
+
### Added
|
|
8
|
+
- Add draw interaction for interactive and static geometry types.
|
|
9
|
+
- WFS: Added function to load wfs features manually.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- The following packages have been updated:
|
|
13
|
+
- dependencies:
|
|
14
|
+
- ol: 7.3.0 to 7.4.0
|
|
15
|
+
- cesium: 1.95.0 to 1.106.0
|
|
16
|
+
- The examples in example/index.js are updated.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- VectorStyle: fixed several bugs of multiple geometries with styling rules.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
6
23
|
## 2.19.2 - 2023-06-12
|
|
7
24
|
### Fixed
|
|
8
25
|
- VectorStyle of multiple geometries with styling rules does not fail on not existing style.
|
|
9
26
|
|
|
10
27
|
---
|
|
28
|
+
|
|
11
29
|
## 2.19.1 - 2023-06-02
|
|
12
30
|
### Changed
|
|
13
31
|
- Exports in src/layer/wmts.js changed to export default {} to provide ES-Syntax.
|
|
@@ -135,32 +135,53 @@
|
|
|
135
135
|
},
|
|
136
136
|
{
|
|
137
137
|
"id": "6001",
|
|
138
|
-
"name": "
|
|
139
|
-
"
|
|
140
|
-
"epsg": "EPSG:25832",
|
|
138
|
+
"name": "ArcGIS VectorTile",
|
|
139
|
+
"shortname": "VectorTile",
|
|
141
140
|
"typ": "VectorTile",
|
|
141
|
+
"visibility": false,
|
|
142
|
+
"preview": {
|
|
143
|
+
"src": "./resources/vectorTile.png"
|
|
144
|
+
},
|
|
145
|
+
"gfiAttributes": "showAll",
|
|
146
|
+
"url": "https://test.geoportal-hamburg.de/vt/esri/tile/{z}/{y}/{x}.pbf",
|
|
147
|
+
"epsg": "EPSG:25832",
|
|
142
148
|
"extent": [
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
149
|
+
441336.2209999999,
|
|
150
|
+
5915995,
|
|
151
|
+
594002,
|
|
152
|
+
5986767.56699999981
|
|
153
|
+
],
|
|
154
|
+
"origin": [
|
|
155
|
+
-9497963.94293634221,
|
|
156
|
+
9997963.94293634221
|
|
147
157
|
],
|
|
148
158
|
"resolutions": [
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
159
|
+
39054.5466520950868,
|
|
160
|
+
19527.2733260475434,
|
|
161
|
+
9763.63666302377169,
|
|
162
|
+
4881.81833151188584,
|
|
163
|
+
2440.90916575594292,
|
|
164
|
+
1220.45458287797146,
|
|
165
|
+
610.227291438985731,
|
|
166
|
+
305.113645719492865,
|
|
167
|
+
152.556822859746433,
|
|
168
|
+
76.2784114298732163,
|
|
169
|
+
38.1392057149366082,
|
|
170
|
+
19.0696028574683041,
|
|
171
|
+
9.534801428734152,
|
|
172
|
+
4.767400714367076,
|
|
173
|
+
2.383700357183538,
|
|
174
|
+
1.191850178591769
|
|
161
175
|
],
|
|
162
|
-
"tileSize":
|
|
163
|
-
"
|
|
176
|
+
"tileSize": 512,
|
|
177
|
+
"vtStyles": [
|
|
178
|
+
{
|
|
179
|
+
"id": "VectorTile_STYLE",
|
|
180
|
+
"name": "Test",
|
|
181
|
+
"url": "https://test.geoportal-hamburg.de/vt/esri/resources/styles/root.json",
|
|
182
|
+
"defaultStyle": true
|
|
183
|
+
}
|
|
184
|
+
]
|
|
164
185
|
},
|
|
165
186
|
{
|
|
166
187
|
"id": "7001",
|
package/example/index.js
CHANGED
|
@@ -18,6 +18,7 @@ function errorCallback (errorEvent) {
|
|
|
18
18
|
console.error("This is an error event:", errorEvent);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
// Definitions:
|
|
21
22
|
//* Add elements to window to play with API in console
|
|
22
23
|
window.mpapi = {
|
|
23
24
|
...mpapi,
|
|
@@ -45,12 +46,12 @@ const hamburgServicesUrl = "https://geodienste.hamburg.de/services-internet.json
|
|
|
45
46
|
// eslint-disable-next-line func-style
|
|
46
47
|
getWfsStyleFunction = function () {
|
|
47
48
|
const styleId = "8712",
|
|
48
|
-
olLayer = window.mpapi.map
|
|
49
|
-
source = olLayer
|
|
49
|
+
olLayer = window.mpapi.map?.getLayers().getArray().find((element) => element.get("id") === "8712"),
|
|
50
|
+
source = olLayer?.getSource(),
|
|
50
51
|
styleObject = styleList.returnStyleObject(styleId);
|
|
51
52
|
let isClusterFeature = false;
|
|
52
53
|
|
|
53
|
-
if (styleObject !== undefined) {
|
|
54
|
+
if (styleObject !== undefined && source !== undefined) {
|
|
54
55
|
source.on("featuresloadend", event => {
|
|
55
56
|
event.features.forEach(element => {
|
|
56
57
|
isClusterFeature = false;
|
|
@@ -61,6 +62,9 @@ const hamburgServicesUrl = "https://geodienste.hamburg.de/services-internet.json
|
|
|
61
62
|
};
|
|
62
63
|
let map2D = null;
|
|
63
64
|
|
|
65
|
+
|
|
66
|
+
// Examples:
|
|
67
|
+
|
|
64
68
|
/* VectorStyle example */
|
|
65
69
|
// Example for using the vectorStyle that is now implemented in the masterportalAPI.
|
|
66
70
|
// Hardcoded to show the school layer "8712" as a wfs and "1534" as wfs with webgl renderer.
|
|
@@ -74,70 +78,8 @@ styleList.initializeStyleList({}, config, config.layers, undefined, (currentStyl
|
|
|
74
78
|
return currentStyleList;
|
|
75
79
|
});
|
|
76
80
|
|
|
77
|
-
// */
|
|
78
81
|
//* Cleans up map before it is re-rendered (happens on every save during dev mode)
|
|
79
82
|
document.getElementById(portalConfig.target).innerHTML = "";
|
|
80
|
-
// add a click-listener to button, that creates a 3D-map on click
|
|
81
|
-
document.getElementById("enable").addEventListener("click", function () {
|
|
82
|
-
if (window.mpapi.map2D === null) {
|
|
83
|
-
window.mpapi.map2D = window.mpapi.map;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (window.mpapi.map.mapMode === "3D") {
|
|
87
|
-
window.mpapi.map.setEnabled(false);
|
|
88
|
-
window.mpapi.map = window.mpapi.map2D;
|
|
89
|
-
window.mpapi.map.getView().setRotation(0);
|
|
90
|
-
document.getElementById("layer-visibility").style.display = "none";
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
const lib = portalConfig.cesiumLib ? portalConfig.cesiumLib : "https://geoportal-hamburg.de/mastercode/cesium/1_99/index.js";
|
|
94
|
-
|
|
95
|
-
document.getElementById("layer-visibility").style.display = "block";
|
|
96
|
-
|
|
97
|
-
load3DScriptModule.load3DScript(lib, function Loaded3DCallback () {
|
|
98
|
-
let tilesetLayer = null;
|
|
99
|
-
|
|
100
|
-
const settings3D = {
|
|
101
|
-
map2D: window.mpapi.map2D,
|
|
102
|
-
// set some options to Cesium scene
|
|
103
|
-
cesiumParameter: {
|
|
104
|
-
fxaa: true,
|
|
105
|
-
globe: {
|
|
106
|
-
enableLighting: true,
|
|
107
|
-
maximumScreenSpaceError: 2,
|
|
108
|
-
tileCacheSize: 20
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
},
|
|
112
|
-
map3D = mapsAPI.map.createMap(settings3D, "3D"),
|
|
113
|
-
rawLayerTerrain = rawLayerList.getLayerWhere({id: "4001"}),
|
|
114
|
-
rawLayerTileset = rawLayerList.getLayerWhere({id: "4002"}),
|
|
115
|
-
rawLayerEntities = rawLayerList.getLayerWhere({id: "4003"});
|
|
116
|
-
|
|
117
|
-
window.mpapi.map = map3D;
|
|
118
|
-
tilesetLayer = new mpapi.Tileset(rawLayerTileset, window.mpapi.map);
|
|
119
|
-
tilesetLayer.setVisible(true, window.mpapi.map);
|
|
120
|
-
|
|
121
|
-
// entities are 2 simple buildings in the park 'planten und blomen' near Tiergartenstraße
|
|
122
|
-
mpapi.entities.createLayer(rawLayerEntities, window.mpapi.map);
|
|
123
|
-
// mpapi.entities.setVisible(true, rawLayerEntities, window.mpapi.map);
|
|
124
|
-
|
|
125
|
-
mpapi.terrain.createLayer(rawLayerTerrain, window.mpapi.map);
|
|
126
|
-
mpapi.terrain.setVisible(true, rawLayerTerrain, window.mpapi.map);
|
|
127
|
-
|
|
128
|
-
window.mpapi.map.setEnabled(true);
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
// add a click-listener to button, that hides background layer in 3d
|
|
134
|
-
document.getElementById("layer-visibility").addEventListener("click", function () {
|
|
135
|
-
map2D.getLayers().forEach(layer => {
|
|
136
|
-
map2D.removeLayer(layer);
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
map2D = mapsAPI.map.createMap(config, "2D", {errorCallback});
|
|
141
83
|
|
|
142
84
|
//* geojson styling function call to override default styling and special wfs styling
|
|
143
85
|
mpapi.geojson.setCustomStyles({
|
|
@@ -167,7 +109,6 @@ const styleWfs = function (feature, resolution) {
|
|
|
167
109
|
};
|
|
168
110
|
|
|
169
111
|
services.find(({id}) => id === "3001").style = styleWfs;
|
|
170
|
-
// */
|
|
171
112
|
|
|
172
113
|
|
|
173
114
|
// eslint-disable-next-line
|
|
@@ -187,6 +128,8 @@ const styleOaf = function (feature, resolution) {
|
|
|
187
128
|
services.find(({id}) => id === "5001").style = styleOaf;
|
|
188
129
|
|
|
189
130
|
//* SYNCHRONOUS EXAMPLE: layerConf is known
|
|
131
|
+
// /*
|
|
132
|
+
map2D = mapsAPI.map.createMap(config, "2D", {errorCallback});
|
|
190
133
|
window.mpapi.map = map2D;
|
|
191
134
|
|
|
192
135
|
["2001", "2002", "1002", "3001", "5001"].forEach(id => window.mpapi.map.addLayer(id, {errorCallback}));
|
|
@@ -204,7 +147,8 @@ services
|
|
|
204
147
|
|
|
205
148
|
// */
|
|
206
149
|
|
|
207
|
-
|
|
150
|
+
//* ASYNCHRONOUS EXAMPLE 1: work with layerConf callback (for testing comment out SYNCHRONOUS EXAMPLE)
|
|
151
|
+
/*
|
|
208
152
|
document.getElementById("enable").style.display = "none";
|
|
209
153
|
mpapi.rawLayerList.initializeLayerList(hamburgServicesUrl,
|
|
210
154
|
conf => {
|
|
@@ -213,49 +157,34 @@ mpapi.rawLayerList.initializeLayerList(hamburgServicesUrl,
|
|
|
213
157
|
layerConf: conf,
|
|
214
158
|
layers: null
|
|
215
159
|
}, "2D");
|
|
216
|
-
["
|
|
160
|
+
["23420", "6074"].forEach(id => window.mpapi.map.addLayer(id));
|
|
217
161
|
});
|
|
218
|
-
|
|
162
|
+
*/
|
|
219
163
|
|
|
220
|
-
|
|
164
|
+
//* ASYNCHRONOUS EXAMPLE 2: work with createMap callback (for testing comment out SYNCHRONOUS EXAMPLE)
|
|
165
|
+
/*
|
|
221
166
|
document.getElementById("enable").style.display = "none";
|
|
222
167
|
window.mpapi.map = mapsAPI.map.createMap({
|
|
223
168
|
...portalConfig, layerConf: hamburgServicesUrl, layers: [
|
|
224
|
-
{id: "
|
|
169
|
+
{id: "23420"},
|
|
225
170
|
{id: "453", transparency: 50}
|
|
226
171
|
]}, "2D",
|
|
227
172
|
{
|
|
228
173
|
callback: () => ["6074"].forEach(id => window.mpapi.map.addLayer(id))
|
|
229
174
|
});
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
/* SEARCH FUNCTION EXAMPLE
|
|
233
|
-
// You may e.g. copy this code to the browser's console to run a search.
|
|
234
|
-
|
|
235
|
-
window.mpapi.search("Eiffe", {
|
|
236
|
-
map: window.mpapi.map,
|
|
237
|
-
zoom: true,
|
|
238
|
-
zoomToParams: {duration: 1000, maxZoom: 8},
|
|
239
|
-
searchStreets: true
|
|
240
|
-
}).then(x => console.log(x)).catch(e => console.error(e));
|
|
241
|
-
|
|
242
|
-
window.mpapi.search("Mümmelmannsberg 72", {
|
|
243
|
-
map: window.mpapi.map,
|
|
244
|
-
zoom: true,
|
|
245
|
-
zoomToParams: {duration: 1000, maxZoom: 8},
|
|
246
|
-
searchAddress: true
|
|
247
|
-
}).then(x => console.log(x)).catch(e => console.error(e));
|
|
175
|
+
*/
|
|
248
176
|
|
|
249
|
-
//*/
|
|
250
177
|
|
|
251
178
|
/* VECTOR TILE EXAMPLE */
|
|
252
179
|
/*
|
|
253
180
|
document.getElementById("enable").style.display = "none";
|
|
254
|
-
|
|
255
|
-
|
|
181
|
+
window.mpapi.map = mapsAPI.map.createMap(config, "2D", {errorCallback});
|
|
182
|
+
|
|
183
|
+
window.mpapi.map.getLayers().forEach(layer => {
|
|
184
|
+
window.mpapi.map.removeLayer(layer);
|
|
256
185
|
});
|
|
257
186
|
|
|
258
|
-
const vtStyleUrl = "https://
|
|
187
|
+
const vtStyleUrl = "https://test.geoportal-hamburg.de/vt/esri/resources/styles/root.json";
|
|
259
188
|
|
|
260
189
|
fetch(vtStyleUrl)
|
|
261
190
|
.then(response => response.json())
|
|
@@ -264,20 +193,105 @@ fetch(vtStyleUrl)
|
|
|
264
193
|
|
|
265
194
|
mpapi.vectorTile.setStyle(vtLayer, style, vtStyleUrl);
|
|
266
195
|
});
|
|
267
|
-
|
|
196
|
+
*/
|
|
268
197
|
|
|
269
198
|
/* WMTS example */
|
|
270
199
|
/*
|
|
271
|
-
|
|
272
|
-
|
|
200
|
+
window.mpapi.map = mapsAPI.map.createMap(config, "2D", {errorCallback});
|
|
201
|
+
|
|
202
|
+
window.mpapi.map.getLayers().forEach(layer => {
|
|
203
|
+
window.mpapi.map.removeLayer(layer);
|
|
273
204
|
});
|
|
274
205
|
window.mpapi.map.addLayer("7001");
|
|
275
206
|
window.mpapi.map.addLayer("7002");
|
|
276
207
|
window.mpapi.map.addLayer("7003");
|
|
277
|
-
|
|
208
|
+
//*/
|
|
278
209
|
|
|
279
210
|
/* VectorStyle example */
|
|
280
211
|
// Example for using the vectorStyle that is now implemented in the masterportalAPI.
|
|
281
212
|
// Apply style to layer "8172"
|
|
282
213
|
// mirrors behavior of Masterportal styling
|
|
283
214
|
getWfsStyleFunction();
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
/* SEARCH FUNCTION EXAMPLE
|
|
218
|
+
// You may e.g. copy this code to the browser's console to run a search.
|
|
219
|
+
|
|
220
|
+
window.mpapi.search("Eiffe", {
|
|
221
|
+
map: window.mpapi.map,
|
|
222
|
+
zoom: true,
|
|
223
|
+
zoomToParams: {duration: 1000, maxZoom: 8},
|
|
224
|
+
searchStreets: true
|
|
225
|
+
}).then(x => console.log(x)).catch(e => console.error(e));
|
|
226
|
+
|
|
227
|
+
window.mpapi.search("Mümmelmannsberg 72", {
|
|
228
|
+
map: window.mpapi.map,
|
|
229
|
+
zoom: true,
|
|
230
|
+
zoomToParams: {duration: 1000, maxZoom: 8},
|
|
231
|
+
searchAddress: true
|
|
232
|
+
}).then(x => console.log(x)).catch(e => console.error(e));
|
|
233
|
+
|
|
234
|
+
//*/
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
// Add 3D functionality to the example:
|
|
238
|
+
|
|
239
|
+
// add a click-listener to button, that creates a 3D-map on click
|
|
240
|
+
document.getElementById("enable").addEventListener("click", function () {
|
|
241
|
+
if (window.mpapi.map2D === null) {
|
|
242
|
+
window.mpapi.map2D = window.mpapi.map;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (window.mpapi.map.mapMode === "3D") {
|
|
246
|
+
window.mpapi.map.setEnabled(false);
|
|
247
|
+
window.mpapi.map = window.mpapi.map2D;
|
|
248
|
+
window.mpapi.map.getView().setRotation(0);
|
|
249
|
+
document.getElementById("layer-visibility").style.display = "none";
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
const lib = portalConfig.cesiumLib ? portalConfig.cesiumLib : "https://geoportal-hamburg.de/mastercode/cesium/1_99/index.js";
|
|
253
|
+
|
|
254
|
+
document.getElementById("layer-visibility").style.display = "block";
|
|
255
|
+
|
|
256
|
+
load3DScriptModule.load3DScript(lib, function Loaded3DCallback () {
|
|
257
|
+
let tilesetLayer = null;
|
|
258
|
+
|
|
259
|
+
const settings3D = {
|
|
260
|
+
map2D: window.mpapi.map2D,
|
|
261
|
+
// set some options to Cesium scene
|
|
262
|
+
cesiumParameter: {
|
|
263
|
+
fxaa: true,
|
|
264
|
+
globe: {
|
|
265
|
+
enableLighting: true,
|
|
266
|
+
maximumScreenSpaceError: 2,
|
|
267
|
+
tileCacheSize: 20
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
},
|
|
271
|
+
map3D = mapsAPI.map.createMap(settings3D, "3D"),
|
|
272
|
+
rawLayerTerrain = rawLayerList.getLayerWhere({id: "4001"}),
|
|
273
|
+
rawLayerTileset = rawLayerList.getLayerWhere({id: "4002"}),
|
|
274
|
+
rawLayerEntities = rawLayerList.getLayerWhere({id: "4003"});
|
|
275
|
+
|
|
276
|
+
window.mpapi.map = map3D;
|
|
277
|
+
tilesetLayer = new mpapi.Tileset(rawLayerTileset, window.mpapi.map);
|
|
278
|
+
tilesetLayer.setVisible(true, window.mpapi.map);
|
|
279
|
+
|
|
280
|
+
// entities are 2 simple buildings in the park 'planten und blomen' near Tiergartenstraße
|
|
281
|
+
mpapi.entities.createLayer(rawLayerEntities, window.mpapi.map);
|
|
282
|
+
// mpapi.entities.setVisible(true, rawLayerEntities, window.mpapi.map);
|
|
283
|
+
|
|
284
|
+
mpapi.terrain.createLayer(rawLayerTerrain, window.mpapi.map);
|
|
285
|
+
mpapi.terrain.setVisible(true, rawLayerTerrain, window.mpapi.map);
|
|
286
|
+
|
|
287
|
+
window.mpapi.map.setEnabled(true);
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
// add a click-listener to button, that hides background layer in 3d
|
|
293
|
+
document.getElementById("layer-visibility").addEventListener("click", function () {
|
|
294
|
+
map2D.getLayers().forEach(layer => {
|
|
295
|
+
map2D.removeLayer(layer);
|
|
296
|
+
});
|
|
297
|
+
});
|
package/jest.setup.js
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
import "regenerator-runtime/runtime";
|
|
2
2
|
|
|
3
|
+
class Worker {
|
|
4
|
+
constructor (stringUrl) {
|
|
5
|
+
this.url = stringUrl;
|
|
6
|
+
this.onmessage = () => {
|
|
7
|
+
// empty
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
postMessage (msg) {
|
|
12
|
+
this.onmessage(msg);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
// a mock for web worker
|
|
16
|
+
window.Worker = Worker;
|
|
17
|
+
|
|
3
18
|
window.URL.createObjectURL = function () {
|
|
4
19
|
// empty
|
|
5
20
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@masterportal/masterportalapi",
|
|
3
3
|
"author": "Implementierungspartnerschaft Masterportal <info@masterportal.org> (https://www.masterportal.org)",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.20.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Basic functions of the Masterportal as api",
|
|
7
7
|
"repository": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"core-js": "^3.30.2",
|
|
23
23
|
"dayjs": "^1.11.7",
|
|
24
|
-
"ol": "7.
|
|
24
|
+
"ol": "7.4.0",
|
|
25
25
|
"olcs": "^2.14.0",
|
|
26
26
|
"proj4": "^2.9.0",
|
|
27
27
|
"xml2js": "^0.5.0"
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"use-resize-observer": "^9.1.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"cesium": "^1.
|
|
50
|
+
"cesium": "^1.106.0"
|
|
51
51
|
},
|
|
52
52
|
"engines": {
|
|
53
53
|
"node": "^16.13.2 || ^18.12.0",
|
package/src/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {createMapView} from "./maps/mapView";
|
|
2
2
|
import crs from "./crs";
|
|
3
|
+
import drawInteractions from "./maps/interactions/drawInteractions";
|
|
3
4
|
import rawLayerList from "./rawLayerList";
|
|
4
5
|
import * as wms from "./layer/wms";
|
|
5
6
|
import wmts from "./layer/wmts";
|
|
@@ -36,5 +37,6 @@ export {
|
|
|
36
37
|
ping,
|
|
37
38
|
search,
|
|
38
39
|
crs,
|
|
40
|
+
drawInteractions,
|
|
39
41
|
webgl
|
|
40
42
|
};
|
package/src/layer/wfs.js
CHANGED
|
@@ -252,3 +252,22 @@ export function createLayer (rawLayer = {}, {layerParams = {}, options = {}} = {
|
|
|
252
252
|
}
|
|
253
253
|
return layer;
|
|
254
254
|
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Load the features manually.
|
|
258
|
+
* @param {Object} layerAttributes raw layer attributes.
|
|
259
|
+
* @param {module:ol/vector/Source} layerSource - the source of the layer
|
|
260
|
+
* @returns {void}
|
|
261
|
+
*/
|
|
262
|
+
export function loadFeaturesManually (layerAttributes, layerSource) {
|
|
263
|
+
const getUrl = createUrl(layerAttributes, layerAttributes.version, {getCode: () => layerAttributes.crs}, "");
|
|
264
|
+
|
|
265
|
+
fetch(getUrl, layerSource)
|
|
266
|
+
.then(response => response.text())
|
|
267
|
+
.then(responseString => {
|
|
268
|
+
layerSource.addFeatures(layerSource.getFormat().readFeatures(responseString));
|
|
269
|
+
})
|
|
270
|
+
.catch(error => {
|
|
271
|
+
console.error(error);
|
|
272
|
+
});
|
|
273
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import {createBox} from "ol/interaction/Draw.js";
|
|
2
|
+
import {Draw} from "ol/interaction.js";
|
|
3
|
+
|
|
4
|
+
const earthRadius = 6378137,
|
|
5
|
+
roh = 180 / Math.PI,
|
|
6
|
+
mappingDrawTypes = {
|
|
7
|
+
box: {
|
|
8
|
+
type: "Circle",
|
|
9
|
+
options: {
|
|
10
|
+
geometryFunction: createBox()
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
circle: {
|
|
14
|
+
type: "Circle"
|
|
15
|
+
},
|
|
16
|
+
doubleCircle: {
|
|
17
|
+
type: "Circle"
|
|
18
|
+
},
|
|
19
|
+
line: {
|
|
20
|
+
type: "LineString"
|
|
21
|
+
},
|
|
22
|
+
pen: {
|
|
23
|
+
type: "LineString",
|
|
24
|
+
options: {
|
|
25
|
+
freehand: true
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
point: {
|
|
29
|
+
type: "Point"
|
|
30
|
+
},
|
|
31
|
+
polygon: {
|
|
32
|
+
type: "Polygon"
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Transform the radius to map projection unit.
|
|
38
|
+
* @param {Number} radius The radius.
|
|
39
|
+
* @param {Object} mapProjection The map projection.
|
|
40
|
+
* @returns {Number} The transformed radius.
|
|
41
|
+
*/
|
|
42
|
+
function transformMapUnitRadius (radius, mapProjection) {
|
|
43
|
+
const unit = mapProjection.getUnits();
|
|
44
|
+
let mapUnitRadius;
|
|
45
|
+
|
|
46
|
+
if (unit === "m") {
|
|
47
|
+
mapUnitRadius = radius;
|
|
48
|
+
}
|
|
49
|
+
else if (unit === "degrees") {
|
|
50
|
+
mapUnitRadius = radius * roh / earthRadius;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return mapUnitRadius;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Create a feature for the outer circle of draw type: double circle.
|
|
58
|
+
* @param {ol/interaction/Draw} drawInteraction The draw interaction.
|
|
59
|
+
* @param {Object} mapProjection The map projection.
|
|
60
|
+
* @param {ol/source} source The vector layer source for draw features.
|
|
61
|
+
* @param {Object} [options={}] The options for drawing features.
|
|
62
|
+
* @param {Number} [options.circleOuterRadius] The radius for the outer circle.
|
|
63
|
+
* @returns {void}
|
|
64
|
+
*/
|
|
65
|
+
function drawOuterCircle (drawInteraction, mapProjection, source, options = {}) {
|
|
66
|
+
drawInteraction.on("drawend", event => {
|
|
67
|
+
const outerCircleFeature = event.feature.clone(),
|
|
68
|
+
mapUnitOuterRadius = transformMapUnitRadius(options.circleOuterRadius, mapProjection);
|
|
69
|
+
|
|
70
|
+
outerCircleFeature.getGeometry().setRadius(mapUnitOuterRadius);
|
|
71
|
+
source.addFeature(outerCircleFeature);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Create features for non-interactive circle or double circle.
|
|
77
|
+
* @param {ol/interaction/Draw} drawInteraction The draw interaction.
|
|
78
|
+
* @param {String} drawType The current draw type.
|
|
79
|
+
* @param {Object} mapProjection The map projection.
|
|
80
|
+
* @param {ol/source} source The vector layer source for draw features.
|
|
81
|
+
* @param {Object} [options={}] The options for drawing features.
|
|
82
|
+
* @param {Number} [options.circleInnerRadius] The radius for the inner circle.
|
|
83
|
+
* @param {Number} [options.circleOuterRadius] The radius for the outer circle.
|
|
84
|
+
* @param {Boolean} [options.interactiveCircle] Circle is drawn interactively or not.
|
|
85
|
+
* @returns {void}
|
|
86
|
+
*/
|
|
87
|
+
function drawCircle (drawInteraction, drawType, mapProjection, source, options = {}) {
|
|
88
|
+
if (options.interactiveCircle === false && options.circleInnerRadius > 0) {
|
|
89
|
+
drawInteraction.on("drawstart", event => {
|
|
90
|
+
const mapUnitInnerRadius = transformMapUnitRadius(options.circleInnerRadius, mapProjection);
|
|
91
|
+
|
|
92
|
+
event.feature.getGeometry().setRadius(mapUnitInnerRadius);
|
|
93
|
+
drawInteraction.finishDrawing();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
if (drawType === "doubleCircle" && options.circleOuterRadius > 0) {
|
|
97
|
+
drawOuterCircle(drawInteraction, mapProjection, source, options);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Create the draw interaction.
|
|
104
|
+
* @param {String} drawType The current draw type.
|
|
105
|
+
* @param {ol/source} source The vector layer source for draw features.
|
|
106
|
+
* @returns {ol/interaction/Draw|null} The draw interaction.
|
|
107
|
+
*/
|
|
108
|
+
function createDrawInteraction (drawType, source) {
|
|
109
|
+
let drawInteraction = null;
|
|
110
|
+
|
|
111
|
+
if (typeof mappingDrawTypes[drawType] === "object") {
|
|
112
|
+
const options = mappingDrawTypes[drawType].options || {};
|
|
113
|
+
|
|
114
|
+
drawInteraction = new Draw({
|
|
115
|
+
source: source,
|
|
116
|
+
type: mappingDrawTypes[drawType].type,
|
|
117
|
+
freehand: options.freehand,
|
|
118
|
+
geometryFunction: options.geometryFunction
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return drawInteraction;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export default {
|
|
126
|
+
createDrawInteraction,
|
|
127
|
+
drawCircle,
|
|
128
|
+
drawOuterCircle,
|
|
129
|
+
transformMapUnitRadius
|
|
130
|
+
};
|
package/src/maps/ol/olMap.js
CHANGED
|
@@ -4,7 +4,7 @@ import setBackgroundImage from "../../lib/setBackgroundImage";
|
|
|
4
4
|
import getInitialLayers from "../../lib/getInitialLayers";
|
|
5
5
|
import defaults from "../../defaults";
|
|
6
6
|
import * as wms from "../../layer/wms";
|
|
7
|
-
import
|
|
7
|
+
import wmts from "../../layer/wmts";
|
|
8
8
|
import * as geojson from "../../layer/geojson";
|
|
9
9
|
import * as wfs from "../../layer/wfs";
|
|
10
10
|
import * as vectorBase from "../../layer/vectorBase";
|
|
@@ -23,7 +23,7 @@ let mapIdCounter = 0;
|
|
|
23
23
|
*/
|
|
24
24
|
const layerBuilderMap = {
|
|
25
25
|
wms,
|
|
26
|
-
wmts,
|
|
26
|
+
"wmts": wmts,
|
|
27
27
|
wfs,
|
|
28
28
|
geojson,
|
|
29
29
|
vectorBase,
|
package/src/renderer/webgl.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import WebGLPointsLayer from "ol/layer/WebGLPoints";
|
|
2
2
|
import WebGLVectorLayerRenderer from "ol/renderer/webgl/VectorLayer";
|
|
3
3
|
import VectorLayer from "ol/layer/Layer";
|
|
4
|
-
import {packColor} from "ol/renderer/webgl/shaders";
|
|
5
4
|
import styleList from "../vectorStyle/styleList";
|
|
6
5
|
import {getRulesForFeature} from "../vectorStyle/lib/getRuleForIndex";
|
|
6
|
+
import {returnColor} from "../vectorStyle/lib/colorConvertions";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* The default style for OpenLayers WebGLPoints class
|
|
@@ -11,82 +11,26 @@ import {getRulesForFeature} from "../vectorStyle/lib/getRuleForIndex";
|
|
|
11
11
|
* @private
|
|
12
12
|
*/
|
|
13
13
|
const defaultStyle = {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* parses the styling rules for the renderer
|
|
26
|
-
* @static
|
|
27
|
-
* @private
|
|
28
|
-
* @returns {Object} the style options object with conditional functions
|
|
29
|
-
*/
|
|
30
|
-
export function getRenderFunctions () {
|
|
31
|
-
return {
|
|
32
|
-
/**
|
|
33
|
-
* Used for polygon fills
|
|
34
|
-
* Reads the relevant properties from the Masterportal style object
|
|
35
|
-
* @see https://bitbucket.org/geowerkstatt-hamburg/masterportal/src/dev/doc/style.json.md
|
|
36
|
-
*/
|
|
37
|
-
fill: {
|
|
38
|
-
attributes: {
|
|
39
|
-
color: (feature) => {
|
|
40
|
-
return packColor(feature.styleRule?.style.polygonFillColor || "#006688");
|
|
41
|
-
},
|
|
42
|
-
opacity: (feature) => {
|
|
43
|
-
return typeof feature.styleRule?.style.polygonFillColor?.[3] === "number" ?
|
|
44
|
-
feature.styleRule.style.polygonFillColor[3] : 1;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
stroke: {
|
|
49
|
-
/**
|
|
50
|
-
* Used for polygon edges and lineStrings
|
|
51
|
-
* Reads the relevant properties from the Masterportal style object
|
|
52
|
-
* @see https://bitbucket.org/geowerkstatt-hamburg/masterportal/src/dev/doc/style.json.md
|
|
53
|
-
*/
|
|
54
|
-
attributes: {
|
|
55
|
-
color: (feature) => {
|
|
56
|
-
return packColor(feature.styleRule?.style.polygonStrokeColor || "#006688");
|
|
57
|
-
},
|
|
58
|
-
width: (feature) => {
|
|
59
|
-
return feature.styleRule?.style.polygonStrokeWidth || 1;
|
|
60
|
-
},
|
|
61
|
-
opacity: (feature) => {
|
|
62
|
-
return typeof feature.styleRule?.style.polygonStrokeColor?.[3] === "number" ?
|
|
63
|
-
feature.styleRule.style.polygonStrokeColor[3] : 1;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
point: {
|
|
68
|
-
/**
|
|
69
|
-
* As of now, the generic VectorLayerRenderer only supports points rendered as quads
|
|
70
|
-
* available attributes: color, size, opacity
|
|
71
|
-
* Due to that, we use WebGLPoints Layer Class for point geom types
|
|
72
|
-
* Reads the relevant properties from the Masterportal style object
|
|
73
|
-
* @see https://bitbucket.org/geowerkstatt-hamburg/masterportal/src/dev/doc/style.json.md
|
|
74
|
-
*/
|
|
75
|
-
attributes: {
|
|
76
|
-
color: (feature) => {
|
|
77
|
-
return packColor(feature.styleRule?.style.circleFillColor || "#006688");
|
|
78
|
-
},
|
|
79
|
-
size: (feature) => {
|
|
80
|
-
return feature.styleRule?.style.circleRadius || 20;
|
|
81
|
-
},
|
|
82
|
-
opacity: (feature) => {
|
|
83
|
-
return typeof feature.styleRule?.style.circleFillColor?.[3] === "number" ?
|
|
84
|
-
feature.styleRule.style.circleFillColor[3] : 1;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
14
|
+
symbol: {
|
|
15
|
+
symbolType: "circle",
|
|
16
|
+
size: 20,
|
|
17
|
+
color: "#006688",
|
|
18
|
+
rotateWithView: false,
|
|
19
|
+
offset: [0, 0],
|
|
20
|
+
opacity: 0.6
|
|
87
21
|
}
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
/** @type {import('../src/ol/style/literal.js').LiteralStyle} */
|
|
25
|
+
style = {
|
|
26
|
+
"stroke-color": ["get", "STROKECOLOR"],
|
|
27
|
+
// NOTICE: does not work with ol 7.4.0, throws errors -> use 1 pixel width
|
|
28
|
+
// "stroke-width": ["get", "STROKEWIDTH"],
|
|
29
|
+
"stroke-width": 1,
|
|
30
|
+
"fill-color": ["get", "FILLCOLOR"],
|
|
31
|
+
"opacity": ["get", "OPACITY"],
|
|
32
|
+
"size": ["get", "CIRCLESIZE"]
|
|
88
33
|
};
|
|
89
|
-
}
|
|
90
34
|
|
|
91
35
|
/**
|
|
92
36
|
* Creates a layer object to extend from.
|
|
@@ -109,7 +53,9 @@ export function createVectorLayerRenderer () {
|
|
|
109
53
|
* @experimental
|
|
110
54
|
*/
|
|
111
55
|
createRenderer () {
|
|
112
|
-
return new WebGLVectorLayerRenderer(this,
|
|
56
|
+
return new WebGLVectorLayerRenderer(this, {
|
|
57
|
+
style
|
|
58
|
+
});
|
|
113
59
|
}
|
|
114
60
|
}
|
|
115
61
|
|
|
@@ -132,9 +78,24 @@ export function formatFeatureStyles (feature, styleObject) {
|
|
|
132
78
|
// extract first matching rule only
|
|
133
79
|
const rule = getRulesForFeature(styleObject, feature)[0];
|
|
134
80
|
|
|
135
|
-
// don't set on properties to avoid GFI issues
|
|
136
81
|
// undefined if no match
|
|
137
82
|
feature.styleRule = rule;
|
|
83
|
+
|
|
84
|
+
if (rule && rule.style) {
|
|
85
|
+
// TODO set style on properties will be visible in GFI
|
|
86
|
+
const polygonFillColor = returnColor(rule.style.polygonFillColor, "hex"),
|
|
87
|
+
circleFillColor = returnColor(rule.style.circleFillColor, "hex"),
|
|
88
|
+
fillColor = polygonFillColor ? polygonFillColor : circleFillColor,
|
|
89
|
+
polygonStrokeColor = returnColor(rule.style.polygonStrokeColor, "hex"),
|
|
90
|
+
polygonStrokeWidth = rule.style.polygonStrokeWidth,
|
|
91
|
+
size = rule.style.circleRadius;
|
|
92
|
+
|
|
93
|
+
feature.set("FILLCOLOR", fillColor ? fillColor : "#006688");
|
|
94
|
+
feature.set("STROKECOLOR", polygonStrokeColor ? polygonStrokeColor : "#006688");
|
|
95
|
+
feature.set("STROKEWIDTH", polygonStrokeWidth ? polygonStrokeWidth : 1);
|
|
96
|
+
feature.set("OPACITY", polygonFillColor ? polygonFillColor[3] : 1);
|
|
97
|
+
feature.set("CIRCLESIZE", size ? size : 20);
|
|
98
|
+
}
|
|
138
99
|
}
|
|
139
100
|
|
|
140
101
|
/**
|
|
@@ -6,8 +6,7 @@ import LineStringStyle from "./styles/styleLine";
|
|
|
6
6
|
import CesiumStyle from "./styles/styleCesium";
|
|
7
7
|
import {getRuleForIndex, getRulesForFeature} from "./lib/getRuleForIndex";
|
|
8
8
|
|
|
9
|
-
const legendsOfAllStyles = []
|
|
10
|
-
uniqueStyles = [];
|
|
9
|
+
const legendsOfAllStyles = [];
|
|
11
10
|
let legendInformationLength = 0;
|
|
12
11
|
|
|
13
12
|
/**
|
|
@@ -30,17 +29,13 @@ function isMultiGeometry (geometryType) {
|
|
|
30
29
|
*/
|
|
31
30
|
function getSimpleGeometryStyle (geometryType, feature, rule, isClustered, wfsImgPathFromConfig) {
|
|
32
31
|
const style = rule?.style,
|
|
33
|
-
legendValue = style ? style.legendValue : null
|
|
34
|
-
alreadyExisitingStyle = uniqueStyles.find(element => element.featureStyle === style && element.geometryType === geometryType);
|
|
32
|
+
legendValue = style ? style.legendValue : null;
|
|
35
33
|
let styleObject,
|
|
36
34
|
styleObjectForLegend = null;
|
|
37
35
|
|
|
38
36
|
feature.legendValue = legendValue ? legendValue : null;
|
|
39
37
|
|
|
40
|
-
if (
|
|
41
|
-
styleObject = alreadyExisitingStyle.featureStyleObject;
|
|
42
|
-
}
|
|
43
|
-
else if (geometryType === "Point") {
|
|
38
|
+
if (geometryType === "Point") {
|
|
44
39
|
styleObject = new PointStyle(feature, style, isClustered);
|
|
45
40
|
if (isClustered) {
|
|
46
41
|
styleObjectForLegend = new PointStyle(feature, style, false);
|
|
@@ -78,7 +73,6 @@ function getSimpleGeometryStyle (geometryType, feature, rule, isClustered, wfsIm
|
|
|
78
73
|
styleObjectForLegend.initialize(feature, style, false, wfsImgPathFromConfig);
|
|
79
74
|
styleObjectForLegend.legendValue = legendValue;
|
|
80
75
|
}
|
|
81
|
-
uniqueStyles.push({featureStyle: style, featureStyleObject: styleObject, geometryType});
|
|
82
76
|
styleObject.initialize(feature, style, isClustered, wfsImgPathFromConfig);
|
|
83
77
|
styleObject.addLegendInfo(geometryType, styleObjectForLegend === null ? styleObject : styleObjectForLegend, rule);
|
|
84
78
|
styleObject.legendValue = legendValue;
|
|
@@ -122,6 +116,7 @@ function getMultiGeometryStyle (geometryType, feature, rules, isClustered, wfsIm
|
|
|
122
116
|
console.warn("Multi encapsulated multiGeometries are not supported.");
|
|
123
117
|
}
|
|
124
118
|
else if (!simpleStyle.styleMultiGeomOnlyWithRule || rule) {
|
|
119
|
+
simpleStyle.getStyle()?.setGeometry(geometry);
|
|
125
120
|
olStyle.push(simpleStyle);
|
|
126
121
|
}
|
|
127
122
|
});
|
|
@@ -136,7 +131,7 @@ function getMultiGeometryStyle (geometryType, feature, rules, isClustered, wfsIm
|
|
|
136
131
|
else {
|
|
137
132
|
const simpleStyle = getSimpleGeometryStyle(geometryType, feature, rules, isClustered, wfsImgPathFromConfig);
|
|
138
133
|
|
|
139
|
-
simpleStyle.getStyle()
|
|
134
|
+
simpleStyle.getStyle()?.setGeometry(geometryType);
|
|
140
135
|
olStyle.push(simpleStyle);
|
|
141
136
|
}
|
|
142
137
|
return olStyle;
|
|
@@ -251,7 +246,7 @@ function createStyle (styleObject, feature, isClustered, wfsImgPathFromConfig) {
|
|
|
251
246
|
captureLegendFromFeature(styleObject.styleId, legendInformation);
|
|
252
247
|
}
|
|
253
248
|
// label style is optional and depends on some fields
|
|
254
|
-
if (isClustered || hasLabelField) {
|
|
249
|
+
if (styleObjectGeometry !== null && (isClustered || hasLabelField)) {
|
|
255
250
|
if (Array.isArray(styleObjectGeometry)) {
|
|
256
251
|
styleObjectGeometry[0].setText(getLabelStyle(feature, style, isClustered));
|
|
257
252
|
}
|
|
@@ -38,14 +38,14 @@ class PointStyle extends StyleClass {
|
|
|
38
38
|
this.setFeature(feature);
|
|
39
39
|
this.setIsClustered(isClustered);
|
|
40
40
|
this.overwriteStyling(styles);
|
|
41
|
-
this.setStyle(this.
|
|
41
|
+
this.setStyle(this.createStyle());
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
45
|
* This function returns a style for each feature.
|
|
46
46
|
* @returns {ol/style} - The created style.
|
|
47
47
|
*/
|
|
48
|
-
|
|
48
|
+
createStyle () {
|
|
49
49
|
if (this.nullStyle) {
|
|
50
50
|
return null;
|
|
51
51
|
}
|
|
@@ -28,14 +28,14 @@ class PolygonStyle extends StyleClass {
|
|
|
28
28
|
this.setFeature(feature);
|
|
29
29
|
this.setIsClustered(isClustered);
|
|
30
30
|
this.overwriteStyling(styles);
|
|
31
|
-
this.setStyle(this.
|
|
31
|
+
this.setStyle(this.createStyle());
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* This function returns a style for each feature.
|
|
36
36
|
* @returns {ol/style} - The created style.
|
|
37
37
|
*/
|
|
38
|
-
|
|
38
|
+
createStyle () {
|
|
39
39
|
if (this.nullStyle) {
|
|
40
40
|
return null;
|
|
41
41
|
}
|
|
@@ -22,14 +22,14 @@ class CesiumStyle extends StyleClass {
|
|
|
22
22
|
initialize (rule) {
|
|
23
23
|
this.overwriteStyling(rule.style);
|
|
24
24
|
this.setConditions(rule.conditions);
|
|
25
|
-
this.setStyle(this.
|
|
25
|
+
this.setStyle(this.createStyle());
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* This function returns a style for each feature.
|
|
30
30
|
* @returns {ol/style} - The created style.
|
|
31
31
|
*/
|
|
32
|
-
|
|
32
|
+
createStyle () {
|
|
33
33
|
return this.createCondition(this.get("conditions"), this.get("style"));
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -26,14 +26,14 @@ class LineStringStyle extends StyleClass {
|
|
|
26
26
|
this.setFeature(feature);
|
|
27
27
|
this.setIsClustered(isClustered);
|
|
28
28
|
this.overwriteStyling(styles);
|
|
29
|
-
this.setStyle(this.
|
|
29
|
+
this.setStyle(this.createStyle());
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* This function returns a style for each feature.
|
|
34
34
|
* @returns {ol/style/Style} - The created style.
|
|
35
35
|
*/
|
|
36
|
-
|
|
36
|
+
createStyle () {
|
|
37
37
|
if (this.nullStyle) {
|
|
38
38
|
return null;
|
|
39
39
|
}
|
|
@@ -28,14 +28,14 @@ class TextStyle extends StyleClass {
|
|
|
28
28
|
this.setFeature(feature);
|
|
29
29
|
this.setIsClustered(isClustered);
|
|
30
30
|
this.overwriteStyling(styles);
|
|
31
|
-
this.setStyle(this.
|
|
31
|
+
this.setStyle(this.createStyle());
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* This function returns a style for each feature.
|
|
36
36
|
* @returns {ol/style} - The created style.
|
|
37
37
|
*/
|
|
38
|
-
|
|
38
|
+
createStyle () {
|
|
39
39
|
if (this.nullStyle) {
|
|
40
40
|
return null;
|
|
41
41
|
}
|
package/test/layer/wfs.test.js
CHANGED
|
@@ -414,5 +414,57 @@ describe("wfs.js", function () {
|
|
|
414
414
|
expect(webgl.afterLoading).toHaveBeenCalled();
|
|
415
415
|
});
|
|
416
416
|
});
|
|
417
|
+
describe("loadFeaturesManually", function () {
|
|
418
|
+
const consoleError = console.error;
|
|
419
|
+
let tick;
|
|
420
|
+
|
|
421
|
+
beforeEach(() => {
|
|
422
|
+
tick = () => {
|
|
423
|
+
return new Promise(resolve => {
|
|
424
|
+
setTimeout(resolve, 0);
|
|
425
|
+
});
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
if (global.fetch) {
|
|
429
|
+
global.fetch.mockClear();
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
// to reset show error on load in console
|
|
433
|
+
afterEach(() => {
|
|
434
|
+
console.error = consoleError;
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
it("load features manually", async function () {
|
|
438
|
+
global.fetch = jest.fn().mockImplementationOnce(() => {
|
|
439
|
+
return new Promise((resolve) => {
|
|
440
|
+
resolve({
|
|
441
|
+
ok: true,
|
|
442
|
+
status: 200,
|
|
443
|
+
text: () => {
|
|
444
|
+
return featureCollection;
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
});
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
const format = new WFS(),
|
|
451
|
+
source = new VectorSource({
|
|
452
|
+
format: format,
|
|
453
|
+
url: "https://url.de",
|
|
454
|
+
version: "1.1.0",
|
|
455
|
+
featureType: "krankenhaeuser_hh",
|
|
456
|
+
featureNS: "http://www.deegree.org/app"
|
|
457
|
+
}),
|
|
458
|
+
layerAttributes = {
|
|
459
|
+
crs: "EPSG:25832",
|
|
460
|
+
version: "1.1.0",
|
|
461
|
+
url: "https://url.de"
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
wfs.loadFeaturesManually(layerAttributes, source);
|
|
465
|
+
await tick();
|
|
466
|
+
expect(source.getFeatures()).toHaveLength(1);
|
|
467
|
+
});
|
|
468
|
+
});
|
|
417
469
|
});
|
|
418
470
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {Draw} from "ol/interaction.js";
|
|
2
|
+
import VectorSource from "ol/source/Vector";
|
|
3
|
+
|
|
4
|
+
import drawInteractions from "../../../src/maps/interactions/drawInteractions";
|
|
5
|
+
|
|
6
|
+
describe("src/maps/interactions/drawInteractions.js", () => {
|
|
7
|
+
describe("createDrawInteraction", () => {
|
|
8
|
+
it("should create a draw interaction", () => {
|
|
9
|
+
const source = new VectorSource(),
|
|
10
|
+
drawType = "pen",
|
|
11
|
+
drawInteraction = drawInteractions.createDrawInteraction(drawType, source);
|
|
12
|
+
|
|
13
|
+
expect(drawInteraction).not.toBeUndefined();
|
|
14
|
+
expect(drawInteraction).not.toBeNull();
|
|
15
|
+
expect(drawInteraction).toBeInstanceOf(Draw);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("should return null, if drawType is not supported", () => {
|
|
19
|
+
const source = new VectorSource(),
|
|
20
|
+
drawType = "abc",
|
|
21
|
+
drawInteraction = drawInteractions.createDrawInteraction(drawType, source);
|
|
22
|
+
|
|
23
|
+
expect(drawInteraction).not.toBeUndefined();
|
|
24
|
+
expect(drawInteraction).toBeNull();
|
|
25
|
+
expect(drawInteraction).not.toBeInstanceOf(Draw);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
describe("transformMapUnitRadius", () => {
|
|
30
|
+
it("should return the input meter radius in meter ", () => {
|
|
31
|
+
const radius = 100,
|
|
32
|
+
mapProjection = {
|
|
33
|
+
getUnits: () => "m"
|
|
34
|
+
},
|
|
35
|
+
mapUnitRadius = drawInteractions.transformMapUnitRadius(radius, mapProjection);
|
|
36
|
+
|
|
37
|
+
expect(mapUnitRadius).toEqual(100);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("should return the input degree radius in meter ", () => {
|
|
41
|
+
const radius = 100,
|
|
42
|
+
mapProjection = {
|
|
43
|
+
getUnits: () => "degrees"
|
|
44
|
+
},
|
|
45
|
+
mapUnitRadius = drawInteractions.transformMapUnitRadius(radius, mapProjection);
|
|
46
|
+
|
|
47
|
+
expect(mapUnitRadius).toEqual(0.0008983152841195215);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -4,7 +4,6 @@ import Polygon from "ol/geom/Polygon";
|
|
|
4
4
|
import * as webgl from "../../src/renderer/webgl";
|
|
5
5
|
import WebGLPointsLayer from "ol/layer/WebGLPoints";
|
|
6
6
|
import Layer from "ol/layer/Layer";
|
|
7
|
-
import {packColor} from "ol/renderer/webgl/shaders";
|
|
8
7
|
import styleList from "../../src/vectorStyle/styleList";
|
|
9
8
|
|
|
10
9
|
describe("webgl.js", () => {
|
|
@@ -108,54 +107,5 @@ describe("webgl.js", () => {
|
|
|
108
107
|
expect($feature.styleRule).toEqual(styleRule);
|
|
109
108
|
});
|
|
110
109
|
});
|
|
111
|
-
describe("getRenderFunctions", () => {
|
|
112
|
-
it("should read the style from styleRule and pack them to single float", () => {
|
|
113
|
-
const renderFunctions = webgl.getRenderFunctions();
|
|
114
|
-
|
|
115
|
-
$feature = feature.clone();
|
|
116
|
-
webgl.formatFeatureStyles($feature, styleObject);
|
|
117
|
-
expect(renderFunctions.fill.attributes.color($feature)).toEqual(packColor(styleRule.style.polygonFillColor));
|
|
118
|
-
expect(renderFunctions.fill.attributes.opacity($feature)).toEqual(styleRule.style.polygonFillColor[3]);
|
|
119
|
-
expect(renderFunctions.stroke.attributes.color($feature)).toEqual(packColor(styleRule.style.polygonStrokeColor));
|
|
120
|
-
expect(renderFunctions.stroke.attributes.width($feature)).toEqual(styleRule.style.polygonStrokeWidth);
|
|
121
|
-
expect(renderFunctions.stroke.attributes.opacity($feature)).toEqual(styleRule.style.polygonStrokeColor[3]);
|
|
122
|
-
expect(renderFunctions.point.attributes.color($feature)).toEqual(packColor(styleRule.style.circleFillColor));
|
|
123
|
-
expect(renderFunctions.point.attributes.size($feature)).toEqual(styleRule.style.circleRadius);
|
|
124
|
-
expect(renderFunctions.point.attributes.opacity($feature)).toEqual(styleRule.style.circleFillColor[3]);
|
|
125
|
-
});
|
|
126
|
-
it("should return default values if style is empty, i.e. \"default\" style", () => {
|
|
127
|
-
const renderFunctions = webgl.getRenderFunctions();
|
|
128
|
-
|
|
129
|
-
styleObject = {
|
|
130
|
-
rules: [{
|
|
131
|
-
style: {}
|
|
132
|
-
}]
|
|
133
|
-
};
|
|
134
|
-
$feature = feature.clone();
|
|
135
|
-
webgl.formatFeatureStyles($feature, styleObject);
|
|
136
|
-
expect(typeof renderFunctions.fill.attributes.color($feature)).toEqual("number");
|
|
137
|
-
expect(typeof renderFunctions.fill.attributes.opacity($feature)).toEqual("number");
|
|
138
|
-
expect(typeof renderFunctions.stroke.attributes.color($feature)).toEqual("number");
|
|
139
|
-
expect(typeof renderFunctions.stroke.attributes.width($feature)).toEqual("number");
|
|
140
|
-
expect(typeof renderFunctions.stroke.attributes.opacity($feature)).toEqual("number");
|
|
141
|
-
expect(typeof renderFunctions.point.attributes.color($feature)).toEqual("number");
|
|
142
|
-
expect(typeof renderFunctions.point.attributes.size($feature)).toEqual("number");
|
|
143
|
-
expect(typeof renderFunctions.point.attributes.opacity($feature)).toEqual("number");
|
|
144
|
-
});
|
|
145
|
-
it("should return default values if no style rule is found", () => {
|
|
146
|
-
const renderFunctions = webgl.getRenderFunctions();
|
|
147
|
-
|
|
148
|
-
$feature = feature.clone();
|
|
149
|
-
expect(feature.styleRule).toBeUndefined();
|
|
150
|
-
expect(typeof renderFunctions.fill.attributes.color($feature)).toEqual("number");
|
|
151
|
-
expect(typeof renderFunctions.fill.attributes.opacity($feature)).toEqual("number");
|
|
152
|
-
expect(typeof renderFunctions.stroke.attributes.color($feature)).toEqual("number");
|
|
153
|
-
expect(typeof renderFunctions.stroke.attributes.width($feature)).toEqual("number");
|
|
154
|
-
expect(typeof renderFunctions.stroke.attributes.opacity($feature)).toEqual("number");
|
|
155
|
-
expect(typeof renderFunctions.point.attributes.color($feature)).toEqual("number");
|
|
156
|
-
expect(typeof renderFunctions.point.attributes.size($feature)).toEqual("number");
|
|
157
|
-
expect(typeof renderFunctions.point.attributes.opacity($feature)).toEqual("number");
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
110
|
});
|
|
161
111
|
});
|
|
@@ -27,8 +27,11 @@ describe("stylePoint", () => {
|
|
|
27
27
|
expect(typeof stylePointClass.setSize).toBe("function");
|
|
28
28
|
});
|
|
29
29
|
});
|
|
30
|
-
describe("
|
|
30
|
+
describe("createStyle", function () {
|
|
31
31
|
it("returns an instance of openlayers style", () => {
|
|
32
|
+
const createdStyle = stylePointClass.createStyle();
|
|
33
|
+
|
|
34
|
+
stylePointClass.setStyle(createdStyle);
|
|
32
35
|
expect(stylePointClass.getStyle()).toBeInstanceOf(Style);
|
|
33
36
|
});
|
|
34
37
|
it("returns an instance of openlayers circleStyle", () => {
|
|
@@ -39,6 +42,9 @@ describe("stylePoint", () => {
|
|
|
39
42
|
legendValue: "Krankenhaus",
|
|
40
43
|
imageName: "krankenhaus.png"
|
|
41
44
|
};
|
|
45
|
+
const createdStyle = stylePointClass.createStyle();
|
|
46
|
+
|
|
47
|
+
stylePointClass.setStyle(createdStyle);
|
|
42
48
|
|
|
43
49
|
expect(stylePointClass.getStyle()).toBeInstanceOf(Style);
|
|
44
50
|
expect(stylePointClass.getStyle().getImage()).toBeInstanceOf(CircleStyle);
|
|
@@ -15,8 +15,11 @@ describe("stylePolygon", () => {
|
|
|
15
15
|
isClustered = false,
|
|
16
16
|
stylePolygonClass = new PolygonStyle(feature, style, isClustered);
|
|
17
17
|
|
|
18
|
-
describe("
|
|
18
|
+
describe("createStyle", function () {
|
|
19
19
|
it("returns an instance of openlayers style", () => {
|
|
20
|
+
const createdStyle = stylePolygonClass.createStyle();
|
|
21
|
+
|
|
22
|
+
stylePolygonClass.setStyle(createdStyle);
|
|
20
23
|
expect(stylePolygonClass.getStyle()).toBeInstanceOf(Style);
|
|
21
24
|
});
|
|
22
25
|
});
|
|
@@ -21,8 +21,11 @@ describe("styleLine", () => {
|
|
|
21
21
|
});
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
describe("
|
|
24
|
+
describe("createStyle", function () {
|
|
25
25
|
it("returns an instance of openlayers style", () => {
|
|
26
|
+
const createdStyle = styleLineClass.createStyle();
|
|
27
|
+
|
|
28
|
+
styleLineClass.setStyle(createdStyle);
|
|
26
29
|
expect(styleLineClass.getStyle()).toBeInstanceOf(Style);
|
|
27
30
|
});
|
|
28
31
|
});
|