效果如下:
leaflet生成等值面网上搜索了好多资料但测试感觉都有点瑕疵,kriging.js 生成的canvas图片每个都是小方格影响美感,turf.js会有非法Polygon且有白色缝隙。就想着可不可以使用kriging.js生成等值面,turf,js进行裁剪。
但kriging.js返回的是栅格图片,偶然间查看到kriging-contour.js 可以返回矢量数据。(
https://github.com/FreeGIS/kriging-contour
)
具体代码如下:
kriging-contour.js 生成等值面的边界是根据传入的点坐标最大值最小值计算的,但按照我的点位数据,最后生成的等值面不能填充满geojson边界数据,我又在源码修改下,传个边界参数,如果有需要的可以自己加一下。
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>leaflet克里金空间加插值turf.js</title>
<style>
html,
body,
#map {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
cursor: default;
</style>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.8.0/dist/leaflet.css" integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9+580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ==" crossorigin="" />
<!-- Make sure you put this AFTER Leaflet's CSS -->
<script src="https://unpkg.com/leaflet@1.8.0/dist/leaflet.js" integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ==" crossorigin=""></script>
<script src="./js/truf.js"></script>
<script src="./js/kriging-contour.js"></script>
<script src="./json/clip.js"></script>
<script src="./json/clippoint.js"></script>
</head>
<div id="map"></div>
<script>
var map = L.map('map', {
center: [38.65953686, 120.8696333],
zoom: 9
let name = L.tileLayer(
"http://wprd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7",
).addTo(map);
// 计算边界范围
let dd1 = turf.bbox(boundaries);
let points1 = {
type: "FeatureCollection",
features: []
pointvalue.map(item => {
points1.features.push({
geometry: {
coordinates: [item.lng, item.lat],
type: 'Point'
properties: {
value: item.value
type: 'Feature'
//计算克里金等值面
let levelV = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 250, 260, 270, 280, 290, 300, 400];
let colors = [{
fill: "#ffdc84"
fill: "#ffd782"
fill: "#ffd281"
fill: "#ffcd7f"
fill: "#ffc87e"
fill: "#ffc37c"
fill: "#ffbe7a"
fill: "#ffb979"
fill: "#feb477"
fill: "#feaf76"
fill: "#feaa74"
fill: "#fea573"
fill: "#fea071"
fill: "#fe9b6f"
fill: "#fe966e"
fill: "#fe906c"
fill: "#fe8b6b"
fill: "#fe8669"
fill: "#fe8167"
fill: "#fe7c66"
fill: "#fe7764"
fill: "#fe7263"
fill: "#fd6d61"
fill: "#fd6860"
fill: "#fd635e"
fill: "#fd5e5c"
fill: "#fd595b"
fill: "#fd5459"
fill: "#fd4f58"
fill: "#fd4a56"
let kriging_contours = kriging.getVectorContour(points1, 'value', {
model: 'exponential',
sigma2: 0,
alpha: 100
}, levelV, dd1);
function hotColor(d) {
let index = levelV.findIndex((item) => item >= d);
if (index > -1) {
return colors[index].fill
} else {
return colors[colors.length - 1].fill
function sortArea(a, b) {
return turf.area(b) - turf.area(a);
//按照面积对图层进行排序,规避turf的一个bug
kriging_contours.features.sort(sortArea)
//后面使用要求输入的参数为Feature<Polygon> ,而turf.isobands的是 MultiPolygon,需要先 flatten() 处理一下,同时去掉图形为空的记录
boundaries = turf.flatten(boundaries); //行政边界
kriging_contours = turf.flatten(kriging_contours); //等值面边界
//console.log('kriging_contours:'+JSON.stringify(kriging_contours));
//根据行政边界裁剪图形,
//现在放大一些区域边界还是没有充满 后面可以封装成一个插件,在源码里面进行canvas clip 剪辑只显示的geojson区域,其余的栅格部分不显示
let features = []; //裁剪后的结果集
kriging_contours.features.forEach(function(feature1) {
boundaries.features.forEach(function(feature2) {
let intersection = null;
try {
intersection = turf.intersect(feature1, feature2);
} catch (e) {
try {
//色斑图绘制之后,可能会生成一些非法 Polygon
//解决的方法通常就是做一次 turf.buffer() 操作,这样可以把一些小的碎片 Polygon 清理掉。
feature1 = turf.buffer(feature1, 0);
intersection = turf.intersect(feature1, feature2);
} catch (e) {
intersection = feature1; //实在裁剪不了就不裁剪了,根据业务需求自行决定
if (intersection != null) {
intersection.properties = feature1.properties;
intersection.id = (Math.random() * 100000).toFixed(0);
features.push(intersection);
let intersection = turf.featureCollection(features);
L.geoJSON(intersection, {
style: function(feature) {
return {
fillColor: hotColor(feature.properties.value),
weight: 0,
fillOpacity: 0.3,
}).addTo(map);
</script>
</body>
</html>
clip.js 是geojson 边界数据,
clippoint.js是插值点数据,部分格式如下:
"lat": 34.42,
"lng": 115.66,
"value": 299,
"lat": 36.53,
"lng": 118.44,
"value": 312,
"lat": 36.4,
"lng": 117,
"value": 321,
........
参考文档:https://segmentfault.com/a/1190000022293641?utm_source=tag-newest