UNPKG

@ngageoint/mage.arcgis.service

Version:

A mage service plugin that synchronizes mage observations to a configured ArcGIS feature layer.

492 lines 20.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ObservationsTransformer = void 0; const entities_events_forms_1 = require("@ngageoint/mage.service/lib/entities/events/entities.events.forms"); /** * Class that transforms observations into a json string that can then be sent to an arcgis server. */ class ObservationsTransformer { /** * Constructor. * @param {ArcGISPluginConfig} config The plugins configuration. * @param {Console} console Used to log to the console. */ constructor(config, console) { /** * Initialized flag */ this._initialized = false; /** * Default values */ this._defaults = {}; /** * Omit attributes */ this._omit = []; this._config = config; this._console = console; } /** * Initialize configuration settings */ init() { if (!this._initialized) { this._initialized = true; if (this._config.attributes != null) { for (const attributes of Object.entries(this._config.attributes)) { const attribute = attributes[0]; const attributeConfig = attributes[1]; const defaults = attributeConfig.defaults; if (defaults != null && defaults.length > 0) { this._defaults[attribute] = defaults; } if (attributeConfig.omit) { this._omit.push(attribute); } } } } } /** * Converts the specified observation into an ArcObservation that can be sent to an arcgis server. * @param {ObservationAttrs} observation The observation to convert. * @param {EventTransform} transform The Event transform. * @param {User | null} user The MAGE user. * @returns {ArcObservation} The ArcObservation of the observation. */ transform(observation, transform, user) { this.init(); const arcObject = {}; this.observationToAttributes(observation, transform, user, arcObject); if (observation.geometry != null) { const geometry = observation.geometry; const arcGeometry = this.geometryToArcGeometry(geometry); this._console.info('ArcGIS new ' + geometry.type + ' at ' + JSON.stringify(arcGeometry) + ' with id ' + observation.id); arcObject.geometry = arcGeometry; } let formIds = {}; if (observation.properties != null) { formIds = this.propertiesToAttributes(observation.properties, transform, arcObject); } const arcObservation = this.createObservation(observation); if (this._config.geometryType != null) { this.addAttribute(this._config.geometryType, arcObservation.esriGeometryType, arcObject); } this.addDefaults(arcObject); arcObservation.createdAt = new Date(observation.createdAt).getTime(); arcObservation.lastModified = new Date(observation.lastModified).getTime(); arcObservation.object = arcObject; arcObservation.attachments = this.attachments(observation.attachments, formIds, transform); this.removeOmissions(arcObject); return arcObservation; } /** * Creates a base ArcObservation with id and geometry type. * @param {ObservationAttrs} observation The observation to convert. * @returns {ArcObservation} The ArcObservation of the observation. */ createObservation(observation) { const arcObservation = {}; arcObservation.id = observation.id; arcObservation.esriGeometryType = this.esriGeometryType(observation); return arcObservation; } /** * Converts a mage geometry type to an esri geometry type. * @param {string} mageGeometryType The mage geometry type. * @returns {string} The esri geometry type. */ mageTypeToEsriType(mageGeometryType) { switch (mageGeometryType) { case 'Point': return 'esriGeometryPoint'; case 'LineString': return 'esriGeometryPolyline'; case 'Polygon': return 'esriGeometryPolygon'; default: return ''; } } /** * Determine the observation Esri geometry type. * @param {ObservationAttrs} observation The observation. * @returns {string} The Esri geometry type. */ esriGeometryType(observation) { let esriGeometryType = ''; if (observation.geometry != null) { esriGeometryType = this.mageTypeToEsriType(observation.geometry.type); } return esriGeometryType; } /** * Converts and adds observation values to ArcObject attributes. * @param {ObservationAttrs} observation The observation to convert. * @param {EventTransform} transform The Event transform. * @param {User | null} user The MAGE user. * @param {ArcObject} arcObject The converted ArcObject. */ observationToAttributes(observation, transform, user, arcObject) { let observationIdValue = observation.id; if (this._config.eventIdField == null) { observationIdValue += this._config.idSeparator + observation.eventId; } else { this.addAttribute(this._config.eventIdField, observation.eventId, arcObject); } this.addAttribute(this._config.observationIdField, observationIdValue, arcObject); const mageEvent = transform.mageEvent; if (this._config.eventNameField != null && mageEvent != null) { this.addAttribute(this._config.eventNameField, mageEvent.name, arcObject); } if (this._config.userIdField != null && observation.userId != null) { this.addAttribute(this._config.userIdField, observation.userId, arcObject); } if (user != null) { if (this._config.usernameField != null) { this.addAttribute(this._config.usernameField, user.username, arcObject); } if (this._config.userDisplayNameField != null) { this.addAttribute(this._config.userDisplayNameField, user.displayName, arcObject); } } if (this._config.deviceIdField != null && observation.deviceId != null) { this.addAttribute(this._config.deviceIdField, observation.deviceId, arcObject); } if (this._config.createdAtField != null) { this.addAttribute(this._config.createdAtField, observation.createdAt, arcObject); } if (this._config.lastModifiedField != null) { this.addAttribute(this._config.lastModifiedField, observation.lastModified, arcObject); } } /** * Converts an observation geometry to an ArcGeometry. * @param {Geometry} geometry The observation geometry to convert. * @returns {ArcGeometry} The converted ArcGeometry. */ geometryToArcGeometry(geometry) { let arcGeometry = {}; switch (geometry.type) { case 'Point': arcGeometry = this.pointToArcPoint(geometry); break; case 'LineString': arcGeometry = this.lineStringToArcPolyline(geometry); break; case 'Polygon': arcGeometry = this.polygonToArcPolygon(geometry); break; default: break; } arcGeometry.spatialReference = { wkid: 4326 }; return arcGeometry; } /** * Converts an observation Point to an ArcPoint. * @param {Point} point The observation Point to convert. * @returns {ArcPoint} The converted ArcPoint. */ pointToArcPoint(point) { const arcPoint = {}; arcPoint.x = point.coordinates[0]; arcPoint.y = point.coordinates[1]; return arcPoint; } /** * Converts an observation LineString to an ArcPolyline. * @param {LineString} lineString The observation LineString to convert. * @returns {ArcPolyline} The converted ArcPolyline. */ lineStringToArcPolyline(lineString) { const arcPolyline = {}; arcPolyline.paths = [lineString.coordinates]; return arcPolyline; } /** * Converts an observation Polygon to an ArcPolygon. * @param {Polygon} polygon The observation Polygon to convert. * @returns {ArcPolygon} The converted ArcPolygon. */ polygonToArcPolygon(polygon) { const arcPolygon = {}; arcPolygon.rings = polygon.coordinates; return arcPolygon; } /** * Converts and adds observation properties to ArcObject attributes. * @param {{ [name: string]: unknown }} properties The observation properties to convert. * @param {EventTransform} transform The Event transform. * @param {ArcObject} arcObject The converted ArcObject. * @returns {{ [name: string]: number }} form ids map */ propertiesToAttributes(properties, transform, arcObject) { let formIds = {}; for (const property in properties) { const value = properties[property]; if (property === 'forms') { formIds = this.formsToAttributes(value, transform, arcObject); } else { this.addAttribute(property, value, arcObject); } } return formIds; } /** * Converts and adds observation property forms data to ArcObject attributes. * @param {[{ [name: string]: unknown }]} forms The observation property forms to convert. * @param {EventTransform} transform The Event transform. * @param {ArcObject} arcObject The converted ArcObject. * @returns {{ [name: string]: number }} form ids map */ formsToAttributes(forms, transform, arcObject) { const formIds = {}; const formIdCount = {}; const mageEvent = transform.mageEvent; for (let i = 0; i < forms.length; i++) { const form = forms[i]; const formId = form['formId']; const id = form['id']; let fields = null; let formCount = 1; if (formId != null && id != null) { formIds[id] = formId; let count = formIdCount[formId]; if (count == null) { count = 0; } formCount = count + 1; formIdCount[formId] = formCount; fields = transform.get(formId); } for (const formProperty in form) { let value = form[formProperty]; if (value != null) { if (mageEvent != null && formId != null) { const field = mageEvent.formFieldFor(formProperty, formId); if (field != null && field.type !== entities_events_forms_1.FormFieldType.Attachment) { let title = field.title; if (fields != null) { const fieldTitle = fields.get(title); if (fieldTitle != null) { const sanitizedName = ObservationsTransformer.replaceSpaces(fieldTitle); const sanitizedFormName = ObservationsTransformer.replaceSpaces(fields.name); title = `${sanitizedFormName}_${sanitizedName}`.toLowerCase(); } } if (field.type === entities_events_forms_1.FormFieldType.Geometry) { value = this.geometryToArcGeometry(value); } this.addFormAttribute(title, formCount, value, arcObject); } } else { this.addFormAttribute(formProperty, formCount, value, arcObject); } } } } return formIds; } /** * Add an ArcObject attribute for a form field. * @param {string} name The attribute name. * @param {number} count The form count. * @param {unknown} value The attribute value. * @param {ArcObject} arcObject The converted ArcObject. */ addFormAttribute(name, count, value, arcObject) { var _a; if (count > 1 && this._config.attributes != null) { const concat = (_a = this._config.attributes[name]) === null || _a === void 0 ? void 0 : _a.concatenation; if (concat != null && (concat.sameForms == null || concat.sameForms)) { count = 1; } } const attribute = this.appendCount(name, count); this.addAttribute(attribute, value, arcObject); } /** * Add an ArcObject attribute. * @param {string} name The attribute name. * @param {unknown} value The attribute value. * @param {ArcObject} arcObject The converted ArcObject. */ addAttribute(name, value, arcObject) { if (value != null) { if (arcObject.attributes == null) { arcObject.attributes = {}; } let attribute = ObservationsTransformer.replaceSpaces(name); if (Object.prototype.toString.call(value) === '[object Date]') { value = new Date(value).getTime(); } let config = null; if (this._config.attributes != null) { config = this._config.attributes[name]; } if ((config === null || config === void 0 ? void 0 : config.mappings) != null) { const fieldValue = config.mappings[value]; if (fieldValue != null) { value = fieldValue; } } const existingValue = arcObject.attributes[attribute]; if (existingValue !== undefined) { const concat = config === null || config === void 0 ? void 0 : config.concatenation; if (concat != null && (concat.differentForms == null || concat.differentForms)) { let delimiter = concat.delimiter; if (delimiter == null) { delimiter = ', '; } value = existingValue + delimiter + value; } else { let baseKey = attribute; let count = 1; const countIndex = attribute.lastIndexOf('_'); if (countIndex !== -1) { const countString = attribute.substring(countIndex + 1); if (countString != null && countString !== '') { const countNumber = Number(countString); if (!isNaN(countNumber)) { baseKey = attribute.substring(0, countIndex); count = countNumber; } } } do { count += 1; attribute = this.appendCount(baseKey, count); } while (arcObject.attributes[attribute] !== undefined); } } arcObject.attributes[attribute] = value; } } /** * Add ArcObject attribute defaults. * @param {ArcObject} arcObject The converted ArcObject. */ addDefaults(arcObject) { for (const attributeDefaults of Object.entries(this._defaults)) { const attribute = attributeDefaults[0]; if (arcObject.attributes[attribute] == null) { const defaults = attributeDefaults[1]; for (const attributeDefault of defaults) { let setDefault = true; const condition = attributeDefault.condition; if (condition != null && condition.length > 0) { for (const valueConfig of condition) { const value = arcObject.attributes[valueConfig.attribute]; const values = valueConfig.values; if (values.length === 0) { setDefault = value == null; } else { setDefault = values.includes(value); } if (!setDefault) { break; } } } if (setDefault) { arcObject.attributes[attribute] = attributeDefault.value; break; } } } } } /** * Transform observation attachments. * @param {readonly Attachment[]} attachments The observation attachments. * @param {{ [name: string]: number }} formIds Form ids map. * @param {EventTransform} transform The Event transform. * @returns {ArcAttachment[]} The converted ArcAttachments. */ attachments(attachments, formIds, transform) { const arcAttachments = []; const mageEvent = transform.mageEvent; for (const attachment of attachments) { if (attachment.contentLocator != null) { let fieldName = attachment.fieldName; if (mageEvent != null) { const formId = formIds[attachment.observationFormId]; if (formId != null) { const field = mageEvent.formFieldFor(fieldName, formId); if (field != null) { fieldName = field.title; } } } const arcAttachment = {}; arcAttachment.field = ObservationsTransformer.replaceSpaces(fieldName); if (attachment.lastModified != null) { arcAttachment.lastModified = new Date(attachment.lastModified).getTime(); } if (attachment.size != null) { arcAttachment.size = attachment.size; } if (attachment.name != null) { const extensionIndex = attachment.name.lastIndexOf('.'); if (extensionIndex !== -1) { arcAttachment.name = attachment.name.substring(0, extensionIndex); } else { arcAttachment.name = attachment.name; } } else { arcAttachment.name = attachment.id; } arcAttachment.contentLocator = attachment.contentLocator; arcAttachments.push(arcAttachment); } } return arcAttachments; } /** * Replace spaces in the name with underscores. * @param {string} name The name. * @returns {string} name with replaced spaces. */ static replaceSpaces(name) { return name.replace(/ /g, '_'); } /** * Append a count to a name for additional duplicate field names. * @param {string} name The name. * @param {number} count The count. * @returns {string} name with count. */ appendCount(name, count) { let value = name; if (count > 1) { value += '_' + count; } return value; } /** * Remove ArcObject attribute omissions. * @param {ArcObject} arcObject The converted ArcObject. */ removeOmissions(arcObject) { const attributes = arcObject.attributes; const attributeKeys = Object.keys(attributes); for (const omit of this._omit) { const regex = new RegExp('^' + omit + '(_\\d+)?$'); const regexAttributes = attributeKeys.filter((name) => regex.test(name)); for (const attribute of regexAttributes) { delete attributes[attribute]; } } } } exports.ObservationsTransformer = ObservationsTransformer; //# sourceMappingURL=ObservationsTransformer.js.map