@masterportal/masterportalapi 2.63.0 → 2.64.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 +22 -0
- package/README.md +8 -0
- package/bitbucket-pipelines.yml +9 -9
- package/example/config/services.json +4 -4
- package/jest.setup.js +4 -0
- package/package.json +5 -5
- package/publiccode.yml +2 -2
- package/src/index.js +5 -1
- package/src/lib/attributeMapper.js +1 -1
- package/src/maps/interactions/drawInteraction.js +172 -15
- package/src/maps/interactions/modifyInteraction.js +15 -2
- package/src/shared/exportItem.js +216 -0
- package/src/shared/kmlExport.js +315 -0
- package/src/shared/utils.js +60 -0
- package/test/lib/attributeMapper.test.js +10 -0
- package/test/maps/interactions/drawInteraction.test.js +159 -3
- package/test/maps/interactions/modifyInteraction.test.js +28 -0
- package/test/shared/exportItem.test.js +265 -0
- package/test/shared/kmlExport.test.js +257 -0
- package/test/shared/utils.test.js +35 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,27 @@
|
|
|
3
3
|
|
|
4
4
|
The [Semantic Versioning](https://semver.org/spec/v2.0.0.html) is used.
|
|
5
5
|
|
|
6
|
+
## 2.64.0 - 2026-09-23
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
- Readme: Information and link to issues in opencode added.
|
|
10
|
+
- Draw: Added functions to draw and modify features: write text and draw square. Integrated wfsImgPath to apply configured styles.
|
|
11
|
+
- Export: Added functions to export drawn features in kml, geojson, gpx and csv formats.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- The following packages have been updated:
|
|
15
|
+
- dependencies:
|
|
16
|
+
- ol: 10.9.0 to 10.10.0
|
|
17
|
+
- ol-mapbox-style: 13.4.1 to 13.5.0
|
|
18
|
+
- olcs: 2.23.0 to 2.23.1
|
|
19
|
+
- peerDependencies:
|
|
20
|
+
- @cesium/engine: 26.0.0 to 26.3.0
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- AttributeMapper: prevented mapping of empty strings for GFI.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
6
27
|
## 2.63.0 - 2026-07-17
|
|
7
28
|
|
|
8
29
|
### Changed
|
|
@@ -11,6 +32,7 @@
|
|
|
11
32
|
- core-js: 3.33.1 to 3.49.0
|
|
12
33
|
- dayjs: 1.11.10 to 1.11.21
|
|
13
34
|
- proj4: 2.10.0 to 2.20.9
|
|
35
|
+
- ol-mapbox-style: 13.3.0 to 13.4.1
|
|
14
36
|
- devDependencies:
|
|
15
37
|
- @parcel/config-default: 2.15.4 to 2.16.4
|
|
16
38
|
- @parcel/transformer-sass: 2.15.4 to 2.16.4
|
package/README.md
CHANGED
|
@@ -25,3 +25,11 @@ Both methods may be required for useful user feedback. For example, a WMS may an
|
|
|
25
25
|
|``npm run generate-jsdoc``|Generates the project documentation within the folder ``./docs``.|
|
|
26
26
|
|``npm test``|Runs all tests. Prints code coverage to console.|
|
|
27
27
|
|``npm run test:watch``|Runs all tests in watch mode. Good practive to let this run during development in a separate terminal. |
|
|
28
|
+
|
|
29
|
+
## Community
|
|
30
|
+
|
|
31
|
+
The Bitbucket issue tracker is being removed on August 20, 2026. All issues have been migrated to openCode. You can access them via the link listed below, where you can also create new issues.
|
|
32
|
+
|
|
33
|
+
* [Issue tracker](https://gitlab.opencode.de/lgvhh/urban-data-solutions/masterportalapi/-/work_items)
|
|
34
|
+
|
|
35
|
+
**Please do not report security vulnerabilities via the public issue tracker.** Instead, report them privately by email as described in our [Security Policy](./SECURITY.md).
|
package/bitbucket-pipelines.yml
CHANGED
|
@@ -8,15 +8,15 @@ pipelines:
|
|
|
8
8
|
tags:
|
|
9
9
|
'v2.*.*':
|
|
10
10
|
- step:
|
|
11
|
-
name: deploy on openCode
|
|
11
|
+
name: deploy on new openCode
|
|
12
12
|
script:
|
|
13
|
-
- echo 'deploy to opencode:'$BITBUCKET_TAG
|
|
13
|
+
- echo 'deploy to new opencode:'$BITBUCKET_TAG
|
|
14
14
|
- git fetch --all --tags
|
|
15
15
|
- git checkout tags/$BITBUCKET_TAG
|
|
16
|
-
- git push https://$OpenCode_User:$OpenCode_Password@gitlab.opencode.de/
|
|
16
|
+
- git push https://$OpenCode_User:$OpenCode_Password@gitlab.opencode.de/lgvhh/urban-data-solutions/masterportalapi.git $BITBUCKET_TAG
|
|
17
17
|
- git clone --single-branch --branch master https://geowerkstatt@bitbucket.org/geowerkstatt-hamburg/masterportalapi.git
|
|
18
18
|
- cd masterportalapi
|
|
19
|
-
- git push https://$OpenCode_User:$OpenCode_Password@gitlab.opencode.de/
|
|
19
|
+
- git push https://$OpenCode_User:$OpenCode_Password@gitlab.opencode.de/lgvhh/urban-data-solutions/masterportalapi.git -f
|
|
20
20
|
custom: # Pipelines that are triggered manually
|
|
21
21
|
npm audit:
|
|
22
22
|
- step:
|
|
@@ -26,18 +26,18 @@ pipelines:
|
|
|
26
26
|
script:
|
|
27
27
|
- npm install
|
|
28
28
|
- npm audit --json
|
|
29
|
-
deploy last tag on openCode:
|
|
29
|
+
deploy last tag on new openCode:
|
|
30
30
|
- variables:
|
|
31
31
|
- name: BITBUCKET_TAG
|
|
32
32
|
description: tag to publish docs for
|
|
33
33
|
- step:
|
|
34
|
-
name: deploy last tag on openCode
|
|
34
|
+
name: deploy last tag on new openCode
|
|
35
35
|
script:
|
|
36
36
|
- apt-get update && apt-get install -y curl wput jq
|
|
37
37
|
- git fetch --all --tags
|
|
38
|
-
- echo '
|
|
38
|
+
- echo 'deploy to new opencode:'$BITBUCKET_TAG
|
|
39
39
|
- git checkout tags/$BITBUCKET_TAG
|
|
40
|
-
- git push https://$OpenCode_User:$OpenCode_Password@gitlab.opencode.de/
|
|
40
|
+
- git push https://$OpenCode_User:$OpenCode_Password@gitlab.opencode.de/lgvhh/urban-data-solutions/masterportalapi.git $BITBUCKET_TAG
|
|
41
41
|
- git clone --single-branch --branch master https://geowerkstatt@bitbucket.org/geowerkstatt-hamburg/masterportalapi.git
|
|
42
42
|
- cd masterportalapi
|
|
43
|
-
- git push https://$OpenCode_User:$OpenCode_Password@gitlab.opencode.de/
|
|
43
|
+
- git push https://$OpenCode_User:$OpenCode_Password@gitlab.opencode.de/lgvhh/urban-data-solutions/masterportalapi.git -f
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
{
|
|
59
59
|
"id": "4001",
|
|
60
60
|
"name": "Gelaende",
|
|
61
|
-
"url": "https://daten-hamburg.de/gdi3d/datasource-data/Gelaende",
|
|
61
|
+
"url": "https://www.daten-hamburg.de/gdi3d/datasource-data/Gelaende",
|
|
62
62
|
"typ": "Terrain3D",
|
|
63
63
|
"cesiumTerrainProviderOptions": {
|
|
64
64
|
"requestVertexNormals": true
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
{
|
|
68
68
|
"id": "4002",
|
|
69
69
|
"name": "Gebäude LoD2",
|
|
70
|
-
"url": "https://daten-hamburg.de/gdi3d/datasource-data/LoD2",
|
|
70
|
+
"url": "https://www.daten-hamburg.de/gdi3d/datasource-data/LoD2",
|
|
71
71
|
"typ": "TileSet3D",
|
|
72
72
|
"styleId": "3DTileSetStyle",
|
|
73
73
|
"cesium3DTilesetOptions": {
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"typ": "Entities3D",
|
|
81
81
|
"entities": [
|
|
82
82
|
{
|
|
83
|
-
"url": "https://daten-hamburg.de/gdi3d/datasource-data/Simple_Building.glb",
|
|
83
|
+
"url": "https://www.daten-hamburg.de/gdi3d/datasource-data/Simple_Building.glb",
|
|
84
84
|
"attributes": {
|
|
85
85
|
"name": "einfaches Haus in Planten und Blomen"
|
|
86
86
|
},
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
"show": true
|
|
96
96
|
},
|
|
97
97
|
{
|
|
98
|
-
"url": "https://daten-hamburg.de/gdi3d/datasource-data/Simple_Building.glb",
|
|
98
|
+
"url": "https://www.daten-hamburg.de/gdi3d/datasource-data/Simple_Building.glb",
|
|
99
99
|
"attributes": {
|
|
100
100
|
"name": "einfaches Haus im See"
|
|
101
101
|
},
|
package/jest.setup.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@masterportal/masterportalapi",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.64.0",
|
|
4
4
|
"description": "Basic functions of the Masterportal as api",
|
|
5
5
|
"homepage": "https://bitbucket.org/geowerkstatt-hamburg/masterportalapi#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"core-js": "^3.49.0",
|
|
37
37
|
"dayjs": "^1.11.21",
|
|
38
|
-
"ol": "10.
|
|
39
|
-
"ol-mapbox-style": "13.
|
|
40
|
-
"olcs": "^2.23.
|
|
38
|
+
"ol": "^10.10.0",
|
|
39
|
+
"ol-mapbox-style": "^13.5.0",
|
|
40
|
+
"olcs": "^2.23.1",
|
|
41
41
|
"proj4": "^2.20.9"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"util": "^0.12.5"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
|
-
"@cesium/engine": "^26.
|
|
71
|
+
"@cesium/engine": "^26.3.0"
|
|
72
72
|
},
|
|
73
73
|
"engines": {
|
|
74
74
|
"node": "^22.19.0 || ^24.11.1",
|
package/publiccode.yml
CHANGED
|
@@ -81,8 +81,8 @@ maintenance:
|
|
|
81
81
|
name: Masterportal
|
|
82
82
|
platforms:
|
|
83
83
|
- web
|
|
84
|
-
releaseDate: '2026-
|
|
84
|
+
releaseDate: '2026-09-23'
|
|
85
85
|
roadmap: 'https://bitbucket.org/geowerkstatt-hamburg/masterportalapi/src/master/'
|
|
86
86
|
softwareType: api
|
|
87
|
-
softwareVersion: 2.
|
|
87
|
+
softwareVersion: 2.64.0
|
|
88
88
|
url: 'https://bitbucket.org/geowerkstatt-hamburg/masterportalapi.git'
|
package/src/index.js
CHANGED
|
@@ -16,6 +16,8 @@ import {search, setGazetteerUrl} from "./searchAddress";
|
|
|
16
16
|
import setBackgroundImage from "./lib/setBackgroundImage";
|
|
17
17
|
import ping from "./lib/ping";
|
|
18
18
|
import ogcApiProcesses from "./api/ogcApiProcesses";
|
|
19
|
+
import * as exportItem from "./shared/exportItem";
|
|
20
|
+
import * as kmlExport from "./shared/kmlExport";
|
|
19
21
|
|
|
20
22
|
export {
|
|
21
23
|
createMapView,
|
|
@@ -36,5 +38,7 @@ export {
|
|
|
36
38
|
search,
|
|
37
39
|
crs,
|
|
38
40
|
webgl,
|
|
39
|
-
ogcApiProcesses
|
|
41
|
+
ogcApiProcesses,
|
|
42
|
+
exportItem,
|
|
43
|
+
kmlExport
|
|
40
44
|
};
|
|
@@ -266,7 +266,7 @@ function mapAttributes (properties, mappingObject, isNested = true) {
|
|
|
266
266
|
value = prepareValueFromObject(key, newKey, properties);
|
|
267
267
|
newKey = newKey.name;
|
|
268
268
|
}
|
|
269
|
-
if (value && value !== "undefined") {
|
|
269
|
+
if (value !== undefined && value !== null && value !== "" && value !== "undefined") {
|
|
270
270
|
mappedProperties[newKey] = value;
|
|
271
271
|
}
|
|
272
272
|
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {createBox} from "ol/interaction/Draw.js";
|
|
1
|
+
import {createBox, createRegularPolygon} from "ol/interaction/Draw.js";
|
|
2
|
+
import {Circle as CircleStyle, Icon, Style, Fill} from "ol/style.js";
|
|
3
|
+
import Text from "ol/style/Text.js";
|
|
2
4
|
import {Draw} from "ol/interaction.js";
|
|
3
5
|
|
|
4
6
|
import createStyle from "../../vectorStyle/createStyle";
|
|
@@ -32,12 +34,29 @@ const earthRadius = 6378137,
|
|
|
32
34
|
},
|
|
33
35
|
polygon: {
|
|
34
36
|
type: "Polygon"
|
|
37
|
+
},
|
|
38
|
+
writeText: {
|
|
39
|
+
type: "Point"
|
|
40
|
+
},
|
|
41
|
+
square: {
|
|
42
|
+
type: "Circle",
|
|
43
|
+
options: {
|
|
44
|
+
geometryFunction: createRegularPolygon(4)
|
|
45
|
+
}
|
|
35
46
|
}
|
|
36
47
|
};
|
|
37
48
|
let styleObject = null,
|
|
38
49
|
styleObjectOuterCircle = null,
|
|
39
50
|
zIndex = 0;
|
|
40
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Returns the current style rule from styleObject.
|
|
54
|
+
* @returns {Object|null} The current style rule or null.
|
|
55
|
+
*/
|
|
56
|
+
function getCurrentStyleRule () {
|
|
57
|
+
return styleObject?.rules?.[0]?.style || null;
|
|
58
|
+
}
|
|
59
|
+
|
|
41
60
|
/**
|
|
42
61
|
* Converts a value from one unit to another.
|
|
43
62
|
* @param {Number} value The value to convert.
|
|
@@ -66,12 +85,9 @@ function convertUnits (value, sourceUnit, targetUnit) {
|
|
|
66
85
|
*/
|
|
67
86
|
function transformMapUnitRadius (radius, mapProjection) {
|
|
68
87
|
const unit = mapProjection.getUnits();
|
|
69
|
-
let mapUnitRadius;
|
|
88
|
+
let mapUnitRadius = radius;
|
|
70
89
|
|
|
71
|
-
if (unit === "
|
|
72
|
-
mapUnitRadius = radius;
|
|
73
|
-
}
|
|
74
|
-
else if (unit === "degrees") {
|
|
90
|
+
if (unit === "degrees") {
|
|
75
91
|
mapUnitRadius = radius * roh / earthRadius;
|
|
76
92
|
}
|
|
77
93
|
|
|
@@ -86,6 +102,7 @@ function transformMapUnitRadius (radius, mapProjection) {
|
|
|
86
102
|
* @param {Object} [options={}] The options for drawing features.
|
|
87
103
|
* @param {Number} [options.innerRadius] The radius for the inner circle.
|
|
88
104
|
* @param {Number} [options.outerRadius] The radius for the outer circle.
|
|
105
|
+
* @param {String} [options.unit] The unit for the radii (e.g. "m", "km").
|
|
89
106
|
* @returns {void}
|
|
90
107
|
*/
|
|
91
108
|
function drawOuterCircle (feature, mapProjection, source, options = {}) {
|
|
@@ -110,10 +127,11 @@ function drawOuterCircle (feature, mapProjection, source, options = {}) {
|
|
|
110
127
|
|
|
111
128
|
/**
|
|
112
129
|
* Create a feature for the (inner) circle of draw type: circle or double circle.
|
|
113
|
-
* @param {ol/feature} feature The ol feature.
|
|
130
|
+
* @param {ol/feature} feature The ol feature.
|
|
114
131
|
* @param {Object} mapProjection The map projection.
|
|
115
132
|
* @param {Object} [options={}] The options for drawing features.
|
|
116
133
|
* @param {Number} [options.innerRadius] The radius for the (inner) circle.
|
|
134
|
+
* @param {String} [options.unit] The unit for the radius (e.g. "m", "km").
|
|
117
135
|
* @returns {void}
|
|
118
136
|
*/
|
|
119
137
|
function drawInnerCircle (feature, mapProjection, options = {}) {
|
|
@@ -133,6 +151,7 @@ function drawInnerCircle (feature, mapProjection, options = {}) {
|
|
|
133
151
|
* @param {Number} [options.innerRadius] The radius for the inner circle.
|
|
134
152
|
* @param {Boolean} [options.interactive] Circle is drawn interactively or not.
|
|
135
153
|
* @param {Number} [options.outerRadius] The radius for the outer circle.
|
|
154
|
+
* @param {String} [options.unit] The unit for the radii (e.g. "m", "km").
|
|
136
155
|
* @returns {void}
|
|
137
156
|
*/
|
|
138
157
|
function drawCircle (drawInteraction, drawType, mapProjection, source, options = {}) {
|
|
@@ -157,7 +176,9 @@ function drawCircle (drawInteraction, drawType, mapProjection, source, options =
|
|
|
157
176
|
*/
|
|
158
177
|
function setStyleObject (currentLayout, outerCircle = false) {
|
|
159
178
|
const fillOpacity = 1 - (currentLayout.fillTransparency / 100),
|
|
179
|
+
strokeOpacity = fillOpacity,
|
|
160
180
|
fillColorRgba = [...currentLayout.fillColor, fillOpacity],
|
|
181
|
+
strokeColorRgba = [...currentLayout.strokeColor, strokeOpacity],
|
|
161
182
|
style = {
|
|
162
183
|
rules: [
|
|
163
184
|
{
|
|
@@ -165,13 +186,16 @@ function setStyleObject (currentLayout, outerCircle = false) {
|
|
|
165
186
|
circleFillColor: fillColorRgba,
|
|
166
187
|
circleStrokeColor: currentLayout.strokeColor,
|
|
167
188
|
circleStrokeWidth: currentLayout.strokeWidth,
|
|
168
|
-
lineStrokeColor:
|
|
189
|
+
lineStrokeColor: strokeColorRgba,
|
|
169
190
|
lineStrokeWidth: currentLayout.strokeWidth,
|
|
170
191
|
polygonFillColor: fillColorRgba,
|
|
171
192
|
polygonStrokeColor: currentLayout.strokeColor,
|
|
172
193
|
polygonStrokeDash: currentLayout.polygonDash,
|
|
173
194
|
polygonStrokeDashOffset: currentLayout.polygonStrokeDashOffset,
|
|
174
|
-
polygonStrokeWidth: currentLayout.strokeWidth
|
|
195
|
+
polygonStrokeWidth: currentLayout.strokeWidth,
|
|
196
|
+
text: currentLayout.text || "Text",
|
|
197
|
+
textFont: currentLayout.font || "Arial",
|
|
198
|
+
textFontSize: currentLayout.fontSize || 10
|
|
175
199
|
}
|
|
176
200
|
}
|
|
177
201
|
]
|
|
@@ -188,11 +212,12 @@ function setStyleObject (currentLayout, outerCircle = false) {
|
|
|
188
212
|
/**
|
|
189
213
|
* Sets the style to overlay and feature.
|
|
190
214
|
* @param {ol/interaction/Draw} drawInteraction The draw interaction.
|
|
215
|
+
* @param {String} wfsImgPath Path to the image folder from Config.
|
|
191
216
|
* @returns {void}
|
|
192
217
|
*/
|
|
193
|
-
function setStyleToDrawInteraction (drawInteraction) {
|
|
218
|
+
function setStyleToDrawInteraction (drawInteraction, wfsImgPath) {
|
|
194
219
|
drawInteraction.on("drawstart", event => {
|
|
195
|
-
const style = createStyle.createStyle(styleObject, event.feature, false);
|
|
220
|
+
const style = createStyle.createStyle(styleObject, event.feature, false, wfsImgPath);
|
|
196
221
|
|
|
197
222
|
style.setZIndex(zIndex++);
|
|
198
223
|
drawInteraction.getOverlay().setStyle(style);
|
|
@@ -200,16 +225,139 @@ function setStyleToDrawInteraction (drawInteraction) {
|
|
|
200
225
|
});
|
|
201
226
|
}
|
|
202
227
|
|
|
228
|
+
/**
|
|
229
|
+
* Sets the style to the text.
|
|
230
|
+
* @param {ol/interaction/Draw} drawInteraction The draw interaction.
|
|
231
|
+
* @returns {void}
|
|
232
|
+
*/
|
|
233
|
+
function setStyleToDrawText (drawInteraction) {
|
|
234
|
+
drawInteraction.on("drawstart", event => {
|
|
235
|
+
const style = getCurrentStyleRule();
|
|
236
|
+
|
|
237
|
+
event.feature.set("drawType", "writeText");
|
|
238
|
+
|
|
239
|
+
if (!style?.text) {
|
|
240
|
+
console.error("Style object for text is not properly initialized.");
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const textStyle = new Text({
|
|
245
|
+
text: style.text ?? "",
|
|
246
|
+
font: `${style.textFontSize}px ${style.textFont}`,
|
|
247
|
+
fill: new Fill({color: style.polygonFillColor || "black"}),
|
|
248
|
+
textAlign: style.textAlign || "left",
|
|
249
|
+
textBaseline: "bottom"
|
|
250
|
+
}),
|
|
251
|
+
olStyle = new Style({text: textStyle});
|
|
252
|
+
|
|
253
|
+
olStyle.setZIndex(zIndex++);
|
|
254
|
+
event.feature.set("textContent", style.text);
|
|
255
|
+
event.feature.set("textFontSize", style.textFontSize);
|
|
256
|
+
event.feature.set("textFont", style.textFont);
|
|
257
|
+
event.feature.set("textFillColor", style.polygonFillColor);
|
|
258
|
+
event.feature.setStyle(olStyle);
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Returns the current text style from the styleObject for use as sketch/preview.
|
|
264
|
+
* @returns {ol/style/Style|null} The text style or null.
|
|
265
|
+
*/
|
|
266
|
+
function getTextStyle () {
|
|
267
|
+
const style = getCurrentStyleRule();
|
|
268
|
+
|
|
269
|
+
if (!style) {
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (!style.text || style.text === "Text") {
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return new Style({
|
|
278
|
+
text: new Text({
|
|
279
|
+
text: style.text,
|
|
280
|
+
font: `${style.textFontSize}px ${style.textFont}`,
|
|
281
|
+
fill: new Fill({color: style.polygonFillColor || "black"}),
|
|
282
|
+
textAlign: style.textAlign || "left",
|
|
283
|
+
textBaseline: "bottom"
|
|
284
|
+
})
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Returns a style for simple point features without stroke.
|
|
290
|
+
* Uses the current circleFillColor from the styleObject.
|
|
291
|
+
* @returns {ol/style/Style} The point style.
|
|
292
|
+
*/
|
|
293
|
+
function getSimplePointStyle () {
|
|
294
|
+
const rawColor = getCurrentStyleRule()?.circleFillColor || [0, 0, 0, 1],
|
|
295
|
+
fillColor = [rawColor[0], rawColor[1], rawColor[2], 1];
|
|
296
|
+
|
|
297
|
+
return new Style({
|
|
298
|
+
image: new CircleStyle({
|
|
299
|
+
radius: 8,
|
|
300
|
+
fill: new Fill({color: fillColor})
|
|
301
|
+
})
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
|
|
203
305
|
/**
|
|
204
306
|
* Create the draw interaction.
|
|
205
307
|
* @param {String} drawType The current draw type.
|
|
206
308
|
* @param {ol/source} source The vector layer source for draw features.
|
|
309
|
+
* @param {Object[]} [iconList=[]] The list of symbols for the draw type symbols.
|
|
310
|
+
* @param {String} [wfsImgPath=""] Path to the image folder, used as prefix when symbol value is not an absolute path.
|
|
207
311
|
* @returns {ol/interaction/Draw|null} The draw interaction.
|
|
208
312
|
*/
|
|
209
|
-
function createDrawInteraction (drawType, source) {
|
|
313
|
+
function createDrawInteraction (drawType, source, iconList, wfsImgPath = "") {
|
|
210
314
|
let drawInteraction = null;
|
|
315
|
+
const symbol = iconList?.length > 0 ? iconList.find(val => val.id === drawType) : null;
|
|
316
|
+
|
|
317
|
+
if (symbol) {
|
|
318
|
+
if (symbol.type === "image") {
|
|
319
|
+
const iconSrc = symbol.value.startsWith("/") || symbol.value.startsWith("http") || symbol.value.startsWith(".")
|
|
320
|
+
? symbol.value
|
|
321
|
+
: `${wfsImgPath}${symbol.value}`,
|
|
322
|
+
svgStyle = new Style({
|
|
323
|
+
image: new Icon({
|
|
324
|
+
src: iconSrc,
|
|
325
|
+
scale: symbol.scale || 1,
|
|
326
|
+
anchor: [0.5, 1]
|
|
327
|
+
})
|
|
328
|
+
});
|
|
211
329
|
|
|
212
|
-
|
|
330
|
+
drawInteraction = new Draw({
|
|
331
|
+
source: source,
|
|
332
|
+
type: "Point",
|
|
333
|
+
style: svgStyle
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
else if (symbol.type === "simple_point") {
|
|
337
|
+
drawInteraction = new Draw({
|
|
338
|
+
source: source,
|
|
339
|
+
type: "Point",
|
|
340
|
+
style: getSimplePointStyle
|
|
341
|
+
});
|
|
342
|
+
drawInteraction.on("drawstart", event => {
|
|
343
|
+
const style = getSimplePointStyle();
|
|
344
|
+
|
|
345
|
+
style.setZIndex(zIndex++);
|
|
346
|
+
event.feature.setStyle(style);
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
drawInteraction = new Draw({
|
|
351
|
+
source: source,
|
|
352
|
+
type: "Point"
|
|
353
|
+
});
|
|
354
|
+
if (styleObject !== null) {
|
|
355
|
+
setStyleToDrawInteraction(drawInteraction, wfsImgPath);
|
|
356
|
+
}
|
|
357
|
+
drawInteraction.getOverlay().setStyle([]);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
else if (typeof mappingDrawTypes[drawType] === "object") {
|
|
213
361
|
const options = mappingDrawTypes[drawType].options || {};
|
|
214
362
|
|
|
215
363
|
drawInteraction = new Draw({
|
|
@@ -219,8 +367,16 @@ function createDrawInteraction (drawType, source) {
|
|
|
219
367
|
type: mappingDrawTypes[drawType].type
|
|
220
368
|
});
|
|
221
369
|
|
|
222
|
-
if (styleObject !== null && drawType !== "doubleCircle") {
|
|
223
|
-
setStyleToDrawInteraction(drawInteraction);
|
|
370
|
+
if (styleObject !== null && drawType !== "doubleCircle" && drawType !== "writeText") {
|
|
371
|
+
setStyleToDrawInteraction(drawInteraction, wfsImgPath);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
if (drawType === "writeText") {
|
|
375
|
+
setStyleToDrawText(drawInteraction);
|
|
376
|
+
drawInteraction.getOverlay().setStyle(getTextStyle() ?? []);
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
drawInteraction.getOverlay().setStyle([]);
|
|
224
380
|
}
|
|
225
381
|
}
|
|
226
382
|
|
|
@@ -235,6 +391,7 @@ export default {
|
|
|
235
391
|
drawCircle,
|
|
236
392
|
drawInnerCircle,
|
|
237
393
|
drawOuterCircle,
|
|
394
|
+
getTextStyle,
|
|
238
395
|
setStyleObject,
|
|
239
396
|
transformMapUnitRadius
|
|
240
397
|
};
|
|
@@ -3,11 +3,24 @@ import {Modify} from "ol/interaction.js";
|
|
|
3
3
|
/**
|
|
4
4
|
* Create the modify interaction.
|
|
5
5
|
* @param {ol/source} source The vector layer source containing the features to be modified.
|
|
6
|
+
* @param {Object} [options={}] Optional object to register watchers for modification of features.
|
|
7
|
+
* @param {Function} [options.onModifyEnd] Callback function triggered when a modify operation ends.
|
|
8
|
+
* @param {Function} [options.onModifyStart] Callback function triggered when a modify operation starts.
|
|
6
9
|
* @returns {ol/interaction/Modify} The modify interaction.
|
|
7
10
|
*/
|
|
8
|
-
function createModifyInteraction (source) {
|
|
11
|
+
function createModifyInteraction (source, options = {}) {
|
|
9
12
|
const modifyInteraction = new Modify({
|
|
10
|
-
|
|
13
|
+
source: source
|
|
14
|
+
}),
|
|
15
|
+
watcherMap = {
|
|
16
|
+
modifyend: options.onModifyEnd,
|
|
17
|
+
modifystart: options.onModifyStart
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
Object.entries(watcherMap).forEach(([eventName, callback]) => {
|
|
21
|
+
if (typeof callback === "function") {
|
|
22
|
+
modifyInteraction.on(eventName, callback);
|
|
23
|
+
}
|
|
11
24
|
});
|
|
12
25
|
|
|
13
26
|
return modifyInteraction;
|