Skip to content

Commit 18ccdd2

Browse files
committed
Add option to set WFS flag & fylr tag for newly drawn geometries (for marking them as temporary)
1 parent b9579ba commit 18ccdd2

5 files changed

Lines changed: 96 additions & 41 deletions

File tree

l10n/custom-data-type-nfis-geometry.csv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ server.config.parameter.system.nfisGeoservices.geoserver_write_password.label,Ge
3737
server.config.parameter.system.nfisGeoservices.wfs_geometry_id_field_name.label,Name des Geometrie-ID-Feldes im WFS,Name of the geometry ID field in the WFS
3838
server.config.parameter.system.nfisGeoservices.show_upload_button.label,Hochladen von Geometrien im Masterportal,Upload geometries in Masterportal
3939
server.config.parameter.system.nfisGeoservices.show_upload_button.checkbox,Button anzeigen,Show button
40+
server.config.parameter.system.nfisGeoservices.show_upload_button.label,Hochladen von Geometrien im Masterportal,Upload geometries in Masterportal
41+
server.config.parameter.system.nfisGeoservices.wfs_temporary_geometry_field_name.label,Name des Feldes zur Kennzeichnung provisorischer Geometrien im WFS,Name of field for marking geometries as temporary in WFS
42+
server.config.parameter.system.nfisGeoservices.temporary_geometry_tag_id.label,ID des Tags zur Kennzeichnung von Objekten mit provisorischen Geometrien,ID of tag for marking objects with temporary geometries
4043
server.config.parameter.system.nfisGeoservices.wfs_configuration.label,Objekttypen,Object types
4144
server.config.parameter.system.nfisGeoservices.wfs_configuration.object_type.label,Name des Objekttyps,Object type name
4245
server.config.parameter.system.nfisGeoservices.wfs_configuration.geometry_fields.label,Geometrie-Felder,Geometry fields

manifest.master.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ base_config:
5959
show_upload_button:
6060
type: bool
6161
position: 7
62+
wfs_temporary_geometry_field_name:
63+
type: text
64+
position: 8
65+
temporary_geometry_tag_id:
66+
type: int
67+
position: 9
6268
wfs_configuration:
6369
type: table
6470
fields:
@@ -142,7 +148,7 @@ base_config:
142148
position: 0
143149
position: 14
144150
position: 1
145-
position: 8
151+
position: 10
146152
linked_objects:
147153
type: table
148154
fields:
@@ -152,7 +158,7 @@ base_config:
152158
- name: link_field_name
153159
type: text
154160
position: 1
155-
position: 9
161+
position: 11
156162
masterportal_configurations:
157163
type: table
158164
fields:
@@ -165,7 +171,7 @@ base_config:
165171
- name: file_name
166172
type: text
167173
position: 2
168-
position: 10
174+
position: 12
169175

170176
callbacks:
171177
db_pre_save:

src/server/sendDataToGeoserver.js

