如题,请教下解决思路。
闭关修行中......
我自己实现了一下,可以自己在百度地图上随便画图形,基本原理就是,监听touch事件,touchMove,保存当前的经纬度,转化为pixel坐标,重复绘制线段,当touchEnd时,绘制矩形图形。最后会连接首位2点,并判断矩形是否有效,同时如果在画得过程中已经有闭合图形,则终止画图。
演示地址,需要使用手机浏览测试: JS 实现代码:
var app = app || {}; app.BM = { map: false, init: function() { // 百度地图API功能 this.map = new BMap.Map("allmap"); // 创建Map实例 this.map.centerAndZoom(new BMap.Point(116.404, 39.915), 11); // 初始化地图,设置中心点坐标和地图级别 this.map.addControl(new BMap.MapTypeControl()); //添加地图类型控件 this.map.setCurrentCity("北京"); // 设置地图显示的城市 此项是必须设置的 this.map.enableScrollWheelZoom(); //开启鼠标滚轮缩放 this.map.enableDragging(); } }; // 电子围栏 // @todo 数据交互部分 app.Fence = { cache_points: [], // 缓存折线数据,取消操作时,重新画图。 polyline:false, // 百度折线覆盖物 points: [], // 折线数据 [H,H,H,...] H{lat:"",lng:""} coordinate: [], // 像素数据 [P,P,...] P{x:"",y:""} cur_point: false, cur_pixel: false, isOver: false, // 围栏是否已经完成 cross_at: false, // 相交的点索引 state: 0, // 界面状态 0 待设定状态, 1 开始设定, 2 设定完成 polygon: false, // 完成后的栏栅覆盖物 polylineOption: {strokeColor:"blue", strokeWeight:4, strokeOpacity:0.5}, init: function() { app.BM.init(); this.initClickEvent(); }, initClickEvent: function() { // 设定或取消 document.getElementById('action').addEventListener('click', this.clickSettingHandler, false); // 确定或重新设定事件监听 document.getElementById('setok').addEventListener('click', this.setOKHandler, false); document.getElementById('reset').addEventListener('click', this.resetHandler, false); }, clickSettingHandler: function(){ if (app.Fence.state == 0) { app.Fence.initTouchEvent(); if (app.Fence.polygon){ app.BM.map.removeOverlay(app.Fence.polygon); } app.Fence.resetData(); app.Fence.state = 1; app.Fence.setElementHidden('fence_show'); app.Fence.setElementDisplay('fence_begin_draw'); document.getElementById('action').innerHTML = "取消"; } else { app.Fence.removeTouchEvent(); if (app.Fence.polyline) { app.BM.map.removeOverlay(app.Fence.polyline); } app.Fence.resetData(); app.Fence.state = 0; if (app.Fence.cache_points) { app.Fence.polygon = new BMap.Polygon(app.Fence.cache_points, app.Fence.polylineOption); app.BM.map.addOverlay(app.Fence.polygon); } app.Fence.setElementDisplay('fence_show'); app.Fence.setElementHidden('fence_begin_draw'); document.getElementById('action').innerHTML = "设定"; } }, finishDrawing: function(){ app.Fence.state = 2; // 画图完成后立即清除移动 app.Fence.removeTouchEvent(); app.Fence.setElementHidden('fence_begin_draw'); app.Fence.setElementDisplay('fence_end_draw'); }, drawPolygon: function(){ app.BM.map.removeOverlay(app.Fence.polyline); app.Fence.polygon = new BMap.Polygon(app.Fence.points, app.Fence.polylineOption); app.BM.map.addOverlay(app.Fence.polygon); }, removeClickEvent: function(){ document.getElementById('setok').removeEventListener('click', app.Fence.setOKHandler, false); document.getElementById('reset').removeEventListener('click', app.Fence.resetHandler, false); }, setOKHandler: function(){ app.Fence.state = 0; // 最后画一个多边形polygon app.Fence.drawPolygon(); app.Fence.setElementDisplay('fence_show'); app.Fence.setElementHidden('fence_end_draw'); document.getElementById('action').innerHTML = "设定"; document.getElementById('setting_state').innerHTML = "电子栏栅设定成功"; // 缓存数据 app.Fence.cache_points = app.Fence.points; // @todo 同步数据到服务器 }, // 不满意,重新画图 resetHandler: function(){ app.Fence.state = 1; app.BM.map.removeOverlay(app.Fence.polyline); app.Fence.resetData(); app.Fence.initTouchEvent(); app.Fence.setElementHidden('fence_end_draw'); app.Fence.setElementDisplay('fence_begin_draw'); }, // 触摸事件 @important 开始画图时init 画完图后remove initTouchEvent: function(){ app.BM.map.addEventListener("touchstart", app.Fence.touchStartHandler, false); app.BM.map.addEventListener("touchend", app.Fence.touchEndHandler, false); app.BM.map.addEventListener("touchmove", app.Fence.touchMoveHandler, false); }, removeTouchEvent: function(){ app.BM.map.removeEventListener("touchstart", app.Fence.touchStartHandler, false); app.BM.map.removeEventListener("touchend", app.Fence.touchEndHandler, false); app.BM.map.removeEventListener("touchmove", app.Fence.touchMoveHandler, false); }, touchStartHandler: function(){ app.BM.map.disableDragging(); app.Bm.map.disableScrollWheelZoom(); }, touchEndHandler: function(){ // 正确的画完图形 if (app.Fence.isOver){ app.Fence.finishDrawing(); } else { if (!app.Fence.finalCheckIsCrossed()) { var last = app.Fence.points.length - 1; app.Fence.polyline = new BMap.Polyline([app.Fence.points[0], app.Fence.points[last]], app.Fence.polylineOption); //创建多边形 app.BM.map.addOverlay(app.Fence.polyline); app.Fence.finishDrawing(); } else { alert("电子栏栅设定错误,请重新设定!"); app.BM.map.removeOverlay(app.Fence.polyline); app.Fence.resetData(); app.Fence.state = 1; app.Fence.setElementHidden('fence_end_draw'); app.Fence.setElementDisplay('fence_begin_draw'); } } app.BM.map.enableDragging(); app.BM.map.enableScrollWheelZoom(); }, touchMoveHandler: function(e){ app.Fence.cur_point = e.point; app.Fence.cur_pixel = e.pixel; app.Fence.points.push(e.point); app.Fence.coordinate.push(e.pixel); if (app.Fence.checkIsCrossed()) { app.Fence.redrawPolyline(); app.Fence.isOver = true; } else { if (!app.Fence.isOver) app.Fence.redraw(); } }, checkIsCrossed: function(){ var last = app.Fence.coordinate.length - 1; for (var i = 1; i < last - 2; i++) { if (last > 5 && app.Fence.intersect(app.Fence.coordinate[last-1], app.Fence.coordinate[last], app.Fence.coordinate[i-1], app.Fence.coordinate[i])) { app.Fence.cross_at = i; return true; } } return false; }, finalCheckIsCrossed: function(){ var last = app.Fence.coordinate.length - 1; for (var i = 2; i < last - 2; i++) { if (app.Fence.intersect(app.Fence.coordinate[i-1], app.Fence.coordinate[i], app.Fence.coordinate[0], app.Fence.coordinate[last])) { return true; } } return false; }, redrawPolyline: function(){ app.Fence.points.splice(0, app.Fence.cross_at); // 重画图形 if (app.Fence.polyline) { app.BM.map.removeOverlay(app.Fence.polyline); } if (app.Fence.points) { app.Fence.polyline = new BMap.Polyline(app.Fence.points, app.Fence.polylineOption); //创建多边形 app.BM.map.addOverlay(app.Fence.polyline); //增加多边形 var last = app.Fence.points.length -1 ; app.Fence.polyline = new BMap.Polyline([app.Fence.points[0], app.Fence.points[last]], app.Fence.polylineOption); //创建多边形 app.BM.map.addOverlay(app.Fence.polyline); } }, redraw: function(){ if (app.Fence.polyline) { app.BM.map.removeOverlay(app.Fence.polyline); } if (app.Fence.points) { app.Fence.polyline = new BMap.Polyline(app.Fence.points, app.Fence.polylineOption); //创建多边形 app.BM.map.addOverlay(app.Fence.polyline); //增加多边形 } }, /* 叉积 判断2条线段是否相交 */ mult: function(a, b, c) { return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y); }, /* pa, pb为一条线段两端点 pc, pd为另一条线段的两端点 相交返回true, 不相交返回false*/ intersect: function(pa, pb, pc, pd) { if ( Math.max(pa.x, pb.x)<Math.min(pc.x, pd.x) ) { return false; } if ( Math.max(pa.y, pb.y)<Math.min(pc.y, pd.y) ) { return false; } if ( Math.max(pc.x, pd.x)<Math.min(pa.x, pb.x) ) { return false; } if ( Math.max(pc.y, pd.y)<Math.min(pa.y, pb.y) ) { return false; } if ( app.Fence.mult(pc, pb, pa)*app.Fence.mult(pb, pd, pa)<0 ) { return false; } if ( app.Fence.mult(pa, pd, pc)*app.Fence.mult(pd, pb, pc)<0 ) { return false; } return true; }, resetData: function(){ app.Fence.polyline = false; app.Fence.points = []; app.Fence.coordinate = []; app.Fence.isOver = false; app.Fence.cur_point = false; app.Fence.cur_pixel = false; app.Fence.polygon = false; }, setElementDisplay:function(id){ document.getElementById(id).style.display = "block"; }, setElementHidden: function(id){ document.getElementById(id).style.display = "none"; } };
触摸时获取触摸点的经纬度,然后调用api里画圆的方法画圆
http://developer.baidu.com/map/reference/index.phptitle=Class:%E8%A6%8...百度地图API的Circle类画圆
我自己实现了一下,可以自己在百度地图上随便画图形,基本原理就是,监听touch事件,touchMove,保存当前的经纬度,转化为pixel坐标,重复绘制线段,当touchEnd时,绘制矩形图形。最后会连接首位2点,并判断矩形是否有效,同时如果在画得过程中已经有闭合图形,则终止画图。
演示地址,需要使用手机浏览测试:
JS 实现代码:
触摸时获取触摸点的经纬度,然后调用api里画圆的方法画圆
http://developer.baidu.com/map/reference/index.phptitle=Class:%E8%A6%8...百度地图API的Circle类画圆