openlayers translate实现要素在限制图形内移动

点只能在线上移动

/**
 * 点只能在线上移动
 * @param {*} pointFeature 可移动的点
 * @param {*} lineFeature 限制的线段
 */
const pointInLine = (pointFeature, lineFeature) => {
  const pointGeom = pointFeature.getGeometry();
  const pointCoordinates = pointGeom.getCoordinates();
  const lineGeom = lineFeature.getGeometry();
  const closestPoint = lineGeom.getClosestPoint(pointCoordinates); //当前鼠标位置距离线段最近的点
  pointGeom.setCoordinates(closestPoint);
};

图形只能在面内移动

let lastCoordinates = []; //上一次移动的图形坐标
/**
 * 图形只能在面内移动
 * @param {*} graphFeature 可移动图形
 * @param {*} polygonFeature2 限制图形
 * @param {*} options 可选参数:appintSideCoord为面的某条边
 */
const graphInPolygon = (graphFeature, polygonFeature2, options = undefined) => {
  const graphGeom = graphFeature.getGeometry();
  const polygonGeom2 = polygonFeature2.getGeometry();
  let coordinates = []; //当前拖动图形坐标
  /**思路:圆和多边形计算拖动图形的外接矩形,判断外接矩形的上的一点是否超出限制范围,超出范围则设置拖动图形坐标为上一次记录的拖动图形坐标 */
  if (graphGeom instanceof Circle) {
    const center = graphGeom.getCenter();
    const r = graphGeom.getRadius();
    coordinates = [
      [center[0] - r, center[1] + r],
      [center[0] - r, center[1] - r],
      [center[0] + r, center[1] - r],
      [center[0] + r, center[1] + r],
      [center[0] - r, center[1] + r],
    ];
    const cross = coordinates.find((item) => {
      return !polygonGeom2.intersectsCoordinate(item);
    });
    if (cross) {
      graphGeom.setCenterAndRadius(lastCoordinates[0], lastCoordinates[1]);
    } else {
      lastCoordinates = [center, r];
    }
  } else if (graphGeom instanceof Polygon) {
    coordinates = graphGeom.getCoordinates()[0];
    const cross = coordinates.find((item) => {
      return !polygonGeom2.intersectsCoordinate(item);
    });
    if (cross) {
      graphGeom.setCoordinates([lastCoordinates]);
    } else {
      lastCoordinates = coordinates;
    }
  } else if (graphGeom instanceof LineString) {
    coordinates = graphGeom.getCoordinates();
    if (options) {
      /**appintSideCoord有值表示线只能在某个范围内的某条边上移动,且线段初始点必须保证在范围内的边上*/
      const {appintSideCoord} = options;
      const dx = coordinates[1][0] - coordinates[0][0];
      const dy = coordinates[1][1] - coordinates[0][1];
      const appintSideGeom = new LineString(appintSideCoord);
      let cross = [];
      let shortLength;
      /**判断线段哪一头离指定线段最近 */
      coordinates.forEach((item) => {
        const closestPoint = appintSideGeom.getClosestPoint(item);
        const length = Math.sqrt(
          Math.pow(item[0] - closestPoint[0], 2) +
            (item[1] - closestPoint[1], 2)
        );
        if (!shortLength) {
          shortLength = length;
          cross = closestPoint;
        } else if (length < shortLength) {
          cross = closestPoint;
        }
      });
      const newCoordinates = [cross, [cross[0] + dx, cross[1] + dy]];
      graphGeom.setCoordinates(newCoordinates);
    } else {
      const cross = coordinates.find((item) => {
        return !polygonGeom2.intersectsCoordinate(item);
      });
      if (cross) {
        graphGeom.setCoordinates(lastCoordinates);
      } else {
        lastCoordinates = coordinates;
      }
    }
  }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值