cesium绘制三角网可视化及mesh网格数据解析

news2024/9/21 22:18:48

可视化运行效果(水质污染扩散)
在这里插入图片描述
实现运行效果
在这里插入图片描述
在这里插入图片描述

术语

Mesh网格数据解析

Mesh(网格)在不同领域有不同的应用和定义。在计算机网络中,Mesh网络指的是一种无中心的网状结构,每个节点都与其他节点相连。而在3D计算机图形学中,Mesh是一个由许多小而简单的三角形构成的3D模型。

Mesh网格的应用场景
  1. 三维建模:Mesh用于创建三维模型,提供网格、曲面及多边形建模技术。
  2. 游戏开发:构建游戏角色、场景和特效。
  3. 计算机辅助设计(CAD):建立几何模型,提供建模工具和技术。
  4. 数值分析:用于数值分析、有限元模拟和计算流体动力学等计算应用程序。
  5. 医学领域:生成三维重建的解剖结构。
  6. 建筑设计:建立建筑外观、结构和平面图。
  7. 制造业:模拟非线性、动态和多物理场景下的部件行为。
  8. 流体力学:用于数值模拟和计算流体力学。
  9. 结构力学:用于有限元分析和结构优化。
  10. 计算机动画:用于人物建模、环境建模和特效制作。
  11. 环境工程:水污染扩散模拟,水质模拟预测。
Cesium中的Mesh网格可视化

Cesium是一个强大的三维地理空间可视化平台,它支持对Mesh网格数据的解析和可视化。通过Cesium,可以将Mesh网格数据转化为可视化的三角网格模型,实现以下功能:

  • 数据解析:解析各种格式的Mesh网格数据。
  • 三角网格生成:将网格数据转换为三角网格,用于可视化。
  • 动态渲染:根据视角和光照条件动态渲染三角网格。
  • 交互操作:支持用户与三角网格模型的交互操作,如旋转、缩放和探索。
实现步骤
  1. 数据准备:收集并准备Mesh网格数据。
  2. 数据导入:将Mesh数据导入Cesium平台。
  3. 网格解析:解析网格数据,提取网格结构和属性。
  4. 三角网格构建:根据解析结果构建三角网格模型。
  5. 可视化设置:设置光照、材质和其他视觉效果参数。
  6. 用户交互:实现用户与三角网格模型的交互功能。

通过上述步骤,可以在Cesium中实现Mesh网格数据的解析及可视化,为用户提供直观、动态的三维网格模型展示。

解析接口关键代码编写

//http://localhost:8085/ReadMesh/getMeshDataFiltered?FileName=A.mesh
   @RequestMapping(value = "/getMeshDataFiltered",method = RequestMethod.GET)
public @ResponseBody Map getMeshDataFiltered(String FileName) {

       //! 获取传入的参数,存在传入的文件名,则替换默认的文件名
   String defaultfilename = "A.mesh";
       String filename = FileName;
   if (!filename.isEmpty()){
      defaultfilename = filename;
   }
   String Meshpath = defaultfilename;
   String fileTyle = Meshpath.substring(Meshpath.lastIndexOf("."),Meshpath.length());

   Map map = new HashMap();
   if (fileTyle.equals(".mesh")){
      map = GenDataFromMesh(Meshpath);
   }

   if (fileTyle.equals(".msh")){
      map = GenDataFromMsh(Meshpath);
   }

   return  map;
}
前端可视化关键代码编写

