Atlaslog
Atlaslog / Examples / Turf.js / Nearest Point
Turf.js · Runnable Example

Nearest Point

Runnable Turf.js example: Nearest Point. Open the live demo, read the complete source, and copy the file into your project. No build step or API key.

Open standalone → Chinese notes All Turf.js examples
/demos/turf-nearest-point.htmlLIVE
single HTML file · CDN dependencies onlyinterface may contain Chinese labels

Source

demos/turf-nearest-point.html
<!--
  示例:最近点查找 — turf.nearestPoint 在候选点中找离目标最近的一个
  核心逻辑:目标点随机移动,每次重算最近点并读取 featureIndex
  依赖:Turf.js 7 · jsDelivr CDN
-->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta name="robots" content="noindex,follow">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>最近点查找</title>
<style>
  html,body{height:100%;margin:0}
  body{display:flex;flex-direction:column;overflow:hidden;
       font:13px/1.6 -apple-system,"Segoe UI","PingFang SC",sans-serif;color:#16181d;background:#fff}
  .bar{flex:0 0 auto;display:flex;gap:10px;align-items:center;padding:8px 12px;
       background:#f6f7f9;border-bottom:1px solid #e3e6ea;font-size:12px;color:#58606e;flex-wrap:wrap}
  .bar button{font:inherit;font-size:12px;padding:4px 10px;border-radius:4px;cursor:pointer;
       border:1px solid #ccd1d9;background:#fff;color:#16181d}
  .bar button:hover{background:#eef0f3}
  svg{flex:1 1 auto;min-height:0;width:100%;display:block;background:#fbfcfd}
  .out{flex:0 0 auto;display:flex;gap:22px;flex-wrap:wrap;padding:8px 12px;
       border-top:1px solid #e3e6ea;
       font-family:ui-monospace,Consolas,monospace;font-size:11.5px;color:#3a4250}
  .out b{color:#1f5fd0}
</style>
</head>
<body>
<div class="bar">
  <button id="move">移动目标点</button>
  <span>八个候选点,绿地表示最近的一个</span>
</div>
<svg id="stage" viewBox="0 0 640 320" preserveAspectRatio="xMidYMid meet"></svg>
<div class="out">
  <span>最近点 <b id="idx">—</b></span>
  <span>距离 <b id="dist">—</b></span>
  <span>目标 <span id="tgt">—</span></span>
</div>
<script src="https://cdn.jsdelivr.net/npm/@turf/turf@7/turf.min.js"></script>
<script>
(function () {
  'use strict';

  if (typeof turf === 'undefined') {
    document.body.innerHTML =
      '<div style="padding:24px;color:#b42318">Turf.js 加载失败,请检查能否访问 cdn.jsdelivr.net</div>';
    return;
  }

  var candidates = [
    { name: 'A', c: [116.310, 39.870] },
    { name: 'B', c: [116.360, 39.940] },
    { name: 'C', c: [116.430, 39.900] },
    { name: 'D', c: [116.500, 39.950] },
    { name: 'E', c: [116.460, 39.990] },
    { name: 'F', c: [116.380, 39.850] },
    { name: 'G', c: [116.520, 39.870] },
    { name: 'H', c: [116.280, 39.930] }
  ];

  var fc = turf.featureCollection(candidates.map(function (o, i) {
    return turf.point(o.c, { name: o.name, seq: i });
  }));

  var W = 640, H = 320, PAD = 34;
  var BOX = [116.25, 39.82, 116.56, 40.02];
  var stage = document.getElementById('stage');

  var kx = Math.cos(((BOX[1] + BOX[3]) / 2) * Math.PI / 180);
  var x0 = BOX[0] * kx, x1 = BOX[2] * kx;
  var y0 = BOX[1], y1 = BOX[3];
  var s = Math.min((W - PAD * 2) / (x1 - x0), (H - PAD * 2) / (y1 - y0));
  var ox = (W - (x1 - x0) * s) / 2;
  var oy = (H - (y1 - y0) * s) / 2;

  function pr(c) {
    return [(c[0] * kx - x0) * s + ox, (y1 - c[1]) * s + oy];
  }

  var target = turf.point([116.402, 39.921]);

  function draw() {
    var near = turf.nearestPoint(target, fc);
    var seq = near.properties.featureIndex;

    /* 不同版本的字段名可能不一致,退化到按坐标匹配 */
    if (typeof seq !== 'number') {
      var nc = near.geometry.coordinates;
      seq = 0;
      candidates.forEach(function (o, i) {
        if (o.c[0] === nc[0] && o.c[1] === nc[1]) seq = i;
      });
    }

    var np = candidates[seq];

    var parts = ['<rect x="0" y="0" width="640" height="320" fill="none" stroke="#e3e6ea"/>'];

    candidates.forEach(function (o) {
      var p = pr(o.c);
      var isNear = o === np;
      parts.push('<circle cx="' + p[0].toFixed(1) + '" cy="' + p[1].toFixed(1) +
                 '" r="' + (isNear ? 6 : 4) + '" fill="' + (isNear ? '#17694a' : '#8a929f') +
                 '" stroke="#fff" stroke-width="2"/>');
      parts.push('<text x="' + (p[0] + 9).toFixed(1) + '" y="' + (p[1] + 4).toFixed(1) +
                 '" font-size="11" fill="' + (isNear ? '#17694a' : '#8a929f') + '">' +
                 o.name + '</text>');
    });

    var tp = pr(target.geometry.coordinates);
    var qp = pr(np.c);

    parts.push('<line x1="' + tp[0].toFixed(1) + '" y1="' + tp[1].toFixed(1) +
               '" x2="' + qp[0].toFixed(1) + '" y2="' + qp[1].toFixed(1) +
               '" stroke="#17694a" stroke-width="2" stroke-dasharray="5 4"/>');

    parts.push('<circle cx="' + tp[0].toFixed(1) + '" cy="' + tp[1].toFixed(1) +
               '" r="6" fill="#c2410c" stroke="#fff" stroke-width="2"/>');
    parts.push('<text x="' + (tp[0] + 10).toFixed(1) + '" y="' + (tp[1] - 10).toFixed(1) +
               '" font-size="11" fill="#c2410c">目标点</text>');

    /* 最近点与目标点的中点处标注距离 */
    var km = turf.distance(target, near, { units: 'kilometers' });
    parts.push('<text x="' + ((tp[0] + qp[0]) / 2).toFixed(1) + '" y="' +
               ((tp[1] + qp[1]) / 2 - 6).toFixed(1) +
               '" font-size="11" text-anchor="middle" fill="#17694a">' +
               km.toFixed(2) + ' km</text>');

    stage.innerHTML = parts.join('');

    document.getElementById('idx').textContent = np.name + '(序号 ' + seq + ')';
    document.getElementById('dist').textContent = km.toFixed(3) + ' km';
    document.getElementById('tgt').textContent =
      target.geometry.coordinates[0].toFixed(4) + ', ' +
      target.geometry.coordinates[1].toFixed(4);
  }

  document.getElementById('move').addEventListener('click', function () {
    target = turf.point([
      BOX[0] + 0.03 + Math.random() * (BOX[2] - BOX[0] - 0.06),
      BOX[1] + 0.03 + Math.random() * (BOX[3] - BOX[1] - 0.06)
    ]);
    draw();
  });

  draw();
})();
</script>
</body>
</html>
Language: the code and this page are in English; the full tutorial and API notes for this example are in Chinese. The demo itself is the authoritative version — it runs exactly as shown.

More Turf.js examples

Turf.js · EXAMPLENearest Point Line Turf.js · EXAMPLEPoint in Polygon Turf.js · EXAMPLEPoint in Polygon Batch