无法读取元素属性

后端开发 2026-07-12

我正在学习Autodesk Tandem REST教程 https://github.com/autodesk-tandem/tutorial-rest/blob/master/elements/list-element-source-properties.js,并使用 list-element-source-properties.js 示例从我的设施模型查询元素属性。

我正在尝试像这样检索一个属性定义:

const propDef = schema.attributes.find(
  p => p.fam === ColumnFamilies.Source &&
       p.category === 'Identity Data' &&
       p.name === 'Type Name'
);

然而,我没有得到任何结果。

经过更深入的调查,我发现我的模型架构中,category 的值包含非英文(本地化)的字符。当我传入本地化的类别字符串而不是 "Identity Data" 时,才会起作用。

我希望以一种通用的方式同时支持英文和非英文的模型。

我的问题如下:

  1. 在查询属性时,处理本地化的模式类别名称的推荐做法是什么?
  2. 是否有一个语言无关的标识符,应该用来替代 category
  3. 一个模型模式可以同时包含英文和本地化的类别名称吗,还是始终以单一的本地化形式存储?

感谢您提供任何指导或最佳实践,以在不同语言模型中实现更强的鲁棒性。谢谢!

解决方案

源属性来自源模型(即Revit),并由Model Derivative服务提取——Tandem在用属性细节填充模式时使用该服务的数据。遗憾的是,目前似乎没有同时获取全局名称和本地化名称的方法。

另外补充一句,我在你的示例中看到你在提到Identity Data.Type Name。这与Revit的元素类型概念有关。请注意,Tandem也在遵循这一概念。要想了解类型信息,可以从元素读取QC.FamilyType参数来获取相关类型。

/*
    This example demonstrates how to get assets from facility and print their type properties.

    It uses 2-legged authentication - this requires that application is added to facility as service.
*/
import { createToken } from '../common/auth.js';
import { TandemClient } from '../common/tandemClient.js';
import { QC } from '../common/constants.js';

// update values below according to your environment
const APS_CLIENT_ID = 'YOUR_CLIENT_ID';
const APS_CLIENT_SECRET = 'YOUR_CLIENT_SECRET';
const FACILITY_URN = 'YOUR_FACILITY_URN';

async function main() {
    // STEP 1 - obtain token to authenticate subsequent API calls
    const token = await createToken(APS_CLIENT_ID,
        APS_CLIENT_SECRET, 'data:read');
    const client = new TandemClient(() => {
        return token;
    });

    // STEP 2 - get facility
    const facilityId = FACILITY_URN;
    const facility = await client.getFacility(facilityId);

    // STEP 3 - iterate through facility models and collect tagged assets
    for (const link of facility.links) {
        const assets = await client.getTaggedAssets(link.modelId);
        const assetTypes = new Set();
        const assetTypeMap = {};

        // STEP 4 - iterate through assets and collect asset types
        for (const asset of assets) {
            const familyType = asset[QC.FamilyType];

            if (!familyType) {
                continue;
            }
            assetTypes.add(familyType);
            assetTypeMap[asset[QC.Key]] = familyType;
        }
        if (assetTypes.size === 0) {
            continue;
        }
        // STEP 5 - get type properties
        const familyTypes = await client.getElements(link.modelId, [... assetTypes]);

        for (const asset of assets) {
            const assetTypeKey = assetTypeMap[asset[QC.Key]];

            if (!assetTypeKey) {
                continue;
            }
            // STEP 6 - print out asset name & asset type name
            // first check for name override, if empty then use default name
            const name = asset[QC.OName] ?? asset[QC.Name];
            const familyType = familyTypes.find(i => i[QC.Key] === assetTypeKey);

            console.log(`${name}: ${familyType?.[QC.Name]}`);
        }
    }   
}

main()
    .then(() => {
        console.log('success');
        process.exit(0);
    })
    .catch((err) => {
        console.error('failure', err);
        process.exit(1);
    });

来源

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章