UNPKG

@geogirafe/lib-geoportal

Version:

GeoGirafe is a flexible application to build online geoportals.

122 lines (121 loc) 4.97 kB
import { removeUnwantedOlParams } from './utils/olutils.js'; import WfsManager from './wfs/wfsmanager.js'; /** * A feature-to-grid data converter, to show feature's properties in grid-like system. */ export default class FeatureToGridDataById { context; options; constructor(context, options) { this.context = context; this.options = { ...{ keepGeomProperty: false, removeEmptyColumns: true }, ...options }; } /** * Takes an array of OpenLayers features and converts them into a grid data object, where each feature * is mapped by its ID as the key. * @returns The grid data objects, by id. */ toGridDataById(features) { const gridDataById = features.reduce((gridDataById, feature) => this.addFeatureToGridDataById(gridDataById, feature), {}); if (this.options.removeEmptyColumns) { Object.values(gridDataById).forEach((gridData) => FeatureToGridDataById.removeEmptyColumns(gridData)); } return gridDataById; } /** * @returns a gridDataByID for a single converted OL feature. * @private */ addFeatureToGridDataById(gridDataById, feature) { const featureType = FeatureToGridDataById.getUserFeatureType(feature); let notOlProperties = removeUnwantedOlParams(feature, this.options.keepGeomProperty); if (!Object.keys(notOlProperties).length) { // Don't keep feature without properties. return gridDataById; } // Apply default prefix to links and images if necessary notOlProperties = Object.fromEntries(Object.entries(notOlProperties).map(([key, value]) => [key, this.ensureAbsolutePath(value)])); if (!Object.keys(gridDataById).includes(featureType)) { gridDataById[featureType] = FeatureToGridDataById.createGridDataWithColumns(notOlProperties); } const gridData = gridDataById[featureType]; // Add feature and not OL properties backref gridData.features.push(feature); gridData.notOlProperties.push(notOlProperties); // Add cell content. const data = gridData.columns.map((column) => notOlProperties[column]); gridData.data.push(data); return gridDataById; } ensureAbsolutePath(attributeContent) { if (this.context.configManager.Config.general.defaultUrlPrefix && this.isLikelyHtml(attributeContent)) { const regex = /(href|src)="\/([^"]*)"/g; return attributeContent.replaceAll(regex, (_match, attr, path) => { return `${attr}="${this.context.configManager.Config.general.defaultUrlPrefix}/${path}"`; }); } // Not an HTML string return attributeContent; } isLikelyHtml(str) { return /<[a-z][\s\S]*>/i.test(str); } /** * @returns {GridData} A new empty grid data object with columns from given properties. * @static */ static createGridDataWithColumns(properties) { return { columns: Object.keys(properties), notOlProperties: [], data: [], features: [] }; } /** * Removes empty columns (columns and data) from a given gridData object. * It's expected that all features in the gridData have the same properties. * @static */ static removeEmptyColumns(gridData) { const emptyColumnIndexes = FeatureToGridDataById.findEmptyColumnIndexOf(gridData.data); gridData.columns = gridData.columns.filter((_column, index) => !emptyColumnIndexes.includes(index)); gridData.data.forEach((_, index) => { gridData.data[index] = gridData.data[index].filter((_val, index) => !emptyColumnIndexes.includes(index)); }); } /** * This method finds the indexes of empty columns in a given 2D array. * @param data - The 2D array to search for empty columns. * @returns An array of indexes representing the empty columns. * @static */ static findEmptyColumnIndexOf(data) { if (!data[0]) { return []; } const emptyColumnIndexes = Array.from({ length: data[0].length }, (_, index) => index); data.forEach((column) => { const notEmptyColumnIndexes = []; emptyColumnIndexes.forEach((emptyIndex) => { if (column[emptyIndex]) { notEmptyColumnIndexes.push(emptyIndex); } }); notEmptyColumnIndexes.forEach((indexToRemove) => { const idx = emptyColumnIndexes.findIndex((emptyColumnIndex) => emptyColumnIndex === indexToRemove); emptyColumnIndexes.splice(idx, 1); }); }); return emptyColumnIndexes; } static getUserFeatureType(feature) { return WfsManager.extractFeatureTypeFromId(feature); } }