HarmonyOS鸿蒙Next中WEB CAD与Mapbox结合实现在线地图CAD编辑(JS实现预览DWG)

HarmonyOS鸿蒙Next中WEB CAD与Mapbox结合实现在线地图CAD编辑(JS实现预览DWG)

一、项目概述

MxCAD与Mapbox结合项目是一个创新性的解决方案,将在线 CAD 编辑功能与地图服务无缝集成,该项目通过自定义的Mapbox版本支持中国国家大地坐标系(CGCS2000),并结合 MxCAD 强大的在线CAD编辑能力,实现了在地图上直接加载、编辑和管理 CAD 图纸的功能。

图片

核心技术栈包括:

  • 修改版 Mapbox GL JS(支持 CGCS2000)
  • MxCAD 在线 CAD 编辑引擎
  • WebAssembly 技术
  • TypeScript/JavaScript

二、Mapbox修改版支持CGCS2000坐标系

2.1、CGCS2000坐标系介绍

CGCS2000(China Geodetic Coordinate System 2000)是中国国家大地坐标系,是中国测绘基准的重要组成部分,用于替代原有的北京 54 坐标系和西安 80 坐标系。在国内 GIS 应用中,支持 CGCS2000 是必不可少的功能。

2.2、基于@cgcs2000/mapbox-gl的坐标系扩展

项目使用了自定义的[@cgcs2000](/user/cgcs2000)/mapbox-gl包,这是对标准 Mapbox GL JS 的扩展,主要增加了对 CGCS2000 坐标系的支持。在代码中的引用方式:

import {
  type AnyLayer,
  Map as _Map,
  type AnySourceData,
  LngLat,
  Point,
} from "[@cgcs2000](/user/cgcs2000)/mapbox-gl";
import mapboxgl from "[@cgcs2000](/user/cgcs2000)/mapbox-gl";

我们对修改后的 js 进行了处理,使其支持 CGCS2000 坐标系和 mxcad 的交互。

2.3、坐标转换与投影实现

在使用时我们依然要扩展了 Map 类,扩展的方法都是必须的,用于配合 mxcad 实现坐标的转换和交互:

// 扩展重写Map类
export class Map extends _Map {
  public dom_mousePos(event: any) {
    return this.dom_mousePos_imp(this.getCanvasContainer(), event);
  }
  public lnglat_to_mercator(lng: any, lat: any): any {
    let pt = mapboxgl.MercatorCoordinate.fromLngLat([lng, lat], 0);
    return pt;
  }
  public mercator_to_lnglat(x: number, y: number, z: number): any {
    let mecatorcoord = new mapboxgl.MercatorCoordinate(x, y, z);
    return mecatorcoord.toLngLat();
  }
  public mercatorCoordinate_from_LngLat(
    lngLat: number[],
    modelAltitude: number
  ): any {
    return mapboxgl.MercatorCoordinate.fromLngLat(lngLat as any, modelAltitude);
  }
  protected getScaledPoint(
    el: HTMLElement,
    rect: ClientRect,
    e: MouseEvent | WheelEvent | Touch
  ) {
    const scaling =
      el.offsetWidth === rect.width ? 1 : el.offsetWidth / rect.width;
    return new Point(
      (e.clientX - rect.left) * scaling,
      (e.clientY - rect.top) * scaling
    );
  }
  protected dom_mousePos_imp(el: HTMLElement, e: MouseEvent | WheelEvent) {
    const rect = el.getBoundingClientRect();
    return this.getScaledPoint(el, rect, e);
  }
}

三、MxCAD 与 Mapbox 的结合实践

3.1、MxCAD 在线 CAD 编辑引擎与 Mapbox 集成

MxCAD 是一个功能强大的在线 CAD 编辑引擎,通过 WebAssembly 技术实现了高性能的 CAD 渲染和编辑功能。在项目中,我们将 MxCAD 与 Mapbox 无缝集成,实现了在地图上直接操作 CAD 图纸的能力,关键集成代码:

import { MxMap } from "mxcad";
let mx_map = new MxMap();
// 设置坐标点对齐,将CAD坐标系与地图坐标系对齐
//  图纸中的中心在地址上的位置,单位经纬度
let mapOrigin = [116.42787, 39.93232];
// 小=右,大=下
//  CAD图纸中的中心中,CAD图纸单位
let cadOrigin = [506411.1543, 307348.2786];
// 1 CAD单位与米的比例 这里 1 cad单位是1m
let meterInCADUnits = 1;
mx_map.setCoordinatePointAlignment(mapOrigin, cadOrigin, meterInCADUnits);
const style = {
  version: 8,
  sources: {
    tianditu: {
      type: "raster",
      tiles: [
        "http://t0.tianditu.gov.cn/img_c/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=c&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=天地图的密钥",
      ],
      tileSize: 256,
      maxzoom: 18,
    },
  },
  layers: [
    {
      id: "tianditu-layer",
      type: "raster",
      source: "tianditu",
      minzoom: 0,
      maxzoom: 18,
    }
  ],
};
let map = new Map({
  // Mapbox GL JS 进行地图渲染的 HTML 元素,或该元素的字符串 id 。该指定元素不能有子元素。
  container: "map",
  // crs: 'EGSP:4490',
  // 地图最小缩放级别(0-24)。
  minZoom: 0,
  // 地图最大缩放级别(0-24)。
  maxZoom: 24,
  // 地图初始化时的地理中心点
  center: mapOrigin,
  // 地图初始化时的层级
  zoom: 16,
  // 地图的 Mapbox 配置样式
  style: style,
});
// 你需要打开的图纸
 let cadFile = new URL("../../public/demo/line3.dwg.mxweb", import.meta.url).href;
// 在地图加载完成后初始化MxCAD
map.on("style.load", async function () {
  // 设置canvas ID
  map.getCanvas().id = "myCanvas";
  // 创建MxCAD实例
  mx_map.create(map, {
    locateFile: (fileName: string) => {
      return new URL(
        `../../node_modules/mxcad/dist/wasm/${mode}/${fileName}`,
        import.meta.url
      ).href;
    },
    fileUrl: cadFile,
    middlePan: true,
    viewBackgroundColor: load_local_title
      ? { red: 0, green: 0, blue: 0 }
      : { red: 255, green: 255, blue: 255 },
  });
});

3.2、坐标系统对齐实现

坐标系统对齐是 MxCAD 与 Mapbox 结合的核心。我们通过setCoordinatePointAlignment方法将 CAD 坐标系与地图坐标系进行对齐:

// 图纸中的中心在地址上的位置,单位经纬度
let mapOrigin = [116.42787, 39.93232];
// CAD图纸中的中心中,CAD图纸单位
let cadOrigin = [506411.1543, 307348.2786];
// CAD单位与米的比例
let meterInCADUnits = 1;
// 设置坐标点对齐
mx_map.setCoordinatePointAlignment(mapOrigin, cadOrigin, meterInCADUnits);

这样设置后,当用户在地图上点击时,可以获取对应的 CAD 坐标:

map.on("click", async function (e) {
  let { lng, lat } = e.lngLat;
  // 获取墨卡托坐标
  let pt = mapboxgl.MercatorCoordinate.fromLngLat([lng, lat], 0);
  // 转换为CAD坐标
  let ptCAD = mx_map.mercatorCoord2CAD(pt.x, pt.y);
  console.log("CAD坐标:", JSON.stringify(ptCAD));
});

四、天地图 CGCS2000 加载实现

4.1、天地图服务介绍

天地图是中国国家测绘地理信息局主办的国家地理信息公共服务平台,提供了基于 CGCS2000 坐标系的地图服务。在本项目中,我们集成了天地图作为底图服务。

4.2、天地图key 申请流程

  1. 访问天地图开发者平台
  2. 注册并登录开发者账号
  3. 选择地图API
  4. 申请key
  5. 在"控制台"页面选择"创建应用"
  6. 填写应用名称、应用类型等信息
  7. 提交后获取应用 key
  8. 使用获取的 key 替换代码中的 tk 参数

图片

4.3、天地图 CGCS2000 图层配置

在项目中,我们通过以下方式配置天地图图层:

const style = {
  version: 8,
  sources: {
    tianditu: {
      type: "raster",
      tiles: [
        "http://t0.tianditu.gov.cn/img_c/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=c&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=",
      ],
      tileSize: 256,
      maxzoom: 18,
    },
  },
  layers: [
    {
      id: "tianditu-layer",
      type: "raster",
      source: "tianditu",
      minzoom: 0,
      maxzoom: 18,
    }
  ]
} as mapboxgl.Style;

注意:在实际使用时,需要将上述代码中的tk=后面添加您申请的天地图key。

天地图提供了多种图层类型,常用的包括:

  • img_c: 影像底图
  • vec_c: 矢量底图
  • cva_c: 矢量注记
  • cia_c: 影像注记

可以根据需求选择不同的图层类型。

MxCAD与Mapbox的结合为CAD图纸的在线编辑与地理位置关联提供了强大的解决方案。通过支持 CGCS2000坐标系和集成天地图服务,该项目特别适合中国国内的GIS应用开发。项目的核心功能包括坐标系转换、CAD图纸在地图上的精确定位与编辑、图层管理等,为城市规划、管网管理、不动产管理等领域提供了有力的技术支持。

