Skip to content

Commit b550115

Browse files
committed
Allow triggering update of geometry database when linked objects are edited via new configuration option "Linked objects"
1 parent 4f65820 commit b550115

3 files changed

Lines changed: 74 additions & 34 deletions

File tree

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ server.config.parameter.system.nfisGeoservices.wfs_configuration.geometry_fields
5959
server.config.parameter.system.nfisGeoservices.wfs_configuration.geometry_fields.fields.fylr_function.label,JavaScript-Funktion zum Auslesen des Wertes aus dem fylr-Objekt (Alternative zur Angabe des Feldnamens),JavaScript function for reading the value from the fylr object (Alternative to specifying the field name)
6060
server.config.parameter.system.nfisGeoservices.wfs_configuration.geometry_fields.wfs_pool_field.label,WFS-Zielfeld für die Poolbezeichnung,WFS target field for pool name
6161
server.config.parameter.system.nfisGeoservices.wfs_configuration.geometry_fields.pool_names.label,Poolbezeichnungen für Datenübertragung,Pool names for data transfer
62+
server.config.parameter.system.nfisGeoservices.linked_objects.label,Verknüpfte Objekte,Linked objects
63+
server.config.parameter.system.nfisGeoservices.linked_objects.object_type.label,Objekttyp,Object type
64+
server.config.parameter.system.nfisGeoservices.linked_objects.link_field_name.label,Name des Verknüpfungsfeldes,Link field name
6265
server.config.parameter.system.nfisGeoservices.masterportal_configurations.label,Masterportal-Konfigurationen,Masterportal configurations
6366
server.config.parameter.system.nfisGeoservices.masterportal_configurations.id.label,Identifier,Identifier
6467
server.config.parameter.system.nfisGeoservices.masterportal_configurations.name.label,Bezeichnung,Name

manifest.master.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,16 @@ base_config:
140140
position: 14
141141
position: 1
142142
position: 7
143+
linked_objects:
144+
type: table
145+
fields:
146+
- name: object_type
147+
type: text
148+
position: 0
149+
- name: link_field_name
150+
type: text
151+
position: 1
152+
position: 8
143153
masterportal_configurations:
144154
type: table
145155
fields:
@@ -152,7 +162,7 @@ base_config:
152162
- name: file_name
153163
type: text
154164
position: 2
155-
position: 8
165+
position: 9
156166

157167
callbacks:
158168
db_pre_save:

src/server/sendDataToGeoserver.js

Lines changed: 60 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ const info = process.argv.length >= 3
22
? JSON.parse(process.argv[2])
33
: {};
44

