Openlayer地图折线上点的信息错位标注方法

23 篇文章 0 订阅
7 篇文章 0 订阅

Openlayer地图折线上点的信息错位标注方法,尽量不压到线,如下图所示:

 解决思路如下:

一、起点处理
起点与第二点标牌方向相反
二、中间点处理
以中间点为坐标系原点,求中间点连接的两条边线在第几象限,并求出每天条边线与y轴正半轴之间的夹角。
1、两个边不在一条直线上,标牌标在中间点连接的边线的两个夹角的角度最大的一边
(1)两个边在同一象限
case 同象限1、1  标牌标在象限3
case 同象限2、2  标牌标在象限4
case 同象限3、3  标牌标在象限1
case 同象限4、4  标牌标在象限2
(2)两个边在两个相连象限
case 象限1、2  标牌标在y轴负半轴
case 象限2、3  标牌标在x轴正半轴
case 象限3、4  标牌标在y轴正半轴
case 象限1、4  标牌标在x轴负半轴
(3)两个边在两个不相连象限
case 象限1、3  if(大角-小角)>180 标牌标在象限4 else 标牌标在象限2
case 象限2、4  if(大角-小角)>180 标牌标在象限3 else 标牌标在象限1
2、如果两个夹角的角度相等,即两个边在一条直线上,标牌标注与上一个点的标注相反错开标注
case 边线与坐标Y轴正方向角度小的线在[0<=a<45 and 135<=a<=180]  标牌左右标注,第一个点默认右(最好与上一标牌左右错开)
case 边线与坐标Y轴正方向角度小的线在[45<=a<135]  标牌上下标注,第一个点默认下(最好与上一标牌上下错开)
三、终点处理
终点与前一点标牌方向相反。

javascript关键代码如下:

    //获得线上结点标牌显示位置以该点为原点,与X轴正半轴之间的夹角(先调用这个函数)
    //sx 要标注点的前一个点的x坐标
    //sy 要标注点的前一个点的y坐标
    //mx 要标注点的x坐标
    //my 要标注点的y坐标
    //ex 要标注点后一个点的x坐标
    //ey 要标注点后一个点的y坐标
    //pAngle 要标注点前一个点的标牌标准角度
    getLabelPlace (sx, sy, mx, my, ex, ey, pAngle = -1) {
      //console.log('sssss:', sx + ',' + sy + ',' + mx + ',' + my + ',' + ex + ',' + ey);
      let mSAngle = this.getAngle(mx, my, sx, sy);
      let mEAngle = this.getAngle(mx, my, ex, ey);
      //console.log('pAngle:', pAngle);
      //console.log('mSAngle:', mSAngle);
      //console.log('mEAngle:', mEAngle);
      let minAngle = mSAngle < mEAngle ? mSAngle : mEAngle;
      let maxAngle = mSAngle > mEAngle ? mSAngle : mEAngle;
      //console.log('pAngle0:', pAngle);
      //console.log('minAngle:', minAngle);
      //console.log('maxAngle:', maxAngle);
      let angle = 0;
      //判断大角与小角是否在一条直线上
      if ((maxAngle - minAngle) == 180) {//在一条直线上
        if ((minAngle >= 0 && minAngle < 45) || (minAngle >= 135 && minAngle <= 180)) {
          if (0 <= pAngle && pAngle < 180) {
            angle = 270;
          }
          else {
            angle = 90;
          }
        }
        else {
          if (90 <= pAngle && pAngle < 270) {
            angle = 0;
          }
          else {
            angle = 180;
          }
        }
        //console.log('直线不考虑象限');
      }
      else {//不在一条直线上
        //判断大角与小角所在象限情况
        switch (true) {
          case 0 <= minAngle && minAngle < 90 && 0 <= maxAngle && maxAngle <= 90://大、小角同在象限1
            angle = 225;
            //console.log('象限:', '大、小角同在象限1');
            break;
          case 90 <= minAngle && minAngle < 180 && 90 <= maxAngle && maxAngle <= 180://大、小角同在象限2
            angle = 315;
            //console.log('象限:', '大、小角同在象限2');
            break;
          case 180 <= minAngle && minAngle < 270 && 180 <= maxAngle && maxAngle <= 270://大、小角同在象限3
            angle = 45;
            //console.log('象限:', '大、小角同在象限3');
            break;
          case 270 <= minAngle && minAngle < 360 && 270 <= maxAngle && maxAngle <= 360://大、小角同在象限4
            angle = 135;
            //console.log('象限:', '大、小角同在象限4');
            break;
          case 0 <= minAngle && minAngle < 90 && 90 < maxAngle && maxAngle <= 180://大角象限2、小角象限1
            angle = 270;
            //console.log('象限:', '大角象限2、小角象限1');
            break;
          case 90 <= minAngle && minAngle < 180 && 180 < maxAngle && maxAngle <= 270://大角象限3、小角象限2
            angle = 0;
            //console.log('象限:', '大角象限3、小角象限2');
            break;
          case 180 <= minAngle && minAngle < 270 && 270 < maxAngle && maxAngle <= 360://大角象限4、小角象限3
            angle = 90;
            //console.log('象限:', '大角象限4、小角象限3');
            break;
          case 0 <= minAngle && minAngle < 90 && 270 < maxAngle && maxAngle <= 360://大角象限4、小角象限1
            angle = 180;
            //console.log('象限:', '大角象限4、小角象限1');
            break;
          case 0 <= minAngle && minAngle < 90 && 180 <= maxAngle && maxAngle < 270: //大角象限3、小角象限1
            if ((maxAngle - minAngle) < 180) {
              angle = 315;
            }
            else {
              angle = 135;
            }
            //console.log('象限:', '大角象限3、小角象限1');
            break;
          case 90 <= minAngle && minAngle < 180 && 270 < maxAngle && maxAngle <= 360://大角象限4、小角象限2
            if ((maxAngle - minAngle) < 180) {
              angle = 45;
            }
            else {
              angle = 225;
            }
            //console.log('象限:', '大角象限4、小角象限2');
            break;
          default:
            angle = -1;
            //console.log('象限:', '输入角度范围错误!');
            break;
        }
      }

      return angle;
    },
    //获得两坐标点连线,与X轴正半轴之间的夹角
    getAngle (sx, sy, ex, ey) {
      let x = Math.abs(ex - sx);
      let y = Math.abs(ey - sy);
      let z = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
      let sin = y / z;
      let radina = Math.asin(sin);//用反三角函数求弧度
      let angle = Math.floor(180 / (Math.PI / radina));//将弧度转换成角度
      //console.log('angle:', angle);

      if (ex == sx && ey > sy) {//在y轴正方向上
        angle = 90;
      }
      if (ex < sx && ey > sy) {//在第二象限
        angle = 180 - angle;
      }
      if (ex < sx && ey == sy) {//在x轴负方向
        angle = 180;
      }
      if (ex < sx && ey < sy) {//在第三象限
        angle = 180 + angle;
      }
      if (ex == sx && ey < sy) {//在y轴负方向上
        angle = 270;
      }
      if (ex > sx && ey < sy) {//在第四象限
        angle = 360 - angle;
      }
      return angle;
    },
    //求传入角度直线反方向上角度
    getAngleReverse (labelAngle) {
      if (labelAngle < 180) {
        labelAngle = labelAngle + 180;
      }
      else {
        labelAngle = labelAngle - 180;
      }
      return labelAngle;
    },

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值