实习项目梳理(研究生篇)

项目梳理(重点)

1.基于C#和Vue开发的达同数字孪生三维数据辅助设计系统的管线展示和分析模块

功能一 :用户设定的爆管点(startx,starty),查找离爆管点最近的线和沿着管网向上游查找所有受影响阀门的功能

步骤:

1.通过执行SQL查询语句,找到离起点最近的线。这里使用了ST_DWithin和ST_Distance函数来计算距离和排序。

ST_DWithin:检测一个对象是否在另一个对象的缓冲区范围内,不生成缓冲区对象 ST_Distance:查询两点间的距离

sql 复制代码
--查询离起点最近的线
    --3857坐标系
    --找起点15米范围内的最近线
    execute 'select geom, source, target, ST_StartPoint(geom) as startpoint,ST_EndPoint(geom) as endpoint from ' ||tbl||
                            ' where ST_DWithin(geom,ST_Geometryfromtext(''point('|| startx ||' ' || starty ||')'',3857),15)
                            order by ST_Distance(geom,ST_GeometryFromText(''point('|| startx ||' '|| starty ||')'',3857))  limit 1'
                            into v_startLine, v_startSource ,v_startTarget, v_statpoint ,v_endpoint;

2.初始化变量和数组,记录需要查询的管段和已经遍历过的管段。

3.使用循环和游标,在管网上向上游查找阀门。循环中的步骤包括:

清空需要查询的点和初始执行节点。

查询与当前管段相交的管网上的点

如果找不到阀门,则判断新的source和target是否已经在需要查询的管段数组中,如果不在,则将它们添加到数组中。

如果找到了阀门,则返回该阀门的ID和几何形状。

使用的算法:

空间几何函数、数据库查询和循环

最近邻算法(寻找离起点最近的线)

图遍历算法(向上游查找阀门)

功能二:关闭上游最近阀门

利用pgRouting的pgr_dijkstraCost 函数,逆向找出与爆点管段相接的阀门

pgr_dijkstraCost函数是用于计算图中节点对最短路径的代价之和

Dijkstra算法的具体步骤:

1.初始化:将所有顶点的距离值初始化为无穷大,将起点的距离值初始化为0

2.选取距离起点最近的未访问的顶点,标记为已访问,同时更新该顶点相邻接的所有顶点的距离值 。具体地,对于每个未访问的相邻接的顶点,如果通过当前选定的顶点到达该顶点的距离小于该顶点当前的距离值,则更新其距离值

3.重复执行步骤2,直到所有顶点都被标记为已访问。此时,起点到其他所有顶点的最短路径就被计算出来了

功能在前端实现 :在geoserver的图层界面新建SQL视图,将前端请求的参数(爆管点的经纬度)和设计好的爆管分析函数导入到SQL视图中得到查询结果的WMS用cesium加载出来

cesium.js的写法

csharp 复制代码
function queryPath() {
    //定义起始点和目标点的位置
    var startCoord = Cesium.Cartographic.fromDegrees(116.43442149206543, 39.927703206481944);
    var destCoord = Cesium.Cartographic.fromDegrees(116.410648020996, 39.9069321798706);
    //构造WMS图层需要的参数
    var params = {
        LAYERS: 'postgis:shortestpath',
        FORMAT: 'image/png'
    };
    var viewparams = [
        'x1:' + Cesium.Math.toDegrees(startCoord.longitude), 'y1:' + Cesium.Math.toDegrees(startCoord.latitude),
        'x2:' + Cesium.Math.toDegrees(destCoord.longitude), 'y2:' + Cesium.Math.toDegrees(destCoord.latitude)
    ];
    params.viewparams = viewparams.join(';');

    //创建ImageLayer并添加到地图上
    var imageLayer = new Cesium.ImageryLayer(new Cesium.WebMapServiceImageryProvider({
        url: 'http://localhost:8088/geoserver/postgis/wms',
        layers: params.LAYERS,
        parameters: params
    }));
    viewer.imageryLayers.add(imageLayer);
}