Lines changed: 73 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,26 @@ process.stdin.on('data', d => {
1616

1717
process.stdin.on('end', async () => {
1818
const data = JSON.parse(input);
19+
const changedObjects = [];
1920

2021
for (let object of data.objects) {
2122
await updateObject(
2223
getObjectData(object),
2324
object._current ? getObjectData(object._current) : undefined
2425
);
26+
if (await handleNewlyDrawnGeometries(object)) changedObjects.push(object);
2527
}
2628

27-
console.log(JSON.stringify({ objects: [] }));
28-
console.error('No changes');
29-
process.exit(0);
30-
return;
29+
console.log(JSON.stringify({ objects: changedObjects }));
30+
31+
if (!changedObjects.length) {
32+
console.error('No changes');
33+
process.exit(0);
34+
}
3135
});
3236

3337
function getObjectData(object) {
34-
const objectData = object[object._objecttype];
38+
const objectData = JSON.parse(JSON.stringify(object[object._objecttype]));
3539
objectData._uuid = object._uuid;
3640
objectData._objecttype = object._objecttype;
3741
return objectData;
@@ -46,16 +50,8 @@ function getWFSConfiguration(configuration, objectType) {
4650
return wfsConfiguration?.find(configuration => configuration.object_type === objectType);
4751
}
4852

49-
function getAuthorizationString(configuration) {
50-
const username = configuration.geoserver_write_username;
51-
const password = configuration.geoserver_write_password;
52-
53-
return btoa(username + ':' + password);
54-
}
55-
5653
async function updateObject(object, currentObject) {
5754
const configuration = getPluginConfiguration();
58-
const authorizationString = getAuthorizationString(configuration);
5955

6056
if (currentObject) addDataFromCurrentObject(object, currentObject);
6157
addToObjectCache(object);
@@ -72,8 +68,8 @@ async function updateObject(object, currentObject) {
7268
return throwErrorToFrontend('Eine oder mehrere Geometrien sind bereits mit anderen Objekten verknüpft.', undefined, 'multipleGeometryLinking');
7369
}
7470

75-
await editGeometries(object, fieldConfiguration, geometryIds, authorizationString);
76-
if (currentObject) await deleteGeometries(fieldConfiguration, geometryIds, currentObject, authorizationString);
71+
await editGeometries(object, fieldConfiguration, geometryIds);
72+
if (currentObject) await deleteGeometries(fieldConfiguration, geometryIds, currentObject);
7773
}
7874
}
7975

@@ -145,19 +141,20 @@ function getGeometryFieldPaths(configuration) {
145141
return fieldPaths;
146142
}
147143

148-
async function editGeometries(object, fieldConfiguration, geometryIds, authorizationString) {
144+
async function editGeometries(object, fieldConfiguration, geometryIds) {
149145
if (isSendingDataToGeoserverActivated(fieldConfiguration, geometryIds)) {
150146
const changeMap = await getChangeMap(object, fieldConfiguration);
151147
if (Object.keys(changeMap).length) {
152-
await performEditTransaction(geometryIds, changeMap, fieldConfiguration, authorizationString);
148+
const requestXml = getEditRequestXml(geometryIds, changeMap, fieldConfiguration.edit_wfs_feature_type);
149+
await performEditTransaction(geometryIds, requestXml, fieldConfiguration);
153150
}
154151
}
155152
}
156153

157-
async function deleteGeometries(fieldConfiguration, geometryIds, currentObject, authorizationString) {
154+
async function deleteGeometries(fieldConfiguration, geometryIds, currentObject) {
158155
if (!currentObject) return;
159156
const deletedGeometryIds = await getDeletedGeometryIds(geometryIds, currentObject, fieldConfiguration);
160-
if (deletedGeometryIds.length) await performDeleteTransaction(deletedGeometryIds, fieldConfiguration, authorizationString);
157+
if (deletedGeometryIds.length) await performDeleteTransaction(deletedGeometryIds, fieldConfiguration);
161158
}
162159

163160
async function getDeletedGeometryIds(geometryIds, currentObject, fieldConfiguration) {
@@ -332,39 +329,34 @@ function isDanteConcept(fieldValue) {
332329
&& fieldValue.conceptURI !== undefined && typeof fieldValue.conceptURI === 'string';
333330
}
334331

335-
async function performEditTransaction(geometryIds, changeMap, fieldConfiguration, authorizationString) {
336-
const result = await performTransaction(
337-
getEditRequestXml(geometryIds, changeMap, fieldConfiguration.edit_wfs_feature_type),
338-
fieldConfiguration.edit_wfs_url,
339-
authorizationString
340-
);
332+
async function performEditTransaction(geometryIds, requestXml, fieldConfiguration) {
333+
const result = await performTransaction(requestXml, fieldConfiguration.edit_wfs_url);
341334

342335
if (!new RegExp('<wfs:totalUpdated>' + geometryIds.length + '<\/wfs:totalUpdated>').test(result)) {
343336
throwErrorToFrontend('Bei der Aktualisierung von Geometrie-Datensätzen ist ein Fehler aufgetreten:', result);
344337
}
345338
}
346339

347-
async function performDeleteTransaction(geometryIds, fieldConfiguration, authorizationString) {
340+
async function performDeleteTransaction(geometryIds, fieldConfiguration) {
348341
const result = await performTransaction(
349342
getDeleteRequestXml(geometryIds, fieldConfiguration.edit_wfs_feature_type),
350-
fieldConfiguration.edit_wfs_url,
351-
authorizationString
343+
fieldConfiguration.edit_wfs_url
352344
);
353345

354346
if (!new RegExp('<wfs:totalDeleted>' + geometryIds.length + '<\/wfs:totalDeleted>').test(result)) {
355347
throwErrorToFrontend('Beim Löschen von Geometrie-Datensätzen ist ein Fehler aufgetreten:', result);
356348
}
357349
}
358350

359-
async function performTransaction(requestXml, wfsUrl, authorizationString) {
360-
const transactionUrl = wfsUrl + '?service=WFS&version=1.1.0&request=Transaction';
351+
async function performTransaction(requestXml, wfsUrl) {
352+
const transactionUrl = wfsUrl + '?service=WFS&version=1.1.0&request=Transaction';;
361353

362354
try {
363355
const response = await fetch(transactionUrl, {
364356
method: 'POST',
365357
headers: {
366358
'Content-Type': 'application/xml',
367-
'Authorization': 'Basic ' + authorizationString
359+
'Authorization': 'Basic ' + getAuthorizationString(getPluginConfiguration())
368360
},
369361
body: requestXml
370362
});
@@ -383,6 +375,18 @@ function getEditRequestXml(geometryIds, changeMap, featureType) {
383375
);
384376
}
385377

378+
function getMarkAsTemporaryRequestXml(geometryIds, propertyName, featureType) {
379+
return getTransactionXml(
380+
'<wfs:Update typeName="' + featureType + '">'
381+
+ '<wfs:Property>'
382+
+ '<wfs:Name>' + propertyName + '</wfs:Name>'
383+
+ '<wfs:Value>true</wfs:Value>'
384+
+ '</wfs:Property>'
385+
+ getFilterXml(geometryIds)
386+
+ '</wfs:Update>'
387+
);
388+
}
389+
386390
function getDeleteRequestXml(geometryIds, featureType) {
387391
return getTransactionXml(
388392
'<wfs:Delete typeName="' + featureType + '">'
@@ -431,6 +435,44 @@ function getGeometryFilterXml(geometryId) {
431435
+ '</ogc:PropertyIsEqualTo>';
432436
}
433437

438+
async function handleNewlyDrawnGeometries(object) {
439+
const configuration = getPluginConfiguration();
440+
const wfsConfiguration = getWFSConfiguration(configuration, object._objecttype);
441+
if (!wfsConfiguration) return false;
442+
443+
const wfsTemporaryGeometryFieldName = configuration.wfs_temporary_geometry_field_name;
444+
const temporaryGeometryTagId = configuration.temporary_geometry_tag_id;
445+
446+
let changed = false;
447+
for (let fieldConfiguration of wfsConfiguration.geometry_fields) {
448+
for (let fieldValue of await getFieldValues(object[object._objecttype], fieldConfiguration.field_path.split('.'))) {
449+
const newlyDrawnGeometryIds = fieldValue.newly_drawn_geometry_ids;
450+
delete fieldValue.newly_drawn_geometry_ids;
451+
changed = true;
452+
if (!newlyDrawnGeometryIds?.length) continue;
453+
454+
if (wfsTemporaryGeometryFieldName) {
455+
await markGeometriesAsTemporary(newlyDrawnGeometryIds, fieldConfiguration, wfsTemporaryGeometryFieldName);
456+
}
457+
if (temporaryGeometryTagId) object._tags = [{ _id: temporaryGeometryTagId }];
458+
}
459+
}
460+
461+
return changed;
462+
}
463+
464+
async function markGeometriesAsTemporary(geometryIds, fieldConfiguration, wfsTemporaryGeometryFieldName) {
465+
const requestXml = getMarkAsTemporaryRequestXml(geometryIds, wfsTemporaryGeometryFieldName, fieldConfiguration.edit_wfs_feature_type);
466+
await performEditTransaction(geometryIds, requestXml, fieldConfiguration);
467+
}
468+
469+
function getAuthorizationString(configuration) {
470+
const username = configuration.geoserver_write_username;
471+
const password = configuration.geoserver_write_password;
472+
473+
return btoa(username + ':' + password);
474+
}
475+
434476
function throwErrorToFrontend(error, description, realm) {
435477
console.log(JSON.stringify({
436478
error: {

src/webfrontend/js/customDataType/contentLoader.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ function createGeometry(contentElement, cdata, settings, wfsData, extent, upload
195195
const newGeometryId = window.crypto.randomUUID();
196196
navigator.clipboard.writeText(newGeometryId);
197197
window.open(getEditGeometryUrl(settings, wfsData, extent, upload), '_blank');
198-
openCreateGeometryModal(contentElement, cdata, settings, newGeometryId);
198+
openCreateGeometryModal(contentElement, cdata, settings, newGeometryId, !upload);
199199
}
200200

201201
function openEditGeometryModal(contentElement, cdata, settings) {
@@ -216,7 +216,7 @@ function openEditGeometryModal(contentElement, cdata, settings) {
216216
return modalDialog.show();
217217
}
218218

219-
function openCreateGeometryModal(contentElement, cdata, settings, newGeometryId, error) {
219+
function openCreateGeometryModal(contentElement, cdata, settings, newGeometryId, drawn, error) {
220220
let text = '';
221221
if (error) text += $$('custom.data.type.nfis.geometry.create.modal.error.notFound') + '\n\n';
222222
text += $$('custom.data.type.nfis.geometry.create.modal.text.1') + '\n\n'
@@ -234,12 +234,12 @@ function openCreateGeometryModal(contentElement, cdata, settings, newGeometryId,
234234
text: $$('custom.data.type.nfis.geometry.modal.ok'),
235235
primary: true,
236236
onClick: () => {
237-
setGeometryId(contentElement, cdata, settings, newGeometryId).then(
237+
setGeometryId(contentElement, cdata, settings, newGeometryId, drawn).then(
238238
() => {},
239239
error => {
240240
if (error) console.error(error);
241241
openCreateGeometryModal(
242-
contentElement, cdata, settings, newGeometryId, true
242+
contentElement, cdata, settings, newGeometryId, drawn, true
243243
);
244244
}
245245
);
@@ -270,12 +270,15 @@ function openSetGeometryModal(contentElement, cdata, settings, title, error) {
270270
});
271271
}
272272

273-
function setGeometryId(contentElement, cdata, settings, newGeometryId) {
273+
function setGeometryId(contentElement, cdata, settings, newGeometryId, drawn = false) {
274274
return new Promise((resolve, reject) => {
275275
loadWFSData(settings, [newGeometryId]).then((wfsData) => {
276276
if (wfsData.totalFeatures > 0) {
277277
if (!cdata.geometry_ids.includes(newGeometryId)) {
278278
cdata.geometry_ids = cdata.geometry_ids.concat([newGeometryId]);
279+
if (drawn && !cdata.newly_drawn_geometry_ids.includes(newGeometryId)) {
280+
cdata.newly_drawn_geometry_ids = cdata.newly_drawn_geometry_ids.concat([newGeometryId]);
281+
}
279282
}
280283
applyChanges(
281284
contentElement, cdata, settings, wfsData,
@@ -333,7 +336,6 @@ function renderMap(contentElement, cdata, settings, wfsData, allowSelection, onL
333336
CUI.dom.append(mapElement, createLegendButton(mapElement, settings.fieldConfiguration));
334337

335338
initializeMap(contentElement, mapElement, cdata, settings, wfsData, allowSelection, onLoad);
336-
337339
}
338340

339341
function createLegendButton(mapElement, fieldConfiguration) {

src/webfrontend/js/customDataType/main.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ CustomDataTypeNFISGeometry = (function(superClass) {
5050
}
5151

5252
if (!cdata.geometry_ids) cdata.geometry_ids = [];
53+
cdata.newly_drawn_geometry_ids = [];
5354

5455
return cdata;
5556
}
@@ -94,7 +95,8 @@ CustomDataTypeNFISGeometry = (function(superClass) {
9495
const cdata = data[this.name()];
9596
if (this.__isValidData(cdata)) {
9697
save_data[this.name()] = {
97-
geometry_ids: cdata.geometry_ids
98+
geometry_ids: cdata.geometry_ids,
99+
newly_drawn_geometry_ids: cdata.newly_drawn_geometry_ids
98100
};
99101
} else {
100102
save_data[this.name()] = null;

0 commit comments

Comments
 (0)