5+
const objectCache = {};
6+
57
let input = '';
68
process.stdin.on('data', d => {
79
try {
@@ -14,17 +16,11 @@ process.stdin.on('data', d => {
1416

1517
process.stdin.on('end', async () => {
1618
const data = JSON.parse(input);
17-
const configuration = getPluginConfiguration();
18-
const authorizationString = getAuthorizationString(configuration);
1919

2020
for (let object of data.objects) {
2121
await updateObject(
22-
object[object._objecttype],
23-
object._objecttype,
24-
object._uuid,
25-
await getCurrentObjectData(object[object._objecttype]._id, object._objecttype),
26-
configuration,
27-
authorizationString
22+
getObjectData(object),
23+
await getCurrentObjectData(object[object._objecttype]._id, object._objecttype)
2824
);
2925
}
3026

@@ -34,6 +30,13 @@ process.stdin.on('end', async () => {
3430
return;
3531
});
3632

33+
function getObjectData(object) {
34+
const objectData = object[object._objecttype];
35+
objectData._uuid = object._uuid;
36+
objectData._objecttype = object._objecttype;
37+
return objectData;
38+
}
39+
3740
function getPluginConfiguration() {
3841
return info.config.plugin['custom-data-type-nfis-geometry'].config.nfisGeoservices;
3942
}
@@ -90,13 +93,22 @@ async function getPreferredMask(objectType) {
9093
}
9194
}
9295

93-
async function updateObject(object, objectType, uuid, currentObject, configuration, authorizationString) {
94-
const wfsConfiguration = getWFSConfiguration(configuration, objectType);
96+
async function updateObject(object, currentObject) {
97+
const configuration = getPluginConfiguration();
98+
const authorizationString = getAuthorizationString(configuration);
99+
100+
addDataFromCurrentObject(object, currentObject);
101+
addToObjectCache(object);
102+
103+
const linkedObjectConfiguration = getLinkedObjectConfiguration(object._objecttype, configuration);
104+
if (linkedObjectConfiguration) return await updateLinkedObjects(object, linkedObjectConfiguration);
105+
106+
const wfsConfiguration = getWFSConfiguration(configuration, object._objecttype);
95107
if (!wfsConfiguration) return;
96108

97109
for (let fieldConfiguration of wfsConfiguration.geometry_fields) {
98110
const geometryIds = await getGeometryIds(object, fieldConfiguration.field_path.split('.'));
99-
if (geometryIds.length && await hasUsedGeometryIds(configuration, geometryIds, uuid)) {
111+
if (geometryIds.length && await hasUsedGeometryIds(configuration, geometryIds, object._uuid)) {
100112
return throwErrorToFrontend('Eine oder mehrere Geometrien sind bereits mit anderen Objekten verknüpft.', undefined, 'multipleGeometryLinking');
101113
}
102114

@@ -105,6 +117,18 @@ async function updateObject(object, objectType, uuid, currentObject, configurati
105117
}
106118
}
107119

120+
function getLinkedObjectConfiguration(objectType, configuration) {
121+
return configuration.linked_objects.find(entry => entry.object_type === objectType);
122+
}
123+
124+
async function updateLinkedObjects(object, linkedObjectConfiguration) {
125+
const linkedObjects = await getFieldValues(object, linkedObjectConfiguration.link_field_name.split('.'));
126+
127+
for (let linkedObject of linkedObjects) {
128+
await updateObject(linkedObject, linkedObject);
129+
}
130+
}
131+
108132
async function getGeometryIds(object, pathSegments) {
109133
let geometryIds = [];
110134

@@ -163,7 +187,6 @@ function getGeometryFieldPaths(configuration) {
163187

164188
async function editGeometries(object, currentObject, fieldConfiguration, geometryIds, authorizationString) {
165189
if (isSendingDataToGeoserverActivated(fieldConfiguration, geometryIds)) {
166-
addDataFromCurrentObject(object, currentObject);
167190
const changeMap = await getChangeMap(object, fieldConfiguration);
168191
if (Object.keys(changeMap).length) {
169192
await performEditTransaction(geometryIds, changeMap, fieldConfiguration, authorizationString);
@@ -207,10 +230,8 @@ function hasLinkedObjectData(fieldContent) {
207230
return Object.values(fieldContent).find(subfield => subfield._mask && subfield._objecttype);
208231
}
209232

210-
211233
async function getChangeMap(object, fieldConfiguration) {
212234
const changeMap = {};
213-
const linkedObjects = {};
214235
addPoolFieldToChangeMap(object, fieldConfiguration, changeMap);
215236

216237
if (!fieldConfiguration.fields) return changeMap;
@@ -221,7 +242,7 @@ async function getChangeMap(object, fieldConfiguration) {
221242
const fylrFunction = field.fylr_function;
222243
if (fylrFieldName || fylrFunction) {
223244
const fieldValue = fylrFieldName
224-
? (await getFieldValues(object, fylrFieldName.split('.'), linkedObjects))?.[0]
245+
? (await getFieldValues(object, fylrFieldName.split('.')))?.[0]
225246
: getValueFromCustomFunction(object, fylrFunction);
226247
addToChangeMap(wfsFieldName, fieldValue, changeMap);
227248
}
@@ -230,13 +251,17 @@ async function getChangeMap(object, fieldConfiguration) {
230251
return changeMap;
231252
}
232253

233-
async function getFieldValues(object, pathSegments, linkedObjects = {}) {
254+
async function getFieldValues(object, pathSegments) {
234255
const fieldName = pathSegments.shift();
235256
let field = object[fieldName];
236257

237-
if (field === undefined) {
238-
return [];
239-
} else if (pathSegments.length === 0) {
258+
if (field === undefined) return [];
259+
260+
if (!Array.isArray(field) && field._objecttype && field._mask && field[field._objecttype]?._id !== undefined) {
261+
field = await getLinkedObject(field);
262+
}
263+
264+
if (pathSegments.length === 0) {
240265
return [field];
241266
} else if (Array.isArray(field)) {
242267
let fieldValues = [];
@@ -246,33 +271,33 @@ async function getFieldValues(object, pathSegments, linkedObjects = {}) {
246271
return fieldValues.filter(data => data !== undefined)
247272
.reduce((result, fieldValues) => result.concat(fieldValues), []);
248273
} else {
249-
if (field._objecttype && field._mask && field[field._objecttype]?._id) {
250-
field = await getLinkedObject(field, linkedObjects);
251-
}
252274
return await getFieldValues(field, pathSegments);
253275
}
254276
}
255277

256-
async function getLinkedObject(field, linkedObjects) {
257-
const cachedObject = linkedObjects[field._objecttype]?.[field._id];
278+
async function getLinkedObject(field) {
279+
const objectType = field._objecttype;
280+
const id = field[objectType]._id;
281+
282+
const cachedObject = objectCache[objectType]?.[id];
258283
if (cachedObject) return cachedObject;
259284

260-
const linkedObject = (await fetchObject(field._objecttype, field._mask, field[field._objecttype]._id))?.[field._objecttype];
285+
const linkedObject = await fetchObject(field._objecttype, field._mask, id);
261286
if (!linkedObject) {
262-
throwErrorToFrontend('Das Objekt ' + field[field._objecttype]._id + ' vom Typ ' + field._objecttype + ' konnte nicht abgerufen werden.');
287+
throwErrorToFrontend('Das Objekt ' + id + ' vom Typ ' + objectType + ' konnte nicht abgerufen werden.');
263288
}
264289

265-
addToLinkedObjectsCache(linkedObject, linkedObjects);
290+
addToObjectCache(linkedObject);
266291

267292
return linkedObject;
268293
}
269294

270-
function addToLinkedObjectsCache(linkedObject, linkedObjects) {
271-
const objectType = linkedObject._objecttype;
272-
const id = linkedObject._id;
295+
function addToObjectCache(object) {
296+
const objectType = object._objecttype;
297+
const id = object._id;
273298

274-
if (!linkedObjects[objectType]) linkedObject[objectType] = {};
275-
linkedObject[objectType][id] = linkedObject;
299+
if (!objectCache[objectType]) objectCache[objectType] = {};
300+
objectCache[objectType][id] = object;
276301
}
277302

278303
async function fetchObject(objectType, mask, id) {
@@ -281,7 +306,9 @@ async function fetchObject(objectType, mask, id) {
281306
try {
282307
const response = await fetch(url, { method: 'GET' });
283308
const result = await response.json();
284-
return result?.length ? result[0] : undefined;
309+
return result?.length
310+
? getObjectData(result[0])
311+
: undefined;
285312
} catch (err) {
286313
throwErrorToFrontend('Objektabfrage fehlgeschlagen.', JSON.stringify(err));
287314
}

0 commit comments

Comments
 (0)