4.4、集成mxcad 在线CAD项目地图模式

刚刚我们介绍了从0到1的MxCAD与Mapbox结合实现,但是所有CAD的功能都要从头开发, 所以我们提供了在线CAD项目集成方案, 同时可以启动地图模式, 简单开发一个扩展插件轻松集成 MxCAD 与 Mapbox 结合实现在线地图 CAD 编辑系统。

开发前我们一定要下载[MxDraw云图开发包],然后解压可以看到一个exe程序点击运行点击“打开MxCAD代码开发目录” 就可以看到dist目录了。

扩展插件开发

通过开发一个简单的插件,我们可以快速集成MxCAD与Mapbox。以下是一个基本的插件代码示例:

import { MxCADPluginBase, MxCADUI, MxMap } from "mxcad";
import { MxFun } from "mxdraw";
import * as mapboxgl from "mapbox-gl";
import { Map } from "mapbox-gl";
class MxCADPlugin extends MxCADPluginBase {
    constructor() {
        super()
        this.map_default_data = {
            /**  地图与CAD图纸的对齐位置 */
            mapOrigin: [116.42787, 39.93232],
            /** CAD图纸与地图的对齐点 */
            cadOrigin: [506411.1543, 307348.2786],
            meterInCADUnits: 1,
            /** mapbox地图token */
            mapbox_accessToken: '',
            /** 需要打开的cad图纸 */
            openFile: new URL("../demo/line3.dwg.mxweb", import.meta.url).href,
            /** 栅格瓦片图层列表 */
            rasterTileLayerList: []
        }
    }
}
let mxcadui;
// cad应用加载开始
MxFun.on("mxcadApplicationStart", (mxcaduiimp) => {
    mxcadui = mxcaduiimp;
    mxcadui.init(new MxCADPlugin());
});
let mx_map;
let map;
// 初始化gis
MxFun.on("mxcadApplicationInitMap", () => {
    mx_map = mxcadui.mxmap;
    map = mx_map.getMapbox()
    map.getCanvas().id = "mxcad"
    // 可以在这里设置地图样式
    // map.setStyle({
    //     version: 8,
    //     sources: {
    //         tianditu: {
    //             type: 'raster',
    //             tiles: [
    //                 'http://t0.tianditu.gov.cn/img_c/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=c&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=密钥'
    //             ],
    //             tileSize: 256,
    //             maxzoom: 18
    //         }
    //     },
    //     layers: [
    //         {
    //             id: 'tianditu-layer',
    //             type: 'raster',
    //             source: 'tianditu',
    //             minzoom: 0,
    //             maxzoom: 18
    //         }
    //     ]
    // })
    map.on("click", async function (e) {
        let { lng, lat } = e.lngLat;
        let pt = mapboxgl.MercatorCoordinate.fromLngLat(
            [lng, lat],
            0
        );
        console.log("经纬度坐标:", JSON.stringify([lng, lat]));
        let ptCAD = mx_map.mercatorCoord2CAD(pt.x, pt.y);
        console.log("CAD坐标:", JSON.stringify(ptCAD))
    });
});

插件部署与配置

  1. 插件文件结构 将上述JavaScript代码保存为一个index.js文件,放置在dist/plugins/mapPlugin/目录下(目录名可自定义)。
  2. 配置config.json 在dist/plugins/config.json文件中添加插件配置:
   {
     "plugins": [
       "loginPlugin",
       {"name": "pluginCodeEdit", "isAfterLoad": true, "dir": true, "version": "1.0.0"},
       {"name": "pluginIdentifyPattern", "isAfterLoad": true, "dir": true, "version": "1.0.0"},
       {"name": "pluginBaseTemplate", "isAfterLoad": false, "dir": true, "version": "1.0.0"},
       {"name": "mapPlugin", "isAfterLoad": false, "dir": true, "version": "1.0.0"}
     ]
   }

注意:

  • 插件名称应与目录名一致
  • isAfterLoad表示是否在主应用加载完成后再加载插件
  • dir设置为true表示插件在独立目录中

启动地图模式

访问应用时,在URL后添加?map=true参数即可启动地图模式,例如:

your-domain.com/mxcad/?map=true

集成到现有项目

