js数组添加数据_当iModel.js遇到CSV数据之一:RPC读取

编者注:

原英文版由Roop Saini发布在Medium.com上,本文由Bentley资深开发工程师 叶萌华(叶子)翻译而成,叶子老师现在主要负责中国iTwin相关平台、产品的开发支持工作,具有丰富的行业应用经验,特别是iTwin数字孪生在中国区落地的项目和产品上。后续,叶子老师将会与大家分享更多此过程中的经验。

ff377dff76a93da337347842f2a362e4.png

iModel.js是Bentley iTwin数字孪生解决方案提供的开源开发工具包,用户可以利用它,既可以在已有数字孪生产品上进行功能拓展,又可以全新开发自己的数据孪生服务应用。CSV是一种简单的结构化序列数据。在本例中,我们将介绍如何利用iModel.js将CSV数据与三维模型连接起来。这是建立智能基础设施最基础的使用,也是数据集成的常规应用,我们将分为三篇介绍,本文为第一篇。

  • 当iModel.js遇到CSV数据之一:RPC读取

  • 当iModel.js遇到CSV数据之二:定位三维模型

  • 当iModel.js遇到CSV数据之三:突出显示数据

以下为叶子老师的翻译。


上周我被拽到一堆邮件里,内容是从文件中读取数据并在iModel的视口中展示,我津津有味的看着,结果画风一变后来这帮人开始邮件@我,他们想让我准备个demo,以便可以给用户展示分享一些代码!

行吧,那就开始吧。我们现在有个excel文件,里面有两列,一列是控件的id,一列是控件的状态。

38505053adb40dbc6545728918095aa4.png

我个人啊,不是很喜欢去解析excel文件,对我来说CSV格式更简单点,老天保佑,excel可以导出为CSV格式。

1171ed831958ca27ba0e3aa3e5f60ff3.png

去掉列名,因为反正他们也不是数据,现在我们得到了csv文件,如下所示

14d2cc58a693271a3ed33bfa05895f9e.png

不错不错。接下来,我们要克隆一个iModeljs案例中的simple view App的代码,为了能让他顺利的跑起来我们需要用已知的iModel和project对其进行配置。因为它已经具有展示视口功能,我们只要可以继续扩展它,满足演示的需求就行了。我们的原始模型是这样的:

146fefc0c6b84fb2eeb2b6bde192839c.png

你肯定想知道这些控件ID是描述的什么玩意,其实是垫圈,管道上那些灰色球球就是。我们想通过文件列表去高亮这些垫圈,并显示它们的状态。

第一步我们得弄清楚的怎么把CSV文件读入这个应用程序。这实际上取决于文件放在那里。如果是在:

1. 前端(客户端):需要创建文件上传功能并读取。

2. 后端(服务器):直接读取文件,解析后将其发送到前端。

本例子中,文件存在于服务器上。我们需要获取文件的路径,读取它并将信息送到前端。底该怎么做呢?也许有一个方便iModel.js的API,后端只要调用他,打开文件,读取数据,解析,  返回数据,一气呵成?

你想的美啊,让我们看看到底怎么实现。

iModel.js允许您编写自定义RPC接口。这允许前端直接调用一个异步函数,该函数被转发到后端。

让我们用通过FileReaderRpcInterface来调用函数fetchInfo。我从文档中复制了接口定义的模板,最后得到了以下接口定义:

5d1e0719b186e0190734f6d9b2dfc9c9.png

我们将从前端调用fetchInfo来读取文件数据。现在让我们为这个接口创建一个相应的后端实现。让我们看看……需要做些什么来获得这些数据?

1. 阅读文件-我们可以使用fs库。

2. 解析数据-获取一个数组,数组里每个元素包含一个组件的id和状态。肯定能找到一个干这事的包。

Google了一圈,我找到了csvparse这个库,它可以将csv数据转换成数组,完美。

让我们获取服务器端RPC实现的模板,并编写fetchInfo函数来完成上述任务:

91b156b54034e423effe9992744e0087.png

最后一件事是注册我们的RPC。我们可以通过在后端初始化后注册RPC实现类,在后端完成这项工作。就是在iModelHost.startup() 函数之后调用。

4fae0e1e9c23bd37f0e29b7c3e8bfc88.png

在前端,我们只需将PRC接口其添加到rpc.ts文件(支持rpc接口列表)。

 fab90ca0954a258760fb724d405cd1dc.png

通过上述操作…终于准备好使用我们的自定义RPC!现在,我们应该从前端哪里去读文件呢?

我觉得在刚打开iModel之后这个时机就不错。现在,我们知道已经有一些数据需要处理。处理的位置是App.tsx下的_onIModelSelected 函数. 让我们在此添加接口调用,编译并运行:

 6de839502a358681b9b0af7e9a36fd4a.png

拿到了,CSV文件中的数据…

…通过后端API的调用,打开文件,读取数据,解析数据,并返回一个我们可以接着使用的的数组数据。这是我们下一篇文章中,需要介绍的内容,我们将讲解如何通过数组找到模型的三维坐标,以进行数据连接,好了,下次见,我要去吃点好吃的庆祝下,公司旁边新开的“肉夹馍”不错(编者注:叶子是西安人,她认为原作者同样会喜欢肉夹馍)

好了,下次见!欢迎订阅关注!

- END - 

?

感觉不错,请订阅,分享!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
System.InvalidOperationException: The LINQ expression 'DbSet<z_tjdj_yydj>() .Where(z => z.YYBH.Substring( startIndex: 0, length: z.YYBH.Length - 6) == __Substring_0) .Max(z => int.Parse(z.YYBH.Substring( startIndex: 10, length: 5)))' could not be translated. Additional information: Translation of method 'int.Parse' failed. If this method can be mapped to your custom function, see https://go.microsoft.com/fwlink/?linkid=2132413 for more information. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information. at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.<VisitMethodCall>g__CheckTranslated|15_0(ShapedQueryExpression translated, <>c__DisplayClass15_0& ) at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression) at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query) at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_0`1.<Execute>b__0() at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query) at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression) at System.Linq.Queryable.Max[TSource,TResult](IQueryable`1 source, Expression`1 selector) at VOL.TJYY.Services.z_tjdj_yydjService.<>c__DisplayClass10_0.<Import1>b__0(List`1 list) at VOL.Core.BaseProvider.ServiceBase`2.Import(List`1 files) in D:\work\TJYYHT_VOL\Net6版本\VOL.Core\BaseProvider\ServiceBase.cs:line 459 at VOL.TJYY.Services.z_tjdj_yydjService.Import(List`1 files) at VOL.TJYY.Services.z_tjdj_yydjService.Import1(List`1 fileInput, Dictionary`2 data) at VOL.TJYY.Controllers.z_tjdj_yydjController.Import1(List`1 fileInput, Dictionary`2 data) at lambda_method901(Closure , Object , Object[] ) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync() at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
06-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值