@masterportal/masterportalapi 2.46.0 → 2.47.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 CHANGED
@@ -18,6 +18,23 @@
18
18
  ### Fixed
19
19
 
20
20
  ---
21
+
22
+ ## 2.47.0 - 2025-03-20
23
+
24
+ ### Added
25
+ - An interface to OGC API Processes has been added.
26
+
27
+ ### Changed
28
+ - The following package has been updated:
29
+ - peerDependencies:
30
+ - cesium/engine: 13.0.0 to 15.0.0
31
+
32
+ ### Fixed
33
+ - Reset the depthTestAgainstTerrain parameter to true due to problems with the height of the terrain model.
34
+ - WMS-Layer: fixed setting of projection for olcs.
35
+
36
+ ---
37
+
21
38
  ## 2.46.0 - 2025-03-10
22
39
 
23
40
  ### Changed
@@ -44,6 +44,17 @@
44
44
  "version": "1.1.0",
45
45
  "featureNS": "http://www.deegree.org/app"
46
46
  },
47
+ {
48
+ "id": "2426",
49
+ "name": "Bezirke",
50
+ "url": "https://geodienste.hamburg.de/HH_WMS_Verwaltungsgrenzen",
51
+ "typ": "WMS",
52
+ "layers": "bezirke",
53
+ "version": "1.3.0",
54
+ "singleTile": true,
55
+ "transparent": true,
56
+ "transparency": 0
57
+ },
47
58
  {
48
59
  "id": "4001",
49
60
  "name": "Gelaende",
package/example/index.js CHANGED
@@ -132,7 +132,7 @@ services.find(({id}) => id === "5001").style = styleOaf;
132
132
  map2D = mapsAPI.map.createMap(config, "2D", {errorCallback});
133
133
  window.mpapi.map = map2D;
134
134
 
135
- ["2001", "2002", "1002", "3001", "5001"].forEach(id => window.mpapi.map.addLayer(id, {errorCallback}));
135
+ ["2001", "2002", "1002", "3001", "5001", "2426"].forEach(id => window.mpapi.map.addLayer(id, {errorCallback}));
136
136
 
137
137
  // ping all layers
138
138
  services
@@ -231,8 +231,36 @@ window.mpapi.search("Mümmelmannsberg 72", {
231
231
  searchAddress: true
232
232
  }).then(x => console.log(x)).catch(e => console.error(e));
233
233
 
234
- //*/
234
+ // */
235
+
236
+ /* OGC API - PROCESSES EXAMPLE */
237
+ /*
238
+ // Enter the URL to an OGC API - Processes service here.
239
+ const ogcApiProcessUrl = ""; // eslint-disable-line
240
+
241
+ async function testOgcApiProcesses (processUrl) {
242
+ const processList = await window.mpapi.ogcApiProcesses.processList(processUrl),
243
+ processDescription = await window.mpapi.ogcApiProcesses.processDescription(processUrl, processList[0].id),
244
+ jobList = await window.mpapi.ogcApiProcesses.jobList(processUrl),
245
+ data = {};
246
+
247
+ console.log("### OGC API - PROCESSES EXAMPLE ###"); // eslint-disable-line
248
+ console.log("Process list:", processList); // eslint-disable-line
249
+ console.log("Process Description:", processDescription); // eslint-disable-line
250
+
251
+ // create example data from process input schema
252
+ Object.keys(processDescription.inputs).forEach(key => data[key] = `Example ${key}`); // eslint-disable-line
253
+ console.log("Execute Process:", await window.mpapi.ogcApiProcesses.executeProcess(processUrl, processList[0].id, data)); // eslint-disable-line
254
+
255
+ console.log("Job List:", jobList); // eslint-disable-line
256
+ console.log("Job Status of last job:", await window.mpapi.ogcApiProcesses.jobStatus(processUrl, jobList.at(-1).jobID)); // eslint-disable-line
257
+ console.log("Job Results of last job:", await window.mpapi.ogcApiProcesses.jobResults(processUrl, jobList.at(-1).jobID)); // eslint-disable-line
258
+ console.log("Cancle the last Job:", await window.mpapi.ogcApiProcesses.cancelJob(processUrl, jobList.at(-1).jobID)); // eslint-disable-line
259
+ console.log("Job list:", await window.mpapi.ogcApiProcesses.jobList(processUrl)); // eslint-disable-line
260
+ }
235
261
 
262
+ testOgcApiProcesses(ogcApiProcessUrl);
263
+ // */
236
264
 
237
265
  // Add 3D functionality to the example:
238
266
  // ---------------------------------------
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@masterportal/masterportalapi",
3
3
  "author": "Implementierungspartnerschaft Masterportal <info@masterportal.org> (https://www.masterportal.org)",
4
- "version": "2.46.0",
4
+ "version": "2.47.0",
5
5
  "license": "MIT",
6
6
  "description": "Basic functions of the Masterportal as api",
7
7
  "repository": {
@@ -56,7 +56,7 @@
56
56
  "util": "^0.12.5"
57
57
  },
58
58
  "peerDependencies": {
59
- "@cesium/engine": "^13.0.0"
59
+ "@cesium/engine": "^15.0.0"
60
60
  },
61
61
  "engines": {
62
62
  "node": "^16.13.2 || ^18.12.0 || ^20.12.2",
@@ -0,0 +1,205 @@
1
+ /**
2
+ * This is an implementation of the interface to OGC API - Processes - Part 1: Core.
3
+ * @module api/ogcApiProcesses
4
+ * @see {@link https://ogcapi.ogc.org/processes|OGC API - Processes} for further information
5
+ */
6
+
7
+ /**
8
+ * Returns the url params for a DELETE request.
9
+ * @returns {object} The url params for DELETE request.
10
+ */
11
+ function fetchDeleteParams () {
12
+ return {
13
+ method: "DELETE"
14
+ };
15
+ }
16
+
17
+ /**
18
+ * Returns the url params for a GET request.
19
+ * @returns {object} The url params for GET request.
20
+ */
21
+ function fetchGetParams () {
22
+ return {
23
+ method: "GET"
24
+ };
25
+ }
26
+
27
+ /**
28
+ * Returns the url params for a POST request.
29
+ * @param {object} body The request body.
30
+ * @returns {object} The url params for poPOSTst request.
31
+ */
32
+ function fetchPostParams (body) {
33
+ return {
34
+ method: "POST",
35
+ headers: {
36
+ "Content-Type": "application/json"
37
+ },
38
+ body: JSON.stringify(body)
39
+ };
40
+ }
41
+
42
+ /**
43
+ * Returns the fetch params by request method.
44
+ * @param {string} method The fetch method.
45
+ * @param {object} body The request body.
46
+ * @returns {object} The fetch params.
47
+ */
48
+ function fetchParams (method, body) {
49
+ const fetchParamsByMethod = {
50
+ DELETE: fetchDeleteParams,
51
+ GET: fetchGetParams,
52
+ POST: fetchPostParams
53
+ };
54
+
55
+ return fetchParamsByMethod[method](body);
56
+ }
57
+ /**
58
+ * Fetch the url with fetch api and catch errors.
59
+ * @param {string} processUrl The process url.
60
+ * @param {string} [method=GET] The fetch method.
61
+ * @param {object} [body={}] The request body, only used if request-method is POST.
62
+ * @returns {object} The response object.
63
+ */
64
+ function fetchUrl (processUrl, method = "GET", body = {}) {
65
+ return new Promise((resolve, reject) => {
66
+ fetch(processUrl, fetchParams(method, body))
67
+ .then(response => {
68
+ const errorMessage = `Status code: ${response.status}.`;
69
+
70
+ if (response.ok) {
71
+ return response.json();
72
+ }
73
+ else if (response.status === "400") {
74
+ throw new Error(`${errorMessage} The URL: ${response.url} is an bad request! Perhaps the status of the process or job is failure!`);
75
+ }
76
+ else if (response.status === "404") {
77
+ throw new Error(`${errorMessage} The URL: ${response.url} was not found!`);
78
+ }
79
+
80
+ throw new Error(`${errorMessage} The response of the URL: ${response.url} has an error occured!`);
81
+ })
82
+ .then(responseJson => resolve(responseJson))
83
+ .catch(error => {
84
+ reject(error);
85
+ });
86
+ });
87
+ }
88
+
89
+ /**
90
+ * Retrieve the list of available processes.
91
+ * @param {string} processUrl The process url.
92
+ * @param {boolean} [nextLink=false] If processurl is a nextLink.
93
+ * @returns {object[]} The process list.
94
+ */
95
+ async function processList (processUrl, nextLink = false) {
96
+ const url = nextLink ? processUrl : `${processUrl}/processes`,
97
+ responseJson = await fetchUrl(url),
98
+ nextLinkObject = responseJson?.links?.find(link => link.rel === "next");
99
+ let processes = responseJson.processes;
100
+
101
+ if (typeof nextLinkObject !== "undefined") {
102
+ processes = processes.concat(await processList(nextLinkObject.href, true));
103
+ }
104
+
105
+ return processes;
106
+ }
107
+
108
+ /**
109
+ * Retrieve the description of a process.
110
+ * @param {string} processUrl The process url.
111
+ * @param {string} processId The process id.
112
+ * @returns {object} The process description.
113
+ */
114
+ async function processDescription (processUrl, processId) {
115
+ const url = `${processUrl}/processes/${processId}`,
116
+ responseJson = await fetchUrl(url);
117
+
118
+ return responseJson;
119
+ }
120
+
121
+ /**
122
+ * Execute a process.
123
+ * @param {string} processUrl The process url.
124
+ * @param {string} processId The process id.
125
+ * @param {object} data The data.
126
+ * @returns {object} The response data.
127
+ */
128
+ async function executeProcess (processUrl, processId, data) {
129
+ const url = `${processUrl}/processes/${processId}/execution`,
130
+ body = {
131
+ inputs: data
132
+ },
133
+ responseJson = await fetchUrl(url, "POST", body);
134
+
135
+ return responseJson;
136
+ }
137
+
138
+ /**
139
+ * Retrieve the list of jobs.
140
+ * @param {string} processUrl The process url.
141
+ * @param {boolean} [nextLink=false] If processurl is a nextLink.
142
+ * @returns {object[]} The job list.
143
+ */
144
+ async function jobList (processUrl, nextLink = false) {
145
+ const url = nextLink ? processUrl : `${processUrl}/jobs`,
146
+ responseJson = await fetchUrl(url),
147
+ nextLinkObject = responseJson?.links?.find(link => link.rel === "next");
148
+ let jobs = responseJson.jobs;
149
+
150
+ if (typeof nextLinkObject !== "undefined") {
151
+ jobs = jobs.concat(await jobList(nextLinkObject.href, true));
152
+ }
153
+
154
+ return jobs;
155
+ }
156
+
157
+ /**
158
+ * Retrieve the status of a job.
159
+ * @param {string} processUrl The process url.
160
+ * @param {string} jobId The job id.
161
+ * @returns {object} The job status.
162
+ */
163
+ async function jobStatus (processUrl, jobId) {
164
+ const url = `${processUrl}/jobs/${jobId}`,
165
+ responseJson = await fetchUrl(url);
166
+
167
+ return responseJson;
168
+ }
169
+
170
+ /**
171
+ * Cancel a job execution, remove a finished job.
172
+ * @param {string} processUrl The process url.
173
+ * @param {string} jobId The job id.
174
+ * @returns {object} The canceled job status.
175
+ */
176
+ async function cancelJob (processUrl, jobId) {
177
+ const url = `${processUrl}/jobs/${jobId}`,
178
+ responseJson = await fetchUrl(url, "DELETE");
179
+
180
+ return responseJson;
181
+ }
182
+
183
+ /**
184
+ * Retrieve the result(s) of a job.
185
+ * @param {string} processUrl The process url.
186
+ * @param {string} jobId The job id.
187
+ * @param {string} [format=json] The result format can be `html` or `json`.
188
+ * @returns {object} The job dismissed status.
189
+ */
190
+ async function jobResults (processUrl, jobId, format = "json") {
191
+ const url = `${processUrl}/jobs/${jobId}/results?f=${format}`,
192
+ responseJson = await fetchUrl(url);
193
+
194
+ return responseJson;
195
+ }
196
+
197
+ export default {
198
+ processList,
199
+ processDescription,
200
+ executeProcess,
201
+ jobList,
202
+ cancelJob,
203
+ jobStatus,
204
+ jobResults
205
+ };
package/src/defaults.js CHANGED
@@ -40,7 +40,7 @@ export default {
40
40
  enableTerrainAdjustmentWhenLoading: true
41
41
  },
42
42
  globe: {
43
- depthTestAgainstTerrain: false
43
+ depthTestAgainstTerrain: true // is necessary for scene.pickedPosition and correct height of the terrain. @see {https://github.com/CesiumGS/cesium/issues/5676}
44
44
  },
45
45
  highDynamicRange: false,
46
46
  pickTranslucentDepth: true,
package/src/index.js CHANGED
@@ -15,6 +15,7 @@ import * as layerLib from "./layer/lib";
15
15
  import {search, setGazetteerUrl} from "./searchAddress";
16
16
  import setBackgroundImage from "./lib/setBackgroundImage";
17
17
  import ping from "./lib/ping";
18
+ import ogcApiProcesses from "./api/ogcApiProcesses";
18
19
 
19
20
  export {
20
21
  createMapView,
@@ -34,5 +35,6 @@ export {
34
35
  ping,
35
36
  search,
36
37
  crs,
37
- webgl
38
+ webgl,
39
+ ogcApiProcesses
38
40
  };
package/src/layer/wms.js CHANGED
@@ -164,7 +164,7 @@ export function createLayer (rawLayer, layerParams = {}, options) {
164
164
  const source = createLayerSource(rawLayer, options),
165
165
  Layer = rawLayer.singleTile ? ImageLayer : TileLayer;
166
166
 
167
- source.set("olcs.projection", getProjection(OLCS_DEFAULT_OLCS_PROJECTION_CRS));
167
+ source.set("olcs_projection", getProjection(OLCS_DEFAULT_OLCS_PROJECTION_CRS));
168
168
 
169
169
  return new Layer(Object.assign({
170
170
  source,
@@ -0,0 +1,113 @@
1
+ import ogcApiProcesses from "../../src/api/ogcApiProcesses";
2
+
3
+ describe("ogcApiProcesses.js", () => {
4
+ const processUrl = "https://example.de",
5
+ processId = "process-id",
6
+ jobId = "job-id";
7
+
8
+ beforeEach(() => {
9
+ if (global.fetch) {
10
+ fetch.mockClear();
11
+ }
12
+
13
+ global.fetch = jest.fn().mockImplementationOnce(() => {
14
+ return new Promise((resolve) => {
15
+ resolve({
16
+ ok: true,
17
+ status: 200,
18
+ json: () => {
19
+ return {};
20
+ }
21
+ });
22
+ });
23
+ });
24
+ });
25
+
26
+ describe("processList", () => {
27
+ it("should return a process list", async () => {
28
+ await ogcApiProcesses.processList(processUrl);
29
+
30
+ expect(fetch).toHaveBeenCalledWith(`${processUrl}/processes`, {method: "GET"});
31
+ });
32
+
33
+ it("should return a process list with next link", async () => {
34
+ const offsetProcessUrl = `${processUrl}/processes?offset=30`;
35
+
36
+ await ogcApiProcesses.processList(offsetProcessUrl, true);
37
+
38
+ expect(fetch).toHaveBeenCalledWith(offsetProcessUrl, {method: "GET"});
39
+ });
40
+ });
41
+
42
+ describe("processDescription", () => {
43
+ it("should return a process description", async () => {
44
+ await ogcApiProcesses.processDescription(processUrl, processId);
45
+
46
+ expect(fetch).toHaveBeenCalledWith(`${processUrl}/processes/${processId}`, {method: "GET"});
47
+ });
48
+ });
49
+
50
+ describe("executeProcess", () => {
51
+ it("should execute a process", async () => {
52
+ const data = {
53
+ attr: "test-attribute"
54
+ };
55
+
56
+ await ogcApiProcesses.executeProcess(processUrl, processId, data);
57
+
58
+ expect(fetch).toHaveBeenCalledWith(`${processUrl}/processes/${processId}/execution`, {
59
+ method: "POST",
60
+ headers: {
61
+ "Content-Type": "application/json"
62
+ },
63
+ body: "{\"inputs\":{\"attr\":\"test-attribute\"}}"
64
+ });
65
+ });
66
+ });
67
+
68
+ describe("jobList", () => {
69
+ it("should return a job list", async () => {
70
+ await ogcApiProcesses.jobList(processUrl);
71
+
72
+ expect(fetch).toHaveBeenCalledWith(`${processUrl}/jobs`, {method: "GET"});
73
+ });
74
+
75
+ it("should return a job list with next link", async () => {
76
+ const offsetProcessUrl = `${processUrl}/jobs?offset=20`;
77
+
78
+ await ogcApiProcesses.processList(offsetProcessUrl, true);
79
+
80
+ expect(fetch).toHaveBeenCalledWith(offsetProcessUrl, {method: "GET"});
81
+ });
82
+ });
83
+
84
+ describe("jobStatus", () => {
85
+ it("should return a job status", async () => {
86
+ await ogcApiProcesses.jobStatus(processUrl, jobId);
87
+
88
+ expect(fetch).toHaveBeenCalledWith(`${processUrl}/jobs/${jobId}`, {method: "GET"});
89
+ });
90
+ });
91
+
92
+ describe("cancelJob", () => {
93
+ it("should cancle a job", async () => {
94
+ await ogcApiProcesses.cancelJob(processUrl, jobId);
95
+
96
+ expect(fetch).toHaveBeenCalledWith(`${processUrl}/jobs/${jobId}`, {method: "DELETE"});
97
+ });
98
+ });
99
+
100
+ describe("jobResults", () => {
101
+ it("should return job results in json format", async () => {
102
+ await ogcApiProcesses.jobResults(processUrl, jobId);
103
+
104
+ expect(fetch).toHaveBeenCalledWith(`${processUrl}/jobs/${jobId}/results?f=json`, {method: "GET"});
105
+ });
106
+
107
+ it("should return job results in html format", async () => {
108
+ await ogcApiProcesses.jobResults(processUrl, jobId, "html");
109
+
110
+ expect(fetch).toHaveBeenCalledWith(`${processUrl}/jobs/${jobId}/results?f=html`, {method: "GET"});
111
+ });
112
+ });
113
+ });