您可以通过以下方式将MxCAD地图模式集成到现有项目中:

  1. 使用iframe嵌入
   <iframe src="http://your-domain.com/mxcad/?map=true" width="100%" height="600px"></iframe>
  1. 页面通信 通过postMessage实现父页面与iframe中的MxCAD应用通信:
   // 父页面发送消息
   const mxcadFrame = document.getElementById('mxcad-frame');
   mxcadFrame.contentWindow.postMessage({
     type: 'COMMAND',
     command: 'ZOOM_TO',
     data: { center: [116.42787, 39.93232], zoom: 16 }
   }, '*');
   // 在MxCAD插件中接收消息
   window.addEventListener('message', (event) => {
     if (event.data.type === 'COMMAND') {
       // 处理来自父页面的命令
       handleCommand(event.data);
     }
   });
   function handleCommand(data) {
     if (data.command === 'ZOOM_TO' && map) {
       map.flyTo({
         center: data.data.center,
         zoom: data.data.zoom,
         essential: true
       });
     }
   }

通过这种方式,您可以在自己的项目中轻松集成MxCAD与Mapbox结合的在线地图CAD编辑系统,同时保留对地图和CAD操作的完全控制能力,同时集成了mxcad在线CAD项目的各种功能。

4.5、坐标系统选择注意事项

在集成MxCAD与Mapbox时,坐标系统的选择非常重要:

  1. CGCS2000与WGS84的区别

    • 本项目中采用的是CGCS2000坐标系
    • 默认的Mapbox使用的是WGS84坐标系
    • 两种坐标系在中国区域的偏差约为几米到几十米不等
  2. 坐标系选择建议

    • 如果您的项目需要精确对应中国国内地理位置,建议使用修改版的Mapbox CGCS2000
    • 使用CGCS2000时,所有经纬度输入和输出都是CGCS2000坐标系下的值

更多关于HarmonyOS鸿蒙Next中WEB CAD与Mapbox结合实现在线地图CAD编辑(JS实现预览DWG)的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

关注

更多关于HarmonyOS鸿蒙Next中WEB CAD与Mapbox结合实现在线地图CAD编辑(JS实现预览DWG)的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


鸿蒙Next中可通过ArkTS调用Web组件加载Web CAD SDK,结合Mapbox GL JS实现地图渲染。使用JS Bridge进行ArkTS与WebView通信,传递DWG解析数据至前端。Web端利用JavaScript解析DWG二进制流,转换为GeoJSON格式叠加到Mapbox矢量图层。通过Canvas 2D或WebGL实现CAD图形绘制与交互编辑功能。

这是一个非常专业且完整的HarmonyOS Next Web项目技术分享,展示了将MxCAD在线CAD编辑引擎与Mapbox地图服务深度集成的优秀实践。以下是对您技术实现的几点专业评价:

1. 坐标系处理的专业性 您采用@cgcs2000/mapbox-gl扩展包支持CGCS2000坐标系,这在国内GIS应用中至关重要。通过扩展Map类实现lnglat_to_mercatormercator_to_lnglat等方法,建立了完整的坐标转换链条,确保了CAD图纸与地理坐标的精确对应。

2. 集成架构的合理性

  • 核心对齐机制setCoordinatePointAlignment方法通过定义mapOrigin(经纬度)、cadOrigin(CAD单位)和meterInCADUnits(比例因子),实现了两个坐标系的空间配准。
  • 渲染层集成:将Mapbox的Canvas直接作为MxCAD的渲染容器,避免了图层叠加的视觉冲突,保证了交互事件的一致性。

3. 技术栈选型的先进性

  • WebAssembly应用:MxCAD基于WebAssembly实现高性能CAD渲染,在HarmonyOS Next的Web环境中能充分发挥性能优势。
  • TypeScript类型安全:完整的类型定义提升了代码可维护性。
  • 插件化架构:通过MxCADPluginBase实现的插件系统,使地图功能模块化,便于功能扩展和维护。

4. 实际部署的实用性

  • 天地图集成:使用国内可访问的天地图服务,避免了Mapbox海外服务的访问限制。
  • 配置灵活性:支持通过URL参数?map=true快速切换地图模式,便于不同场景的使用。
  • 通信机制:提供postMessage跨域通信方案,支持嵌入第三方系统。

5. HarmonyOS Next适配考量 虽然您展示的是Web技术实现,但完全兼容HarmonyOS Next的WebView环境。需要注意的是:

  • 确保使用的WebAssembly模块支持HarmonyOS Next的ARM架构
  • 地图服务的网络请求需符合HarmonyOS的网络权限配置
  • 触控交互需适配HarmonyOS的触摸事件机制

技术亮点总结

  1. 解决了国内GIS项目必需的CGCS2000坐标系支持
  2. 实现了CAD工程图纸与地理信息系统的无缝融合
  3. 提供了从零集成到插件化部署的完整路径
  4. 性能优化良好,通过WebAssembly保障了CAD渲染效率

这个方案为城市规划、基础设施管理、不动产登记等领域的HarmonyOS Next应用开发提供了成熟的技术基础,特别是在需要将专业CAD数据与地理空间信息结合的场景中具有显著优势。

回到顶部