primitiveTriangle:{
  isRLayerPanel: true,
  primitives:[],
  url: '/static/data/trangles.json',
  dataPath: '',
  dataIdField: 'code',
  options:{
    id:'primitiveTriangle',
    name:'三角格网',
    type:'triangles',
    isShow: false
  },
  location: {
    "destination":{"x":-2194142.1719457568,"y":4477352.104342483,"z":3981503.0453665117},
    "orientation":{"heading":6.283185231778362,"pitch":-0.6090220537393618,"roll":7.622047348831984e-8},
    duration: 2
  },
  entityType:'primitive'
}
<template>
  <div class="container">
    <div id="cesiumContainer1" style="height: 85%">
      <div id="tooltippop" class="ol-popup-tip" style="display:none; z-index:120; height:30px;">
        <div id="tooltip-title"></div>
        <div id="tooltip-content"></div>
      </div>
      <div id="gisToolPopoup">
        <GisTool :zjnCesium="zjnCesium" @setLayerVisible="setLayerVisible"  @zoomToC="zoomToC"></GisTool>
      </div>
      <div id="layersPanel">
        <layerPanel :layersInfo="layersInfo" @setLayerVisible="setLayerVisible"  @zoomToC="zoomToC"></layerPanel>
      </div>
    </div>
    <popHover :popHoverInfo="popHoverInfo" :popHoverScreenPoint="popHoverScreenPoint" :popHoverVisible="popHoverVisible"></popHover>
    <popClick :popAspect="popAspect" :popClickScreenPoint="popClickScreenPoint" :popClickVisible="popClickVisible" :popClickTitleInfo="popClickTitleInfo" :popClickContentInfo="popClickContentInfo"></popClick>
    <div class="CoordinateLabel">
      <p><label id="lon"></label></p>
      <p><label id="lat"></label></p>
      <p><label id="cdem"></label></p>
      <p><label id="cvInfo"></label></p>
    </div>
    <div>
      <input value="获取当前视图" type="button" style="height: 50px;width:100px" @click="getCv()">
    </div>
  </div>

</template>