ImageryLayer 是 Cesium 中用于显示图像数据的图层。 Cesium.WebMapServiceImageryProvider 是 Cesium 中用于访问 Web Map Service(WMS)提供的地理数据的图像提供器

特别:cesium加载3dtiles

csharp 复制代码
var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
    url: 'path/to/your/tileset.json'
}));

viewer.scene.primitives 是 Cesium 的一个基础元素集合,包括场景中所有的静态和动态元素,比如地形、模型、图像、点、线、面等等

3D Tiles的核心概念是将3D地理数据切割成瓦片(Tiles),类似于Web地图中的将地图区域切割成瓦片来提供动态加载和渲染的方式

功能三:管线分析中点选实现模型属性的展示

实际上模型的3dtiles中不包含属性信息,因此只能做管道模型的展示(甲方数据为平铺的管道)

因此采用的使用二维已发布的WFS服务来做点选

具体做法:WFS请求某一圆周范围的地图要素(方法:filter字段

ini 复制代码
http://localhost:28080/geoserver/sf/ows?service=WFS&version=1.0.0
&request=GetFeature
&typeName=sf:bugsites
&maxFeatures=50
&outputFormat=application%2Fjson
&filter=  
<ogc:Filter>
<ogc:DWithin>
<ogc:PropertyName>the_geom</ogc:PropertyName>
<gml:Point>
<gml:coordinates>540000,4210000</gml:coordinates>
</gml:Point>
<ogc:Distance unit="m">5</ogc:Distance>
</ogc:DWithin>
</ogc:Filter>

功能四:3dtiles三维模型的合并

3D Tilles是Cesium定义的一种三维模型的瓦片数据结构。这种数据结构能够处理三维的地理大数据

  1. 读取每个文件夹内的tileset.json文件,并修改其中的content字段的uri属性。
  2. 将修改后的数据写回tileset.json文件。
  3. 获取每个文件夹内的transform矩阵。
  4. 处理所有的JSON文件,提取其中的boundingVolume、children、content、geometricError、refine等字段,并存储在一个列表中。
  5. 将提取的字段替换到第一个文件夹的tileset.json文件中。
  6. 第一个文件夹的tileset.json 文件进行进一步处理,更新boundingVolume字段的值(范围)。
  7. 将最终处理结果写回tileset.json文件。

核心:

①修改每个tilest.json中content字段的uri属性

②transform矩阵的修改------使得合并后的3dtiles模型不发生位置偏移

transform=data['root']['transform']

css 复制代码
def alert_transform(A,B):
   A=np.mat(A)
   B=np.mat(B)
   A.resize(4,4)
   B.resize(4,4)
   C = np.dot(B, A.I)
   C.resize(16,1)
   C=np.array(C)
   return C

调整它们的维度为4x4(A.resize(4,4)和B.resize(4,4))

函数计算矩阵B和矩阵A的逆的乘积,并将结果存储在矩阵C中

对矩阵B和矩阵A的逆的乘积进行操作,实际上是将B中的坐标系应用到A的内容上 ,从而在合并3D Tiles数据集时,将A的内容正确转换到B的坐标系

2. ETL入库工具的功能模块实现

功能一:基于GeoTools的矢量数据处理

矢量要素数据(shp、geojson、csv、GML、KML等)在GeoTools通常用SimpleFeature 进行描述,SimpleFeature 是表示一个带有名称和属性集的要素(feature), SimpleFeature 可用于存储每个要素对象的各种信息,最重要的位置信息存储在Geometry字段里

DataStore:访问和查找特定类型数据存储,获取 FeatureSource,导出数据,执行事务等操作

在 Geotools 中,使用 DataStoreFactory 来创建 DataStore 实例 ,其中的 createDataStore() 方法就是一个工厂方法。通过这个方法,可以根据具体的数据源类型(如 shapefile、PostGIS 等)来创建相应的 DataStore 对象

FeatureSource:FeatureSource 是 GeoTools 中读取和写入空间数据存储的主要方式,提供了对源数据的统一访问;

FeatureCollection:多个feature对象的集合

ETL工具里面,Geotools 的FeatureCollection是一个矢量要素的集合,可以通过迭代器来遍历其中的要素。FeatureCollection 实现了 Iterator 接口,可以使用迭代器模式来逐个访问其中的元素

FeatureCollection 是一个接口,它继承了 Java 标准库中的 Iterable 接口,表示可以进行迭代的集合

csharp 复制代码
public interface FeatureCollection extends Iterable<Feature> {
    int size();
    FeatureIterator features();
    SimpleFeatureType getSchema();
    // ...
}

features() 方法返回一个 FeatureIterator 对象,用于获取矢量要素的迭代器

调用 features() 方法,可以获取到一个 FeatureIterator 对象,然后可以使用迭代器模式逐个访问矢量要素的元素

使用迭代器模式,在 while 循环中逐个访问矢量要素的元素 。在每次循环中,通过调用 next() 方法获取当前迭代的要素对象,并进行相应的处理。

java 复制代码
FeatureCollection featureCollection = ...; // 获取矢量要素集合
        // 使用迭代器遍历矢量要素集合
        try (FeatureIterator iterator = featureCollection.features()) {
        while (iterator.hasNext()) {
        Feature feature = iterator.next();
        // 处理当前要素
        }
        } catch (IOException e) {
        // 异常处理
        }

迭代器模式:提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示,是行为形的设计模式

核心: 抽象迭代器(Iterator):定义访问和遍历聚合元素的接口,通常包含** hasNext()、next() **等方法。

具体迭代器(Concretelterator):实现抽象迭代器接口中所定义的方法,完成对聚合对 象的遍历,记录遍历的当前位置

SimpleFeatureType:定义了矢量数据属性结构,在入库处理时可以明确当前数据格式具体 features 属性的类型,也是矢量数据的的表结构在geotools里的映射。

FeatureIterator:用于迭代遍历FeatureCollection中的每一个feature对象,从第一个要素开始逐一读取、检索要素

功能二:基于GeoTools的栅格数据处理

GridCoverage2D作为遥感影像的基础数据结构,并使用其成员变量记录特定坐标参考系统中的地理空间信息,其中

GridGeometry存储遥感影像的网格几何地理信息

PlanarImage存储遥感影像的栅格数据信息

①栅格数据的重采样(Resample),得到同网格地理空间下较小行列数的栅格。简单一点说,可以理解为栅格数据的抽稀。

GridCoverage2D covresample = (GridCoverage2D) Operations.DEFAULT.resample((GridCoverage) gridCoverage, crs, (GridGeometry) transgeomtry, null);

最主要参数为gridGeometry,即目标栅格影像的地理空间网格范围 ,GridGeometry的构造用到GridEnvelope和Envelope2D 两个参数,前者表示遥感影像的尺寸范围,后者为实际地理坐标范围 。通过修改遥感影像的尺寸范围并保持Envelope2D不变的方法实现了影像的重采样

②栅格裁剪

即根据限定的地理范围参见出所需的栅格影像的操作,GeoTools使用CoverageCrop操作得到目标瓦片的coverage(将一张完整的GeoTIFF裁剪为多个256*256大小的瓦片集)

Envelope的尺寸确定是切片的重点:1.得到瓦片的数量 2.根据瓦片的数量和排列情况确定每一个Envelope的范围(即瓦片在整个影像中的位置范围)

③序列化与遥感影像的入库

由于GridCoverage2D属于二维影像数据映射的类,因此对GridCoverage2D的两个组成对象PlanarImage和GridGeometry2D 进行序列化处理,即将原先的byte类型利用base64decode转化为String类型后进行入库处理,为了解决反序列化失败的问题,利用SerializableRenderedImage作为遥感影像PlanarImage的对象进行序列化,完成了反序列化后数据信息不改变的结果。

功能三:postgresql解决存入矢量数据字段的拓扑有效性

PostgreSQL 提供了 PostGIS 扩展,用于处理地理空间数据。PostGIS 可以执行拓扑规则的校验,例如检查线段是否闭合、面是否具有正确的边界等

例子:

线段闭合性校验: 使用 PostGIS 中的函数 ST_IsClosed() 来检查线段是否闭合

查找未闭合的线 SELECT * FROM roads WHERE NOT ST_IsClosed(geom);

面边界正确性校验: 使用 PostGIS 的 ST_IsValid() 函数可以对面的边界进行校验,以确保它们是有效的

查找无效的面 SELECT * FROM buildings WHERE NOT ST_IsValid(geom);

3.时空大数据服务平台WPS工作流

工作流设计展示模块使用了Vue +bpmn.js

工作流管理模块使用了Vue + Element-UI的技术栈

工作流结果展示模块使用了Vue +openlayer API

后端接口服务使用的是Springboot框架和activiti引擎,可以方便的实现postgresql数据库的连接和流程图绘制的BPMN_xml的解析

功能一:后端activiti引擎定义和管理工作流程

Activiti是一个流程引擎框架,它提供了一系列的服务类用于处理流程定义、流程实例、任务等相关操作

RepositoryService :流程仓库服务,用于管理和部署流程定义。可以通过该服务类进行流程定义的部署、查询、删除等操作

HistoryService :历史数据服务,用于查询流程实例、任务和变量等的历史数据。可以通过该服务类查询流程执行历史记录、生成流程图等操作

①从前端保存工作流

ini 复制代码
public void saveBpmn(String id, String bpmnXml) {
    // 根据ID获取模型
    Model modelData = repositoryService.getModel(id);
    // 如果模型不存在,则创建一个新模型
    if (modelData == null) {
        modelData = repositoryService.newModel();
        modelData.setName("BPMN Model");
    }
    // 将BPMN XML信息转为字节数组
    byte[] bpmnBytes = bpmnXml.getBytes();
    // 设置模型的基本信息
    repositoryService.saveModel(modelData);
    repositoryService.addModelEditorSource(modelData.getId(), bpmnBytes);
}

repositoryService.getModel(id) 方法根据指定的 ID 获取模型数据。使用 bpmnXml.getBytes() 将传入的 BPMN XML 字符串转换为字节数组。

通过 repositoryService.saveModel(modelData) 将模型的基本信息 保存到仓库中。 使用 repositoryService.addModelEditorSource(modelData.getId(), bpmnBytes) 将 BPMN XML 的字节数组作为模型的编辑源添加到模型中

②读取数据库工作流

scss 复制代码
public InputStream exportModel(String id) throws Exception {
    Model modelData = repositoryService.getModel(id);
    if (modelData != null) {
        String name = modelData.getName();
        List<Deployment> deployments = repositoryService.createDeploymentQuery()
                .deploymentName(name)
                .orderByDeploymentId()
                .desc()
                .list();
    
        if (modelSource.trim().startsWith("{")) {
            // 如果没有找到与模型对应的部署,则返回保存的 BPMN XML
            BpmnJsonConverter jsonConverter = new BpmnJsonConverter();
            JsonNode modelNode = new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));
            BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(modelNode);
            if (bpmnModel != null && bpmnModel.getMainProcess() != null && !bpmnModel.getMainProcess().getFlowElements().isEmpty()) {
                BpmnXMLConverter xmlConverter = new BpmnXMLConverter();
                byte[] bpmnXmlBytes = xmlConverter.convertToXML(bpmnModel);
                return new ByteArrayInputStream(bpmnXmlBytes);
            } else {
                return null;// 流程图为空,返回 null
            }
        }else if (modelSource.trim().startsWith("<?xml")) {
            // 使用 xml 解析器解析
            byte[] bpmnBytes = repositoryService.getModelEditorSource(modelData.getId());
            return new ByteArrayInputStream(bpmnBytes);
        }

    }
    // 如果模型不存在,则返回 null 或者空的 InputStream
    return null;
}

