@masterportal/masterportalapi 2.24.0 → 2.25.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 +19 -0
- package/example/config/portal.json +6 -0
- package/example/config/services.json +10 -0
- package/package.json +66 -66
- package/src/index.js +0 -2
- package/src/layer/geojson/index.js +7 -5
- package/src/layer/oaf.js +3 -2
- package/src/layer/tileset.js +1 -1
- package/src/layer/vectorBase.js +2 -2
- package/src/layer/vectorTile.js +32 -8
- package/src/layer/wfs.js +4 -3
- package/src/layer/wmts.js +4 -2
- package/src/maps/ol/olMap.js +0 -2
- package/src/renderer/webgl.js +140 -23
- package/src/vectorStyle/styleList.js +8 -24
- package/test/layer/geojson/index.test.js +15 -3
- package/test/layer/oaf.test.js +16 -3
- package/test/layer/vectorTile.test.js +23 -4
- package/test/layer/wfs.test.js +16 -3
- package/test/renderer/webgl.test.js +76 -9
- package/test/layer/vectorBase.test.js +0 -85
package/CHANGELOG.md
CHANGED
|
@@ -3,11 +3,30 @@
|
|
|
3
3
|
|
|
4
4
|
The [Semantic Versioning](https://semver.org/spec/v2.0.0.html) is used.
|
|
5
5
|
|
|
6
|
+
### Unreleased - in development
|
|
7
|
+
## Added
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- WebGL: method "afterLoading" catches MultiPoint geometries and parses them to a single point feature for proper rendering
|
|
11
|
+
- WebGL Render-Pipeline for VectorLayer of type VectorTile can be called using {"renderer": "webgl"} in config.json.
|
|
12
|
+
|
|
13
|
+
## Changed
|
|
14
|
+
- The styleList is now loading asynchronus
|
|
15
|
+
|
|
16
|
+
## Deprecated
|
|
17
|
+
|
|
18
|
+
## Removed
|
|
19
|
+
|
|
20
|
+
## Fixed
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
6
24
|
## 2.24.0 - 2023-08-03
|
|
7
25
|
### Added
|
|
8
26
|
- The following packages have been installed:
|
|
9
27
|
- @swc/jest: 0.2.27
|
|
10
28
|
- Add a function to convertUnits in drawInteractions.
|
|
29
|
+
- Remove VectorBase layer and add it to masterportal.
|
|
11
30
|
|
|
12
31
|
### Changed
|
|
13
32
|
- The following packages have been updated:
|
|
@@ -133,6 +133,16 @@
|
|
|
133
133
|
"version" : "1.1.0",
|
|
134
134
|
"featureNS" : "https://registry.gdi-de.org/id/de.hh.up"
|
|
135
135
|
},
|
|
136
|
+
{
|
|
137
|
+
"id" : "5097",
|
|
138
|
+
"name" : "de.hh.up:strassenbaumkataster hpa",
|
|
139
|
+
"url" : "https://geodienste.hamburg.de/HH_WFS_Strassenbaumkataster",
|
|
140
|
+
"typ" : "WFS",
|
|
141
|
+
"featureType" : "strassenbaumkataster_hpa",
|
|
142
|
+
"outputFormat" : "XML",
|
|
143
|
+
"version" : "1.1.0",
|
|
144
|
+
"featureNS" : "https://registry.gdi-de.org/id/de.hh.up"
|
|
145
|
+
},
|
|
136
146
|
{
|
|
137
147
|
"id": "6001",
|
|
138
148
|
"name": "ArcGIS VectorTile",
|
package/package.json
CHANGED
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@masterportal/masterportalapi",
|
|
3
|
-
"author": "Implementierungspartnerschaft Masterportal <info@masterportal.org> (https://www.masterportal.org)",
|
|
4
|
-
"version": "2.
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"description": "Basic functions of the Masterportal as api",
|
|
7
|
-
"repository": {
|
|
8
|
-
"type": "git",
|
|
9
|
-
"url": "git+https://bitbucket.org/geowerkstatt-hamburg/masterportalapi.git"
|
|
10
|
-
},
|
|
11
|
-
"main": "src/index.js",
|
|
12
|
-
"scripts": {
|
|
13
|
-
"test": "jest .test.js --config ./jest.config.js --collectCoverage",
|
|
14
|
-
"test:trace": "node --trace-warnings node_modules/jest/bin/jest.js .test.js --config ./jest.config.js",
|
|
15
|
-
"test:watch": "jest .test.js --config ./jest.config.js --watch",
|
|
16
|
-
"example": "parcel example/index.html",
|
|
17
|
-
"generate-jsdoc": "jsdoc ./src -r -d ./docs/ -R ./README.md -c jsdoc.json",
|
|
18
|
-
"prePushHook": "eslint --max-warnings 0 \"./**/*.js\" && npm run test",
|
|
19
|
-
"prepare": "husky install"
|
|
20
|
-
},
|
|
21
|
-
"dependencies": {
|
|
22
|
-
"core-js": "^3.32.0",
|
|
23
|
-
"dayjs": "^1.11.9",
|
|
24
|
-
"ol": "7.4.0",
|
|
25
|
-
"olcs": "^2.15.0",
|
|
26
|
-
"proj4": "^2.9.0",
|
|
27
|
-
"xml2js": "^0.6.2"
|
|
28
|
-
},
|
|
29
|
-
"devDependencies": {
|
|
30
|
-
"@babel/core": "^7.22.9",
|
|
31
|
-
"@babel/plugin-transform-modules-commonjs": "^7.22.5",
|
|
32
|
-
"@parcel/transformer-sass": "^2.9.3",
|
|
33
|
-
"@swc/jest": "^0.2.27",
|
|
34
|
-
"buffer": "^6.0.3",
|
|
35
|
-
"canvas": "^2.11.2",
|
|
36
|
-
"eslint": "^8.46.0",
|
|
37
|
-
"events": "^3.3.0",
|
|
38
|
-
"husky": "^8.0.3",
|
|
39
|
-
"jest": "^29.6.2",
|
|
40
|
-
"jest-canvas-mock": "^2.5.2",
|
|
41
|
-
"jest-environment-jsdom": "^29.6.2",
|
|
42
|
-
"jest-fetch-mock": "^3.0.3",
|
|
43
|
-
"jsdoc": "^4.0.2",
|
|
44
|
-
"parcel": "^2.9.3",
|
|
45
|
-
"process": "^0.11.10",
|
|
46
|
-
"sass": "^1.64.2",
|
|
47
|
-
"stream-browserify": "^3.0.0",
|
|
48
|
-
"timers-browserify": "^2.0.12",
|
|
49
|
-
"use-resize-observer": "^9.1.0"
|
|
50
|
-
},
|
|
51
|
-
"peerDependencies": {
|
|
52
|
-
"@cesium/engine": "^2.4.1"
|
|
53
|
-
},
|
|
54
|
-
"engines": {
|
|
55
|
-
"node": "^16.13.2 || ^18.12.0",
|
|
56
|
-
"npm": "^8.1.2 || ^9.3.1"
|
|
57
|
-
},
|
|
58
|
-
"homepage": "https://bitbucket.org/geowerkstatt-hamburg/masterportalapi#readme",
|
|
59
|
-
"directories": {
|
|
60
|
-
"example": "example",
|
|
61
|
-
"test": "test"
|
|
62
|
-
},
|
|
63
|
-
"bugs": {
|
|
64
|
-
"url": "https://bitbucket.org/geowerkstatt-hamburg/masterportalapi/issues"
|
|
65
|
-
}
|
|
66
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@masterportal/masterportalapi",
|
|
3
|
+
"author": "Implementierungspartnerschaft Masterportal <info@masterportal.org> (https://www.masterportal.org)",
|
|
4
|
+
"version": "2.25.0",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"description": "Basic functions of the Masterportal as api",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://bitbucket.org/geowerkstatt-hamburg/masterportalapi.git"
|
|
10
|
+
},
|
|
11
|
+
"main": "src/index.js",
|
|
12
|
+
"scripts": {
|
|
13
|
+
"test": "jest .test.js --config ./jest.config.js --collectCoverage",
|
|
14
|
+
"test:trace": "node --trace-warnings node_modules/jest/bin/jest.js .test.js --config ./jest.config.js",
|
|
15
|
+
"test:watch": "jest .test.js --config ./jest.config.js --watch",
|
|
16
|
+
"example": "parcel example/index.html",
|
|
17
|
+
"generate-jsdoc": "jsdoc ./src -r -d ./docs/ -R ./README.md -c jsdoc.json",
|
|
18
|
+
"prePushHook": "eslint --max-warnings 0 \"./**/*.js\" && npm run test",
|
|
19
|
+
"prepare": "husky install"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"core-js": "^3.32.0",
|
|
23
|
+
"dayjs": "^1.11.9",
|
|
24
|
+
"ol": "7.4.0",
|
|
25
|
+
"olcs": "^2.15.0",
|
|
26
|
+
"proj4": "^2.9.0",
|
|
27
|
+
"xml2js": "^0.6.2"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@babel/core": "^7.22.9",
|
|
31
|
+
"@babel/plugin-transform-modules-commonjs": "^7.22.5",
|
|
32
|
+
"@parcel/transformer-sass": "^2.9.3",
|
|
33
|
+
"@swc/jest": "^0.2.27",
|
|
34
|
+
"buffer": "^6.0.3",
|
|
35
|
+
"canvas": "^2.11.2",
|
|
36
|
+
"eslint": "^8.46.0",
|
|
37
|
+
"events": "^3.3.0",
|
|
38
|
+
"husky": "^8.0.3",
|
|
39
|
+
"jest": "^29.6.2",
|
|
40
|
+
"jest-canvas-mock": "^2.5.2",
|
|
41
|
+
"jest-environment-jsdom": "^29.6.2",
|
|
42
|
+
"jest-fetch-mock": "^3.0.3",
|
|
43
|
+
"jsdoc": "^4.0.2",
|
|
44
|
+
"parcel": "^2.9.3",
|
|
45
|
+
"process": "^0.11.10",
|
|
46
|
+
"sass": "^1.64.2",
|
|
47
|
+
"stream-browserify": "^3.0.0",
|
|
48
|
+
"timers-browserify": "^2.0.12",
|
|
49
|
+
"use-resize-observer": "^9.1.0"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"@cesium/engine": "^2.4.1"
|
|
53
|
+
},
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": "^16.13.2 || ^18.12.0",
|
|
56
|
+
"npm": "^8.1.2 || ^9.3.1"
|
|
57
|
+
},
|
|
58
|
+
"homepage": "https://bitbucket.org/geowerkstatt-hamburg/masterportalapi#readme",
|
|
59
|
+
"directories": {
|
|
60
|
+
"example": "example",
|
|
61
|
+
"test": "test"
|
|
62
|
+
},
|
|
63
|
+
"bugs": {
|
|
64
|
+
"url": "https://bitbucket.org/geowerkstatt-hamburg/masterportalapi/issues"
|
|
65
|
+
}
|
|
66
|
+
}
|
package/src/index.js
CHANGED
|
@@ -5,7 +5,6 @@ import * as wms from "./layer/wms";
|
|
|
5
5
|
import wmts from "./layer/wmts";
|
|
6
6
|
import wfs from "./layer/wfs";
|
|
7
7
|
import * as geojson from "./layer/geojson";
|
|
8
|
-
import * as vectorBase from "./layer/vectorBase";
|
|
9
8
|
import * as vectorTile from "./layer/vectorTile";
|
|
10
9
|
import * as oaf from "./layer/oaf";
|
|
11
10
|
import * as terrain from "./layer/terrain";
|
|
@@ -24,7 +23,6 @@ export {
|
|
|
24
23
|
wfs,
|
|
25
24
|
geojson,
|
|
26
25
|
layerLib,
|
|
27
|
-
vectorBase,
|
|
28
26
|
vectorTile,
|
|
29
27
|
oaf,
|
|
30
28
|
terrain,
|
|
@@ -23,10 +23,11 @@ export {setCustomStyles};
|
|
|
23
23
|
* @param {"default" | "webgl" | undefined} [rawLayer.renderer] - use default canvas or webgl renderer
|
|
24
24
|
* @param {string} [rawLayer.styleId] - the styleId of the layer, only necessary for webgl style pipeline
|
|
25
25
|
* @param {string[]} [rawLayer.excludeTypesFromParsing] - types that should not be parsed from strings, only necessary for webgl
|
|
26
|
+
* @param {string[]} [rawLayer.isPointLayer] - whether the layer consists merely of points (or multi points)
|
|
26
27
|
* @param {object} options - options of the geojson layer
|
|
27
28
|
* @returns {ol.source.Vector} created VectorSource
|
|
28
29
|
*/
|
|
29
|
-
export function createLayerSource ({url, features, clusterDistance, renderer, styleId, excludeTypesFromParsing}, options) {
|
|
30
|
+
export function createLayerSource ({url, features, clusterDistance, renderer, styleId, excludeTypesFromParsing, isPointLayer}, options) {
|
|
30
31
|
const format = new GeoJSON();
|
|
31
32
|
let source = null;
|
|
32
33
|
|
|
@@ -46,11 +47,11 @@ export function createLayerSource ({url, features, clusterDistance, renderer, st
|
|
|
46
47
|
if (renderer === "webgl") {
|
|
47
48
|
// if features were provided before source creation
|
|
48
49
|
if (features?.length > 0) {
|
|
49
|
-
webgl.afterLoading(source.getFeatures(), styleId, excludeTypesFromParsing);
|
|
50
|
+
webgl.afterLoading(source.getFeatures(), styleId, excludeTypesFromParsing, isPointLayer);
|
|
50
51
|
}
|
|
51
52
|
// wait for loading
|
|
52
53
|
source.once("featuresloadend", event => {
|
|
53
|
-
webgl.afterLoading(event?.features, styleId, excludeTypesFromParsing);
|
|
54
|
+
webgl.afterLoading(event?.features, styleId, excludeTypesFromParsing, isPointLayer);
|
|
54
55
|
});
|
|
55
56
|
}
|
|
56
57
|
|
|
@@ -75,7 +76,8 @@ export function createLayer (rawLayer = {}, {layerParams = {}, options = {}} = {
|
|
|
75
76
|
...rawLayer,
|
|
76
77
|
renderer: layerParams.renderer,
|
|
77
78
|
styleId: layerParams.styleId,
|
|
78
|
-
excludeTypesFromParsing: layerParams.excludeTypesFromParsing
|
|
79
|
+
excludeTypesFromParsing: layerParams.excludeTypesFromParsing,
|
|
80
|
+
isPointLayer: layerParams.isPointLayer
|
|
79
81
|
}, options);
|
|
80
82
|
layer = webgl.createLayer({
|
|
81
83
|
...rawLayer,
|
|
@@ -118,7 +120,7 @@ export function updateSource (layer) {
|
|
|
118
120
|
// perform necessary feature operations if renderer is webgl
|
|
119
121
|
if (layer.get("renderer") === "webgl") {
|
|
120
122
|
layer.getSource().once("featuresloadend", event => {
|
|
121
|
-
webgl.afterLoading(event?.features, layer.get("styleId"), layer.get("excludeTypesFromParsing"));
|
|
123
|
+
webgl.afterLoading(event?.features, layer.get("styleId"), layer.get("excludeTypesFromParsing"), layer.get("isPointLayer"));
|
|
122
124
|
});
|
|
123
125
|
}
|
|
124
126
|
}
|
package/src/layer/oaf.js
CHANGED
|
@@ -188,7 +188,7 @@ export function createLayerSource (rawLayer, options = {}) {
|
|
|
188
188
|
|
|
189
189
|
if (rawLayer.renderer === "webgl") {
|
|
190
190
|
source.once("featuresloadend", event => {
|
|
191
|
-
webgl.afterLoading(event?.features, rawLayer.styleId, rawLayer.excludeTypesFromParsing);
|
|
191
|
+
webgl.afterLoading(event?.features, rawLayer.styleId, rawLayer.excludeTypesFromParsing, rawLayer.isPointLayer);
|
|
192
192
|
});
|
|
193
193
|
}
|
|
194
194
|
|
|
@@ -212,7 +212,8 @@ export function createLayer (rawLayer = {}, {layerParams = {}, options = {}} = {
|
|
|
212
212
|
...rawLayer,
|
|
213
213
|
renderer: layerParams.renderer,
|
|
214
214
|
styleId: layerParams.styleId,
|
|
215
|
-
excludeTypesFromParsing: layerParams.excludeTypesFromParsing
|
|
215
|
+
excludeTypesFromParsing: layerParams.excludeTypesFromParsing,
|
|
216
|
+
isPointLayer: layerParams.isPointLayer
|
|
216
217
|
}, options);
|
|
217
218
|
layer = webgl.createLayer({
|
|
218
219
|
...rawLayer,
|
package/src/layer/tileset.js
CHANGED
|
@@ -14,7 +14,7 @@ function createTileSet (rawLayer) {
|
|
|
14
14
|
Object.assign(options, rawLayer.cesium3DTilesetOptions);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
return Promise.resolve(Cesium.Cesium3DTileset.fromUrl(url, options));
|
|
17
|
+
return Promise.resolve(Cesium.Cesium3DTileset.fromUrl(url, options));
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
/**
|
package/src/layer/vectorBase.js
CHANGED
|
@@ -15,7 +15,7 @@ export function createLayerSource (attrs) {
|
|
|
15
15
|
|
|
16
16
|
// perform necessary feature operations if renderer is webgl
|
|
17
17
|
if (attrs.renderer === "webgl") {
|
|
18
|
-
webgl.afterLoading(source.getFeatures(), attrs.styleId, attrs.excludeTypesFromParsing);
|
|
18
|
+
webgl.afterLoading(source.getFeatures(), attrs.styleId, attrs.excludeTypesFromParsing, attrs.isPointLayer);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
return source;
|
|
@@ -30,7 +30,7 @@ export function createLayerSource (attrs) {
|
|
|
30
30
|
export function updateSource (layer, features) {
|
|
31
31
|
// perform necessary feature operations if renderer is webgl
|
|
32
32
|
if (layer.get("renderer") === "webgl") {
|
|
33
|
-
webgl.afterLoading(features, layer.get("styleId"), layer.get("excludeTypesFromParsing"));
|
|
33
|
+
webgl.afterLoading(features, layer.get("styleId"), layer.get("excludeTypesFromParsing"), layer.get("isPointLayer"));
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
layer.getSource().clear(true);
|
package/src/layer/vectorTile.js
CHANGED
|
@@ -3,6 +3,7 @@ import VectorTileLayer from "ol/layer/VectorTile";
|
|
|
3
3
|
import VectorTileSource from "ol/source/VectorTile";
|
|
4
4
|
import OpenLayersTileGrid from "ol/tilegrid/TileGrid";
|
|
5
5
|
import {extentFromProjection} from "ol/tilegrid";
|
|
6
|
+
import * as webgl from "../renderer/webgl";
|
|
6
7
|
|
|
7
8
|
import {stylefunction, apply} from "ol-mapbox-style";
|
|
8
9
|
|
|
@@ -108,11 +109,13 @@ function mustCreateTileGrid (options = {}) {
|
|
|
108
109
|
*
|
|
109
110
|
* @param {string} url - url to vector tile service
|
|
110
111
|
* @param {tileGridProperties} [options] - properties for tileGrid
|
|
112
|
+
* @param {"default" | "webgl" | undefined} [options.renderer] - use default canvas or webgl renderer
|
|
113
|
+
* @param {string} [options.styleId] - the styleId of the layer, only necessary for webgl style pipeline
|
|
114
|
+
* @param {string[]} [options.excludeTypesFromParsing] - types that should not be parsed from strings, only necessary for webgl
|
|
111
115
|
* @returns {ol.source.VectorTile} Source
|
|
112
116
|
*/
|
|
113
117
|
export function createLayerSource (url, options = {}) {
|
|
114
118
|
options.epsg = options.epsg ? options.epsg : defaults.epsg;
|
|
115
|
-
|
|
116
119
|
const sourceParams = {
|
|
117
120
|
projection: options.epsg,
|
|
118
121
|
format: new MVT(),
|
|
@@ -126,7 +129,6 @@ export function createLayerSource (url, options = {}) {
|
|
|
126
129
|
if (mustCreateTileGrid(options)) {
|
|
127
130
|
sourceParams.tileGrid = createTileGrid(options);
|
|
128
131
|
}
|
|
129
|
-
|
|
130
132
|
return new VectorTileSource(sourceParams);
|
|
131
133
|
}
|
|
132
134
|
|
|
@@ -143,13 +145,35 @@ export function createLayer (rawLayer = {}, {layerParams = {}, options = {}} = {
|
|
|
143
145
|
console.error(`Cancelled creation of layer "${rawLayer.id}"(${rawLayer.name}) because of missing required parameters`);
|
|
144
146
|
return undefined;
|
|
145
147
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
let layer, source;
|
|
149
|
+
|
|
150
|
+
// use WebGL render pipeline, if specified
|
|
151
|
+
if (layerParams.renderer === "webgl") {
|
|
152
|
+
source = createLayerSource(rawLayer.url, {
|
|
153
|
+
...rawLayer,
|
|
154
|
+
renderer: layerParams.renderer,
|
|
155
|
+
styleId: layerParams.styleId,
|
|
156
|
+
excludeTypesFromParsing: layerParams.excludeTypesFromParsing
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
layer = webgl.createLayer({
|
|
160
|
+
extent: source.getTileGrid().getExtent(),
|
|
161
|
+
...rawLayer,
|
|
162
|
+
...layerParams,
|
|
163
|
+
source
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
return layer;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// use default canvas renderer
|
|
170
|
+
source = createLayerSource(rawLayer.url, rawLayer);
|
|
171
|
+
layer = new VectorTileLayer(Object.assign({
|
|
172
|
+
id: rawLayer.id, name: rawLayer.name, attribution: rawLayer.olAttribution, extent: source.getTileGrid().getExtent(),
|
|
173
|
+
minZoom: rawLayer.minZoom, maxZoom: rawLayer.maxZoom, source: source,
|
|
174
|
+
declutter: true}, layerParams));
|
|
151
175
|
|
|
152
|
-
if (options.style) {
|
|
176
|
+
if (options.style && rawLayer.renderer !== "webgl") {
|
|
153
177
|
layer.setStyle(options.style);
|
|
154
178
|
}
|
|
155
179
|
|
package/src/layer/wfs.js
CHANGED
|
@@ -209,12 +209,12 @@ function createLayerSource (rawLayer, options = {}) {
|
|
|
209
209
|
if (rawLayer.renderer === "webgl") {
|
|
210
210
|
if (options.loadingStrategy === bbox) {
|
|
211
211
|
source.on("featuresloadend", event => {
|
|
212
|
-
webgl.afterLoading(event?.features, rawLayer.styleId, rawLayer.excludeTypesFromParsing);
|
|
212
|
+
webgl.afterLoading(event?.features, rawLayer.styleId, rawLayer.excludeTypesFromParsing, rawLayer.isPointLayer);
|
|
213
213
|
});
|
|
214
214
|
}
|
|
215
215
|
else {
|
|
216
216
|
source.once("featuresloadend", event => {
|
|
217
|
-
webgl.afterLoading(event?.features, rawLayer.styleId, rawLayer.excludeTypesFromParsing);
|
|
217
|
+
webgl.afterLoading(event?.features, rawLayer.styleId, rawLayer.excludeTypesFromParsing, rawLayer.isPointLayer);
|
|
218
218
|
});
|
|
219
219
|
}
|
|
220
220
|
}
|
|
@@ -238,7 +238,8 @@ function createLayer (rawLayer = {}, {layerParams = {}, options = {}} = {}) {
|
|
|
238
238
|
...rawLayer,
|
|
239
239
|
renderer: layerParams.renderer,
|
|
240
240
|
styleId: layerParams.styleId,
|
|
241
|
-
excludeTypesFromParsing: layerParams.excludeTypesFromParsing
|
|
241
|
+
excludeTypesFromParsing: layerParams.excludeTypesFromParsing,
|
|
242
|
+
isPointLayer: layerParams.isPointLayer
|
|
242
243
|
}, options);
|
|
243
244
|
layer = webgl.createLayer({
|
|
244
245
|
...rawLayer,
|
package/src/layer/wmts.js
CHANGED
|
@@ -112,8 +112,10 @@ function createLayerSourceByCapabilities (attrs, tileLayer) {
|
|
|
112
112
|
const layerIdentifier = attrs.layers,
|
|
113
113
|
url = attrs.capabilitiesUrl,
|
|
114
114
|
matrixSet = attrs.tileMatrixSet,
|
|
115
|
+
format = attrs.format,
|
|
115
116
|
capabilitiesOptions = {
|
|
116
|
-
layer: layerIdentifier
|
|
117
|
+
layer: layerIdentifier,
|
|
118
|
+
format
|
|
117
119
|
};
|
|
118
120
|
|
|
119
121
|
// use the matrixSet (if defined) for optionsFromCapabilities
|
|
@@ -201,4 +203,4 @@ export default {
|
|
|
201
203
|
getWMTSCapabilities,
|
|
202
204
|
generateArrays,
|
|
203
205
|
showErrorMessage
|
|
204
|
-
};
|
|
206
|
+
};
|
package/src/maps/ol/olMap.js
CHANGED
|
@@ -7,7 +7,6 @@ import * as wms from "../../layer/wms";
|
|
|
7
7
|
import wmts from "../../layer/wmts";
|
|
8
8
|
import * as geojson from "../../layer/geojson";
|
|
9
9
|
import wfs from "../../layer/wfs";
|
|
10
|
-
import * as vectorBase from "../../layer/vectorBase";
|
|
11
10
|
import * as vectortile from "../../layer/vectorTile";
|
|
12
11
|
import * as oaf from "../../layer/oaf";
|
|
13
12
|
import {createMapView} from "../../maps/mapView";
|
|
@@ -26,7 +25,6 @@ const layerBuilderMap = {
|
|
|
26
25
|
"wmts": wmts,
|
|
27
26
|
wfs,
|
|
28
27
|
geojson,
|
|
29
|
-
vectorBase,
|
|
30
28
|
vectortile,
|
|
31
29
|
oaf
|
|
32
30
|
},
|
package/src/renderer/webgl.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import WebGLPointsLayer from "ol/layer/WebGLPoints";
|
|
2
2
|
import WebGLVectorLayerRenderer from "ol/renderer/webgl/VectorLayer";
|
|
3
|
+
import WebGLVectorTileLayerRenderer from "ol/renderer/webgl/VectorTileLayer.js";
|
|
4
|
+
import VectorTile from "ol/layer/VectorTile.js";
|
|
3
5
|
import VectorLayer from "ol/layer/Layer";
|
|
4
6
|
import styleList from "../vectorStyle/styleList";
|
|
5
7
|
import {getRulesForFeature} from "../vectorStyle/lib/getRuleForIndex";
|
|
6
8
|
import {returnColor} from "../vectorStyle/lib/colorConvertions";
|
|
9
|
+
import {asArray} from "ol/color.js";
|
|
10
|
+
import {packColor, parseLiteralStyle} from "ol/webgl/styleparser.js";
|
|
7
11
|
|
|
8
12
|
/**
|
|
9
13
|
* The default style for OpenLayers WebGLPoints class
|
|
@@ -23,20 +27,20 @@ const defaultStyle = {
|
|
|
23
27
|
|
|
24
28
|
/** @type {import('ol/style/literal.js').LiteralStyle} */
|
|
25
29
|
style = {
|
|
26
|
-
"stroke-color": ["get", "
|
|
27
|
-
"stroke-width": ["get", "
|
|
28
|
-
"fill-color": ["get", "
|
|
29
|
-
"opacity": ["get", "
|
|
30
|
-
"size": ["get", "
|
|
30
|
+
"stroke-color": ["get", "strokeColor"],
|
|
31
|
+
"stroke-width": ["get", "strokeWidth", "number"],
|
|
32
|
+
"fill-color": ["get", "fillColor"],
|
|
33
|
+
"opacity": ["get", "opacity", "number"],
|
|
34
|
+
"size": ["get", "circleSize", "number"],
|
|
35
|
+
symbol: defaultStyle.symbol
|
|
31
36
|
};
|
|
32
37
|
|
|
33
38
|
/**
|
|
34
|
-
*
|
|
39
|
+
* Creates a vector layer with custom renderer.
|
|
35
40
|
* @augments VectorLayer
|
|
36
41
|
* @private
|
|
37
42
|
* @implements {WebGLVectorLayerRenderer}
|
|
38
|
-
* @
|
|
39
|
-
* @returns {module:ol/layer/Layer} the LocalWebGLLayer with a custom renderer for WebGL styling
|
|
43
|
+
* @returns {module:ol/layer/VectorLayer} the LocalWebGLLayer with a custom renderer for WebGL styling
|
|
40
44
|
*/
|
|
41
45
|
export function createVectorLayerRenderer () {
|
|
42
46
|
/**
|
|
@@ -46,7 +50,7 @@ export function createVectorLayerRenderer () {
|
|
|
46
50
|
*/
|
|
47
51
|
class LocalWebGLLayer extends VectorLayer {
|
|
48
52
|
/**
|
|
49
|
-
* Creates a new renderer that takes the defined style of the new layer as an input
|
|
53
|
+
* Creates a new renderer that takes the defined style of the new layer as an input.
|
|
50
54
|
* @returns {module:ol/renderer/webgl/WebGLVectorLayerRenderer} the custom renderer
|
|
51
55
|
* @experimental
|
|
52
56
|
*/
|
|
@@ -60,9 +64,101 @@ export function createVectorLayerRenderer () {
|
|
|
60
64
|
return LocalWebGLLayer;
|
|
61
65
|
}
|
|
62
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Creates a vector tile layer with custom renderer.
|
|
69
|
+
* @augments VectorTile
|
|
70
|
+
* @private
|
|
71
|
+
* @implements {WebGLVectorTileLayerRenderer}
|
|
72
|
+
* @returns {module:ol/layer/VectorTile} the LocalWebGLLayer with a custom renderer for WebGL styling of vectorTile layers.
|
|
73
|
+
*/
|
|
74
|
+
export function createVectorTileLayerRenderer () {
|
|
75
|
+
/**
|
|
76
|
+
* @class LocalWebGLLayer
|
|
77
|
+
* @see https://openlayers.org/en/latest/examples/webgl-vector-tiles.html
|
|
78
|
+
* @description the temporary class with a custom renderer to render the vectortiles with WebGL
|
|
79
|
+
*/
|
|
80
|
+
class LocalWebGLLayer extends VectorTile {
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Creates a new renderer that takes the defined style of the new layer as an input.
|
|
84
|
+
* @returns {module:ol/renderer/webgl/WebGLVectorTileLayerRenderer} the custom renderer
|
|
85
|
+
* @experimental
|
|
86
|
+
*/
|
|
87
|
+
createRenderer () {
|
|
88
|
+
const result = parseLiteralStyle(style),
|
|
89
|
+
invisible = [255, 255, 255, 0],
|
|
90
|
+
grey = [119, 119, 119, 1];
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
return new WebGLVectorTileLayerRenderer(this, {
|
|
94
|
+
style: {
|
|
95
|
+
fill: {
|
|
96
|
+
fragment: result.builder.getFillFragmentShader(),
|
|
97
|
+
vertex: result.builder.getFillVertexShader()
|
|
98
|
+
},
|
|
99
|
+
stroke: {
|
|
100
|
+
fragment: result.builder.getStrokeFragmentShader(),
|
|
101
|
+
vertex: result.builder.getStrokeVertexShader()
|
|
102
|
+
},
|
|
103
|
+
symbol: {
|
|
104
|
+
fragment: result.builder.getSymbolFragmentShader(),
|
|
105
|
+
vertex: result.builder.getSymbolVertexShader()
|
|
106
|
+
},
|
|
107
|
+
attributes: {
|
|
108
|
+
fillColor: {
|
|
109
|
+
size: 2,
|
|
110
|
+
callback: (feature) => {
|
|
111
|
+
const featureStyle = this.getStyle()(feature, 1);
|
|
112
|
+
|
|
113
|
+
if (featureStyle && featureStyle[0]) {
|
|
114
|
+
const color = featureStyle[0]?.getFill()?.getColor();
|
|
115
|
+
|
|
116
|
+
return packColor(color && typeof color === "string" ? asArray(color) : invisible);
|
|
117
|
+
}
|
|
118
|
+
return packColor(grey);
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
strokeColor: {
|
|
122
|
+
size: 2,
|
|
123
|
+
callback: (feature) => {
|
|
124
|
+
const featureStyle = this.getStyle()(feature, 1);
|
|
125
|
+
|
|
126
|
+
if (featureStyle && featureStyle[0]) {
|
|
127
|
+
const color = featureStyle[0]?.getStroke()?.getColor();
|
|
128
|
+
|
|
129
|
+
return packColor(color ? asArray(color) : invisible);
|
|
130
|
+
}
|
|
131
|
+
return packColor(grey);
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
strokeWidth: {
|
|
135
|
+
size: 1,
|
|
136
|
+
callback: (feature) => {
|
|
137
|
+
const featureStyle = this.getStyle()(feature, 1);
|
|
138
|
+
|
|
139
|
+
if (featureStyle && featureStyle[0]) {
|
|
140
|
+
const width = featureStyle[0]?.getStroke()?.getWidth();
|
|
141
|
+
|
|
142
|
+
if (width !== undefined) {
|
|
143
|
+
return width > 10 ? width / 10 : 1;/** @todo needs refactoring in later versions */
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return 1;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return LocalWebGLLayer;
|
|
156
|
+
}
|
|
157
|
+
|
|
63
158
|
/**
|
|
64
159
|
* Parses the vectorStyle from style.json to the feature
|
|
65
|
-
* to reduce processing on runtime
|
|
160
|
+
* to reduce processing on runtime.
|
|
161
|
+
* Sets properties with style at feature to use by literalSytle of renderer of VectorLayer.
|
|
66
162
|
* @private
|
|
67
163
|
* @param {module:ol/Feature} feature - the feature to check
|
|
68
164
|
* @param {module:Backbone/Model} [styleObject] - (optional) the style model from StyleList
|
|
@@ -87,11 +183,11 @@ export function formatFeatureStyles (feature, styleObject) {
|
|
|
87
183
|
strokeWidth = rule.style.polygonStrokeWidth || rule.style.lineStrokeWidth,
|
|
88
184
|
size = rule.style.circleRadius;
|
|
89
185
|
|
|
90
|
-
feature.set("
|
|
91
|
-
feature.set("
|
|
92
|
-
feature.set("
|
|
93
|
-
feature.set("
|
|
94
|
-
feature.set("
|
|
186
|
+
feature.set("fillColor", fillColor ? fillColor : "#006688");
|
|
187
|
+
feature.set("strokeColor", strokeColor ? strokeColor : "#006688");
|
|
188
|
+
feature.set("strokeWidth", strokeWidth ? strokeWidth : 1);
|
|
189
|
+
feature.set("opacity", fillColor ? (rule.style.polygonFillColor || rule.style.circleFillColor)[3] : 1);
|
|
190
|
+
feature.set("circleSize", size ? size : 20);
|
|
95
191
|
}
|
|
96
192
|
}
|
|
97
193
|
|
|
@@ -134,19 +230,28 @@ export function formatFeatureData (feature, excludeTypes = ["boolean"]) {
|
|
|
134
230
|
}
|
|
135
231
|
|
|
136
232
|
/**
|
|
137
|
-
* feature transformations called after loading
|
|
233
|
+
* feature transformations called after loading - but not for layer of typ VectortTile
|
|
138
234
|
* called by the layer source loader, binds the instance of the layer model
|
|
139
235
|
* should be called on each source refresh
|
|
140
236
|
* @param {module:ol/Feature[]} features - the features loaded by the layer
|
|
141
237
|
* @param {String} styleId - The layer's styleId
|
|
142
238
|
* @param {String[]} excludeTypesFromParsing - types that should not be parsed from strings, only necessary for webgl
|
|
239
|
+
* @param {Boolean} isPointLayer - whether the layer source should consist only of points (or multi points)
|
|
143
240
|
* @returns {void}
|
|
144
241
|
*/
|
|
145
|
-
export function afterLoading (features, styleId, excludeTypesFromParsing) {
|
|
242
|
+
export function afterLoading (features, styleId, excludeTypesFromParsing, isPointLayer) {
|
|
146
243
|
const styleObject = styleList.returnStyleObject(styleId); // load styleModel to extract rules per feature
|
|
147
244
|
|
|
148
245
|
if (Array.isArray(features)) {
|
|
149
246
|
features.forEach(feature => {
|
|
247
|
+
/**
|
|
248
|
+
* extract first point from Multipoint
|
|
249
|
+
* @deprecated will probably not be necessary anymore in release version
|
|
250
|
+
* @example An example for that behavior can be found when rendering "Strassenbaumkataster"
|
|
251
|
+
*/
|
|
252
|
+
if (isPointLayer && feature.getGeometry().getType() === "MultiPoint") {
|
|
253
|
+
feature.setGeometry(feature.getGeometry().getPoint(0)); // other points in the multi point will be ignored for now
|
|
254
|
+
}
|
|
150
255
|
formatFeatureGeometry(feature); /** @deprecated will propbably not be necessary anymore in release version */
|
|
151
256
|
formatFeatureStyles(feature, styleObject); /** @todo needs refactoring in release version */
|
|
152
257
|
formatFeatureData(feature, excludeTypesFromParsing); /** Necessary since the WebGLPoints Style Syntax depends on data types (i.e. numbers not as strings) */
|
|
@@ -175,7 +280,8 @@ export function createLayer (attrs) {
|
|
|
175
280
|
opacity: attrs.transparency ? (100 - attrs.transparency) / 100 : attrs.opacity,
|
|
176
281
|
renderer: "webgl",
|
|
177
282
|
styleId: attrs.styleId,
|
|
178
|
-
excludeTypesFromParsing: attrs.excludeTypesFromParsing
|
|
283
|
+
excludeTypesFromParsing: attrs.excludeTypesFromParsing,
|
|
284
|
+
extent: attrs.extent
|
|
179
285
|
};
|
|
180
286
|
|
|
181
287
|
/**
|
|
@@ -196,11 +302,22 @@ export function createLayer (attrs) {
|
|
|
196
302
|
});
|
|
197
303
|
}
|
|
198
304
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
305
|
+
if (attrs.typ === "VectorTile") {
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* use ol/renderer/webgl/WebGLVectorLayerRenderer if not point layer
|
|
309
|
+
* Point styling as quads only
|
|
310
|
+
*/
|
|
311
|
+
LayerConstructor = createVectorTileLayerRenderer(attrs);
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* use ol/renderer/webgl/WebGLVectorLayerRenderer if not point layer
|
|
317
|
+
* Point styling as quads only
|
|
318
|
+
*/
|
|
319
|
+
LayerConstructor = createVectorLayerRenderer(attrs);
|
|
320
|
+
}
|
|
204
321
|
return new LayerConstructor({
|
|
205
322
|
...options,
|
|
206
323
|
isPointLayer: false
|
|
@@ -230,31 +230,15 @@ function initializeStyleList (styleGetters, Config, layers, tools, callback) {
|
|
|
230
230
|
styleConf = Config.styleConf;
|
|
231
231
|
featureViaUrlLayers = Config.featureViaURL?.layers;
|
|
232
232
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
xhr.onreadystatechange = function (event) {
|
|
237
|
-
const target = event.target,
|
|
238
|
-
status = target.status;
|
|
239
|
-
let data;
|
|
240
|
-
|
|
241
|
-
if (status === 200) {
|
|
242
|
-
try {
|
|
243
|
-
data = JSON.parse(target.response);
|
|
244
|
-
}
|
|
245
|
-
catch (error) {
|
|
246
|
-
console.error("An error occured when parsing the response after loading '" + styleConf + "':", error);
|
|
247
|
-
return callback(false, error);
|
|
248
|
-
}
|
|
233
|
+
fetch(styleConf)
|
|
234
|
+
.then(response => response.json())
|
|
235
|
+
.then(data => {
|
|
249
236
|
styleList = parseStyles(data);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
console.error(
|
|
253
|
-
|
|
254
|
-
}
|
|
255
|
-
return callback(styleList);
|
|
256
|
-
};
|
|
257
|
-
xhr.send();
|
|
237
|
+
})
|
|
238
|
+
.catch(error => {
|
|
239
|
+
console.error(error);
|
|
240
|
+
callback(false, true);
|
|
241
|
+
});
|
|
258
242
|
}
|
|
259
243
|
|
|
260
244
|
/**
|
|
@@ -98,11 +98,23 @@ describe("geojson/index", function () {
|
|
|
98
98
|
it("creates a vectorSource with an additional listener, when renderer is \"webgl\"", () => {
|
|
99
99
|
const
|
|
100
100
|
rawLayer = {url: "example.com/geo.json"},
|
|
101
|
-
|
|
101
|
+
layerParams = {
|
|
102
|
+
renderer: "webgl",
|
|
103
|
+
styleId: "id",
|
|
104
|
+
excludeTypesFromParsing: null,
|
|
105
|
+
isPointLayer: true
|
|
106
|
+
},
|
|
107
|
+
source = geojson.createLayerSource({
|
|
108
|
+
...rawLayer,
|
|
109
|
+
renderer: layerParams.renderer,
|
|
110
|
+
styleId: layerParams.styleId,
|
|
111
|
+
excludeTypesFromParsing: layerParams.excludeTypesFromParsing,
|
|
112
|
+
isPointLayer: layerParams.isPointLayer
|
|
113
|
+
}, {});
|
|
102
114
|
|
|
103
115
|
expect(source.getListeners("featuresloadend")).toHaveLength(2);
|
|
104
|
-
source.getListeners("featuresloadend")[1]({features
|
|
105
|
-
expect(webgl.afterLoading).
|
|
116
|
+
source.getListeners("featuresloadend")[1]({features});
|
|
117
|
+
expect(webgl.afterLoading).toHaveBeenCalledWith(features, layerParams.styleId, layerParams.excludeTypesFromParsing, layerParams.isPointLayer);
|
|
106
118
|
});
|
|
107
119
|
|
|
108
120
|
});
|
package/test/layer/oaf.test.js
CHANGED
|
@@ -267,11 +267,24 @@ describe("oaf.js", function () {
|
|
|
267
267
|
featureType: "krankenhaeuser_hh",
|
|
268
268
|
version: "1.0.0"
|
|
269
269
|
},
|
|
270
|
-
|
|
270
|
+
layerParams = {
|
|
271
|
+
renderer: "webgl",
|
|
272
|
+
styleId: "id",
|
|
273
|
+
excludeTypesFromParsing: null,
|
|
274
|
+
isPointLayer: true
|
|
275
|
+
},
|
|
276
|
+
source = oaf.createLayerSource({
|
|
277
|
+
...rawLayer,
|
|
278
|
+
renderer: layerParams.renderer,
|
|
279
|
+
styleId: layerParams.styleId,
|
|
280
|
+
excludeTypesFromParsing: layerParams.excludeTypesFromParsing,
|
|
281
|
+
isPointLayer: layerParams.isPointLayer
|
|
282
|
+
}),
|
|
283
|
+
features = [];
|
|
271
284
|
|
|
272
285
|
expect(source.getListeners("featuresloadend")).toHaveLength(1);
|
|
273
|
-
source.getListeners("featuresloadend")[0]({features
|
|
274
|
-
expect(webgl.afterLoading).
|
|
286
|
+
source.getListeners("featuresloadend")[0]({features});
|
|
287
|
+
expect(webgl.afterLoading).toHaveBeenCalledWith(features, layerParams.styleId, layerParams.excludeTypesFromParsing, layerParams.isPointLayer);
|
|
275
288
|
});
|
|
276
289
|
});
|
|
277
290
|
});
|
|
@@ -2,6 +2,7 @@ import OpenLayersVectorTileLayer from "ol/layer/VectorTile";
|
|
|
2
2
|
import OpenLayersVectorTileSource from "ol/source/VectorTile";
|
|
3
3
|
import OpenLayersTileGrid from "ol/tilegrid/TileGrid";
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
import {Feature} from "ol";
|
|
6
7
|
import Polygon from "ol/geom/Polygon";
|
|
7
8
|
|
|
@@ -16,11 +17,21 @@ jest.mock("../../src/rawLayerList.js", () => {
|
|
|
16
17
|
return original;
|
|
17
18
|
});
|
|
18
19
|
|
|
20
|
+
jest.mock("../../src/renderer/webgl.js", () => {
|
|
21
|
+
const original = jest.requireActual("../../src/renderer/webgl.js");
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
...original,
|
|
25
|
+
afterLoading: jest.fn()
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
|
|
19
30
|
describe("vectorTile.js", function () {
|
|
20
31
|
|
|
21
32
|
beforeAll(() => crs.registerProjections());
|
|
22
33
|
|
|
23
|
-
const
|
|
34
|
+
const rawLayer = {
|
|
24
35
|
name: "VT Test",
|
|
25
36
|
id: "VT_01",
|
|
26
37
|
url: "https://example.org"
|
|
@@ -79,12 +90,13 @@ describe("vectorTile.js", function () {
|
|
|
79
90
|
source = vectorTile.createLayerSource("https://foo.example.org", sourceParams);
|
|
80
91
|
|
|
81
92
|
expect(source).toBeInstanceOf(OpenLayersVectorTileSource);
|
|
93
|
+
expect(typeof source.getTileLoadFunction()).toEqual("function");
|
|
82
94
|
});
|
|
83
95
|
});
|
|
84
96
|
|
|
85
97
|
describe("createLayer", function () {
|
|
86
98
|
it("creates a vector Tile Layer", function () {
|
|
87
|
-
const layer = vectorTile.createLayer(
|
|
99
|
+
const layer = vectorTile.createLayer(rawLayer);
|
|
88
100
|
|
|
89
101
|
expect(layer).toBeInstanceOf(OpenLayersVectorTileLayer);
|
|
90
102
|
expect(layer.getSource()).toBeInstanceOf(OpenLayersVectorTileSource);
|
|
@@ -92,6 +104,13 @@ describe("vectorTile.js", function () {
|
|
|
92
104
|
expect(layer.get("id")).toEqual("VT_01");
|
|
93
105
|
});
|
|
94
106
|
|
|
107
|
+
it("creates a vector Tile Layer with webgl renderer", function () {
|
|
108
|
+
const layer = vectorTile.createLayer(rawLayer, {layerParams: {renderer: "webgl"}});
|
|
109
|
+
|
|
110
|
+
expect(layer.constructor.name).toEqual("LocalWebGLLayer");
|
|
111
|
+
expect(layer.getSource()).toBeInstanceOf(OpenLayersVectorTileSource);
|
|
112
|
+
});
|
|
113
|
+
|
|
95
114
|
it("should log an error when required param is missing", function () {
|
|
96
115
|
const spyConsole = jest.spyOn(console, "error").mockImplementation(() => ""),
|
|
97
116
|
layer = vectorTile.createLayer({
|
|
@@ -139,7 +158,7 @@ describe("vectorTile.js", function () {
|
|
|
139
158
|
],
|
|
140
159
|
tileSize: 512
|
|
141
160
|
},
|
|
142
|
-
layer = vectorTile.createLayer(
|
|
161
|
+
layer = vectorTile.createLayer(rawLayer),
|
|
143
162
|
source = layer.getSource(),
|
|
144
163
|
tileGrid = source.getTileGrid();
|
|
145
164
|
|
|
@@ -156,7 +175,7 @@ describe("vectorTile.js", function () {
|
|
|
156
175
|
|
|
157
176
|
describe("setStyle", function () {
|
|
158
177
|
it("should apply a given style", function () {
|
|
159
|
-
const layer = vectorTile.createLayer(
|
|
178
|
+
const layer = vectorTile.createLayer(rawLayer);
|
|
160
179
|
|
|
161
180
|
let featureStyle = null;
|
|
162
181
|
|
package/test/layer/wfs.test.js
CHANGED
|
@@ -422,11 +422,24 @@ describe("wfs.js", function () {
|
|
|
422
422
|
featureType: "krankenhaeuser_hh",
|
|
423
423
|
version: "1.0.0"
|
|
424
424
|
},
|
|
425
|
-
|
|
425
|
+
layerParams = {
|
|
426
|
+
renderer: "webgl",
|
|
427
|
+
styleId: "id",
|
|
428
|
+
excludeTypesFromParsing: null,
|
|
429
|
+
isPointLayer: true
|
|
430
|
+
},
|
|
431
|
+
source = wfs.createLayerSource({
|
|
432
|
+
...rawLayer,
|
|
433
|
+
renderer: layerParams.renderer,
|
|
434
|
+
styleId: layerParams.styleId,
|
|
435
|
+
excludeTypesFromParsing: layerParams.excludeTypesFromParsing,
|
|
436
|
+
isPointLayer: layerParams.isPointLayer
|
|
437
|
+
}),
|
|
438
|
+
features = [];
|
|
426
439
|
|
|
427
440
|
expect(source.getListeners("featuresloadend")).toHaveLength(1);
|
|
428
|
-
source.getListeners("featuresloadend")[0]({features
|
|
429
|
-
expect(webgl.afterLoading).
|
|
441
|
+
source.getListeners("featuresloadend")[0]({features});
|
|
442
|
+
expect(webgl.afterLoading).toHaveBeenCalledWith(features, layerParams.styleId, layerParams.excludeTypesFromParsing, layerParams.isPointLayer);
|
|
430
443
|
});
|
|
431
444
|
it("creates a vectorSource with credentials: include as params", () => {
|
|
432
445
|
global.fetch = jest.fn().mockImplementationOnce(() => {
|
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
import VectorSource from "ol/source/Vector.js";
|
|
2
|
+
import VectorTileSource from "ol/source/VectorTile";
|
|
3
|
+
import VectorTile from "ol/layer/VectorTile.js";
|
|
2
4
|
import Feature from "ol/Feature";
|
|
3
5
|
import Polygon from "ol/geom/Polygon";
|
|
6
|
+
import MultiPoint from "ol/geom/MultiPoint";
|
|
4
7
|
import * as webgl from "../../src/renderer/webgl";
|
|
5
8
|
import WebGLPointsLayer from "ol/layer/WebGLPoints";
|
|
6
9
|
import Layer from "ol/layer/Layer";
|
|
7
|
-
import
|
|
10
|
+
import {returnColor} from "../../src/vectorStyle/lib/colorConvertions";
|
|
11
|
+
|
|
12
|
+
jest.mock("../../src/vectorStyle/styleList.js", () => {
|
|
13
|
+
const
|
|
14
|
+
original = jest.requireActual("../../src/vectorStyle/styleList.js");
|
|
15
|
+
|
|
16
|
+
original.returnStyleObject = jest.fn(() => "xyz");
|
|
17
|
+
return original;
|
|
18
|
+
});
|
|
8
19
|
|
|
9
20
|
describe("webgl.js", () => {
|
|
10
|
-
let layerParams, rawLayer, styleRule, styleObject;
|
|
21
|
+
let layerParams, layerParamsVectorTile, rawLayer, rawLayerVectorTile, styleRule, styleObject;
|
|
11
22
|
|
|
12
23
|
beforeEach(() => {
|
|
13
24
|
layerParams = {
|
|
@@ -27,6 +38,26 @@ describe("webgl.js", () => {
|
|
|
27
38
|
featureType: "krankenhaeuser_hh",
|
|
28
39
|
outputFormat: "XML"
|
|
29
40
|
};
|
|
41
|
+
rawLayerVectorTile = {
|
|
42
|
+
id: "4000",
|
|
43
|
+
name: "XPLAN",
|
|
44
|
+
url: "https://xplanung.ldproxy.devops.diplanung.de/rest/services/xplansyn/tiles/WebMercatorQuad/{z}/{y}/{x}?f=mvt",
|
|
45
|
+
typ: "VectorTile",
|
|
46
|
+
epsg: "EPSG:3857",
|
|
47
|
+
tileSize: 512,
|
|
48
|
+
extent: [
|
|
49
|
+
902186.674876469653,
|
|
50
|
+
7054472.60470921732,
|
|
51
|
+
1161598.35425907862,
|
|
52
|
+
7175683.41171819717
|
|
53
|
+
]
|
|
54
|
+
};
|
|
55
|
+
layerParamsVectorTile = {
|
|
56
|
+
id: "4000",
|
|
57
|
+
renderer: "webgl",
|
|
58
|
+
styleId: "4000",
|
|
59
|
+
visibility: true
|
|
60
|
+
};
|
|
30
61
|
styleRule = {style: {
|
|
31
62
|
polygonFillColor: [255, 0, 0, 0.5],
|
|
32
63
|
polygonStrokeColor: [0, 255, 0, 0.5],
|
|
@@ -37,16 +68,10 @@ describe("webgl.js", () => {
|
|
|
37
68
|
styleObject = {
|
|
38
69
|
rules: [styleRule]
|
|
39
70
|
};
|
|
40
|
-
|
|
41
|
-
jest.spyOn(styleList, "returnStyleObject").mockImplementation(() => styleObject);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
afterEach(() => {
|
|
45
|
-
jest.restoreAllMocks();
|
|
46
71
|
});
|
|
47
72
|
|
|
48
73
|
describe("createLayer", () => {
|
|
49
|
-
|
|
74
|
+
let source = new VectorSource();
|
|
50
75
|
|
|
51
76
|
it("should return a WebGLPointsLayer", () => {
|
|
52
77
|
layerParams.isPointLayer = true;
|
|
@@ -63,6 +88,28 @@ describe("webgl.js", () => {
|
|
|
63
88
|
expect(webglLayer).not.toBeInstanceOf(WebGLPointsLayer);
|
|
64
89
|
expect(webglLayer.get("isPointLayer")).toBeFalsy();
|
|
65
90
|
});
|
|
91
|
+
it("vectorTile: should return a VectorTile layer", () => {
|
|
92
|
+
source = new VectorTileSource({...rawLayerVectorTile, ...layerParamsVectorTile});
|
|
93
|
+
layerParams.isPointLayer = false;
|
|
94
|
+
const webglLayer = webgl.createLayer({...rawLayerVectorTile, ...layerParamsVectorTile, source});
|
|
95
|
+
|
|
96
|
+
expect(webglLayer).toBeInstanceOf(Layer);
|
|
97
|
+
expect(webglLayer).toBeInstanceOf(VectorTile);
|
|
98
|
+
expect(webglLayer).not.toBeInstanceOf(WebGLPointsLayer);
|
|
99
|
+
expect(webglLayer.get("isPointLayer")).toBeFalsy();
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
describe("afterLoading", () => {
|
|
103
|
+
const feature = new Feature({
|
|
104
|
+
geometry: new MultiPoint([
|
|
105
|
+
[[0, 0, 0], [1, 0, 0], [1, 1, 0]]
|
|
106
|
+
], "XYZ")
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("should extract single points from MultiPoint geometries, if isPointLayer", () => {
|
|
110
|
+
webgl.afterLoading([feature], layerParams.styleId, null, true);
|
|
111
|
+
expect(feature.getGeometry().getType()).toEqual("Point");
|
|
112
|
+
});
|
|
66
113
|
});
|
|
67
114
|
describe("private format and style functions", () => {
|
|
68
115
|
const
|
|
@@ -106,6 +153,26 @@ describe("webgl.js", () => {
|
|
|
106
153
|
webgl.formatFeatureStyles($feature, styleObject);
|
|
107
154
|
expect($feature.styleRule).toEqual(styleRule);
|
|
108
155
|
});
|
|
156
|
+
it("set the necessary style attributes on the feature for literal style syntax", () => {
|
|
157
|
+
$feature = feature.clone();
|
|
158
|
+
webgl.formatFeatureStyles($feature, styleObject);
|
|
159
|
+
expect($feature.get("fillColor")).toEqual(returnColor(styleRule.style.polygonFillColor, "hex"));
|
|
160
|
+
expect($feature.get("strokeColor")).toEqual(returnColor(styleRule.style.polygonStrokeColor, "hex"));
|
|
161
|
+
expect($feature.get("strokeWidth")).toEqual(styleRule.style.polygonStrokeWidth);
|
|
162
|
+
expect($feature.get("opacity")).toEqual(styleRule.style.polygonFillColor[3]);
|
|
163
|
+
expect($feature.get("circleSize")).toEqual(styleRule.style.circleRadius);
|
|
164
|
+
});
|
|
165
|
+
it("circle: bind the styling rule from the styleObject to each feature", () => {
|
|
166
|
+
styleRule.style.polygonFillColor = undefined;
|
|
167
|
+
styleRule.style.polygonStrokeColor = undefined;
|
|
168
|
+
styleRule.style.polygonStrokeWidth = undefined;
|
|
169
|
+
$feature = feature.clone();
|
|
170
|
+
webgl.formatFeatureStyles($feature, styleObject);
|
|
171
|
+
expect($feature.styleRule).toEqual(styleRule);
|
|
172
|
+
expect($feature.get("fillColor")).toEqual(returnColor(styleRule.style.circleFillColor, "hex"));
|
|
173
|
+
expect($feature.get("opacity")).toEqual(styleRule.style.circleFillColor[3]);
|
|
174
|
+
expect($feature.get("circleSize")).toEqual(styleRule.style.circleRadius);
|
|
175
|
+
});
|
|
109
176
|
});
|
|
110
177
|
});
|
|
111
178
|
});
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import Feature from "ol/Feature";
|
|
2
|
-
import Point from "ol/geom/Point";
|
|
3
|
-
import Polygon from "ol/geom/Polygon";
|
|
4
|
-
import VectorLayer from "ol/layer/Vector";
|
|
5
|
-
import VectorSource from "ol/source/Vector.js";
|
|
6
|
-
import * as vectorBase from "../../src/layer/vectorBase";
|
|
7
|
-
import * as webgl from "../../src/renderer/webgl.js";
|
|
8
|
-
|
|
9
|
-
jest.mock("../../src/renderer/webgl.js", () => {
|
|
10
|
-
const original = jest.requireActual("../../src/renderer/webgl.js");
|
|
11
|
-
|
|
12
|
-
return {
|
|
13
|
-
...original,
|
|
14
|
-
afterLoading: jest.fn()
|
|
15
|
-
};
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
describe("vectorBase.js", function () {
|
|
19
|
-
|
|
20
|
-
describe("createLayerSource", function () {
|
|
21
|
-
it("creates a layerSource with features", function () {
|
|
22
|
-
const attr = {
|
|
23
|
-
features: [
|
|
24
|
-
new Feature({geometry: new Polygon([[[565086.1948534324, 5934664.461947621], [565657.6945448224, 5934738.54524095], [565625.9445619675, 5934357.545446689], [565234.3614400891, 5934346.962119071], [565086.1948534324, 5934664.461947621]]])}),
|
|
25
|
-
new Feature({geometry: new Point([565826.38, 5934174.40])})
|
|
26
|
-
]
|
|
27
|
-
},
|
|
28
|
-
source = vectorBase.createLayerSource(attr);
|
|
29
|
-
|
|
30
|
-
expect(source).toBeInstanceOf(VectorSource);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it("creates a layerSource without features", function () {
|
|
34
|
-
const source = vectorBase.createLayerSource({});
|
|
35
|
-
|
|
36
|
-
expect(source).toBeInstanceOf(VectorSource);
|
|
37
|
-
});
|
|
38
|
-
it("creates a vectorSource with an additional listener, when renderer is \"webgl\"", () => {
|
|
39
|
-
vectorBase.createLayerSource({renderer: "webgl"});
|
|
40
|
-
|
|
41
|
-
expect(webgl.afterLoading).toHaveBeenCalled();
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
describe("createLayer", function () {
|
|
46
|
-
const attr = {
|
|
47
|
-
name: "Albus Percival Wulfric Brian Dumbledore",
|
|
48
|
-
typ: "VectorBase",
|
|
49
|
-
gfiAttributes: "ignore",
|
|
50
|
-
id: "Rawenclaw_01"
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
it("creates a vector Base Layer", function () {
|
|
54
|
-
const layer = vectorBase.createLayer(attr);
|
|
55
|
-
|
|
56
|
-
expect(layer).toBeInstanceOf(VectorLayer);
|
|
57
|
-
expect(layer.get("name")).toEqual("Albus Percival Wulfric Brian Dumbledore");
|
|
58
|
-
expect(layer.get("typ")).toEqual("VectorBase");
|
|
59
|
-
expect(layer.get("id")).toEqual("Rawenclaw_01");
|
|
60
|
-
});
|
|
61
|
-
it("creates a WebGLLayer, with param renderer \"webgl\"", function () {
|
|
62
|
-
const layer = vectorBase.createLayer({...attr, renderer: "webgl"});
|
|
63
|
-
|
|
64
|
-
expect(layer.constructor.name).toEqual("LocalWebGLLayer");
|
|
65
|
-
expect(layer.getSource()).toBeInstanceOf(VectorSource);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
describe("updateSource", function () {
|
|
70
|
-
it("updateSource will fetch layer again", function () {
|
|
71
|
-
const layer = vectorBase.createLayer({id: "id"}),
|
|
72
|
-
layerGetSourceMock = jest.fn(() => {
|
|
73
|
-
return {
|
|
74
|
-
clear: () => this,
|
|
75
|
-
addFeatures: () => this
|
|
76
|
-
};
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
layer.getSource = layerGetSourceMock;
|
|
80
|
-
vectorBase.updateSource(layer);
|
|
81
|
-
expect(layerGetSourceMock.mock.calls.length).toBe(2);
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
});
|