Canvas加载AGV地图

前面发表了Javascript加载AGV地图的文章,虽然用的是原生JS,但是绘图用的是WebGL,对于没有WebGL基础的同学来讲是有一定难度的,所以这里特地将webGL对应的代码转成2D画布,大家应用起来会更容易些。

首先还是看下效果图,做了一些简单的修改。增加了曲线的绘制。

代码也是超级简单,一个html文件打包带走。

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>加载地图</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <style type="text/css">
            #canvasbtm{
                position:absolute;
                left:0;
                top:25;
                width:500;
                height:400;
            }
            #canvastop{
                position:absolute;
                left:0;
                top:25;
                width:500;
                height:400;
            }
        </style>
    </head>
    <body>
        <a><input aria-label="Search" type="file" id="selectFiles" onchange="LoadMap()"  value="加载smap文件" /></a>
        <div id="container">
            <div id="btmdiv">
                <canvas id="canvasbtm"></canvas>
            </div>
            <div id="topdiv">
                <canvas id="canvastop"></canvas>
            </div>
        </div>
        <script type="text/javascript">
            //底部画布,用来画点
            const canvasbtm = document.getElementById('canvasbtm');
            const ctxbtm = canvasbtm.getContext('2d');
            let scale = 1; // 初始缩放比例为1
            //画个图形,也可以是LOGO
            ctxbtm.fillStyle = 'blue';
            ctxbtm.fillRect(50, 50, 100, 100);

            //顶部画布,用来画线条
            const canvastop = document.getElementById('canvastop');
            const ctxtop = canvastop.getContext('2d');
            ctxtop.fillStyle = 'blue';
            ctxtop.fillRect(50, 50, 100, 100);
            //临时画布,先在上面画好后再画到正式画布上可以减少闪烁
            const tempcanvas = document.createElement('canvas')
            tempcanvas.width = document.getElementById("canvastop").clientWidth
            tempcanvas.height = document.getElementById("canvastop").clientHeight
            tempcanvas.id = 'tempcanvas'
            let tempctx = tempcanvas.getContext('2d') //画笔

            function LoadMap() {
                var file = document.getElementById("selectFiles").files[0];
                var name = file.name;//读取选中文件的文件名
                var path = document.getElementById("selectFiles").value;//读取选中文件的路径
                console.log("文件名:"+name+"大小:"+path);
                var reader = new FileReader();//这是核心,读取操作就是由它完成.
                reader.readAsText(file,'UTF-8');//读取文件的内容,也可以读取文件的URL
                reader.onload = function (event) {
                    //当读取完成后回调这个函数,然后此时文件的内容存储到了result中,直接操作即可
                    var res=event.target.result;
                    var strjson=JSON.parse(res);
                    //将地图缩放到最大比例
                    xmin=strjson['header']['minPos']['x'];
                    ymin=strjson['header']['minPos']['y'];
        
                    xmax=strjson['header']['maxPos']['x'];
                    ymax=strjson['header']['maxPos']['y'];
                    var resg=strjson['header']['resolution'];
                    //地图缩放到最大时画布的尺寸
                    var w_map=(xmax-xmin)/resg;
                    var h_map=(ymax-ymin)/resg;
                    console.log("width+height:"+w_map+"/"+h_map);

                    canvastop.width=canvasbtm.width=tempcanvas.width=w_map;
                    canvastop.height=canvasbtm.height=tempcanvas.height=h_map;

                    //画点
                    for(var m=0;m<strjson['normalPosList'].length;m++)
                    {
                        //解析出的x,y值
                        var resx=strjson['normalPosList'][m]['x'];
                        var resy=strjson['normalPosList'][m]['y'];
                        //最小值移动到0,0
                        resx=(resx-xmin)/resg;
                        resy=(resy-ymin)/resg;
                        //y轴方向由向下转为向上.
                        resy=tempcanvas.height-resy;

                        tempctx.fillStyle="rgba(0, 0, 0, 1)";
                        tempctx.fillRect(Math.round(resx), Math.round(resy),1,1);
                    }
                    ctxbtm.clearRect(0,0, canvasbtm.width, canvasbtm.height);
                    ctxbtm.drawImage(tempcanvas,0,0);
                    tempctx.clearRect(0,0, tempcanvas.width, tempcanvas.height);

                    function drawDashedCircle(ctx, x, y, radius, dashArray) {
                        ctx.beginPath();
                        tempctx.strokeStyle = "rgba(50, 205, 50, 0.4)";
                        ctx.arc(x, y, radius, 0, 2 * Math.PI);
                        ctx.setLineDash(dashArray);
                        ctx.stroke();
                    }

                    //画实线
                    tempctx.strokeStyle = "rgba(169, 169, 169, 0.4)";
                    tempctx.lineWidth = 5;
                    const lineArray = [5, 0];
                    for(var m=0;m<strjson['advancedCurveList'].length;m++)
                    {
                        //最小值移动到0,0
                        var res_sx=strjson['advancedCurveList'][m]['startPos']['pos']['x']-xmin;
                        var res_sy=strjson['advancedCurveList'][m]['startPos']['pos']['y']-ymin;
                        var res_ex=strjson['advancedCurveList'][m]['endPos']['pos']['x']-xmin;
                        var res_ey=strjson['advancedCurveList'][m]['endPos']['pos']['y']-ymin;
						var ctl1_x,ctl1_y,ctl2_x,ctl2_y
						if(strjson['advancedCurveList'][m].hasOwnProperty('controlPos1') && strjson['advancedCurveList'][m]['controlPos1'].hasOwnProperty('x'))
						{
							ctl1_x=strjson['advancedCurveList'][m]['controlPos1']['x']-xmin;
							ctl1_y=strjson['advancedCurveList'][m]['controlPos1']['y']-ymin;
							ctl2_x=strjson['advancedCurveList'][m]['controlPos2']['x']-xmin;
							ctl2_y=strjson['advancedCurveList'][m]['controlPos2']['y']-ymin;
							res_sx=res_sx/resg;
							res_sy=res_sy/resg;
							res_sy=canvastop.height-res_sy;
							res_ex=res_ex/resg;
							res_ey=res_ey/resg;
							res_ey=canvastop.height-res_ey;
							ctl1_x=ctl1_x/resg;
							ctl1_y=ctl1_y/resg;
							ctl1_y=canvastop.height-ctl1_y;
							ctl2_x=ctl2_x/resg;
							ctl2_y=ctl2_y/resg;
							ctl2_y=canvastop.height-ctl2_y;
							// 开始绘制路径
							tempctx.beginPath();
							// 移动到起点
							tempctx.moveTo(Math.round(res_sx), Math.round(res_sy));
							// 画一条线到终点,第一第二个点是控制点,第三个点是终点
							tempctx.bezierCurveTo(Math.round(ctl1_x), Math.round(ctl1_y), Math.round(ctl2_x), Math.round(ctl2_y), Math.round(res_ex), Math.round(res_ey));
							tempctx.setLineDash(lineArray);
							// 绘制线条
							tempctx.stroke();
						}
						else
						{
							res_sx=res_sx/resg;
							res_sy=res_sy/resg;
							res_sy=canvastop.height-res_sy;
							res_ex=res_ex/resg;
							res_ey=res_ey/resg;
							res_ey=canvastop.height-res_ey;
							// 开始绘制路径
							tempctx.beginPath();
							// 移动到起点
							tempctx.moveTo(Math.round(res_sx), Math.round(res_sy));
							tempctx.lineTo(Math.round(res_ex), Math.round(res_ey));
							tempctx.setLineDash(lineArray);
							// 绘制线条
							tempctx.stroke();
						}
                        
                    }

                    const radius = 25;
                    tempctx.lineWidth = 1;
                    const dashArray = [3, 2];
                    //画虚线圆,写字
                    var counter=10000;
                    for(var m=0;m<strjson['advancedPointList'].length;m++)
                    {
                        //最小值移动到0,0
                        var res_x=strjson['advancedPointList'][m]['pos']['x']-xmin;
                        var res_y=strjson['advancedPointList'][m]['pos']['y']-ymin;

                        res_x=res_x/resg;
                        res_y=res_y/resg;
                        res_y=canvastop.height-res_y;
                        tempctx.fillStyle="rgba(225, 255, 255, 0.4)";
                        drawDashedCircle(tempctx, Math.round(res_x), Math.round(res_y), radius, dashArray);
                        //tempctx.fillRect(Math.round(res_x)-30, Math.round(res_y)-12,60,24);
                        console.log("x+y:"+res_x+"/"+res_y);
                        //写字
                        // 设置字体样式
                        tempctx.font = '12px Arial';
                        // 设置字体颜色
                        tempctx.fillStyle = '#FF0000';
                        // 写字
                        counter=counter+m;
                        tempctx.fillText("AP"+String(counter), Math.round(res_x)-23, Math.round(res_y)+6);
                    }

                    
                    ctxtop.clearRect(0,0, canvastop.width, canvastop.height);
                    ctxtop.drawImage(tempcanvas,0,0);
                    tempctx.clearRect(0,0, tempcanvas.width, tempcanvas.height);
                }
            }
            
        </script>
    </body>
</html>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水滴与鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值