如何实现通过Leaflet加载dwg格式的CAD图

本文详细介绍了如何在Leaflet中加载DWG格式的CAD图,包括加载栅格瓦片、选择高亮实体、上传DWG图形、切换图层和主题,以及与其他地图叠加显示。此外,还提供了在线体验示例和相关开源代码链接。
摘要由CSDN通过智能技术生成

🚀 优质资源分享 🚀

学习路线指引(点击解锁) 知识定位 人群定位
🧡 Python实战微信订餐小程序 🧡 进阶级 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
💛Python量化交易实战💛 入门级 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统

前言

​ 在前面介绍了通过openlayers加载dwg格式的CAD图并与互联网地图叠加,openlayers功能很全面,但同时也很庞大,入门比较难,适合于大中型项目中。而在中小型项目中,一般用开源的leaflet比较多, leaflet小而美,插件很多。本文介绍如何用Leaflet来加载DWG格式的CAD图,并在上面做应用开发,如与互联网地图叠加显示等。

Leaflet介绍

Leaflet 是领先的用于移动友好交互式地图的开源 JavaScript 库。仅仅重约 39KB 的 JS,它拥有大多数开发者所需要的所有地图功能。Leaflet 在设计时考虑到了简单性、性能和可用性。它可以在所有主要的桌面和移动平台上高效地工作,可以通过大量的插件进行扩展,拥有一个漂亮的、易于使用的、记录良好的 API,以及一个简单的、可读的源代码。。

Leaflet 官网地址 https://leafletjs.com/

Leaflet 源码地址 [https://github.com/Leaflet/

Leaflet中加载CAD栅格瓦片

在leaflet中加载CAD图,需要建立一个由cad建立的坐标系。可以由L.CRS.Simple来进行扩展,设置好坐标系的范围、分辨率及转换参数即可。

image-20221017192818357



|  | // 地图服务对象,调用唯杰地图服务打开地图,获取地图的元数据 |
|  | let svc = new vjmap.Service(env.serviceUrl, env.accessToken) |
|  | // 打开地图 |
|  | let mapId = "sys\_zp"; |
|  | let res = await svc.openMap({ |
|  | mapid: mapId, // 地图ID |
|  | mapopenway: vjmap.MapOpenWay.GeomRender, // 以几何数据渲染方式打开 |
|  | style: vjmap.openMapDarkStyle() // div为深色背景颜色时,这里也传深色背景样式 |
|  | }) |
|  | if (res.error) { |
|  | // 如果打开出错 |
|  |  message.error(res.error) |
|  | } |
|  | // 获取地图范围 |
|  | let mapBounds = vjmap.GeoBounds.fromString(res.bounds); |
|  |  |
|  | // 建立一个基于CAD图范围的坐标系 |
|  | let CadCRS = L.Class.extend({ |
|  | includes: L.CRS.Simple, |
|  | initialize: function (bounds) { |
|  | // 当前CAD图的范围 |
|  | this.bounds = bounds; |
|  | // 投影 |
|  | this.projection = L.Projection.LonLat; |
|  | // 计算分辨率 |
|  | let r = (256 / Math.abs(this.bounds.getEast() - this.bounds.getWest())); |
|  | // 设置转换参数 一个仿射变换:一组系数a, b, c, d,用于将一个形式为(x, y)的点变换为 (ax + b, cy + d)并做相反的变换 |
|  | this.transformation = new L.Transformation(r, -r * this.bounds.getWest(), - r, r * this.bounds.getNorth()); |
|  |  } |
|  | }); |
|  |  |
|  | // leaflet中坐标是反的,如果要用L.latLng传入坐标的时候要传[y,x],如果要传[x,y],官网建议如下方案 |
|  | // https://leafletjs.com/examples/crs-simple/crs-simple.html |
|  | L.XY = function(x, y) { |
|  | if (L.Util.isArray(x)) { // When doing XY([x, y]); |
|  | return L.latLng(x[1], x[0]); |
|  |  } |
|  | return L.latLng(y, x); // When doing XY(x, y); |
|  | }; |
|  |  |
|  | // 当前CAD地图范围 |
|  | let bounds = new L.LatLngBounds([L.XY(mapBounds.min.toArray()), L.XY(mapBounds.max.toArray())]); |
|  | let center = mapBounds.center(); // 地图中心点 |
|  |  |
|  | // 创建leaflet的地图对象 |
|  | let map = L.map('map', { |
|  | // 坐标系 |
|  | crs: new CadCRS(bounds), |
|  | attributionControl: false |
|  | }).setView(L.XY([center.x, center.y]), 2); // 设置初始中心点和缩放级别 |
|  | // 如果要用L.latLng设置的话,x,y应写反进行设置。如 |
|  | // map.setView(L.latLng([center.y, center.x]), 2); |
|  |  |
|  | // 增加一个栅格瓦片图层 |
|  | let layer = L.tileLayer( |
|  |  svc.rasterTileUrl(), // 唯杰地图服务提供的cad的栅格瓦片服务地址 |
|  |  { |
|  | bounds: bounds // 当前CAD地图范围 |
|  |  } |
|  | ).addTo(map); |
|  | // 把图层增加至地图中 |
|  | layer.addTo(map); |


Leaflet中选择高亮CAD实体

选择高亮的实现思路为:响应地图的点击事件,通过当前位置去后台查询当前的实体的数据。通过返回的geojson数据,在前端用leaflet的geoJSON进行绘制即可。

leafletselectHighlight.gif



|  |  |
|  |  |
|  | let highlightLayer; // 高亮图层 |
|  | const highlight\_ent = async co => { |
|  | if (highlightLayer) { |
|  |  highlightLayer.remove(); // 先删除之前的高亮图层 |
|  |  highlightLayer = null; |
|  |  } |
|  | let res = await svc.pointQueryFeature({ |
|  | x: co[0], |
|  | y: co[1], |
|  | zoom: map.getZoom(), |
|  | fields: "" |
|  |  }, pt => { |
|  | // 查询到的每个点进行坐标处理回调 |
|  | return mapPrj.fromMercator(pt);// 转成cad的坐标 |
|  |  }) |
|  | if (res && res.result && res.result.length > 0) { |
|  | let features = []; |
|  | for (let ent of res.result) { |
|  | if (ent.geom && ent.geom.geometries) { |
|  | let clr = vjmap.entColorToHtmlColor(ent.color); |
|  | for (let g = 0; g < ent.geom.geometries.length; g++) { |
|  |  features.push({ |
|  | type: "Feature", |
|  | properties: { |
|  | objectid
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值