<script>
    // import { Viewer,createWorldTerrain,Cesium3DTileset,WebMapTileServiceImageryProvider,ImageryLayer,Cartesian3,HeadingPitchRange,Math} from 'cesium/Cesium'
    import  'cesium/Widgets/widgets.css'
    import './renderStyle/index.css'
    import GisTool from "./gisTool"
    import ZJNCesium from './ZJNCesium.js'
    import layerPanel from './widgets/layerPanel/index'
    import popHover from './widgets/popHover/index'
    import popClick from './widgets/popClick/index'
    import {layersInfo} from './store/LayersInfo'
    import {LayersRenderSet} from './renderSet/LayersRenderSet'
    import {LayersRenderLabelSet} from './renderSet/LayersRenderLabelSet'
    import {layerMsgClick} from "./layerMsg/LayerMsgClick";
    import {
      CommonDrawEntities,
      CommonDrawEntitiesByLayerID,
      CommonDrawWallEntities,
      CommonDrawPolylineEntities,
      setLayerVisible,
      CommonDrawPolygonEntities,
      CommonDrawPointEntitiesByUrl,
      CommonDrawWallEntitiesByUrl,
      CommonDrawPolylineEntitiesByUrl,
      CommonDrawPolygonEntitiesByUrl,
      CommonDrawCorridorEntitiesByUrl,
      CommonDrawByGeojson,
      CommonDrawPolylineVolumeEntitiesByUrl,
      CommonDrawWindyEntitiesByUrl,
      CommonDrawHeatmapByUrl,
      CommonDrawPrimitiveEntitiesByUrl,
      CommonCreateMeshGrid,CommonCreateMeshTriangle
    } from './MapCommon'
    import {carDatas} from "../../common/api/carRoad"
    import {linedata,polygondata} from "./data/pointlinepolygon"
    import {TransferSimUtil} from "./utils/TransferSimUtil"

    var zjnCesium;
    export default {
        name: "earth",
        components: {
          layerPanel,
          GisTool,
          popHover,
          popClick
        },
        data() {
            return {
              zjnCesium: null,
              popHoverScreenPoint: {x: null, y: null},
              popHoverInfo: '',
              popHoverVisible: false,
              popClickScreenPoint: {x: null, y: null},
              popAspect:{cWidth: 600, cHeight: 400},
              popClickPoint: null,
              popClickTitleInfo: '',
              popClickContentInfo: '',
              popClickVisible: false,
              transferSimUtil: null,
              buttondaohe:"道合",
              layersInfo:layersInfo,
              modelList:{
                daohe:{x: -2412207.790025016,y: 4418038.146476992,z: 3904021.2752170297},
                daoheOrientation:{
                  heading : 0,
                  pitch : -0.3,
                  roll : 0
                },
                caike:{x: -2399848.645912107,y: 4425276.703809752,z: 3903524.9361700616},
                caikeOrientation:{
                  heading : 0,
                  pitch : -0.3,
                  roll : 0
                },
                dairuike:{x: -2398945.254669891,y: 4426231.6794353435,z: 3903000.9872286734},
                dairuikeOrientation:{
                  heading : 0,
                  pitch : -0.3,
                  roll : 0
                },
                guangyue:{x: -2410663.34105633, y: 4417042.059943647, z: 3905962.3976926757},
                guangyueOrientation:{heading: 3.282430123199906,pitch: -0.20432213919653686,roll: 7.223571873993251e-7}
              },
            };
        },
        methods:{
          setPosition:function (key){
            zjnCesium.viewer.camera.flyTo({
              destination : this.modelList[key],
              orientation : this.modelList[key+'Orientation'],
              duration: 2
            });
          },
          getCv:function (){
            let cp=zjnCesium.getCurrentViewPosition();
            document.getElementById('cvInfo').innerText=JSON.stringify(cp);
            // this.transferSimUtil.RemoveTrack()
            // this.setViewType(1)
          },
          MousemoveCallback(data,layerId,c){
            // debugger
            if (layersInfo[layerId] && layersInfo[layerId].floatLabelInfo) {
              this.popHoverScreenPoint.x = c.x + layersInfo[layerId].floatLabelInfo.offsetX
              this.popHoverScreenPoint.y = c.y + layersInfo[layerId].floatLabelInfo.offsetY
              this.popHoverInfo = data[layersInfo[layerId].floatLabelInfo.floatLabelField]
              this.popHoverVisible = true
            } else {
              this.popHoverVisible = false
            }
          },
          MouseclickCallback(data,layerId){
            if (layersInfo[layerId].CustomPopupTemplate) {
              this.popClickTitleInfo = data[layersInfo[layerId].CustomPopupTemplate.titleField]
              this.popClickContentInfo = layersInfo[layerId].CustomPopupTemplate.content
              let attrs = Object.keys(data)
              for (let i = 0; i < attrs.length; i++) {
                this.popClickContentInfo = this.popClickContentInfo.replaceAll('{' + attrs[i] + '}', data[attrs[i]])
              }
              this.popAspect.cWidth = layersInfo[layerId].CustomPopupTemplate.width
              this.popAspect.cHeight = layersInfo[layerId].CustomPopupTemplate.height
              this.popClickVisible = true
            }
            if(layerMsgClick[layerId] !== undefined){
              for(var i = 0; i < layerMsgClick[layerId].length; i++){
                var mcmd = layerMsgClick[layerId][i].method+'(';
                for(var j = 0; j < layerMsgClick[layerId][i].params.length; j++){
                  mcmd += layerMsgClick[layerId][i].params[j];
                  if(j < layerMsgClick[layerId][i].params.length - 1){
                    mcmd += ',';
                  }
                }
                mcmd += ')';
                eval(mcmd);
              }
            }
          },
          setLayerVisible(layerId, visible){
            setLayerVisible(layersInfo,layerId,visible)
            var testdata = [
              [115.66560745239256,
                34.41760191899927],
              [115.67530632019043,
                34.41795594404557],
              [115.685133934021,
                34.4180621512672],
              [115.69406032562254,
                34.4180621512672],
              [115.69509029388428,
                34.41700007298082],
              [115.69547653198244,
                34.416079594221465],
              [115.69607734680174,
                34.414769664672725],
              [115.69620609283447,
                34.41186650444182],
              [115.69624900817871,
                34.41048569775086],
              [115.69612026214601,
                34.40917568058836],
              [115.69067001342772,
                34.409211086727375],
              [115.69071292877196,
                34.402412833257614]
            ]
            // this.transferSimUtil.SimulateTansfer(testdata)
          },
          zoomToC(location){
            zjnCesium.viewer.camera.flyTo(location);
          },
          testClick(re,layerId){
            debugger
          },
          setViewType(viewType){
            //0二维,1三维
            zjnCesium.setViewType(viewType)
          },
          // setLayerOpacity (layerId, opacity) {
          //   // getLayerByCode(this.smap, layerId).setOpacity(opacity)
          // }
        },
        mounted() {
          zjnCesium = new ZJNCesium("cesiumContainer1");
          this.zjnCesium = zjnCesium
          zjnCesium.initMap()
          for (let key in layersInfo){
            if(layersInfo[key].entityType == 'rectangle'){
              CommonDrawEntitiesByLayerID(zjnCesium,layersInfo,key)
            }else if((layersInfo[key].entityType == 'point' || layersInfo[key].entityType == 'billboard' || layersInfo[key].entityType == 'ellipse' || layersInfo[key].entityType == 'cylinder' || layersInfo[key].entityType == 'box' || layersInfo[key].entityType == 'ellipsoid') && layersInfo[key].url != undefined && layersInfo[key].url != ""){
              CommonDrawPointEntitiesByUrl(zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,key)
            }
            else if(layersInfo[key].entityType == 'heatmap'){
              CommonDrawHeatmapByUrl(zjnCesium,layersInfo,key)
            }
            else if((layersInfo[key].entityType == 'wall') && layersInfo[key].url != undefined && layersInfo[key].url != ""){
              CommonDrawWallEntitiesByUrl(zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,key)
            }
            else if((layersInfo[key].entityType == 'line') && layersInfo[key].url != undefined && layersInfo[key].url != ""){
              CommonDrawPolylineEntitiesByUrl(zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,key)
            }
            else if((layersInfo[key].entityType == 'corridor') && layersInfo[key].url != undefined && layersInfo[key].url != ""){
              CommonDrawCorridorEntitiesByUrl(zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,key)
            }
            else if((layersInfo[key].entityType == 'polylineVolume') && layersInfo[key].url != undefined && layersInfo[key].url != ""){
              CommonDrawPolylineVolumeEntitiesByUrl(zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,key)
            }
            else if((layersInfo[key].entityType == 'polygon') && layersInfo[key].url != undefined && layersInfo[key].url != ""){
              CommonDrawPolygonEntitiesByUrl(zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,key)
            }
            else if((layersInfo[key].entityType == 'primitive') && layersInfo[key].url != undefined && layersInfo[key].url != ""){
              CommonDrawPrimitiveEntitiesByUrl(zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,key)
            }
            else if((layersInfo[key].entityType == 'windy') && layersInfo[key].url != undefined && layersInfo[key].url != ""){
              CommonDrawWindyEntitiesByUrl(zjnCesium,layersInfo,key)
            }
            else if(layersInfo[key].entityType == 'glb'){
              zjnCesium.CommonCreateGlbEntityModel(layersInfo[key])
            }
            else if(layersInfo[key].entityType == 'geojson'){
              CommonDrawByGeojson(zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,key)
            }
            else{
              zjnCesium.commonAddProviderLayer(layersInfo,key)
            }

          }
          // CommonCreateMeshTriangle(undefined,zjnCesium,layersInfo,'')
          // CommonCreateMeshGrid(zjnCesium,layersInfo,'')
          // CommonCreateMesh(undefined,zjnCesium,layersInfo,'')
          // CommonDrawEntities(outputData,zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,'outPutPoint','lng','lat','outPutId')
          // // setLayerVisible(layersInfo,'outPutPoint',false)
          // CommonDrawWallEntities(roadData,zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,'roadWall','positions','minimumHeights','code')

          // CommonDrawPolylineEntities(linedata,zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,'rline','positions','code')

          // CommonDrawPolygonEntities(polygondata,zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,'rpolygon','positions','code')

          // carDatas().then((res)=>{
          //   // CommonDrawWallEntities(res.data,zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,'roadWall','positions','minimumHeights','code')
          // })
          // setLayerVisible(layersInfo,'roadwall',false)
          // zjnCesium.createGltfEntityModel('/static/model/bingdundun.glb','gltf','xmf',115.650964712670241,34.44454369992611,{heading: 90, pitch: 0, roll: 0})
          //绑定鼠标移动,点击等事件
          zjnCesium.bindMousemoveDefault(this.MousemoveCallback);
          zjnCesium.bindLonLatOnMouseMove("lon", "lat", "cdem");
          //地图点击
          zjnCesium.bindClickDefault(this.MouseclickCallback);
          //设置初始视野
          zjnCesium.Home();
          this.transferSimUtil = new TransferSimUtil(zjnCesium)
        }
    };
