JS加载AGV地图(二)

用网页加载仙工的AGV地图,地图的格式是smap

首先,需要一个加载文件按钮和一个DIV用作画布。

<html>
    <head>
    </head>
    <body>
        <a><input type="file" id="selectFiles" onchange="LoadMap()"  value="加载smap文件" ></a>
        <div id="div" style="border:1px solid #000;"><canvas id="canvas"></canvas></div>

接下来,准备绘图环境:

<script>
	var vShaderSource = 'attribute vec2 a_Position;'+
		'attribute vec2 a_Screen_Size;'+
		'uniform mat4 Pmatrix;'+
		'uniform mat4 Vmatrix;'+
		'uniform mat4 Mmatrix;'+
		'attribute vec3 color;'+//the color of the point
		'varying vec3 vColor;'+
		'void main(void) { '+//pre-built function
			//视图坐标(0~800,0~600)转换为 OPENGL坐标(-1.0,1.0)之间的值
			'vec2 xyposition = (a_Position / a_Screen_Size) * 2.0 - 1.0;'+
			'vec4 position=vec4(xyposition,0.0,1.0);'+
		   'gl_Position = Pmatrix*Vmatrix*Mmatrix*vec4(position);'+
		   'gl_PointSize = 1.0;'+
		   'vColor = color;'+
		'}';

	 var fShaderSource = 'precision mediump float;'+
		'varying vec3 vColor;'+
		'void main(void) {'+
		   'gl_FragColor = vec4(vColor, 1.);'+
		'}';
    let canvas = document.getElementById('canvas');
    canvas.width = window.innerWidth;//当前的宽度
    canvas.height = window.innerHeight;//当前的高度
    let gl = canvas.getContext('webgl');
    //创建顶点着色器
    let vShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vShader,vShaderSource);
    gl.compileShader(vShader);
	
    //创建片元着色器
    let fShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fShader,fShaderSource);
    gl.compileShader(fShader);
	
    //创建一个完整的着色器
    let propgram = gl.createProgram();
    gl.attachShader(propgram,vShader);
    gl.attachShader(propgram,fShader);
    gl.linkProgram(propgram);
    gl.useProgram(propgram);
    let positions =[];//设置一个数据
	let resolution=1;
	let xmin=0;
	let ymin=0;
	let xmax=1;
	let ymax=1;
	let vectexs =[];//设置一个数据
	let x0=0;
	let y0=0;
    //设置缓冲区存放玩家点击的点的坐标
    let buffer = gl.createBuffer();
    //绑定缓冲区
    gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
    //取到我们需要使用的变量
    let a_Position = gl.getAttribLocation(propgram,'a_Position');
    gl.enableVertexAttribArray(a_Position);
    //每次取两个数据
    let size = 2;
    //每个数据的类型是32位浮点型
    let type = gl.FLOAT;
    //不需要归一化数据
    let normalize = false;
    // 每次迭代运行需要移动数据数 * 每个数据所占内存 到下一个数据开始点。
    let stride = 0;
    // 从缓冲起始位置开始读取
    let offset = 0;
    // 将 a_Position 变量获取数据的缓冲区指向当前绑定的 buffer。
    gl.vertexAttribPointer(a_Position, size, type, normalize, stride, offset)

    //片元色器
    let u_Color = gl.getAttribLocation(propgram,'color');
    gl.vertexAttrib3f(u_Color,0.0,0.0,0.0);

    //顶点着色器
    //处理顶点着色器中的变量
    let a_Screen_Size = gl.getAttribLocation(propgram,'a_Screen_Size');//取到屏幕的大小
	//调用绘制上下文对象提供的API: vertexAttrib2f向存储位置进行传值
    gl.vertexAttrib2f(a_Screen_Size,canvas.width,canvas.height);//设置参数
	//获取地址
	var _PM = gl.getUniformLocation(propgram, "Pmatrix");
	var _VM = gl.getUniformLocation(propgram, "Vmatrix");
	var _MM = gl.getUniformLocation(propgram, "Mmatrix");
	//正交投影
	var p_matrix = orth_projection(-1,1,-1,1,1,100);
	//模型举证
	var m_matrix = [ 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 ];
	//视图矩阵
	var v_matrix = [ 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 ];
	//绑定 
	gl.uniformMatrix4fv(_PM, false, p_matrix);
	gl.uniformMatrix4fv(_VM, false, v_matrix);
	gl.uniformMatrix4fv(_MM, false, m_matrix);		 
	//背景色
	gl.clearColor(1,1,1,1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);

