@masterportal/masterportalapi 2.18.0 → 2.19.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 +27 -1
- package/package.json +64 -64
- package/src/layer/wfs.js +9 -4
- package/src/lib/attributeMapper.js +30 -29
- package/src/maps/olcs/olcsMap.js +2 -1
- package/src/vectorStyle/createStyle.js +9 -2
- package/test/lib/attributeMapper.test.js +23 -1
- package/test/map.test.js +63 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,32 @@
|
|
|
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
|
+
### Changed
|
|
9
|
+
### Deprecated
|
|
10
|
+
### Removed
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 2.19.0 - 2023-05-26
|
|
16
|
+
### Added
|
|
17
|
+
- The following package has been added:
|
|
18
|
+
- dependencies:
|
|
19
|
+
- dayjs: "^1.11.7"
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
- AttributeMapper: Object keys are supported with dot notation.
|
|
23
|
+
- WFS: hardcoded URL changed to dynamic url creation.
|
|
24
|
+
- Issue Masterportal #1021: extend vectorStyle in order to handle geometryCollections.
|
|
25
|
+
- Issue Masterportal #1022: attributeMapper supports additional time formats.
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
- Issue Masterportal # 1028: set cesium scene parameter recursively.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
6
32
|
## 2.18.0 - 2023-05-10
|
|
7
33
|
### Changed
|
|
8
34
|
- The following packages have been updated:
|
|
@@ -18,7 +44,7 @@
|
|
|
18
44
|
- jest-canvas-mock: 2.4.0 to 2.5.0
|
|
19
45
|
- parcel: 2.6.0 to 2.8.3
|
|
20
46
|
- sass: 1.59.3 to 1.62.1
|
|
21
|
-
- The devDependency `buffer` ist downgrade from 6.0.3 to 5.7.1 because parcel requires a version 5
|
|
47
|
+
- The devDependency `buffer` ist downgrade from 6.0.3 to 5.7.1 because parcel requires a version 5.
|
|
22
48
|
|
|
23
49
|
---
|
|
24
50
|
|
package/package.json
CHANGED
|
@@ -1,64 +1,64 @@
|
|
|
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/layer/wfs.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.30.2",
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"@babel/
|
|
31
|
-
"@
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"jest
|
|
39
|
-
"jest-
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
"
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
"example": "example",
|
|
59
|
-
"test": "test"
|
|
60
|
-
},
|
|
61
|
-
"bugs": {
|
|
62
|
-
"url": "https://bitbucket.org/geowerkstatt-hamburg/masterportalapi/issues"
|
|
63
|
-
}
|
|
64
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@masterportal/masterportalapi",
|
|
3
|
+
"author": "Implementierungspartnerschaft Masterportal <info@masterportal.org> (https://www.masterportal.org)",
|
|
4
|
+
"version": "2.19.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/layer/wfs.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.30.2",
|
|
23
|
+
"dayjs": "^1.11.7",
|
|
24
|
+
"ol": "7.3.0",
|
|
25
|
+
"olcs": "^2.14.0",
|
|
26
|
+
"proj4": "^2.9.0",
|
|
27
|
+
"xml2js": "^0.5.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@babel/core": "^7.21.8",
|
|
31
|
+
"@babel/plugin-transform-modules-commonjs": "^7.21.5",
|
|
32
|
+
"@parcel/transformer-sass": "^2.8.3",
|
|
33
|
+
"buffer": "^5.7.1",
|
|
34
|
+
"canvas": "^2.11.2",
|
|
35
|
+
"eslint": "^8.40.0",
|
|
36
|
+
"events": "^3.3.0",
|
|
37
|
+
"husky": "^8.0.3",
|
|
38
|
+
"jest": "^29.5.0",
|
|
39
|
+
"jest-canvas-mock": "^2.5.0",
|
|
40
|
+
"jest-environment-jsdom": "^29.5.0",
|
|
41
|
+
"jsdoc": "^4.0.2",
|
|
42
|
+
"parcel": "^2.8.3",
|
|
43
|
+
"process": "^0.11.10",
|
|
44
|
+
"sass": "^1.62.1",
|
|
45
|
+
"stream-browserify": "^3.0.0",
|
|
46
|
+
"timers-browserify": "^2.0.12",
|
|
47
|
+
"use-resize-observer": "^9.1.0"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"cesium": "^1.95.0"
|
|
51
|
+
},
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": "^16.13.2 || ^18.12.0",
|
|
54
|
+
"npm": "^8.1.2 || ^9.3.1"
|
|
55
|
+
},
|
|
56
|
+
"homepage": "https://bitbucket.org/geowerkstatt-hamburg/masterportalapi#readme",
|
|
57
|
+
"directories": {
|
|
58
|
+
"example": "example",
|
|
59
|
+
"test": "test"
|
|
60
|
+
},
|
|
61
|
+
"bugs": {
|
|
62
|
+
"url": "https://bitbucket.org/geowerkstatt-hamburg/masterportalapi/issues"
|
|
63
|
+
}
|
|
64
|
+
}
|
package/src/layer/wfs.js
CHANGED
|
@@ -126,16 +126,21 @@ function loadWFSFilter (filter, url, source, {onErrorFn, success, failure}, opti
|
|
|
126
126
|
* @returns {string} the url
|
|
127
127
|
*/
|
|
128
128
|
function createUrl (rawLayer, version, projection, bboxParam) {
|
|
129
|
-
|
|
129
|
+
const url = new URL(rawLayer.url);
|
|
130
|
+
|
|
131
|
+
url.searchParams.set("service", "WFS");
|
|
132
|
+
url.searchParams.set("version", version);
|
|
133
|
+
url.searchParams.set("request", "GetFeature");
|
|
134
|
+
url.searchParams.set("srsName", projection.getCode());
|
|
130
135
|
|
|
131
136
|
if (version === "1.0.0" || version === "1.1.0") {
|
|
132
|
-
url
|
|
137
|
+
url.searchParams.set("typeName", rawLayer.featureType);
|
|
133
138
|
}
|
|
134
139
|
else if (version === "2.0.0") {
|
|
135
|
-
url
|
|
140
|
+
url.searchParams.set("typeNames", rawLayer.featureType);
|
|
136
141
|
}
|
|
137
142
|
|
|
138
|
-
return url
|
|
143
|
+
return `${url.toString()}${bboxParam}`;
|
|
139
144
|
}
|
|
140
145
|
|
|
141
146
|
/**
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {getValueFromObjectByPath} from "./getValueFromObjectByPath.js";
|
|
2
2
|
import thousandsSeparator from "./thousandsSeparator";
|
|
3
|
+
import dayjs from "dayjs";
|
|
3
4
|
/**
|
|
4
5
|
* checks if value starts with special prefix to determine if value is a object path
|
|
5
6
|
* @param {string} value string to check
|
|
@@ -11,16 +12,25 @@ function isObjectPath (value) {
|
|
|
11
12
|
/**
|
|
12
13
|
* Returns the value of the given key. Also considers, that the key may be an object path.
|
|
13
14
|
* @param {Object} properties properties.
|
|
14
|
-
* @param {String}
|
|
15
|
+
* @param {String} propertyKey Key to derive value from.
|
|
15
16
|
* @returns {*} - Value from key.
|
|
16
17
|
*/
|
|
17
|
-
function prepareValue (properties,
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
function prepareValue (properties, propertyKey) {
|
|
19
|
+
Object.keys(properties).forEach((parentKey) => {
|
|
20
|
+
if (properties[parentKey] && typeof properties[parentKey] === "object") {
|
|
21
|
+
Object.keys(properties[parentKey]).forEach((key) => {
|
|
22
|
+
properties[parentKey + "." + key] = properties[parentKey][key];
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const isPath = isObjectPath(propertyKey);
|
|
28
|
+
let value = properties[Object.keys(properties).find(propertiesKey => propertiesKey.toLowerCase() === propertyKey.toLowerCase())];
|
|
20
29
|
|
|
21
30
|
if (isPath) {
|
|
22
|
-
value = getValueFromObjectByPath(properties,
|
|
31
|
+
value = getValueFromObjectByPath(properties, propertyKey);
|
|
23
32
|
}
|
|
33
|
+
|
|
24
34
|
return value;
|
|
25
35
|
}
|
|
26
36
|
|
|
@@ -128,30 +138,21 @@ function prepareValueFromObject (key, mappingObj, properties) {
|
|
|
128
138
|
switch (type) {
|
|
129
139
|
case "date": {
|
|
130
140
|
date = new Date(String(preparedValue));
|
|
131
|
-
if (
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
else if (format === "YYYY-MM-DD") {
|
|
147
|
-
preparedValue = year + "-" + month + "-" + day;
|
|
148
|
-
}
|
|
149
|
-
else if (format === "DD-MM-YYYY") {
|
|
150
|
-
preparedValue = day + "-" + month + "-" + year;
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
console.error("The format must be 'YYYY-MM-DD' or 'DD-MM-YYYY', if the attribute is missing, ISO 8601 is used.");
|
|
154
|
-
}
|
|
141
|
+
if (format === "YYYY-MM-DDTHH:mm:ss.SSSZ") {
|
|
142
|
+
const offset = date.getTimezoneOffset();
|
|
143
|
+
|
|
144
|
+
let offsetHours = (offset / 60) % 24,
|
|
145
|
+
offsetMinutes = offset % 60;
|
|
146
|
+
|
|
147
|
+
offsetHours = offsetHours < 0 ? "+" + ("0" + Math.abs(offsetHours)).slice(-2) : "-" + ("0" + Math.abs(offsetHours)).slice(-2);
|
|
148
|
+
offsetMinutes = offsetMinutes < 0 ? ":" + ("0" + Math.abs(offsetMinutes)).slice(-2) : ":" + ("0" + offsetMinutes).slice(-2);
|
|
149
|
+
preparedValue = date.toISOString().slice(0, -1) + offsetHours + offsetMinutes;
|
|
150
|
+
}
|
|
151
|
+
else if (!isNaN(date.getDay())) {
|
|
152
|
+
preparedValue = dayjs(String(preparedValue)).format(format);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
console.warn("If the attribute is missing, ISO 8601 is used.");
|
|
155
156
|
}
|
|
156
157
|
break;
|
|
157
158
|
}
|
package/src/maps/olcs/olcsMap.js
CHANGED
|
@@ -9,6 +9,7 @@ import defaults from "../../defaults";
|
|
|
9
9
|
let mapIdCounter = 0;
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
+
* Recursive function.
|
|
12
13
|
* Sets the cesium default scene params.
|
|
13
14
|
* @param {Cesium.scene} scene The cesium scene.
|
|
14
15
|
* @param {Object} params Optional configuration parameters.
|
|
@@ -21,7 +22,7 @@ export function setCesiumSceneParams (scene, params) {
|
|
|
21
22
|
if (typeof paramValue === "object") {
|
|
22
23
|
Object.keys(paramValue).forEach(paramSubKey => {
|
|
23
24
|
if (paramSubKey !== "heading" && paramSubKey !== "tilt" && paramSubKey !== "altitude") {
|
|
24
|
-
scene[paramKey]
|
|
25
|
+
setCesiumSceneParams(scene[paramKey], paramValue);
|
|
25
26
|
}
|
|
26
27
|
});
|
|
27
28
|
}
|
|
@@ -228,9 +228,16 @@ function createStyle (styleObject, feature, isClustered, wfsImgPathFromConfig) {
|
|
|
228
228
|
hasLabelField = style?.labelField,
|
|
229
229
|
geometryStyle = getGeometryStyle(feature, rules, isClustered, wfsImgPathFromConfig),
|
|
230
230
|
legendInformation = Array.isArray(geometryStyle) ? geometryStyle[0].legendInfos : geometryStyle.legendInfos,
|
|
231
|
-
styleObjectGeometry = Array.isArray(geometryStyle) ? geometryStyle
|
|
231
|
+
styleObjectGeometry = Array.isArray(geometryStyle) ? geometryStyle.map(styleItem => styleItem.getStyle()) : geometryStyle.getStyle();
|
|
232
232
|
|
|
233
|
-
|
|
233
|
+
if (geometryStyle.length > 1) {
|
|
234
|
+
for (const i in geometryStyle) {
|
|
235
|
+
captureLegendFromFeature(styleObject.styleId, geometryStyle[i].legendInfos);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
captureLegendFromFeature(styleObject.styleId, legendInformation);
|
|
240
|
+
}
|
|
234
241
|
|
|
235
242
|
// label style is optional and depends on some fields
|
|
236
243
|
if (isClustered || hasLabelField) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {mapAttributes, isObjectPath} from "../../src/lib/attributeMapper";
|
|
1
|
+
import {mapAttributes, isObjectPath, prepareValue} from "../../src/lib/attributeMapper";
|
|
2
2
|
|
|
3
3
|
const props = {
|
|
4
4
|
random_text: "foobar",
|
|
@@ -287,4 +287,26 @@ describe("src/utils/attributeMapper.js", () => {
|
|
|
287
287
|
expect(isObjectPath(true)).toBe(false);
|
|
288
288
|
});
|
|
289
289
|
});
|
|
290
|
+
describe("prepareValue", () => {
|
|
291
|
+
it("returns value from object by dot notation key", () => {
|
|
292
|
+
const properties = {
|
|
293
|
+
address: {
|
|
294
|
+
street: "Platz"
|
|
295
|
+
}
|
|
296
|
+
},
|
|
297
|
+
testkey = "Address.Street";
|
|
298
|
+
|
|
299
|
+
expect(prepareValue(properties, testkey)).toEqual("Platz");
|
|
300
|
+
});
|
|
301
|
+
it("returns undefined from object by dot notation key if parentkey is not found", () => {
|
|
302
|
+
const properties = {
|
|
303
|
+
address: {
|
|
304
|
+
street: "Platz"
|
|
305
|
+
}
|
|
306
|
+
},
|
|
307
|
+
testkey = "Location.Street";
|
|
308
|
+
|
|
309
|
+
expect(prepareValue(properties, testkey)).toBeUndefined();
|
|
310
|
+
});
|
|
311
|
+
});
|
|
290
312
|
});
|
package/test/map.test.js
CHANGED
|
@@ -292,5 +292,68 @@ describe("map.js", function () {
|
|
|
292
292
|
});
|
|
293
293
|
});
|
|
294
294
|
});
|
|
295
|
+
describe("setCesiumSceneParams", function () {
|
|
296
|
+
it("set the cesium scene parameter from config", function () {
|
|
297
|
+
global.Cesium = {};
|
|
298
|
+
global.Cesium.Color = {};
|
|
299
|
+
global.Cesium.Rectangle = {};
|
|
300
|
+
global.Cesium.Color.WHITE = {
|
|
301
|
+
"red": 1,
|
|
302
|
+
"green": 1,
|
|
303
|
+
"blue": 1,
|
|
304
|
+
"alpha": 1
|
|
305
|
+
};
|
|
306
|
+
global.Cesium.Rectangle.fromDegrees = function fromDegrees () {
|
|
307
|
+
return {
|
|
308
|
+
"west": 0.18151424220741028,
|
|
309
|
+
"south": 0.9107128036906411,
|
|
310
|
+
"east": 0.1858775653373961,
|
|
311
|
+
"north": 0.9138543963442309
|
|
312
|
+
};
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
const config = {
|
|
316
|
+
map2D: {
|
|
317
|
+
getView: () => {
|
|
318
|
+
return {
|
|
319
|
+
getProjection: () => {
|
|
320
|
+
return {getCode: () => "code"};
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
},
|
|
324
|
+
getViewport: () => {
|
|
325
|
+
return {
|
|
326
|
+
appendChild: jest.fn()
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
},
|
|
330
|
+
cesiumParameter: {
|
|
331
|
+
globe: {
|
|
332
|
+
showGroundAtmosphere: true,
|
|
333
|
+
baseColor: global.Cesium.Color.WHITE,
|
|
334
|
+
translucency: {
|
|
335
|
+
frontFaceAlpha: 0.50,
|
|
336
|
+
enabled: true,
|
|
337
|
+
rectangle: global.Cesium.Rectangle.fromDegrees(10.40, 52.18, 10.65, 52.36)
|
|
338
|
+
},
|
|
339
|
+
undergroundColor: undefined
|
|
340
|
+
}
|
|
341
|
+
},
|
|
342
|
+
cesiumLib: "https://lib.virtualcitymap.de/v3.6.x/lib/Cesium/Cesium.js"
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
load3DScriptModule.load3DScript(config.cesiumLib, function Loaded3DCallback () {
|
|
346
|
+
const map3D = map.createMap(config, "3D");
|
|
347
|
+
|
|
348
|
+
expect(map3D.mapMode).toBe("3D");
|
|
349
|
+
expect(map3D.getCesiumScene().globe.showGroundAtmosphere).toBe(config.cameraParameter.globe.showGroundAtmosphere);
|
|
350
|
+
expect(map3D.getCesiumScene().globe.baseColor).toBe(config.cameraParameter.globe.baseColor);
|
|
351
|
+
expect(map3D.getCesiumScene().globe.translucency.frontFaceAlpha).toBe(config.cameraParameter.globe.translucency.frontFaceAlpha);
|
|
352
|
+
expect(map3D.getCesiumScene().globe.translucency.enabled).toBe(config.cameraParameter.globe.translucency.enabled);
|
|
353
|
+
expect(map3D.getCesiumScene().globe.translucency.rectangle).toBe(config.cameraParameter.globe.translucency.rectangle);
|
|
354
|
+
expect(map3D.getCesiumScene().globe.undergroundColor()).toBe(config.cameraParameter.globe.undergroundColor);
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
});
|
|
295
358
|
|
|
296
359
|
});
|