</script>
<style>
#layersPanel{
  position: absolute;
  top: 50px;
  right: 300px;
  z-index: 999;
}
#gisToolPopoup{
  position: absolute;
  top: 50px;
  left: 20px;
  z-index: 999;
}
</style>

如果对恁有帮助,请点赞打赏支持,多谢!

技术合作交流qq:2945853209

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1685338.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机专业实习生应该去哪实习?

计算机专业实习生可以选择在各种不同类型的公司和组织中实习。我这里有一套编程入门教程&#xff0c;不仅包含了详细的视频讲解&#xff0c;项目实战。如果你渴望学习编程&#xff0c;不妨点个关注&#xff0c;给个评论222&#xff0c;私信22&#xff0c;我在后台发给你。 这取…

局部直方图均衡化去雾算法

目录 1. 引言 2. 算法流程 3. 代码 4. 去雾效果 1. 引言 局部直方图算法是一种基于块的图像去雾方法&#xff0c;它将图像分割为若干个块&#xff0c;并在每个块内计算块的局部直方图。通过对各个块的直方图进行分析和处理&#xff0c;该算法能够更好地适应图像中不同区域的…

聚鼎科技:现在的装饰画怎么样

当代装饰画以其多样化的风格和形式&#xff0c;在装点生活的同时反映了现代人的审美趣味和文化追求。如今&#xff0c;装饰画不再局限于传统的油画、水彩或版画&#xff0c;它们已经跨越了材质与技法的界限&#xff0c;呈现出前所未有的丰富性。 走进任一家装潢精致的咖啡馆或现…

