前言

Cesium是一个非常优秀的三维地球GIS引擎(开源且免费, 能够加载各种符合标准的地图图层,瓦片图、矢量图等都支持。而AutoCAD是为微型计算机上应用CAD技术而开发的绘图程序,它有很强的图形编辑能力,非常适合绘制工程图纸,绘图的精确性和绘图方法的丰富性使得它在机械、电子、建筑、航空航天等领域有着广泛的应用,常见的一些工程图纸基本上都是AutoCAD绘制的DWG格式的图纸;在实际中经常会遇到需要将CAD的图纸叠加到cesium上面,与地表地形叠加显示查看。那如何实现在Cesium中实现与CAD的DWG图叠加显示分析呢?

技术分析

业内一般的做法步骤为:

  • (1) 在AutoCAD中把DWG图导出为DXF明码格式文件
  • (2) 利用第三方工具如GDAL,把dxf转为shp等GIS数据格式
  • (3) 利用开源的gis服务,如geoserver或mapserver把shp文件发布成gis服务
  • (4) 在cesium中加载gis服务的瓦片图层

上面的方案的优点很明显,基本上利用开源的方案能把流程跑通。但在实际项目中缺点也很明显,主要是在步骤 (1)(2), 因为dwg是私有格式,通过dwg转出成dxf再转化成shp文件时,会丢失图中的很多数据,CAD数据类型较为丰富,支持点、块符号、线、面、多段线、椭圆、块、文字等多种数据类型,而转换到GIS中,只转换为点、线、面、注记等类型,这使得CAD图形数据不能很好的满足GIS的要求,如:CAD中的Text数据类型,直接转换后只转换为GIS中的Point。通过这种转换去绘制,会导致和原始CAD图形绘制不太一样, 同时CAD里面有线型、字体也会导致绘制上的差异性。

唯杰地图vjmap完全兼容AutoCAD格式的DWG文件,无需通过转换可直接发布成gis的WMS格式,可有效解决上面问题。实现步骤为:

  • (1) 上传DWG图形,利用唯杰地图发布为WMS图层
  • (2) 在cesium中加载wms瓦片图层

实现

先上效果图,(红色的线为cad图层)

具体步骤:

  • 确定CAD图的坐标系

    在打开的CAD图中,随便找了图中的一个点坐标,坐标为”614802.89177, 3257472.36997”

    那怎么确定这个坐标是哪个坐标系呢? 如果已经知道坐标能不能倒推坐标系呢?

    可以,但是得分情况。这里我们只讨论高斯克吕格投影。

    假设已经知道数据的投影是高斯克吕格,怎样判定是6°带还是3°带?怎样判定中央经线是多少呢?

    如果坐标范围是6位,我们可以判定坐标系不带带号的。如果Y值范围在333000m~667000m,可能是3°分带法;如果Y值范围在166 000m~834000m,一定是6°分带法。如果取值范围重合的部分有可能3°分带法也可能在6°分带法。

    如果坐标范围是8位,我们可以判定坐标系是以带号命名,并且根据带号可以知道是3°带还是6°带。我们国家的经度范围大致在73°33′E105°05′E,所以如果是以带号命名,带号在1323带之间的,说明是6°分带法;带号在25~45带之间的,说明是3°分带法。

    在这个图中,坐标为”614802“为6位,大概率能确定为省去了带系的3°分带坐标。并且根据图中图框中坐标系写的为2000坐标系,同时地点为重庆附近。而重庆的经度差不多是以106开头。我们去epsg官网查询得知,该坐标系应该是"EPSG:4544".

  • 上传打开CAD图

    如果在Web网页端展示CAD图形(唯杰地图云端图纸管理平台 https://vjmap.com/app/cloud),这个在前面的博文中已讲过,这里不再重复,有需要的朋友可下载工程源代码研究下。

  • 在cesium增加cad图层

    let imageryProvider= new Cesium.WebMapTileServiceImageryProvider({url: "http://t0.tianditu.gov.cn/img_w/wmts?tk=3346bb6ad29b5013c5952cf1117b80e9",layer: "img",style: "default",tileMatrixSetID: "w",format: "tiles",maximumLevel: 14,});let viewer = new Cesium.Viewer('cesiumContainer', {imageryProvider: imageryProvider,contextOptions: {webgl: {alpha: true}},selectionIndicator: false,animation: false, //是否显示动画控件baseLayerPicker: false, //是否显示图层选择控件geocoder: false, //是否显示地名查找控件timeline: false, //是否显示时间线控件sceneModePicker: false, //是否显示投影方式控件navigationHelpButton: false, //是否显示帮助信息控件infoBox: false, //是否显示点击要素之后显示的信息fullscreenButton: false,shouldAnimate: true //动画播放});var layers = viewer.scene.imageryLayers;layers.addImageryProvider(new Cesium.WebMapServiceImageryProvider({// 通过vjmap的wms加载cad图url: `https://vjmap.com/server/api/v1/map/cmd/wms/
    sys_cadcesium/v1?mapbounds=&format=image/png&service=WMS&version=1.1.1&request=GetMap&srs=EPSG:4326&transparent=true&width=256&height=256&layers=se92105f73&crs=EPSG:4544&fourParameter=&token=your token`,}));
    

上面的代码好像简单明了,可实际中发现,在cesium中,cad可以和天地图影像叠加。但在放大的过程中,发现wms生成的瓦片有错开的问题。如下图所示:

问题分析

在cesium中,是WGS84坐标系,而CAD图是4544坐标系。两个不同的椭球体之间转换,在WMS中瓦片生成是根据坐标转换生成的瓦片数据,而由于坐标转换是非线性的,导致生成的图片内容不能完全对上。所以有错开的问题。

那怎么解决呢?

最终的方案是:

  • 先通过四参数,把CAD与墨卡托3857的转换参数求出来

  • 再墨卡托3857转wgs4326

    通过这样的转换,数据转换是线性转换了,就不会有错开的问题了。

    具体代码如下:

    // --Cesium中加载CAD图(WMS图层)--
    // 地图服务对象
    let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
    // 打开地图
    let mapId = "sys_cadcesium";
    let res = await svc.openMap({mapid: mapId, // 地图IDmapopenway: vjmap.MapOpenWay.GeomRender, // 以几何数据渲染方式打开style: vjmap.openMapDarkStyle() // div为深色背景颜色时,这里也传深色背景样式
    })
    if (res.error) {// 如果打开出错message.error(res.error)
    }
    let layer = res.layer;//图层样式名let mapBounds = vjmap.GeoBounds.fromString(res.bounds);
    let boundsArray = mapBounds.toPointArray();// 得到坐标转换后的墨卡托点
    let mktPoints = await svc.cmdTransform("EPSG:4544", "EPSG:3857", boundsArray.map(a => vjmap.geoPoint(a)));
    // cad上面的点坐标
    let cadPoints = [...boundsArray];
    // 通过坐标参数求出四参数
    let fourparam = vjmap.coordTransfromGetFourParamter(mktPoints.map(a => vjmap.geoPoint(a)),cadPoints.map(a => vjmap.geoPoint(a)),true
    );if (typeof Cesium !== "object") {// 如果没有环境await vjmap.addScript([{src: "js/Cesium/Cesium.js"}, {src: "js/Cesium/Widgets/widgets.css"}])
    }let imageryProvider= new Cesium.WebMapTileServiceImageryProvider({url: "https://t0.tianditu.gov.cn/img_w/wmts?tk=3346bb6ad29b5013c5952cf1117b80e9",layer: "img",style: "default",tileMatrixSetID: "w",format: "tiles",maximumLevel: 14,
    });let viewer = new Cesium.Viewer('map', {imageryProvider: imageryProvider,contextOptions: {webgl: {alpha: true}},selectionIndicator: false,animation: false, //是否显示动画控件baseLayerPicker: false, //是否显示图层选择控件geocoder: false, //是否显示地名查找控件timeline: false, //是否显示时间线控件sceneModePicker: false, //是否显示投影方式控件navigationHelpButton: false, //是否显示帮助信息控件infoBox: false, //是否显示点击要素之后显示的信息fullscreenButton: false,shouldAnimate: true //动画播放
    });var layers = viewer.scene.imageryLayers;// 加一个高德注记图层
    layers.addImageryProvider(new Cesium.UrlTemplateImageryProvider({url: "https://webst02.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8",})
    );// 增加cad的wms图层
    let wmsUrl = svc.wmsTileUrl({mapid: mapId, // 地图idlayers: layer, // 图层名称bbox: '', // bbox这里不需要传,cesium会自动加上srs: "EPSG:4326", // cesium地图是wgs84crs: "EPSG:3857", // 先把wgs84转3857fourParameter: [fourparam.dx,fourparam.dy,fourparam.scale,fourparam.rotate] // 转成 3857后,再用四参数去转成cad坐标
    })
    layers.addImageryProvider(new Cesium.WebMapServiceImageryProvider({url: wmsUrl,})
    );// cad图坐标转web wgs84坐标
    const cadToWebCoordinate = point => {// 先用四参数转成墨卡托3857,再墨卡托3857转wgs84// 这里需要用四参数反算,因为上面的四参数是3857转cad的,这里是反过来,要cad转3857,所以需要反算let ptMkt = vjmap.coordTransfromByInvFourParamter(vjmap.geoPoint(point), fourparam);return vjmap.Projection.mercator2LngLat(ptMkt);// 再墨卡托3857转经纬度
    }
    // 转web wgs84坐标转cad图坐标
    const webTocadCoordinate = point => {// 先wgs84转墨卡托3857,再用四参数转成cadlet ptMkt = vjmap.Projection.lngLat2Mercator(vjmap.geoPoint(point));return vjmap.coordTransfromByFourParamter(ptMkt, fourparam);
    }
    // 根据cad图的中心点,计算wgs84的中心点坐标
    let cadCenter = mapBounds.center();
    let webCenter = cadToWebCoordinate(cadCenter);
    //设置初始位置
    viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(webCenter[0], webCenter[1], 30000)
    });// 如果需要在地图上查询cad的实体坐标,可通过svc.rectQueryFeature来实现,需要传入两个cad的点坐标范围
    // 可以通过 webTocadCoordinate 接口把wgs84的坐标转成 cad 的坐标去查询.

    出于对数据保密的需要,我们对CAD图进行了脱敏处理,叠加的效果如下

上面的案例代码已开源。访问 (https://vjmap.com/demo/#/demo/map/web/07cesiumCadWmsLayer) ,查看效果和代码即可。

在Cesium中实现与CAD的DWG图叠加显示分析相关推荐

  1. 高德地图与CAD图叠加显示方法汇总及优缺点分析

    前言 ​ 高德地图应用在许多领域,平常我们用的地图导航,除过正常的地图导航指引功能之外,其实还有很多实用的功能.如高德影像地图应用在包括地理.土地测量.水文学.生态学.气象学以及海洋学等方面.Auto ...

  2. vue项目中,Echarts柱状图和折线图混合显示

    <div ref="myChart" :style="{width: '800px', height: '500px'}"></div> ...

  3. 不打开DWG图如何查看CAD版本

    不打开DWG图如何查看CAD版本 问题 方法 1.用记事本打开要查看的DWG图: 2.看到很多乱码,不用管,但前面有AC1027字样,从这个就可以判断CAD的版本了 3.根据得到的字样和下表进行比对就 ...

  4. Cesium中gltf模型的坐标系

    Cesium中使用gltf格式的模型,而gltf格式的模型的坐标系在加载到Cesium中后,Cesium会自动变换坐标系. 本文简要阐述gltf模型的坐标系加载前后的变化. gltf模型 可以使用各种 ...

  5. Autocad毕业设计CAD机械练习图开始发放啦!

    对于CAD小编有话说!CAD在近几年的发展是越来越好,前几年来说CAD肯定有很多人都不了解CAD,但是现在就不一样了,CAD在建筑设计,室内装修方面都应用的比较广泛,很多大学生都开始逐渐步入CAD设计 ...

  6. 折线迷你图怎么设置_Office小技巧-在EXCEL单元格中也可以有迷你折线图-迷你office...

    大家是否知道表格中的迷你图是什么功能?在Excel2013中迷你图一共有三种:折线迷你图.柱形迷你图.盈亏迷你图.在表格单元格中插入迷你的折线图可以使数据更加的直观,也增加了表格的可读性,并且将数据中 ...

  7. C#实现在CAD图纸中插入另一个DWG图块的代码

    C#实现在CAD图纸中插入另一个DWG图块的代码PromptPointResult ppr = ed.GetPoint("请选择插入点:"); Point3d pt = ppr.V ...

  8. CAD处理控件Aspose.CAD功能演示:在 C#中以编程方式搜索 DWG 图形文件中的文本

    Aspose.CAD 是一个独立的类库,以加强 Java应用程序处理和渲染CAD图纸,而不需要AutoCAD或任何其他渲染工作流程.该CAD类库允许将DWG, DWT, DWF, DWFX, IFC, ...

  9. lisp图库不显示缩略图_[原创]在未安装过任何CAD版本的系统中,也能查看dwg文件的缩略图!...

    本帖最后由 作者 于 2008-4-26 22:27:02 编辑 引言------- 我的电脑原来安装了CAD2002版本,在资源管理器中(文件夹)是看不到CAD文件的缩略图的,可有一天我安装了CAD ...

  10. cad填充图案乱理石_CAD软件中如何自定义CAD填充图案?

    在使用浩辰CAD软件绘制完成图纸后,发现自己绘制的CAD图纸没有做好区域分割,显得特别乱.这个时候该怎么办呢?快试试CAD填充图案吧!接下来就由小编来给大家介绍一下浩辰CAD软件中自定义CAD填充图案 ...

最新文章

  1. 清华本科、港科大准博士被指论文抄袭,网友:这是有技巧的“洗稿”
  2. IDEA 快捷键MacOS
  3. JavaScript 进阶(二)变量作用域
  4. 转整型_156.Ruby烘焙大理石豆沙吐司解锁大理石花纹整型
  5. Android设计模式之——备忘录模式
  6. day6-day9代码片段
  7. Python中的Monkey Patch(猴子补丁)
  8. 使用skyeye运行《Linux设备驱动开发详解》的实例(一)
  9. 计算机技术与园林,计算机技术在园林绿化设计中的应用
  10. 知其然,知其所以然 方是学习的最好态度
  11. 《大清重臣李鸿章·上下》—— 读后总结
  12. Python之数据容器
  13. 将中划线转为驼峰式写法
  14. 账龄分析表excel模板_电商数据分析统计模板工作表
  15. 【荷露叮咚网络学苑】人人需具备的基本信息素养视频录制完成
  16. 数字逻辑实验|逻辑函数及其描述工具(Logisim)
  17. sx html5编辑器,SX HTML5全栈可视编辑器
  18. opengl读取obj模型并绘制2.0
  19. 数据质量稽核工具-datacheck
  20. PHP判断一个点在矩形区域什么位置

热门文章

  1. PS基础冷门小技巧,巧用“标尺工具”…
  2. Ueditor编辑器修改字体和字号?
  3. iOS开发月报#3|201809
  4. 文字转语音软件真人发声(声音自然有感情)
  5. 文字转语音真人发声app哪个好用?几个好用的手机文字转语音软件
  6. 简单的Markdown解析器
  7. 那些年,我们一起找过的工作
  8. 构造器模式(Builder模式)
  9. JAVA程序修改PDF内容_java 修改pdf
  10. tesseract 字典下载_qq阅读官方下载-QQ阅读器下载V7.5.0.888官方最新版