这里还需要有按钮触发事件,该有的注释都加了,还不理解百度一下:

function LoadMap() {
		var file = document.getElementById("selectFiles").files[0];
		var name = file.name;//读取选中文件的文件名
		var path = document.getElementById("selectFiles").value;//读取选中文件的路径
		console.log("文件名:"+name+"大小:"+path);
		//获取读取我文件的File对象
		//alert(title:'hello',content:'success');
		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'];
			//resg[0]=0.02;
			var resg=strjson['header']['resolution'];
			var scale=0;
			resolution=resg;
			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;
				resy=resy-ymin;
				//然后按比例缩放到932,641
				var scalex=canvas.width/(xmax-xmin);
				var scaley=canvas.height/(ymax-ymin);
				
				if(scalex>scaley)
				{
					scale=scaley;
				}else
				{
					scale=scalex;
				}
				//其实最好的办法是坐标除以resolution,然后按比例缩放
				resx=resx*scale;
				resy=resy*scale;
				//y轴方向由向下转为向上.
				resy=canvas.height-resy;
				positions.push(resx,resy);
			}
			gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(positions),gl.STATIC_DRAW);
			gl.drawArrays(gl.POINTS, 0,  positions.length);
			
			//画高级点
			var points=[];
			var width=3;
            var height=2;
            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;
                //其实最好的办法是坐标除以resolution,然后按比例缩放
                res_x=res_x*scale;
                res_y=res_y*scale;
                res_y=canvas.height-res_y;
                points.push(res_x-width,res_y-height);
                points.push(res_x+width,res_y-height);
                points.push(res_x+width,res_y-height);
                points.push(res_x+width,res_y+height);
                points.push(res_x+width,res_y+height);
                points.push(res_x-width,res_y+height);
                points.push(res_x-width,res_y+height);
                points.push(res_x-width,res_y-height);
            }
			gl.vertexAttrib3f(u_Color,0.0,0.0,1.0);
			gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(points),gl.STATIC_DRAW);
			gl.drawArrays(gl.LINES, 0,  points.length/2);
			
			//画高级曲线
			var points=[];
			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;
				//其实最好的办法是坐标除以resolution,然后按比例缩放
				res_sx=res_sx*scale;
				res_sy=res_sy*scale;
				res_sy=canvas.height-res_sy;
				res_ex=res_ex*scale;
				res_ey=res_ey*scale;
				res_ey=canvas.height-res_ey;
				
				points.push(res_sx,res_sy);
				points.push(res_ex,res_ey);
			}
			gl.vertexAttrib3f(u_Color,0.0,0.0,1.0);
			gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(points),gl.STATIC_DRAW);
			gl.drawArrays(gl.LINES, 0,  points.length/2);
		}
	}

两个函数,用到了其中一个:

    function orth_projection(Lpos,Rpos,Tpos,Bpos,Znear,Zfar)
	{
		return [2/(Rpos-Lpos),0,0,0,
		0,2/(Tpos-Bpos),0,0,
		0,0,1/(Zfar-Znear),0,
		-(Rpos+Lpos)/(Rpos-Lpos),-(Tpos+Bpos)/(Tpos-Bpos),-Znear/(Zfar-Znear),1];
	}
	function get_projection(angle, a, zMin, zMax) {
		var ang = Math.tan((angle*.5)*Math.PI/180);//angle*.5
		return [
		   1/ang/a, 0 , 0, 0,
		   0, 1/ang, 0, 0,
		   0, 0, -(zMax+zMin)/(zMax-zMin), -1,
		   0, 0, (-2*zMax*zMin)/(zMax-zMin), 0 
		   ];
	 }
</script>
</body>
</html>

好了,把这些放到一个网页文件中,存为html格式的文件,在浏览其中打开,就可以打开smap地图了。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

水滴与鱼

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

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

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

打赏作者

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

抵扣说明:

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

余额充值