基于机器学习模型预测信用卡潜在用户(XGBoost、LightGBM和Random Forest)

基于机器学习模型预测信用卡潜在用户&#xff08;XGBoost、LightGBM和Random Forest&#xff09; 随着数据科学和机器学习的发展&#xff0c;越来越多的企业开始利用这些技术来提高运营效率。在这篇博客中&#xff0c;我将分享如何利用机器学习模型来预测信用卡的潜在客户。此…

angr使用学习

首先我是直接在kali中安装的&#xff0c;也是边练边学的。 嗯&#xff0c;要在纯净python环境&#xff0c;所以是在 virtualenv 虚拟环境里&#xff0c;也不是特别会用这个&#xff0c;按照教程一步步做的 source venv/bin/activate 进入了对应环境 退出是 deactivate en,ipy…

pdf文件怎么编辑?分享3个专业的pdf软件!

在数字化时代&#xff0c;PDF文件已成为我们工作、学习中的得力助手。然而&#xff0c;面对需要修改的PDF文件&#xff0c;许多人却感到无从下手。今天&#xff0c;就让我们一起探索如何轻松编辑PDF文件&#xff0c;并介绍几款实用的编辑软件&#xff0c;让你轻松应对各种PDF编…

Spring:IoC容器(基于注解管理bean)

1. HelloWorld * 引入依赖* 开启组件扫描* 使用注解定义 Bean* 依赖注入 2.开启组件扫描 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/20…

免费开源人脸识别系统,支持RESTful API

简介 CompreFace 是一个免费开源的人脸识别项目&#xff0c;您不需要具备机器学习技能就能安装设置和使用 CompreFace&#xff0c;官方提供了基于 docker 的部署方法&#xff0c;可以方便地部署在本地或者云端服务器上。 CompreFace 提供了 RESTful API&#xff0c;用于人脸识别…

