【问题标题】:In Mapbox.js, how to smooth a polyline?在 Mapbox.js 中,如何平滑折线?
【发布时间】:2019-11-29 02:59:30
【问题描述】:

代码可以查看

http://jsfiddle.net/qsr5bs6v/

以下是添加折线的线

L.polyline([[31.233, 121.465], [31.233499, 121.500634], [31.190172, 121.588107]], {
    color: '#000',
    smoothFactor: 10.0
}).addTo(map)

可以看出,属于折线的每两条线的连接点都有一个角度,像这样,没有那么吸引人:

我想知道是否有一种简单的方法可以在 Mapbox 中将角度变成圆角曲线..

(我看到这篇关于平滑折线Smooth polyline with minimal deformation 的帖子。在那篇帖子中,我看到建议使用 CHAIKIN 算法,但该算法的缺点是平滑曲线不直接通过控制点...)

【问题讨论】:

  • 我删除了你的曲线和图形标签,因为它们没有多大帮助,添加了 Leaflet 标签。 Mapbox 是 Leaflet 的扩展版本,具有许多附加功能。因此,您可能还希望调整您的搜索努力
  • 在 Leaflet(以及 Mapbox)中,折线基本上是带有一些附加功能的路径:首先要看的是(lineJoin 选项)[leafletjs.com/reference.html#path-linejoin]

标签: javascript geometry leaflet mapbox


【解决方案1】:

您可以使用 turf-bezier 从任何 LineString 几何图形中创建内插贝塞尔线。

【讨论】:

【解决方案2】:

在我的情况下,linejoin 选项不明显,贝塞尔曲线改变路径太多。 受this 解决方案的启发,我为 Leaflet 创建了自定义点到路径方法来平滑L.polyline 中的路径角。我相信这可以很容易地适应 Mapbox。

注意:此方法仅使用折线进行了测试,不需要封闭路径。

示例:https://jsfiddle.net/v51amucr/

结果:

function roundPathCorners(rings, radius) {
  function moveTowardsFractional(movingPoint, targetPoint, fraction) {
    return {
      x: movingPoint.x + (targetPoint.x - movingPoint.x) * fraction,
      y: movingPoint.y + (targetPoint.y - movingPoint.y) * fraction
    };
  }

  function pointForCommand(cmd) {
    return {
      x: parseFloat(cmd[cmd.length - 2]),
      y: parseFloat(cmd[cmd.length - 1])
    };
  }

  var resultCommands = [];
  if (+radius) {
  // negative numbers create artifacts
    radius = Math.abs(radius);
  } else {
    radius = 0.15;
  }

  for (i = 0, len = rings.length; i < len; i++) {
    commands = rings[i];
    // start point    
    resultCommands.push(["M", commands[0].x, commands[0].y]);

    for (var cmdIndex = 1; cmdIndex < commands.length; cmdIndex++) {
      var prevCmd = resultCommands[resultCommands.length - 1];
      var curCmd = commands[cmdIndex];
      var nextCmd = commands[cmdIndex + 1];

      if (nextCmd && prevCmd) {
        // Calc the points we're dealing with
        var prevPoint = pointForCommand(prevCmd); // convert to Object
        var curPoint = curCmd;
        var nextPoint = nextCmd;

        // The start and end of the cuve are just our point moved towards the previous and next points, respectivly
        var curveStart, curveEnd;

        curveStart = moveTowardsFractional(
          curPoint,
          prevCmd.origPoint || prevPoint,
          radius
        );
        curveEnd = moveTowardsFractional(
          curPoint,
          nextCmd.origPoint || nextPoint,
          radius
        );

        // Adjust the current command and add it
        curCmd = Object.values(curveStart);

        curCmd.origPoint = curPoint;
        curCmd.unshift("L");
        resultCommands.push(curCmd);

        // The curve control points are halfway between the start/end of the curve and
        // calculate curve, if radius is different than 0
        if (radius) {
          var startControl = moveTowardsFractional(curveStart, curPoint, 0.5);
          var endControl = moveTowardsFractional(curPoint, curveEnd, 0.5);
          // Create the curve
          var curveCmd = [
            "C",
            startControl.x,
            startControl.y,
            endControl.x,
            endControl.y,
            curveEnd.x,
            curveEnd.y
          ];
          // Save the original point for fractional calculations
          curveCmd.origPoint = curPoint;
          resultCommands.push(curveCmd);
        }
      } else {
        // Pass through commands that don't qualify
        var el = Object.values(curCmd);
        el.unshift("L");
        resultCommands.push(el);
      }
    }
  }

  return (
    resultCommands.reduce(function(str, c) {
      return str + c.join(" ") + " ";
    }, "") || "M0 0"
  );
};

【讨论】:

    【解决方案3】:

    你应该得到一个可以转换为坐标数组的字符串几何

    function decode(str) {
    var flag = true;
    setTimeout(() => { flag = false; return []; }, 3000);
    var index = 0,
      lat = 0,
      lng = 0,
      coordinates = [],
      shift = 0,
      result = 0,
      byte = null,
      latitude_change,
      longitude_change,
      factor = Math.pow(10, 6);
    while (flag && index < str.length) {
      byte = null;
      shift = 0;
      result = 0;
      do {
        byte = str.charCodeAt(index++) - 63;
        result |= (byte & 0x1f) << shift;
        shift += 5;
      } while (flag && byte >= 0x20);
      latitude_change = ((result & 1) ? ~(result >> 1) : (result >> 1));
      shift = result = 0;
      do {
        byte = str.charCodeAt(index++) - 63;
        result |= (byte & 0x1f) << shift;
        shift += 5;
      } while (flag && byte >= 0x20);
      longitude_change = ((result & 1) ? ~(result >> 1) : (result >> 1));
      lat += latitude_change;
      lng += longitude_change;
      coordinates.push([lat / factor, lng / factor]);
    }
    return coordinates;
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      相关资源
      最近更新 更多