@loaders.gl/i3s
Version:
i3s .
109 lines • 4.62 kB
JavaScript
import { load } from '@loaders.gl/core';
import { getAttributeValueType, I3SAttributeLoader } from "../../i3s-attribute-loader.js";
import { getUrlWithToken } from "./url-utils.js";
/**
* Calculate new vertex colors array to visualize 3D objects in a attribute driven way
* @param colors - vertex colors attribute
* @param featureIds - feature Ids attribute
* @param attributeUrls - array of attribute's urls
* @param fields - array of attribute's fileds
* @param attributeStorageInfo - array of attributeStorageInfo
* @param colorsByAttribute - attribute color options
* @param token - access token
* @returns new colors attribute
*/
// eslint-disable-next-line max-params
export async function customizeColors(colors, featureIds, attributeUrls, fields, attributeStorageInfo, colorsByAttribute, token) {
if (!colorsByAttribute) {
return colors;
}
const resultColors = {
...colors,
value: new Uint8Array(colors.value)
};
const colorizeAttributeField = fields.find(({ name }) => name === colorsByAttribute?.attributeName);
if (!colorizeAttributeField ||
!['esriFieldTypeDouble', 'esriFieldTypeInteger', 'esriFieldTypeSmallInteger'].includes(colorizeAttributeField.type)) {
return colors;
}
const colorizeAttributeData = await loadFeatureAttributeData(colorizeAttributeField.name, attributeUrls, attributeStorageInfo, token);
if (!colorizeAttributeData) {
return colors;
}
const objectIdField = fields.find(({ type }) => type === 'esriFieldTypeOID');
if (!objectIdField) {
return colors;
}
const objectIdAttributeData = await loadFeatureAttributeData(objectIdField.name, attributeUrls, attributeStorageInfo, token);
if (!objectIdAttributeData) {
return colors;
}
const attributeValuesMap = {};
// @ts-expect-error
for (let i = 0; i < objectIdAttributeData[objectIdField.name].length; i++) {
// @ts-expect-error
attributeValuesMap[objectIdAttributeData[objectIdField.name][i]] = calculateColorForAttribute(
// @ts-expect-error
colorizeAttributeData[colorizeAttributeField.name][i], colorsByAttribute);
}
for (let i = 0; i < featureIds.length; i++) {
const color = attributeValuesMap[featureIds[i]];
if (!color) {
continue; // eslint-disable-line no-continue
}
/* eslint max-statements: ["error", 30] */
/* eslint complexity: ["error", 12] */
if (colorsByAttribute.mode === 'multiply') {
// multiplying original mesh and calculated for attribute rgba colors in range 0-255
color.forEach((colorItem, index) => {
resultColors.value[i * 4 + index] = (resultColors.value[i * 4 + index] * colorItem) / 255;
});
}
else {
resultColors.value.set(color, i * 4);
}
}
return resultColors;
}
/**
* Calculate rgba color from the attribute value
* @param attributeValue - value of the attribute
* @param colorsByAttribute - attribute color options
* @returns - color array for a specific attribute value
*/
function calculateColorForAttribute(attributeValue, colorsByAttribute) {
if (!colorsByAttribute) {
return [255, 255, 255, 255];
}
const { minValue, maxValue, minColor, maxColor } = colorsByAttribute;
const rate = (attributeValue - minValue) / (maxValue - minValue);
const color = [255, 255, 255, 255];
for (let i = 0; i < minColor.length; i++) {
color[i] = Math.round((maxColor[i] - minColor[i]) * rate + minColor[i]);
}
return color;
}
/**
* Load feature attribute data from the ArcGIS rest service
* @param attributeName - attribute name
* @param attributeUrls - array of attribute's urls
* @param attributeStorageInfo - array of attributeStorageInfo
* @param token - access token
* @returns - Array-like list of the attribute values
*/
async function loadFeatureAttributeData(attributeName, attributeUrls, attributeStorageInfo, token) {
const attributeIndex = attributeStorageInfo.findIndex(({ name }) => attributeName === name);
if (attributeIndex === -1) {
return null;
}
const objectIdAttributeUrl = getUrlWithToken(attributeUrls[attributeIndex], token);
const attributeType = getAttributeValueType(attributeStorageInfo[attributeIndex]);
const objectIdAttributeData = await load(objectIdAttributeUrl, I3SAttributeLoader, {
i3s: {
attributeName,
attributeType
}
});
return objectIdAttributeData;
}
//# sourceMappingURL=customize-colors.js.map