使用给定的GeoJSON线串:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [
            2.6806640625,
            46.437856895024204
          ],
          [
            4.7021484375,
            50.20503326494332
          ],
          [
            13.271484375,
            47.010225655683485
          ],
          [
            17.2265625,
            52.855864177853974
          ]
        ]
      }
    }
  ]
}

我想找到确切的中间点。我不是指给定数组的中间元素,而是要计算恰好位于行中间的中点。因此,如果一条线的总长度为30公里,则将中点放置在15公里处。

我尝试在npm中搜索类似的内容,但找不到。唯一关闭的库可以在线放置n个点,然后可以得到中间的一个。但这对我来说很糟糕,因为精度不是那么好。

完美的选择是在JavaScript中实现此http://postgis.net/docs/manual-1.5/ST_Line_Interpolate_Point.html

我该如何实现?

最佳答案

Here's a working CodePen

以下代码将返回特定距离的点。

对于此特定情况,中点距离为总长度/ 2

假设我们的线串数组存储在points中,则这样调用主函数

var totalLength = totalLen(points);
var midDistance = totalLength / 2;
var midPoint = getPointByDistance(points, midDistance)

Java脚本
myData = {
  "type": "FeatureCollection",
  "features": [{
    "type": "Feature",
    "properties": {},
    "geometry": {
      "type": "LineString",
      "coordinates": [
        [
           2.6806640625,
          46.437856895024204
        ],
        [
          4.7021484375,
          50.20503326494332
        ],
        [
          13.271484375,
          47.010225655683485
        ],
        [
          17.2265625,
          52.855864177853974
        ]
      ]
    }
  }]
}
var points = myData.features[0].geometry.coordinates
var totalLength = totalLen(points);
var midDistance = totalLength / 2;
var midPoint = getPointByDistance(points, midDistance)
alert ("midPoint = " + midPoint[0] + ", " + midPoint[1])
// main function
function getPointByDistance(pnts, distance) {
  var tl = totalLen(pnts);
  var cl = 0;
  var ol;
  var result;
  pnts.forEach(function(point, i, points) {
    ol = cl;
    cl += i ? lineLen([points[i-1], point]) : 0;
    if (distance <= cl && distance > ol){
      var dd = distance - ol;
      result = pntOnLine([points[i-1], point], dd);
    }
  });
  return result
};
// returns a point on a single line (two points) using distance // line=[[x0,y0],[x1,y1]]
function pntOnLine(line, distance) {
  t = distance / lineLen(line)
  xt = (1 - t) * line[0][0] + (t * line[1][0])
  yt = (1 - t) * line[0][1] + (t * line[1][1])
  return [xt, yt]
};
// returns the total length of a linestring (multiple points) // pnts=[[x0,y0],[x1,y1],[x2,y2],...]
function totalLen(pnts) {
  var tl = 0;
  pnts.forEach(function(point, i, points) {
    tl += i ? lineLen([points[i - 1], point]) : 0;
  });
  return tl;
};
// returns the length of a line (two points) // line=[[x0,y0],[x1,y1]]
function lineLen(line) {
  var xd = line[0][0] - line[1][0];
  var yd = line[0][1] - line[1][1];
  return Math.sqrt(xd * xd + yd * yd);
};

说明

1.我们找到线串的总长度:
  • 函数lineLen()计算单行的长度。
  • 函数totalLen()在各行中循环并计算总长度。
    javascript - Javascript-如何计算线串的中点?-LMLPHP

  • *来源和信用here(IgorŠarčević)

    2.中点的距离是全长/ 2:
  • 现在,我们有了遍历直线的所需距离,并检查了该直线起点和该直线终点的距离,并查看它们之间是否存在中点距离。
  • 一旦我们有了一条知道我们的中点的线,我们就计算它到此线起点的距离(总长度-线起点距离)
  • 现在我们使用this formula(函数pntOnLine())查找xtyt(想要的中点)

  • javascript - Javascript-如何计算线串的中点?-LMLPHP

    *贷给参议员雅各布。

    可视化

    我包含了HTML5 canvas来绘制(可视化)线串和中点,而不必包含它们。但如果您想测试代码并实时查看结果,它们将非常有用
    // Just for visualizing on canvas (not needed)
    var canvas = document.getElementById("myCanvas");
    var ctx = canvas.getContext('2d');
    drawLine(points);
    //
    ctx.beginPath();
    ctx.arc(midPoint[0], midPoint[1], 2, 0, 2 * Math.PI);
    ctx.closePath();
    ctx.fillStyle = "red";
    ctx.fill();
    //
    function drawLine(pnts) {
      pnts.forEach(function(point, i, points) {
        if (i === 0) {
          ctx.beginPath();
          ctx.moveTo(point[0], point[1]);
        } else {
          ctx.lineTo(point[0], point[1]);
        }
        if (i === points.length - 1) {
          ctx.stroke();
        }
      });
    }
    

    10-06 07:37