@masterportal/masterportalapi 2.49.0 → 2.51.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 +40 -2
- package/bitbucket-pipelines.yml +43 -0
- package/package.json +29 -17
- package/publiccode.yml +88 -0
- package/src/layer/oaf.js +5 -0
- package/src/layer/wmts.js +1 -1
- package/src/renderer/webgl.js +49 -79
- package/src/vectorStyle/styleList.js +25 -0
- package/test/layer/oaf.test.js +10 -0
- package/test/lib/setBackgroundImage.test.js +3 -2
- package/test/renderer/webgl.test.js +54 -13
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
The [Semantic Versioning](https://semver.org/spec/v2.0.0.html) is used.
|
|
5
5
|
|
|
6
6
|
## Unreleased - in development
|
|
7
|
-
|
|
8
7
|
### __Breaking Changes__
|
|
9
8
|
|
|
10
9
|
### Added
|
|
@@ -19,10 +18,49 @@
|
|
|
19
18
|
|
|
20
19
|
---
|
|
21
20
|
|
|
22
|
-
## 2.
|
|
21
|
+
## 2.51.0 - 2025-09-18
|
|
22
|
+
|
|
23
|
+
### __Breaking Changes__
|
|
24
|
+
- Dropped support for **Node.js 18.x**, **20.x** and **npm 9**. Minimum required is now **Node.js 22.19.0 (LTS)** with **npm 10.x**.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- cesium/engine updated to current Version 20.0.1
|
|
28
|
+
- The following packages have been updated:
|
|
29
|
+
- devDependencies:
|
|
30
|
+
- @parcel: ^2.13.0 to ^2.15.4
|
|
31
|
+
- @swc/jest: ^0.2.29 to ^0.2.39
|
|
32
|
+
- canvas: ^2.11.2 to ^3.1.2
|
|
33
|
+
- jest: ^29.7.0 to ^30.0.5
|
|
34
|
+
- jest-environment-jsdom: ^29.7.0 to ^30.0.5
|
|
35
|
+
- transformer-sass: ^2.13.0 to ^2.15.4
|
|
36
|
+
- the following package has been added:
|
|
37
|
+
- devDependencies:
|
|
38
|
+
- @parcel/config-default": "^2.15.4"
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 2.50.0 - 2025-08-214
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
- vectorStyle: added function `initStyleAndAddToList` to styleList. Adds a style contained in style.json to list of styles.
|
|
46
|
+
- A new parameter "doNotLoadInitially" for OAF layer so that the layer can be loaded without features, which is necessary for external filtering.
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
- The following packages have been updated:
|
|
50
|
+
- dependencies:
|
|
51
|
+
- ol: 10.4.1 to 10.6.0
|
|
52
|
+
|
|
53
|
+
### Fixed
|
|
54
|
+
- WMTS-Layer: Fixed layers without capabilities.
|
|
55
|
+
- WFTS-Layer: Ensured zIndex is applied correctly to layers using webgl renderer.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 2.49.0 - 2025-04-29
|
|
23
60
|
|
|
24
61
|
### Added
|
|
25
62
|
- Add new parameters polygonStrokeDash, polygonStrokeDashOffset in styleObject of drawInteraction.
|
|
63
|
+
- webgl: extended default style for points.
|
|
26
64
|
|
|
27
65
|
### Changed
|
|
28
66
|
- The following packages have been updated:
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
image: node:22.19.0
|
|
2
|
+
|
|
3
|
+
clone:
|
|
4
|
+
depth: 5000 # include the last five hundred commits
|
|
5
|
+
|
|
6
|
+
pipelines:
|
|
7
|
+
# Start pipeline with tag to build examples zips and copy them to the Bitbucket download folder
|
|
8
|
+
tags:
|
|
9
|
+
'v2.*.*':
|
|
10
|
+
- step:
|
|
11
|
+
name: deploy on openCode
|
|
12
|
+
script:
|
|
13
|
+
- echo 'deploy to opencode:'$BITBUCKET_TAG
|
|
14
|
+
- git fetch --all --tags
|
|
15
|
+
- git checkout tags/$BITBUCKET_TAG
|
|
16
|
+
- git push https://$OpenCode_User:$OpenCode_Password@gitlab.opencode.de/geowerkstatt-hamburg/masterportalapi.git $BITBUCKET_TAG
|
|
17
|
+
- git clone --single-branch --branch master https://geowerkstatt@bitbucket.org/geowerkstatt-hamburg/masterportalapi.git
|
|
18
|
+
- cd masterportalapi
|
|
19
|
+
- git push https://$OpenCode_User:$OpenCode_Password@gitlab.opencode.de/geowerkstatt-hamburg/masterportalapi.git -f
|
|
20
|
+
custom: # Pipelines that are triggered manually
|
|
21
|
+
npm audit:
|
|
22
|
+
- step:
|
|
23
|
+
name: npm audit (security)
|
|
24
|
+
caches:
|
|
25
|
+
- node
|
|
26
|
+
script:
|
|
27
|
+
- npm install
|
|
28
|
+
- npm audit --json
|
|
29
|
+
deploy last tag on openCode:
|
|
30
|
+
- variables:
|
|
31
|
+
- name: BITBUCKET_TAG
|
|
32
|
+
description: tag to publish docs for
|
|
33
|
+
- step:
|
|
34
|
+
name: deploy last tag on openCode
|
|
35
|
+
script:
|
|
36
|
+
- apt-get update && apt-get install -y curl wput jq
|
|
37
|
+
- git fetch --all --tags
|
|
38
|
+
- echo 'deply to opencode:'$BITBUCKET_TAG
|
|
39
|
+
- git checkout tags/$BITBUCKET_TAG
|
|
40
|
+
- git push https://$OpenCode_User:$OpenCode_Password@gitlab.opencode.de/geowerkstatt-hamburg/masterportalapi.git $BITBUCKET_TAG
|
|
41
|
+
- git clone --single-branch --branch master https://geowerkstatt@bitbucket.org/geowerkstatt-hamburg/masterportalapi.git
|
|
42
|
+
- cd masterportalapi
|
|
43
|
+
- git push https://$OpenCode_User:$OpenCode_Password@gitlab.opencode.de/geowerkstatt-hamburg/masterportalapi.git -f
|
package/package.json
CHANGED
|
@@ -1,14 +1,25 @@
|
|
|
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.51.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Basic functions of the Masterportal as api",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "git+https://bitbucket.org/geowerkstatt-hamburg/masterportalapi.git"
|
|
10
10
|
},
|
|
11
|
+
"source": "src/index.js",
|
|
11
12
|
"main": "src/index.js",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": "./src/index.js"
|
|
15
|
+
},
|
|
16
|
+
"targets": {
|
|
17
|
+
"library": {
|
|
18
|
+
"source": "src/index.js",
|
|
19
|
+
"distDir": "dist",
|
|
20
|
+
"outputFormat": "commonjs"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
12
23
|
"scripts": {
|
|
13
24
|
"test": "jest .test.js --config ./jest.config.js --collectCoverage",
|
|
14
25
|
"test:trace": "node --trace-warnings node_modules/jest/bin/jest.js .test.js --config ./jest.config.js",
|
|
@@ -21,33 +32,34 @@
|
|
|
21
32
|
"dependencies": {
|
|
22
33
|
"core-js": "^3.33.1",
|
|
23
34
|
"dayjs": "^1.11.10",
|
|
24
|
-
"ol": "^10.
|
|
35
|
+
"ol": "^10.6.0",
|
|
25
36
|
"ol-mapbox-style": "12.5.0",
|
|
26
37
|
"olcs": "^2.22.1",
|
|
27
38
|
"proj4": "^2.10.0",
|
|
28
39
|
"xml2js": "^0.6.2"
|
|
29
40
|
},
|
|
30
41
|
"devDependencies": {
|
|
31
|
-
"@babel/core": "
|
|
42
|
+
"@babel/core": "7.26.0",
|
|
32
43
|
"@babel/plugin-transform-modules-commonjs": "^7.23.0",
|
|
33
|
-
"@parcel/
|
|
34
|
-
"@
|
|
44
|
+
"@parcel/config-default": "^2.15.4",
|
|
45
|
+
"@parcel/transformer-sass": "^2.15.4",
|
|
46
|
+
"@swc/jest": "^0.2.39",
|
|
35
47
|
"assert": "^2.1.0",
|
|
36
48
|
"browserify-zlib": "^0.2.0",
|
|
37
49
|
"buffer": "^6.0.3",
|
|
38
|
-
"canvas": "
|
|
39
|
-
"eslint": "
|
|
50
|
+
"canvas": "3.2.0",
|
|
51
|
+
"eslint": "8.57.1",
|
|
40
52
|
"events": "^3.3.0",
|
|
41
53
|
"https-browserify": "^1.0.0",
|
|
42
|
-
"husky": "
|
|
43
|
-
"jest": "
|
|
44
|
-
"jest-canvas-mock": "
|
|
45
|
-
"jest-environment-jsdom": "
|
|
54
|
+
"husky": "8.0.3",
|
|
55
|
+
"jest": "30.1.3",
|
|
56
|
+
"jest-canvas-mock": "2.5.2",
|
|
57
|
+
"jest-environment-jsdom": "30.1.2",
|
|
46
58
|
"jest-fetch-mock": "^3.0.3",
|
|
47
|
-
"jsdoc": "
|
|
48
|
-
"parcel": "^2.
|
|
59
|
+
"jsdoc": "4.0.2",
|
|
60
|
+
"parcel": "^2.15.4",
|
|
49
61
|
"process": "^0.11.10",
|
|
50
|
-
"sass": "
|
|
62
|
+
"sass": "1.69.4",
|
|
51
63
|
"stream-browserify": "^3.0.0",
|
|
52
64
|
"stream-http": "^3.2.0",
|
|
53
65
|
"timers-browserify": "^2.0.12",
|
|
@@ -56,11 +68,11 @@
|
|
|
56
68
|
"util": "^0.12.5"
|
|
57
69
|
},
|
|
58
70
|
"peerDependencies": {
|
|
59
|
-
"@cesium/engine": "^
|
|
71
|
+
"@cesium/engine": "^20.0.1"
|
|
60
72
|
},
|
|
61
73
|
"engines": {
|
|
62
|
-
"node": "^
|
|
63
|
-
"npm": "^
|
|
74
|
+
"node": "^22.19.0",
|
|
75
|
+
"npm": "^10.5.0"
|
|
64
76
|
},
|
|
65
77
|
"homepage": "https://bitbucket.org/geowerkstatt-hamburg/masterportalapi#readme",
|
|
66
78
|
"directories": {
|
package/publiccode.yml
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# This repository adheres to the publiccode.yml standard by including this
|
|
2
|
+
# metadata file that makes public software easily discoverable.
|
|
3
|
+
# More info at https://github.com/italia/publiccode.yml
|
|
4
|
+
|
|
5
|
+
publiccodeYmlVersion: '0.3'
|
|
6
|
+
categories:
|
|
7
|
+
- geographic-information-systems, api
|
|
8
|
+
description:
|
|
9
|
+
de:
|
|
10
|
+
apiDocumentation: 'https://bitbucket.org/geowerkstatt-hamburg/masterportalapi/src/master/README.md'
|
|
11
|
+
documentation: 'https://www.masterportal.org/dokumentation'
|
|
12
|
+
features:
|
|
13
|
+
- OGC-konform
|
|
14
|
+
- Konfigurierbar
|
|
15
|
+
- OpenSource
|
|
16
|
+
- Adminfreundlich
|
|
17
|
+
- Modular
|
|
18
|
+
genericName: 'MasterportalAPI'
|
|
19
|
+
localisedName: MasterportalAPI
|
|
20
|
+
longDescription: |2
|
|
21
|
+
Die MasterportalAPI ist eine API zum Einbinden und Anzeigen von Karteninhalten auf Ihrer Webseite. Sie basiert auf OpenLayers und wurde um Funktionen erweitert, die die einfache Nutzung von Konfigurations- und Infrastrukturdateien des Masterportals, einer funktionsreichen Mapping-App der Geowerkstatt Hamburg, ermöglichen. Sie ermöglicht außerdem die Erstellung einer 3D-Karte mithilfe von OLCS und Cäsium. Weitere Informationen finden Sie auf masterportal.org. Die MasterportalAPI ist Open-Source-Software. Es ist unter der [++MIT-Lizenz++](https://bitbucket.org/geowerkstatt-hamburg/masterportalapi/src/master/License.txt) veröffentlicht.
|
|
22
|
+
shortDescription: 'Die MasterportalAPI ist eine auf OpenLayers basierende API zum Einbinden und Anzeigen von Karteninhalten auf Ihrer Webseite'
|
|
23
|
+
developmentStatus: stable
|
|
24
|
+
intendedAudience:
|
|
25
|
+
countries:
|
|
26
|
+
- de
|
|
27
|
+
- en
|
|
28
|
+
- es
|
|
29
|
+
- it
|
|
30
|
+
- pt
|
|
31
|
+
- ru
|
|
32
|
+
- tr
|
|
33
|
+
- ua
|
|
34
|
+
- nl
|
|
35
|
+
scope:
|
|
36
|
+
- welfare
|
|
37
|
+
- agriculture
|
|
38
|
+
- culture
|
|
39
|
+
- defence
|
|
40
|
+
- education
|
|
41
|
+
- emergency-services
|
|
42
|
+
- employment
|
|
43
|
+
- energy
|
|
44
|
+
- environment
|
|
45
|
+
- finance-and-economic-development
|
|
46
|
+
- foreign-affairs
|
|
47
|
+
- government
|
|
48
|
+
- healthcare
|
|
49
|
+
- infrastructures
|
|
50
|
+
- local-authorities
|
|
51
|
+
- manufacturing
|
|
52
|
+
- research
|
|
53
|
+
- justice
|
|
54
|
+
- science-and-technology
|
|
55
|
+
- security
|
|
56
|
+
- society
|
|
57
|
+
- sport
|
|
58
|
+
- tourism
|
|
59
|
+
- transportation
|
|
60
|
+
landingURL: 'https://www.masterportal.org'
|
|
61
|
+
legal:
|
|
62
|
+
license: MIT
|
|
63
|
+
mainCopyrightOwner: 'Freie und Hansestadt Hamburg, Landesbetrieb Geoinformation und Vermessung'
|
|
64
|
+
repoOwner: 'Freie und Hansestadt Hamburg, Landesbetrieb Geoinformation und Vermessung'
|
|
65
|
+
localisation:
|
|
66
|
+
availableLanguages:
|
|
67
|
+
- de
|
|
68
|
+
- en
|
|
69
|
+
localisationReady: true
|
|
70
|
+
logo: |-
|
|
71
|
+
https://www.masterportal.org/fileadmin/_processed_/7/d/csm_news_masterportal_ce24f3cc3d.jpg
|
|
72
|
+
maintenance:
|
|
73
|
+
contacts:
|
|
74
|
+
- name: Betrieb Webanwendungen
|
|
75
|
+
affiliation: Freie und Hansestadt Hamburg, Landesbetrieb Geoinformation und Vermessung
|
|
76
|
+
contractors:
|
|
77
|
+
- name: Landesbetrieb Geoinformation und Vermessung
|
|
78
|
+
until: '2025-12-01'
|
|
79
|
+
website: 'https://www.hamburg.de/bsw/landesbetrieb-geoinformation-und-vermessung/'
|
|
80
|
+
type: community
|
|
81
|
+
name: Masterportal
|
|
82
|
+
platforms:
|
|
83
|
+
- web
|
|
84
|
+
releaseDate: '2025-04-29'
|
|
85
|
+
roadmap: 'https://bitbucket.org/geowerkstatt-hamburg/masterportalapi/src/master/'
|
|
86
|
+
softwareType: api
|
|
87
|
+
softwareVersion: 2.49.0
|
|
88
|
+
url: 'https://bitbucket.org/geowerkstatt-hamburg/masterportalapi.git'
|
package/src/layer/oaf.js
CHANGED
|
@@ -23,6 +23,7 @@ import * as webgl from "../renderer/webgl";
|
|
|
23
23
|
* @property {function} beforeLoading - function called before loading
|
|
24
24
|
* @property {function} afterLoading - function called after loading, gets parameter features
|
|
25
25
|
* @property {function} featuresFilter - function called after loading to filter features, gets parameter features
|
|
26
|
+
* @property {function} doNotLoadInitially - default false, if set to true the layer will be initialized without network call, an empty array of features is promoted - this is useful to add features later on (e.g. by filtering) to a full functional but initially empty layer
|
|
26
27
|
* @property {function} clusterGeometryFunction - used in cluster source. Returns the geometry of the cluster, gets parameter feature
|
|
27
28
|
* @property {function} style - style function to style the layer
|
|
28
29
|
* @property {object} loadingParams - added as params to url
|
|
@@ -173,6 +174,10 @@ function getLayerSource (rawLayer, options) {
|
|
|
173
174
|
let source = null;
|
|
174
175
|
|
|
175
176
|
function loader (extent, _, __, success, failure) {
|
|
177
|
+
if (options.doNotLoadInitially) {
|
|
178
|
+
onLoad(source, [], onError, success, failure, options);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
176
181
|
const bboxParam = options.loadingStrategy === bbox ? extent : options.loadingParams.bbox,
|
|
177
182
|
url = createUrl(rawLayer, {
|
|
178
183
|
...options.loadingParams,
|
package/src/layer/wmts.js
CHANGED
|
@@ -186,7 +186,7 @@ function createLayer (rawLayer, layerParams = {}) {
|
|
|
186
186
|
infoFormat: rawLayer.infoFormat
|
|
187
187
|
}, layerParams));
|
|
188
188
|
|
|
189
|
-
if (rawLayer.optionsFromCapabilities
|
|
189
|
+
if (!rawLayer.optionsFromCapabilities || !rawLayer.capabilitiesUrl) {
|
|
190
190
|
createLayerSourceByDefinitions(rawLayer, tileLayer);
|
|
191
191
|
}
|
|
192
192
|
else {
|
package/src/renderer/webgl.js
CHANGED
|
@@ -1,27 +1,38 @@
|
|
|
1
|
-
import WebGLPointsLayer from "ol/layer/WebGLVector";
|
|
2
1
|
import WebGLVectorLayerRenderer from "ol/renderer/webgl/VectorLayer";
|
|
3
2
|
import WebGLVectorTileLayerRenderer from "ol/renderer/webgl/VectorTileLayer.js";
|
|
4
3
|
import VectorTile from "ol/layer/VectorTile.js";
|
|
5
4
|
import VectorLayer from "ol/layer/Layer";
|
|
5
|
+
import WebGLVectorLayer from "ol/layer/WebGLVector.js";
|
|
6
6
|
import styleList from "../vectorStyle/styleList";
|
|
7
7
|
import {getRulesForFeature} from "../vectorStyle/lib/getRuleForIndex";
|
|
8
8
|
import {returnColor} from "../vectorStyle/lib/colorConvertions";
|
|
9
|
-
import {asArray} from "ol/color.js";
|
|
10
|
-
import {packColor, parseLiteralStyle} from "ol/webgl/styleparser.js";
|
|
11
9
|
|
|
12
10
|
/**
|
|
13
11
|
* The default style for OpenLayers WebGLPoints class
|
|
14
12
|
* @see https://openlayers.org/en/latest/examples/webgl-points-layer.html
|
|
15
13
|
* @private
|
|
16
14
|
*/
|
|
17
|
-
const defaultPointStyle =
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
15
|
+
const defaultPointStyle = [
|
|
16
|
+
{
|
|
17
|
+
style: {
|
|
18
|
+
"circle-fill-color": ["match", ["get", "selected"], 1, "#0c2026", "#006688"],
|
|
19
|
+
"circle-radius": [
|
|
20
|
+
"interpolate",
|
|
21
|
+
["exponential", 1.5],
|
|
22
|
+
["zoom"],
|
|
23
|
+
3, 6,
|
|
24
|
+
6, 10,
|
|
25
|
+
9, 20,
|
|
26
|
+
12, 35,
|
|
27
|
+
15, 60,
|
|
28
|
+
18, 110
|
|
29
|
+
],
|
|
30
|
+
"circle-rotate-with-view": false,
|
|
31
|
+
"circle-displacement": [0, 0],
|
|
32
|
+
"circle-opacity": 0.6
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
],
|
|
25
36
|
defaultPolygonStyle = {
|
|
26
37
|
fillColor: "#006688",
|
|
27
38
|
strokeColor: "#006688",
|
|
@@ -29,7 +40,14 @@ const defaultPointStyle = {
|
|
|
29
40
|
opacity: 1
|
|
30
41
|
},
|
|
31
42
|
|
|
32
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* @typedef {Object} LiteralStyle
|
|
45
|
+
* @property {string} [stroke-color]
|
|
46
|
+
* @property {number} [stroke-width]
|
|
47
|
+
* @property {string} [fill-color]
|
|
48
|
+
* @property {number} [opacity]
|
|
49
|
+
* @property {number} [size]
|
|
50
|
+
*/
|
|
33
51
|
style = Object.assign({
|
|
34
52
|
"stroke-color": ["get", "strokeColor"],
|
|
35
53
|
"stroke-width": ["get", "strokeWidth", "number"],
|
|
@@ -52,6 +70,11 @@ export function createVectorLayerRenderer () {
|
|
|
52
70
|
* @description the temporary class with a custom renderer to render the vector data with WebGL
|
|
53
71
|
*/
|
|
54
72
|
class LocalWebGLLayer extends VectorLayer {
|
|
73
|
+
constructor (options) {
|
|
74
|
+
super(options);
|
|
75
|
+
// Initialize with any default style variables
|
|
76
|
+
this.styleVariables = options.styleVariables || {};
|
|
77
|
+
}
|
|
55
78
|
/**
|
|
56
79
|
* Creates a new renderer that takes the defined style of the new layer as an input.
|
|
57
80
|
* @returns {module:ol/renderer/webgl/WebGLVectorLayerRenderer} the custom renderer
|
|
@@ -62,6 +85,13 @@ export function createVectorLayerRenderer () {
|
|
|
62
85
|
style
|
|
63
86
|
});
|
|
64
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Get the current style variables.
|
|
90
|
+
* @returns {Object} - The current style variables.
|
|
91
|
+
*/
|
|
92
|
+
getStyleVariables () {
|
|
93
|
+
return this.styleVariables;
|
|
94
|
+
}
|
|
65
95
|
}
|
|
66
96
|
|
|
67
97
|
return LocalWebGLLayer;
|
|
@@ -72,9 +102,10 @@ export function createVectorLayerRenderer () {
|
|
|
72
102
|
* @augments VectorTile
|
|
73
103
|
* @private
|
|
74
104
|
* @implements {WebGLVectorTileLayerRenderer}
|
|
105
|
+
* @param {Object} attrs - the attributes of the layer
|
|
75
106
|
* @returns {module:ol/layer/VectorTile} the LocalWebGLLayer with a custom renderer for WebGL styling of vectorTile layers.
|
|
76
107
|
*/
|
|
77
|
-
export function createVectorTileLayerRenderer () {
|
|
108
|
+
export function createVectorTileLayerRenderer (attrs) {
|
|
78
109
|
/**
|
|
79
110
|
* @class LocalWebGLLayer
|
|
80
111
|
* @see https://openlayers.org/en/latest/examples/webgl-vector-tiles.html
|
|
@@ -88,70 +119,8 @@ export function createVectorTileLayerRenderer () {
|
|
|
88
119
|
* @experimental
|
|
89
120
|
*/
|
|
90
121
|
createRenderer () {
|
|
91
|
-
const result = parseLiteralStyle(style),
|
|
92
|
-
invisible = [255, 255, 255, 0],
|
|
93
|
-
grey = [119, 119, 119, 1];
|
|
94
|
-
|
|
95
|
-
|
|
96
122
|
return new WebGLVectorTileLayerRenderer(this, {
|
|
97
|
-
style:
|
|
98
|
-
fill: {
|
|
99
|
-
fragment: result.builder.getFillFragmentShader(),
|
|
100
|
-
vertex: result.builder.getFillVertexShader()
|
|
101
|
-
},
|
|
102
|
-
stroke: {
|
|
103
|
-
fragment: result.builder.getStrokeFragmentShader(),
|
|
104
|
-
vertex: result.builder.getStrokeVertexShader()
|
|
105
|
-
},
|
|
106
|
-
symbol: {
|
|
107
|
-
fragment: result.builder.getSymbolFragmentShader(),
|
|
108
|
-
vertex: result.builder.getSymbolVertexShader()
|
|
109
|
-
},
|
|
110
|
-
builder: result.builder,
|
|
111
|
-
attributes: {
|
|
112
|
-
fillColor: {
|
|
113
|
-
size: 2,
|
|
114
|
-
callback: (feature) => {
|
|
115
|
-
const featureStyle = this.getStyle()(feature, 1);
|
|
116
|
-
|
|
117
|
-
if (featureStyle && featureStyle[0]) {
|
|
118
|
-
const color = featureStyle[0]?.getFill()?.getColor();
|
|
119
|
-
|
|
120
|
-
return packColor(color && typeof color === "string" ? asArray(color) : invisible);
|
|
121
|
-
}
|
|
122
|
-
return packColor(grey);
|
|
123
|
-
}
|
|
124
|
-
},
|
|
125
|
-
strokeColor: {
|
|
126
|
-
size: 2,
|
|
127
|
-
callback: (feature) => {
|
|
128
|
-
const featureStyle = this.getStyle()(feature, 1);
|
|
129
|
-
|
|
130
|
-
if (featureStyle && featureStyle[0]) {
|
|
131
|
-
const color = featureStyle[0]?.getStroke()?.getColor();
|
|
132
|
-
|
|
133
|
-
return packColor(color ? asArray(color) : invisible);
|
|
134
|
-
}
|
|
135
|
-
return packColor(grey);
|
|
136
|
-
}
|
|
137
|
-
},
|
|
138
|
-
strokeWidth: {
|
|
139
|
-
size: 1,
|
|
140
|
-
callback: (feature) => {
|
|
141
|
-
const featureStyle = this.getStyle()(feature, 1);
|
|
142
|
-
|
|
143
|
-
if (featureStyle && featureStyle[0]) {
|
|
144
|
-
const width = featureStyle[0]?.getStroke()?.getWidth();
|
|
145
|
-
|
|
146
|
-
if (width !== undefined) {
|
|
147
|
-
return width > 10 ? width / 10 : 1;/** @todo needs refactoring in later versions */
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
return 1;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
123
|
+
style: attrs.style ? attrs.style : style
|
|
155
124
|
});
|
|
156
125
|
}
|
|
157
126
|
}
|
|
@@ -275,10 +244,10 @@ export function afterLoading (features, styleId, excludeTypesFromParsing, isPoin
|
|
|
275
244
|
* Creates the OL Layer instance, used to rebuild the layer when shown again after layer has been disposed
|
|
276
245
|
* @param {Object} attrs - the attributes of the layer
|
|
277
246
|
* @public
|
|
278
|
-
* @returns {VectorLayer |
|
|
247
|
+
* @returns {VectorLayer | WebGLVectorLayer} returns the layer instance
|
|
279
248
|
*/
|
|
280
249
|
export function createLayer (attrs) {
|
|
281
|
-
let LayerConstructor =
|
|
250
|
+
let LayerConstructor = WebGLVectorLayer;
|
|
282
251
|
const options = {
|
|
283
252
|
id: attrs.id,
|
|
284
253
|
source: attrs.source,
|
|
@@ -292,7 +261,8 @@ export function createLayer (attrs) {
|
|
|
292
261
|
renderer: "webgl",
|
|
293
262
|
styleId: attrs.styleId,
|
|
294
263
|
excludeTypesFromParsing: attrs.excludeTypesFromParsing,
|
|
295
|
-
extent: attrs.extent
|
|
264
|
+
extent: attrs.extent,
|
|
265
|
+
zIndex: attrs.zIndex
|
|
296
266
|
};
|
|
297
267
|
|
|
298
268
|
/**
|
|
@@ -274,6 +274,30 @@ function addToStyleList (jsonStyles) {
|
|
|
274
274
|
});
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
+
/**
|
|
278
|
+
* Fetches the style.json file and adds the style for the styleId to the style list, if contained in style.json.
|
|
279
|
+
* @param {object} [Config] - the Config.js object
|
|
280
|
+
* @param {string} [styleId] - the styleId to add
|
|
281
|
+
* @returns {object} the style object for the styleId
|
|
282
|
+
*/
|
|
283
|
+
async function initStyleAndAddToList (Config, styleId) {
|
|
284
|
+
let style;
|
|
285
|
+
|
|
286
|
+
await fetch(Config.styleConf)
|
|
287
|
+
.then(response => response.json())
|
|
288
|
+
.then(data => {
|
|
289
|
+
style = data.find(aStyle => aStyle.styleId === styleId);
|
|
290
|
+
|
|
291
|
+
if (style) {
|
|
292
|
+
styleList.push(style);
|
|
293
|
+
}
|
|
294
|
+
})
|
|
295
|
+
.catch(error => {
|
|
296
|
+
console.error(error);
|
|
297
|
+
});
|
|
298
|
+
return style;
|
|
299
|
+
}
|
|
300
|
+
|
|
277
301
|
/**
|
|
278
302
|
* Returns style object by styleId or by layerId
|
|
279
303
|
* @param {string} layerId layerId
|
|
@@ -285,6 +309,7 @@ function returnStyleObject (layerId) {
|
|
|
285
309
|
|
|
286
310
|
export default {
|
|
287
311
|
initializeStyleList,
|
|
312
|
+
initStyleAndAddToList,
|
|
288
313
|
addToStyleList,
|
|
289
314
|
returnStyleObject
|
|
290
315
|
};
|
package/test/layer/oaf.test.js
CHANGED
|
@@ -52,6 +52,16 @@ describe("oaf.js", function () {
|
|
|
52
52
|
expect(layer.get("id")).toEqual("id");
|
|
53
53
|
expect(layer.getSource()).toBeInstanceOf(VectorSource);
|
|
54
54
|
});
|
|
55
|
+
it("creates empty layer if doNotLoadInitially is true", function () {
|
|
56
|
+
const options = {
|
|
57
|
+
doNotLoadInitially: true
|
|
58
|
+
},
|
|
59
|
+
layer = oaf.createLayer({id: "id"}, {options});
|
|
60
|
+
|
|
61
|
+
expect(layer).toBeInstanceOf(VectorLayer);
|
|
62
|
+
expect(layer.getSource()).toBeInstanceOf(VectorSource);
|
|
63
|
+
expect(layer.getSource().getFeatures().length).toEqual(0);
|
|
64
|
+
});
|
|
55
65
|
it("creates a VectorLayer with style in rawLayer", function () {
|
|
56
66
|
function styleFunction () {
|
|
57
67
|
const icon = new Style({
|
|
@@ -34,11 +34,12 @@ describe("setBackgroundImage.js", function () {
|
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
it("preserves empty string as input to set explicitly no background image", function () {
|
|
37
|
-
const backgroundImage = ""
|
|
37
|
+
const backgroundImage = "",
|
|
38
|
+
got = document.getElementById("map").style.backgroundImage;
|
|
38
39
|
|
|
39
40
|
setBackgroundImage({backgroundImage});
|
|
40
41
|
|
|
41
|
-
expect(
|
|
42
|
+
expect(["", "url()", "url(\"\")"]).toContain(got);
|
|
42
43
|
});
|
|
43
44
|
|
|
44
45
|
it("sets the default background image if none was given", function () {
|
|
@@ -5,7 +5,7 @@ import Feature from "ol/Feature";
|
|
|
5
5
|
import Polygon from "ol/geom/Polygon";
|
|
6
6
|
import MultiPoint from "ol/geom/MultiPoint";
|
|
7
7
|
import * as webgl from "../../src/renderer/webgl";
|
|
8
|
-
import
|
|
8
|
+
import WebGLVectorLayer from "ol/layer/WebGLVector.js";
|
|
9
9
|
import Layer from "ol/layer/Layer";
|
|
10
10
|
import {returnColor} from "../../src/vectorStyle/lib/colorConvertions";
|
|
11
11
|
|
|
@@ -18,7 +18,7 @@ jest.mock("../../src/vectorStyle/styleList.js", () => {
|
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
describe("webgl.js", () => {
|
|
21
|
-
let layerParams, layerParamsVectorTile, rawLayer, rawLayerVectorTile, styleRule, styleObject,
|
|
21
|
+
let layerParams, layerParamsVectorTile, rawLayer, rawLayerVectorTile, styleRule, styleObject, defaultPointStyle;
|
|
22
22
|
|
|
23
23
|
beforeEach(() => {
|
|
24
24
|
layerParams = {
|
|
@@ -68,23 +68,30 @@ describe("webgl.js", () => {
|
|
|
68
68
|
styleObject = {
|
|
69
69
|
rules: [styleRule]
|
|
70
70
|
};
|
|
71
|
-
|
|
71
|
+
defaultPointStyle = {
|
|
72
72
|
fillColor: "#006688",
|
|
73
73
|
strokeColor: "#006688",
|
|
74
74
|
strokeWidth: 1,
|
|
75
75
|
opacity: 1,
|
|
76
|
-
|
|
76
|
+
zoom: [
|
|
77
|
+
3, 6,
|
|
78
|
+
6, 10,
|
|
79
|
+
9, 20,
|
|
80
|
+
12, 35,
|
|
81
|
+
15, 60,
|
|
82
|
+
18, 110
|
|
83
|
+
]
|
|
77
84
|
};
|
|
78
85
|
});
|
|
79
86
|
|
|
80
87
|
describe("createLayer", () => {
|
|
81
88
|
let source = new VectorSource();
|
|
82
89
|
|
|
83
|
-
it("should return a
|
|
90
|
+
it("should return a WebGLVectorLayer", () => {
|
|
84
91
|
layerParams.isPointLayer = true;
|
|
85
92
|
const webglLayer = webgl.createLayer({...rawLayer, ...layerParams, source});
|
|
86
93
|
|
|
87
|
-
expect(webglLayer).toBeInstanceOf(
|
|
94
|
+
expect(webglLayer).toBeInstanceOf(WebGLVectorLayer);
|
|
88
95
|
expect(webglLayer.get("isPointLayer")).toBeTruthy();
|
|
89
96
|
});
|
|
90
97
|
it("should return a custom Layer", () => {
|
|
@@ -92,7 +99,7 @@ describe("webgl.js", () => {
|
|
|
92
99
|
const webglLayer = webgl.createLayer({...rawLayer, ...layerParams, source});
|
|
93
100
|
|
|
94
101
|
expect(webglLayer).toBeInstanceOf(Layer);
|
|
95
|
-
expect(webglLayer).not.toBeInstanceOf(
|
|
102
|
+
expect(webglLayer).not.toBeInstanceOf(WebGLVectorLayer);
|
|
96
103
|
expect(webglLayer.get("isPointLayer")).toBeFalsy();
|
|
97
104
|
});
|
|
98
105
|
it("vectorTile: should return a VectorTile layer", () => {
|
|
@@ -102,7 +109,7 @@ describe("webgl.js", () => {
|
|
|
102
109
|
|
|
103
110
|
expect(webglLayer).toBeInstanceOf(Layer);
|
|
104
111
|
expect(webglLayer).toBeInstanceOf(VectorTile);
|
|
105
|
-
expect(webglLayer).not.toBeInstanceOf(
|
|
112
|
+
expect(webglLayer).not.toBeInstanceOf(WebGLVectorLayer);
|
|
106
113
|
expect(webglLayer.get("isPointLayer")).toBeFalsy();
|
|
107
114
|
});
|
|
108
115
|
});
|
|
@@ -187,12 +194,46 @@ describe("webgl.js", () => {
|
|
|
187
194
|
rules: [styleRule]
|
|
188
195
|
};
|
|
189
196
|
webgl.formatFeatureStyles($feature, styleObject);
|
|
190
|
-
expect($feature.get("fillColor")).toEqual(
|
|
191
|
-
expect($feature.get("strokeColor")).toEqual(
|
|
192
|
-
expect($feature.get("strokeWidth")).toEqual(
|
|
193
|
-
expect($feature.get("opacity")).toEqual(
|
|
194
|
-
expect($feature.get("circleSize")).toEqual(defaultStyle.size);
|
|
197
|
+
expect($feature.get("fillColor")).toEqual(defaultPointStyle.fillColor);
|
|
198
|
+
expect($feature.get("strokeColor")).toEqual(defaultPointStyle.strokeColor);
|
|
199
|
+
expect($feature.get("strokeWidth")).toEqual(defaultPointStyle.strokeWidth);
|
|
200
|
+
expect($feature.get("opacity")).toEqual(defaultPointStyle.opacity);
|
|
195
201
|
});
|
|
202
|
+
|
|
203
|
+
it("should calculate circle-radius based on zoom level", () => {
|
|
204
|
+
const zoomLevels = [3, 6, 9, 12, 15, 18],
|
|
205
|
+
expectedRadii = [6, 10, 20, 35, 60, 110];
|
|
206
|
+
|
|
207
|
+
// eslint-disable-next-line no-use-before-define, max-nested-callbacks
|
|
208
|
+
zoomLevels.forEach((zoom, index) => testZoomLevel(zoom, index, expectedRadii));
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
function interpolateCircleRadius (zoom, zoomArray) {
|
|
212
|
+
for (let i = 0; i < zoomArray.length; i += 2) {
|
|
213
|
+
const z = zoomArray[i],
|
|
214
|
+
r = zoomArray[i + 1];
|
|
215
|
+
|
|
216
|
+
if (zoom <= z) {
|
|
217
|
+
if (i === 0) {
|
|
218
|
+
return r;
|
|
219
|
+
}
|
|
220
|
+
const zPrev = zoomArray[i - 2],
|
|
221
|
+
rPrev = zoomArray[i - 1],
|
|
222
|
+
t = (zoom - zPrev) / (z - zPrev);
|
|
223
|
+
|
|
224
|
+
return rPrev + (t * (r - rPrev));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return zoomArray[zoomArray.length - 1];
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function testZoomLevel (zoom, index, expectedRadii) {
|
|
231
|
+
const expectedRadius = expectedRadii[index],
|
|
232
|
+
actualRadius = interpolateCircleRadius(zoom, defaultPointStyle.zoom);
|
|
233
|
+
|
|
234
|
+
expect(actualRadius).toEqual(expectedRadius);
|
|
235
|
+
}
|
|
236
|
+
|
|
196
237
|
});
|
|
197
238
|
});
|
|
198
239
|
});
|