Intersect
Runnable Turf.js example: Intersect. Open the live demo, read the complete source, and copy the file into your project. No build step or API key.
single HTML file · CDN dependencies onlyinterface may contain Chinese labels
Source
<!--
示例:多边形相交 — 移动第二个面,观察 turf.intersect 的交集与 null 返回
核心逻辑:滑块改变纬度偏移量,每次重算交集并判空
依赖: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:12px;align-items:center;padding:8px 12px;
background:#f6f7f9;border-bottom:1px solid #e3e6ea;font-size:12px;color:#58606e;flex-wrap:wrap}
.bar input[type=range]{width:180px}
.bar b{color:#16181d;font-weight:600}
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}
.warn{color:#c2410c}
</style>
</head>
<body>
<div class="bar">
<label>第二个面北移 <input id="off" type="range" min="0" max="0.10" step="0.005" value="0"> <b id="ov">0.000°</b></label>
<span>相交面积 <b id="area">—</b></span>
</div>
<svg id="stage" viewBox="0 0 640 320" preserveAspectRatio="xMidYMid meet"></svg>
<div class="out">
<span>类型 <b id="type">—</b></span>
<span>状态 <span id="status">—</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 A = turf.polygon([[
[116.300, 39.880], [116.440, 39.880], [116.440, 39.960],
[116.300, 39.960], [116.300, 39.880]
]]);
var B_BASE = [
[116.380, 39.900], [116.520, 39.900], [116.520, 39.980],
[116.380, 39.980], [116.380, 39.900]
];
var W = 640, H = 320, PAD = 34;
var BOX = [116.27, 39.855, 116.55, 40.10];
var stage = document.getElementById('stage');
var slider = document.getElementById('off');
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];
}
function ringPath(ring) {
var d = '';
for (var i = 0; i < ring.length; i++) {
var p = pr(ring[i]);
d += (i ? 'L' : 'M') + p[0].toFixed(1) + ' ' + p[1].toFixed(1);
}
return d + 'Z';
}
function draw() {
var dy = parseFloat(slider.value);
var B = turf.polygon([B_BASE.map(function (c) {
return [c[0], c[1] + dy];
})]);
var inter = turf.intersect(A, B);
var parts = ['<rect x="0" y="0" width="640" height="320" fill="none" stroke="#e3e6ea"/>'];
parts.push('<path d="' + ringPath(A.geometry.coordinates[0]) +
'" fill="rgba(31,95,208,0.10)" stroke="#1f5fd0" stroke-width="1.6"/>');
parts.push('<path d="' + ringPath(B.geometry.coordinates[0]) +
'" fill="rgba(194,65,12,0.10)" stroke="#c2410c" stroke-width="1.6"/>');
if (inter) {
var coords = inter.geometry.type === 'MultiPolygon'
? inter.geometry.coordinates
: [inter.geometry.coordinates];
coords.forEach(function (poly) {
poly.forEach(function (ring) {
parts.push('<path d="' + ringPath(ring) +
'" fill="rgba(23,105,74,0.35)" fill-rule="evenodd" ' +
'stroke="#17694a" stroke-width="2"/>');
});
});
var a = pr(A.geometry.coordinates[0][0]);
parts.push('<text x="' + (a[0] + 6).toFixed(1) + '" y="' + (a[1] + 16).toFixed(1) +
'" font-size="12" fill="#1f5fd0">A</text>');
var b = pr(B.geometry.coordinates[0][0]);
parts.push('<text x="' + (b[0] + 6).toFixed(1) + '" y="' + (b[1] + 16).toFixed(1) +
'" font-size="12" fill="#c2410c">B</text>');
document.getElementById('area').textContent =
(turf.area(inter) / 1e6).toFixed(2) + ' km²';
document.getElementById('type').textContent = inter.geometry.type;
document.getElementById('status').textContent = '有公共部分';
document.getElementById('status').className = '';
} else {
document.getElementById('area').textContent = '0';
document.getElementById('type').textContent = 'null';
document.getElementById('status').textContent = '无交集,返回 null';
document.getElementById('status').className = 'warn';
}
stage.innerHTML = parts.join('');
document.getElementById('ov').textContent = dy.toFixed(3) + '°';
}
slider.addEventListener('input', 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.