百度地图多边形绘制之多边形预判

js文件:https://pan.baidu.com/s/1hsIR8Ni

百度地图提供了多边形绘制的功能,但是对于不符合多边形规则的图形却没有做限制:

 

所以我们在绘制的时候需要判断当前绘制的图形是否是多边形:

1:下载百度地图开源库里面的鼠标绘制工具条库:DrawingManager.js

2:找到DrawingManager.prototype._bindPolylineOrPolygon方法里面的startAction方法,在我们绘制的时候会触发该方法,在startAction里我们会拿到当前准备绘制的点位e.point,而points是绘制之前的多边形的点位数组

3:下载js文件:https://pan.baidu.com/s/1hsIR8Ni

4:在startAction最开始的地方,写下:

if(window.isWillPolygon(points,e.point) == false){
     return;
 }

polygon.js介绍:

  polygon.js主要实现两个功能

    1:isWillPolygon(pointsList,point):判断当前点与之前的多边形组合后 是否可以成为多边形

/*
   方法名称:isWillPolygon
   功能描述:判断点point与点数组pointsList最后一个点相连之后,他们连接成的图形是否有可能成为多边形
   参数描述:
   pointsList:点数组
   point:点
   返回值:
   true:有可能
   false:不可能
   */
  var isWillPolygon = function(pointsList,point){
    var len = pointsList.length,
        isWillPolygon = true,
        line = null,
        currentLine = null;
    if(len < 3){
      return true;
    }
    currentLine = {
      S:{
        x:pointsList[len-1].lat,
        y:pointsList[len-1].lng,
      },
      E:{
        x:point.lat,
        y:point.lng,
      }
    }
    for(var i = 0;i < len-2; i++){
      line = {
        S:{
          x:pointsList[i].lat,
          y:pointsList[i].lng,
        },
        E:{
          x:pointsList[i+1].lat,
          y:pointsList[i+1].lng,
        }
      }
      if(isOverlapping(line,currentLine)){
        isWillPolygon = false;
        break;
      }
    }
    return isWillPolygon;
  }

    2:isPolygon(pointsList):根据当前的点集合,判断这个点根绝数组顺序组合之后的图形是否是多边形

/*
   方法名称:isPolygon
   功能描述:判断是否是多边形
   判断依据:多边形的每条线段最多和两条线段相交
   参数描述:
   pointsList:多边形各个点的顺序数组
   返回值:
   true:是多边形
   false:不是多边形
   */
  var isPolygon = function(pointsList){
    var len = pointsList.length,
        isPolygon = true,
        line = null,
        otherLineList = [],
        currentLine = null,
        item = null,
        OverlapLineCount = 0,
        prevItem = null,
        nextItem = null;
    if(len < 3){
      return false;
    }
    for(var i = 0;i < len; i++){
      item =  pointsList[i];
      prevItem = pointsList[i-1];
      if( i == len-1){
        nextItem = pointsList[0];
      }else{
        nextItem = pointsList[i+1];
      }
      currentLine = {
        S:{
          x:item.lat,
          y:item.lng,
        },
        E:{
          x:nextItem.lat,
          y:nextItem.lng,
        }
      }
      otherLineList = getPolygonLine(pointsList,currentLine);
      OverlapLineCount = getOverlapCount(currentLine,otherLineList);
      if(OverlapLineCount.length > 2){
        isPolygon = false;
        break;
      }
    }
    return isPolygon;
  }

完整代码:

(function(w){
  /*
   方法名称:isWillPolygon
   功能描述:判断点point与点数组pointsList最后一个点相连之后,他们连接成的图形是否有可能成为多边形
   参数描述:
   pointsList:点数组
   point:点
   返回值:
   true:有可能
   false:不可能
   */
  var isWillPolygon = function(pointsList,point){
    var len = pointsList.length,
        isWillPolygon = true,
        line = null,
        currentLine = null;
    if(len < 3){
      return true;
    }
    currentLine = {
      S:{
        x:pointsList[len-1].lat,
        y:pointsList[len-1].lng,
      },
      E:{
        x:point.lat,
        y:point.lng,
      }
    }
    for(var i = 0;i < len-2; i++){
      line = {
        S:{
          x:pointsList[i].lat,
          y:pointsList[i].lng,
        },
        E:{
          x:pointsList[i+1].lat,
          y:pointsList[i+1].lng,
        }
      }
      if(isOverlapping(line,currentLine)){
        isWillPolygon = false;
        break;
      }
    }
    return isWillPolygon;
  }
  /*
   方法名称:isPolygon
   功能描述:判断是否是多边形
   判断依据:多边形的每条线段最多和两条线段相交
   参数描述:
   pointsList:多边形各个点的顺序数组
   返回值:
   true:是多边形
   false:不是多边形
   */
  var isPolygon = function(pointsList){
    var len = pointsList.length,
        isPolygon = true,
        line = null,
        otherLineList = [],
        currentLine = null,
        item = null,
        OverlapLineCount = 0,
        prevItem = null,
        nextItem = null;
    if(len < 3){
      return false;
    }
    for(var i = 0;i < len; i++){
      item =  pointsList[i];
      prevItem = pointsList[i-1];
      if( i == len-1){
        nextItem = pointsList[0];
      }else{
        nextItem = pointsList[i+1];
      }
      currentLine = {
        S:{
          x:item.lat,
          y:item.lng,
        },
        E:{
          x:nextItem.lat,
          y:nextItem.lng,
        }
      }
      otherLineList = getPolygonLine(pointsList,currentLine);
      OverlapLineCount = getOverlapCount(currentLine,otherLineList);
      if(OverlapLineCount.length > 2){
        isPolygon = false;
        break;
      }
    }
    return isPolygon;
  }
  /*
   方法名称:getPolygonLine
   功能描述:获取多边形除指定线段的其他线段
   参数描述:
   pointsList:多边形各个点的顺序数组
   line:指定排除的线段
   返回值:多边形线段数组
   */
  var getPolygonLine = function(pointsList,expectLine){
    var len = pointsList.length,
        line = null,
        item = null,
        lineList = [],
        prevItem = null,
        nextItem = null;
    for(var i = 0;i < len; i++){
      item =  pointsList[i];
      prevItem = pointsList[i-1];
      if( i == len-1){
        nextItem = pointsList[0];
      }else{
        nextItem = pointsList[i+1];
      }
      if(parseFloat(item.lat) == parseFloat(expectLine.S.x) && parseFloat(item.lng) == parseFloat(expectLine.S.y)){
        continue;
      }
      line = {
        S:{
          x:item.lat,
          y:item.lng,
        },
        E:{
          x:nextItem.lat,
          y:nextItem.lng,
        }
      }
      lineList.push(line);
    }
    return lineList;
  }
  /*
   方法名称:getOverlapCount
   功能描述:获取指定线段与线段数组里面相交的线段(不包括斜率一致的)
   参数描述:
   line:指定线段
   lineList:线段数组
   返回值:返回相交的线段
   */
  var getOverlapCount = function(line,lineList){
    var len = lineList.length,
        item = null,
        OverlapLine = [];
    for(var i = 0; i < len; i++){
      item = lineList[i];
      if(isOverlapping(line,item) && isEqualK(line,item) == false){
        OverlapLine.push(item);
      }
    }
    return OverlapLine;
  }
  /*
   方法名称:isEqualK
   功能描述:判断斜率是否一致
   参数描述:
   lineA:线段A
   lineB:线段B
   返回值:
    true:一致
    false:不一致
   */
  var isEqualK = function(lineA,lineB){
    var lineAK = getLineK(lineA.S.x,lineA.S.y,lineA.E.x,lineA.E.y);
    var lineBK = getLineK(lineB.S.x,lineB.S.y,lineB.E.x,lineB.E.y);
    return lineAK == lineBK;
  }
  /*
   方法名称:isOverlapping
   功能描述:判断两个线段是否相交
   参数描述:
   lineA:线段A
   lineB:线段B
   返回值:
   true:交叉
   false:不交叉
   判断依据:1:判断两条线段的端点是否存在在彼此之上的情况,2:判断两个线段的两个端点是否都在彼此的两边
   */
  var isOverlapping = function(lineA,lineB){
    var lineAStartPointInLineB = isPointInLine(lineA.S,lineB.S,lineB.E);
    var lineAEndPointInLineB = isPointInLine(lineA.E,lineB.S,lineB.E);
    var lineBStartPointInLineA = isPointInLine(lineB.S,lineA.S,lineA.E);
    var lineBEndPointInLineA = isPointInLine(lineB.E,lineA.S,lineA.E);
    //只要有一点在另外一条线上我们就认为相交,也就是两条直线相交
    if(lineAStartPointInLineB == 0 || lineAEndPointInLineB == 0 || lineBStartPointInLineA == 0 || lineBEndPointInLineA == 0 ){
      return true;
    }
    //如果上面条件不满足,点都不在对应的线段上,但是有一个点在另外一条线的延长线上,说明一定不会相交
    if(lineAStartPointInLineB == -2 || lineAEndPointInLineB == -2 || lineBStartPointInLineA == -2 || lineBEndPointInLineA == -2 ){
      return false;
    }
    //因为在上面是1,在下面是-1,两个相乘如果小于0则一定在两边,如果两条线段的两个端点分别在对应线段的两端,说明相交
    if(lineAStartPointInLineB*lineAEndPointInLineB < 1 && lineBStartPointInLineA*lineBEndPointInLineA < 1){
      return true;
    }
    return false;//默认不相交
  }
  /*
   方法名称:isPointInLine
   功能描述:判断点point是否在以linePS为起点,linePE为终点的线段上
   参数描述:
   point:点
   linePS:线段起点
   linePE:线段终点
   返回值:
   0:在线段上
   1:不在线段上,而是在线段的上方
   -1:不在线段上,而是在线段的下方
   -2:不在线段上,而是在线段所在的直线上
   */
  var isPointInLine = function(point,linePS,linePE){
    var maxLineX = 0,
        minLineX = 0,
        maxLineY = 0,
        minLineY = 0,
        K = getLineK(linePS.x,linePS.y,linePE.x,linePE.y);
    var B = getLineB(linePS.x,linePS.y,K);
    var linePointY = (K*point.x+B);
    if(linePS.x < linePE.x){
      maxLineX = linePE.x;minLineX = linePS.x;
    }else{
      maxLineX = linePS.x;minLineX = linePE.x;
    }
    if(linePS.y < linePE.y){
      maxLineY = linePE.y;minLineY = linePS.y;
    }else{
      maxLineY = linePS.y;minLineY = linePE.y;
    }
    if(point.x >= minLineX && point.x <= maxLineX && point.y >= minLineY && point.y <= maxLineY){//在线段所在的矩形范围之内
      if(linePointY == point.y){
        return 0;
      }else if(linePointY > point.y){
        if(point.y >= 0){
          return -1
        }else {
          return 1
        }
      }else{
        if(point.y >= 0){
          return 1
        }else {
          return -1
        }
      }
    }else{
      if(linePointY == point.y){
        return -2;
      }else if(linePointY > point.y){
        if(point.y >= 0){
          return -1
        }else{
          return 1
        }
      }else{
        if(point.y >= 0){
          return 1
        }else{
          return -1
        }
      }
    }
  }
  /*
   方法名称:getLineK
   功能描述:获取线段的斜率
   参数描述:
   x1:X坐标1
   y1:Y坐标1
   x2:X坐标2
   y2:Y坐标2
   返回值:斜率
   */
  var getLineK = function(x1,y1,x2,y2){
    return (y1-y2)/(x1-x2);
  }
  /*
   方法名称:getLineB
   功能描述:获取线段的y轴截距
   参数描述:
   x1:X坐标1
   y1:Y坐标1
   k:斜率
   返回值:线段的y轴截距
   */
  var getLineB = function(x1,y1,k){
    return y1-k*x1;
  }
  w.isWillPolygon = isWillPolygon;
  w.isPolygon = isPolygon;
})(window);
时间: 2024-10-12 21:03:10

