CAD图在线Web测量工具代码实现(测量距离、面积、角度等)

本文介绍了一个Web在线打开和测量CAD图形的方法,包括距离、面积、角度和坐标的测量。通过使用特定的测量循环和上下文菜单功能,用户可以精确捕捉坐标,并在测量完成后删除测量结果。代码实现基于vjmap库,提供了测量各种参数的详细步骤和功能,如正交模式、捕捉开关等。

CAD如今在各个领域均得到了普遍的应用并大大提高了工程技术人员的工作效率。在桌面端,AutoCAD测量工具已经非常强大;然后在Web端,如何准确、快速的对CAD图在Web进行测量呢?

功能

  • 能Web在线打开AutoCAD图形

  • 测量距离

  • 测量面积

  • 测量角度

  • 坐标标注

  • 测量时能捕捉Web端CAD图形上面的坐标,提高准确度

  • 测量时能对捕捉进行开关启用

  • 测量时能启用正交模式

  • 测量时能自定义右键菜单功能

  • 能进行连续测量

  • 测量结束后,能删除已测量的结果

效果

能Web在线打开AutoCAD图形

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

测量距离

测量面积

测量角度

坐标标注

其他功能

在测量过程中,按Alt键可开启关闭捕捉;按Ctrl键可启用正交模式;按退格键可删除上一个点;按ESC键取消测量;按Enter键结束测量; 按右键弹出上下文菜单

代码实现

有需要的朋友可以在线体验下。上面的案例代码已开源。访问 (唯杰地图云端图纸管理平台 唯杰地图云端图纸管理平台) ,点击下载此案例源码即可。

import vjmap, { Map } from 'vjmap'
import { sleep } from '~/utils/ui';
import { getMapSnapPoints } from './snap';
let snapObj: any; // 设置的捕捉的实体
let curMeasureCmd: string; // 当前测量命令
export async function runMeasureCmd(map: Map, cmd: string) {
  curMeasureCmd = cmd;
  if (cmd != "measureCancel") {
    // 先结束当前测量
    await measureCancel(map);
    if (!snapObj) {
        // 获取地图上的捕捉点
        snapObj = {};
        getMapSnapPoints(map, snapObj);
    }
  }
  switch (cmd) {
    case "measureDist":
      measureDistLoop(map, snapObj);
      break;
    case "measureArea":
      measureAreaLoop(map, snapObj);
      break;
    case "measureAngle":
      measureAngleLoop(map, snapObj);
      break;
    case "measureCoordinate":
      measureCoordinateLoop(map, snapObj);
      break;
    case "measureCancel":
      await measureCancel(map);
      break;
  }
}
​
// 结束绘制
const measureCancel = async (map: Map)=> {
    // 连续发送取消键,第一次取消当前绘制,第二次退出测量
    map.fire("keyup", {keyCode:27});
    await sleep(100);
    map.fire("keyup", {keyCode:27});
    await sleep(100);
    map.setIsInteracting(false); // 没有进行交互操作了
}
​
let popup: vjmap.Popup | null;
const setPopupText = (text: string, map: Map) => {
    if (text) {
        if (!popup) {
            popup = new vjmap.Popup({
                className: "my-custom-popup",
                closeOnClick: false,
                closeButton: false
            })
                .setHTML(text)
                .setMaxWidth("500px")
                .trackPointer()
                .addTo(map)
        }
        else {
            popup.setHTML(text);
        }
    } else {
        // 如果为空时,则删除popup
        if (popup) {
            popup.setLngLat([0,0]); // 取消trackPointer
            popup.remove();
            popup = null;
        }
    }
​
}
// 测量距离循环,直至按ESC键取消,否则测量完一条后,继续测量下一条
const measureDistLoop = async (map: Map, snapObj: any)=> {
    while(true) {
        let res = await measureDist(map, snapObj);
        if (res.exit === true) break;
        if (curMeasureCmd != "measureDist") break;
    }
}
​
// 测量距离
const measureDist = async (map: Map, snapObj: any)=> {
    let isDrawing = false;
    let line = await vjmap.Draw.actionDrawLineSting(map, {
        api: {
            getSnapFeatures: snapObj //要捕捉的数据项在后面,通过属性features赋值
        },
        updatecoordinate: (e: any) => {
            if (!e.lnglat) return;
            isDrawing = true;
            const co = map.fromLngLat(e.feature.coordinates[e.feature.coordinates.length - 1]);
            let html = `【测量距离】当前坐标:<span style="color: #ff0000"> ${co.x.toFixed(2)}, ${co.y.toFixed(2)}</span>`;
            if (e.feature.coordinates.length == 1) {
                html += "<br/>请指定要测量的第一点的坐标位置"
            } else {
                let len = e.feature.coordinates.length;
                html += `<br/>按Alt键取捕捉; Ctrl键启用正交; 退格键删除上一个点`
                html += `<br/>距上一点距离: <span style="color: #ff0000">${getDist(map, [e.feature.coordinates[len - 2], e.feature.coordinates[len -1]])}</span>`
                html += `;  当前总的距离: <span style="color: #ff0000">${getDist(map, e.feature.coordinates)}</span>`
            }
            setPopupText(html, map)
        },
        contextMenu: (e: any) => {
            new vjmap.ContextMenu({
                event: e.event.originalEvent,
                theme: "dark", //light
                width: "250px",
                items: [
                    {
                        label: '确认',
                        onClick: () => {
                            // 给地图发送Enter键消息即可取消,模拟按Enter键
                            map.fire("keyup", {keyCode:13})
                            setPopupText("", map);
                        }
                    },
                    {
                        label: '取消',
                        onClick: () => {
                            // 给地图发送ESC键消息即可取消,模拟按ESC键
                            map.fire("keyup", {keyCode:27})
                            setPopupText("", map);
                        }
                    },{
                  
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值