@geogirafe/lib-geoportal
Version:
GeoGirafe is a flexible application to build online geoportals.
126 lines (125 loc) • 4.7 kB
JavaScript
import { removeUnwantedOlParams } from './utils/olutils';
/**
* A feature-to-grid data converter, to show feature's properties in grid-like system.
*/
export default class FeatureToGridDataById {
constructor(options) {
Object.defineProperty(this, "options", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
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);
const notOlProperties = removeUnwantedOlParams(feature, this.options.keepGeomProperty);
if (!Object.keys(notOlProperties).length) {
// Don't keep feature without properties.
return gridDataById;
}
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;
}
/**
* @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;
}
/**
* @return The ID of the feature or 'UNKNOWN' if undefined.
* @static
*/
static getUserFeatureId(feature) {
const id = feature.getId();
return id === undefined ? 'UNKNOWN' : `${id}`;
}
static getUserFeatureType(feature) {
const id = feature.getId();
if (!id) {
return 'UNKNOWN';
}
const splitId = `${id}`.split('.');
if (splitId.length <= 1) {
return `${id}`;
}
splitId.pop();
return splitId.join('.');
}
}