大模型效能工具之智能CommitMessage

01 背景 随着大型语言模型的迅猛增长&#xff0c;各种模型在各个领域的应用如雨后春笋般迅速涌现。在研发全流程的效能方面&#xff0c;也出现了一系列贯穿全流程的提效和质量工具&#xff0c;比如针对成本较高的Oncall&#xff0c;首先出现了高质量的RAG助手&#xff1b;在开…

云原生Kubernetes: K8S 1.26版本 部署KubeSphere

目录 一、实验 1.环境 2.K8S 1.26版本部署HELM 3.K8S 1.26版本 部署KubeSphere 4.安装KubeSphere DevOps 二、问题 1.如何安装Zadig 2.扩展插件Zadig安装失败 3.calico 如何实现不同node通信 4.如何清除docker占用的磁盘空间 5.如何强制删除资源 6.namespace删除不…

linux命令中arj使用

arj 用于创建和管理.arj压缩包 补充说明 arj命令 是 .arj 格式的压缩文件的管理器&#xff0c;用于创建和管理 .arj 压缩包。 语法 arj(参数)参数 操作指令&#xff1a;对 .arj 压缩包执行的操作指令&#xff1b;压缩包名称&#xff1a;指定要操作的arj压缩包名称。 更多…

非关系型数据库NOSQL

文章目录 1. NOSQL 概述2. 相关理论基础2.1 一致性2.2 分区2.3 存储分布2.4 查询模型 3. NOSQL 数据库的种类3.1 文档存储3.2 键值存储3.3 列存储3.3 图存储 4. NOSQL 应用案例和新技术4.1 HBase 数据库4.2 云数据库 GeminiDB 非关系型的数据库 NOSQL (Not Only SQL)是对不同于…

2024.05.23 学习记录

1、 react hooks 面经复习 2、xiaolin coding 计算机网络 复习 3、组件库 subMenu、test测试、tabs组件初步开发完成 4、代码随想录刷题&#xff1a;动态规划 01背包 all

sharded jedis pipelined 执行后 数据并未存入redis

前言 因为历史原因&#xff0c;在某个同步菜单操作的方法中先清除缓存&#xff0c;然后在初始化缓存。本来很正常的逻辑&#xff0c;但是这个清除是db查询获取所有的菜单 然后循环一条条删除 然后在db查询有效的菜单操作 在循环一条条插进去 经统计这个菜单操作大概有个7千个 …

实战Java虚拟机-高级篇

一、GraalVM 什么是GraalVM GraalVM是Oracle官方推出的一款高性能JDK&#xff0c;使用它享受比OpenJDK或者OracleJDK更好的性能。GraalVM的官方网址&#xff1a;https://www.graalvm.org/官方标语&#xff1a;Build faster, smaller, leaner applications。 更低的CPU、内存…

化简资源分配图判断是否发生死锁

目录 1.资源分配图的概念 2.判断是否发生死锁 1.资源分配图的概念 资源分配图表示进程和资源之间的请求关系&#xff0c;例如下图&#xff1a; P代表进程&#xff0c;R代表资源&#xff0c;R方框中 有几个圆球就表示有几个这种资源&#xff0c;在图中&#xff0c;R1指向P1&a…

【加密与解密(第四版)】第十五章笔记

第十五章 专用加密软件 15.1 认识壳 15.2 压缩壳 UPX、ASPack、PECompact 15.3 加密壳 ASProtect(压缩、加密、反跟踪代码、CRC校验、花指令)、Armadillo(穿山甲)、EXECryptor、Themida 15.4 虚拟机保护软件 虚拟机引擎&#xff08;编译器解释器虚拟CPU环境指令系统&#xff…

后端数据库开发JDBC编程Mybatis之用基于XML文件的方式映射SQL语句实操

之前的SQL语句是基于注解 以后开发中一般是一个接口对应一个映射文件 书写映射文件 基本结构 框架 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.or…