分类读取:

1.如果没有找到与模型对应的部署,将获取原始的模型源码。

bpmn: {"id":"canvas","resourceId":"canvas","stencilset":{"namespace":"http://b3mn.org/stencilset/bpmn2.0#"}}

将模型源码字节数组转换为字符串形式

2.如果模型源码以{开头,表示其是经过模型编辑器保存的BPMN JSON格式。将使用BpmnJsonConverter将JSON源码转换为BpmnModel。若BpmnModel存在主流程且其中包含流程元素,将使用BpmnXMLConverter将BpmnModel转换为BPMN XML字节数组,并返回相应的输入流。如果BpmnModel为空或未包含流程元素,将返回null表示流程图为空。

3.如果模型源码以<xml开头,表示其是BPMN XML格式,直接将模型源码转换为字节数组,并返回相应的输入流。

4.如果模型不存在,将返回null或空的输入流。

③执行服务算子的任务

模板方法模式:在 Activiti 工作流引擎中,JavaDelegate 接口是用于执行用户自定义的任务(即服务任务)的接口。它是模板方法模式的一个典型应用。

模板方法模式是一种行为设计模式,它定义了一个操作中的算法框架,将某些步骤的实现延迟到子类中。模板方法模式通过定义一个模板方法来封装算法的整体流程,而将具体的实现细节交给子类来完成

在 Activiti 中,JavaDelegate 接口定义了一个模板方法** execute**,该方法用于执行用户定义的任务。

csharp 复制代码
public interface JavaDelegate {
    void execute(DelegateExecution var1);
}

在使用 Activiti 时,用户需要实现 JavaDelegate 接口,并重写其中的 execute 方法,以提供具体的任务逻辑。当流程引擎执行到相应的服务任务时,会调用 execute 方法来执行用户定义的操作 定义一个模板方法 execute 来封装任务的执行流程,具体的任务逻辑则交给子类来实现

优点:提供了一种有效的代码复用机制。通过将公共的地理处理算法步骤放在父类中,子类只需要专注于实现具体的步骤,避免了重复编写相同的代码

缺点:子类太多,模板方法只允许子类改变特定步骤的实现,而不能改变算法的整体流程

④监控资源情况

ExecutionListener

执行监听器监听流程的所有节点和连线。主要有start、end

arduino 复制代码
public void notify(DelegateExecution execution)  {
    String eventName = execution.getEventName();
    switch (eventName) {
        case EVENTNAME_START:
            start(execution);
            break;
        case EVENTNAME_END:
            end(execution);
            break;
        default:
            break;
    }
}

通过监听start和end事件获取工作流的算法资源使用情况、调用情况,服务链的创建情况、删除情况、启动情况和运行成功失败情况。

⑤activiti项目中用到的表

  1. act_re_model 表:

    • 描述:该表存储了流程引擎中的模型定义信息。
    • 用途:每当你在流程设计器中创建或修改一个流程模型时,相应的定义信息将被保存在这个表中。
  2. act_re_procdef 表:

    • 描述:该表存储了流程引擎中的部署流程定义信息。
    • 用途:每当你部署一个流程定义(通常通过将流程模型转换为可执行的流程定义)时,相关的信息会被存储在这个表中。
  3. act_hi_varinst 表:

    • 描述:该表存储了流程引擎中的历史变量实例信息。
    • 用途:当流程实例执行过程中,如果设置了变量,这些变量的值和详细信息将被存储在该表中。可以用于追踪和分析流程中的变量使用情况。
  4. act_ge_bytearray 表:

    • 描述:该表存储了流程引擎中的字节数组数据信息。
    • 用途:在流程引擎中,一些数据(如流程定义的 BPMN XML 文件、流程图等)需要以字节数组的形式进行存储。这些字节数组数据将被保存在该表中

功能二:基于BPMN.js的工作流自定义设计

①读取工作流

javascript 复制代码
    transformCanvas(bpmnXmlStr) {
      // 将字符串转换成图显示出来
      this.bpmnModeler.importXML(bpmnXmlStr, (err) => {
        if (err) {
          console.error(err)
        } else {
          // 这里是成功之后的回调, 可以在这里做一系列事情
          this.success()
        }
        // 让图能自适应屏幕
        var canvas = this.bpmnModeler.get('canvas')
        canvas.zoom('fit-viewport')
      })
    },

将bpmn字符串绘制成图

②自定义左边工具栏元素(PaletteProvider)

Bpmn.js中对左边工具栏的定义文件分为Palette.js和PaletteProvider.js两类

PaletteProvider.js 是一个提供器(Provider),用于将Palette.js中定义的工具栏内容与BPMN编辑器关联起来。它负责将工具栏添加到BPMN编辑器的界面中,并处理用户与工具栏元素的交互

绑定监听事件

①监听modeler并绑定事件 用户在进行不同操作的时候能够监听到他操作的是什么, 从而做想要做的事情. 是进行了shape的新增还是进行了线的新增. 比如如下的一些监听事件:

  • shape.added 新增一个shape之后触发;
  • shape.move.end 移动完一个shape之后触发;
  • shape.removed 删除一个shape之后触发;

②监听element并绑定事件 监听用户点击图形上的element或者监听某个element改变:

  • element.click 点击元素;
  • element.changed 当元素发生改变的时候(包括新增、移动、删除元素)

自定义工具栏的监听事件包括拖拽和点击

特殊:BPMN.js中的设计模式

bpmnFactory:

bpmnFactory 是用于创建 BPMN 元素实例的工厂。它负责根据传入的类型和选项创建具体的 BPMN 元素对象。在 bpmn.js 中,bpmnFactory 是通过 BpmnFactory 类来实现的。该类提供了一系列静态方法用于创建不同类型的 BPMN 元素。

elementFactory:

elementFactory 是用于创建图形元素实例的工厂。它负责根据传入的类型和选项创建具体的图形元素对象,如节点、连接线等。在 bpmn.js 中,elementFactory 是通过 ElementFactory 类来实现的。该类提供了一系列方法用于创建不同类型的图形元素。

这两个工厂模式的实现都遵循了工厂模式 的原则,即将对象的创建过程封装在工厂类中,客户端只需要调用相应的方法,而无需关心对象的具体创建细节。这样可以提高代码的可维护性和可扩展性。

③自定义渲染(Renderer)

方法:与Bpmn.js自定义工具栏一样,将BaseRenderer这个类引入进来, 然后让自定义的CustomRenderer继承它,核心的渲染方法为drawShape

arduino 复制代码
  this.drawCustomElements = function (parentNode, element) {
        console.log(element)
        const type = element.type // 获取到类型
        if (type !== 'label') {
            if (customElements.includes(type)) { // or customConfig[type]
                const { url, attr } = customConfig[type]
                const customIcon = svgCreate('image', {
                    ...attr,
                    href: url
                })
                element['width'] = attr.width // 这里我是取了巧, 直接修改了元素的宽高
                element['height'] = attr.height
                svgAppend(parentNode, customIcon)
                console.log(element.labels.length)
                console.log(element.label)
                //判断是否有name属性来决定是否要渲染出label
                if (!hasLabelElements.includes(type) && element.businessObject.name) {
                    const text = svgCreate('text', {
                        "font-size": "14",
                        "fill": "#000"
                    })
                    text.innerHTML = element.businessObject.name
                    // 设置文本位置
                    text.setAttribute('x', attr.x);
                    text.setAttribute('y', attr.y + attr.height + 20);
                    svgAppend(parentNode, text)
                    console.log(text)
                }
                renderLabel(parentNode, element.label)
                return customIcon
            }
            const shape = this.bpmnRenderer.drawShape(parentNode, element)
            return shape
        } else {
            element
        }
    }

其中重要的组件:

1.customElements:自定义元素的列表,不在其列表的元素类型按默认元素进行渲染 2.customConfig:自定义元素的配置,里面设置自定义元素的渲染样式和大小

④自定义属性栏(properties-panel)

在Bpmn.js的原本初始化界面中并不带有属性栏,而是通过引入properties-panel的插件来将propertiesProviderModule和propertiesPanelModule文件引入搭建属性右边栏,并通过camundaModdleDescriptor 定义BPMN扩展的元素、属性和约束

1.bpmn properties介绍

用bpmn.js画的每一个节点其实都被称之为diagram element(图表元素)

在bpmn文件中的每个xml标签称之为BPMN element

将diagram element与BPMN element的一些属性关联起来靠的是businessObject的属性。在这个对象中可以添加上BPMN扩展的属性, 并且这些属性是可以直接插入到BPMN element上的.

2.读取bpmn properties

通过modeler中的事件点击方法可以得到点击节点的diagram element的信息

3.定制activiti:class

效果:在模型列表拉取出来即给其赋上activiti:class,使其作为定制模型

例如:筛选属性模型对应的activiti:class固定,可以直接执行wps操作 方法:通过前端控制台输出ModdleElement 的节点属性 console.log(element.businessObject)

得到serviceTask对应的activiti:class,在acticiti定义的bpmn文件里这个扩展类节点在$attrs["activiti:class"]上,

通过修改createServiceTask即可使得左边栏的模型具有初始化的activiti:class属性

javascript 复制代码
function createServiceTask(name,classname) {
        return function(event) {
            const businessObject = bpmnFactory.create('bpmn:ServiceTask')
            businessObject.name = name; // 将 name 值赋给 businessObject 的 name 属性
            businessObject.class=classname// 将 classname 值赋给 businessObject 的 camunda:class 属性
            console.log(businessObject)
            const shape = elementFactory.createShape({
                type: 'bpmn:ServiceTask',
                businessObject
            });
            console.log(shape) // 只在拖动或者点击时触发
            create.start(event, shape);
        }
    }

4.模型设置变量(extensionElement)

modeling.updateProperties(element, { }) 可以修改模型节点的属性值

先设置bpmn:ExtensionElements节点

ini 复制代码
var extensionElements = moddle.create('bpmn:ExtensionElements', { values: [] });
        // 将业务对象中的 extensionElements 属性更新为新创建的 ExtensionElements 元素
        modeling.updateProperties(element, {extensionElements: extensionElements });
        // 将 ExtensionElements 元素添加到业务对象中
        businessObject.extensionElements = extensionElements;

再设置camunda:Field节点

csharp 复制代码
    var inputFeatures = bpmnFactory.create('camunda:Field', {
    name: 'inputFeatures',
    string: this.inputVariables[0]
  });

5.自定义属性栏界面

由于自定义属性栏的代码可能会很多, 而且可能还会涉及到很多复杂的业务组件, 将其从引入bpmn.js的地方给抽离出来, 也就是封装成一个通用的自定义属性栏组件。

属性栏设计需求为点击不同的元素来呈现不同的配置

整个modeler作为props传递进去props即父组件向子组件传递的值, 在这里父元素就是引入bpmn.js的地方, 子元素为自定义属性栏组件,设计PropertiesView.vue文件, 用来编写自定义属性栏组件

监听设置:

使用element.click监听流程整体界面

使用selection.changed监听选中的元素;

使用element.changed监听发生改变的元素.

相关推荐
undefined&&懒洋洋13 分钟前
Web和UE5像素流送、通信教程
前端·ue5
大前端爱好者2 小时前
React 19 新特性详解
前端
随云6322 小时前
WebGL编程指南之着色器语言GLSL ES(入门GLSL ES这篇就够了)
前端·webgl
随云6322 小时前
WebGL编程指南之进入三维世界
前端·webgl
寻找09之夏3 小时前
【Vue3实战】:用导航守卫拦截未保存的编辑,提升用户体验
前端·vue.js
多多米10054 小时前
初学Vue(2)
前端·javascript·vue.js
柏箱4 小时前
PHP基本语法总结
开发语言·前端·html·php
新缸中之脑4 小时前
Llama 3.2 安卓手机安装教程
前端·人工智能·算法
hmz8564 小时前
最新网课搜题答案查询小程序源码/题库多接口微信小程序源码+自带流量主
前端·微信小程序·小程序
看到请催我学习4 小时前
内存缓存和硬盘缓存
开发语言·前端·javascript·vue.js·缓存·ecmascript