百度地图多边形绘制之多边形预判的相关文章

百度地图API绘制带头箭头的折线

源代码: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <style type="text/css"> body, html,#allmap {width: 100%;height: 100%;overflow: hidden;marg

百度地图API 绘制轨迹历史

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> 6 &l

百度地图中拖拽地图后,多边形消失的问题

问题描述: 在手机端,在百度地图中绘制多边形区域,当拖动地图时,多边形区域会消失一部分,继续拖动,会继续再消失,拖动到原位置后,又重新现显示完全 代码: var points = [{"lng":116.4935302734375,"lat":40.0506591796875},{"lng":116.4935302734375,"lat":40.05615234375},{"lng":116.4880371

百度地图多边形点击变色

在应用百度地图多边形时会出现点击多边形名称对应多边形变色 使用如下方法 定义map var pologyMap = new Map(); var curPology; 画多边形时 将多边形放入map pologyMap.set(this.id, bmap.polygon); 点击名称时获取对应多边形设置颜色,之前变色的多边形 颜色还原 var polygon = pologyMap.get(parseInt(areaid)); if (curPology != null) { curPology

百度地图实现鼠标绘制多边形并获取所有点坐标

百度地图开放平台http://lbsyun.baidu.com/ 这里使用的是Javascript API http://lbsyun.baidu.com/index.php?title=jspopular 实现鼠标绘制多边形主要用到百度地图JavaScript开源库鼠标绘制工具条库(http://lbsyun.baidu.com/index.php?title=open/library),提供鼠标绘制点.线.面.多边形(矩形.圆)的编辑工具条的开源代码库.且用户可使用JavaScript AP

百度地图多边形画区域、获取节点经纬度坐标、判断某一点是否在此区域内

创建可绘画map: 1 <!DOCTYPE html> 2 3 <html> 4 <head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1, user-scalable=no"> 7 <meta name=&

百度地图 判断marker是否在多边形内

昨天画了圆形,判marker是否存在圆形内.今天来画多边形,判断marker在多边形内. 百度地图API覆盖物多边形类 http://developer.baidu.com/map/reference/index.php?title=Class:%E8%A6%86%E7%9B%96%E7%89%A9%E7%B1%BB/Polygon http://developer.baidu.com/map/reference/index.php?title=Class:%E8%A6%86%E7%9B%96%

百度地图:普通覆盖物,以及多边形覆盖物,及他们的描述信息的添加,修改,删除,查看功能,还有多边形根据名称查询功能;

版权所有,未经本人允许,禁止转载! 这个界面功能是,普通覆盖物,以及多边形覆盖物,及他们的描述信息的添加,修改,删除,查看功能,还有多边形根据名称查询功能: 由于这个界面的数据是存在数据库,还有后台代码,所以这个页面无法直接使用: <%@ page contentType="text/html;charset=UTF-8"%> <%@ include file="/WEB-INF/views/include/taglib.jsp"%> <

百度地图覆盖物多边形拖动,点击,生成新的覆盖物

<html><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312" /><meta name="viewport" content="initial-scale=1.0, user-scalable=no" /><style type="text/css">