Leaflet加turf生成等值线图(或色斑图)并单击显示值,效果如下图所示:

参考代码如下:

index.html

<!DOCTYPE html>
<html lang="en" >
<head><meta charset="UTF-8"><title>CodePen - turfjs-interpolate-isoband</title><link rel='stylesheet' href='../leaflet1.2.css'><link rel="stylesheet" href="style.css"></head>
<body>
<!-- partial:index.partial.html -->
<div id='menu-ui' class='menu-ui'></div>
<div id='map'></div>
<!-- partial --><script src='../turf5.1.6.min.js'></script>
<script src='../leaflet1.2.js'></script>
<script  src="script.js"></script></body>
</html>

script.js

let boundaries = {type: "FeatureCollection",name: "boundaries",crs: { type: "name", properties: { name: "urn:ogc:def:crs:OGC:1.3:CRS84" } },features: [{type: "Feature",properties: {},geometry: {type: "MultiPolygon",coordinates: [ [ [ [ 110.763, 41.376 ], [ 110.823, 41.381 ], [ 110.815, 41.357 ], [ 110.944, 41.317 ], [ 110.978, 41.346 ], [ 111.026, 41.299 ], [ 111.085, 41.285 ], [ 111.096, 41.306 ], [ 111.232, 41.238 ], [ 111.273, 41.289 ], [ 111.439, 41.327 ], [ 111.724, 41.309 ], [ 111.833, 41.252 ], [ 111.822, 41.216 ], [ 111.862, 41.204 ], [ 111.874, 41.129 ], [ 112.027, 41.046 ], [ 112.011, 41.003 ], [ 112.035, 40.968 ], [ 112.138, 40.938 ], [ 112.178, 40.818 ], [ 112.144, 40.761 ], [ 112.086, 40.738 ], [ 112.124, 40.697 ], [ 112.108, 40.657 ], [ 112.038, 40.654 ], [ 112.092, 40.587 ], [ 112.046, 40.559 ], [ 112.218, 40.448 ], [ 112.259, 40.391 ], [ 112.229, 40.354 ], [ 112.264, 40.356 ], [ 112.305, 40.253 ], [ 111.964, 39.795 ], [ 111.925, 39.611 ], [ 111.829, 39.619 ], [ 111.777, 39.588 ], [ 111.64, 39.643 ], [ 111.511, 39.663 ], [ 111.43, 39.642 ], [ 111.435, 39.67 ], [ 111.358, 39.721 ], [ 111.366, 39.789 ], [ 111.439, 39.896 ], [ 111.405, 40.044 ], [ 111.308, 40.151 ], [ 111.039, 40.27 ], [ 111.024, 40.31 ], [ 111.108, 40.33 ], [ 111.121, 40.382 ], [ 110.953, 40.495 ], [ 110.895, 40.483 ], [ 110.837, 40.534 ], [ 110.874, 40.585 ], [ 110.796, 40.611 ], [ 110.78, 40.79 ], [ 110.705, 40.805 ], [ 110.739, 40.917 ], [ 110.623, 40.941 ], [ 110.672, 41.053 ], [ 110.639, 41.1 ], [ 110.65, 41.164 ], [ 110.554, 41.224 ], [ 110.559, 41.261 ], [ 110.512, 41.291 ], [ 110.547, 41.288 ], [ 110.569, 41.331 ], [ 110.629, 41.31 ], [ 110.719, 41.385 ], [ 110.763, 41.376 ] ] ] ] } }]
};let points = turf.randomPoint(30, { bbox: turf.bbox(boundaries) });turf.featureEach(points, function (currentFeature, featureIndex) {currentFeature.properties = { value: (Math.random() * 100).toFixed(2) };
});
//console.log(JSON.stringify(points));var interpolate_options = {gridType: "points",property: "value",units: "degrees",weight: 10
};
let grid = turf.interpolate(points, 0.05, interpolate_options);
// 适当降低插值结果的精度便于显示
grid.features.map((i) => (i.properties.value = i.properties.value.toFixed(2)));var isobands_options = {zProperty: "value",commonProperties: {"fill-opacity": 0.8},// breaksProperties: [//   {fill: "#e3e3ff"},//   {fill: "#c6c6ff"},//   {fill: "#a9aaff"},//   {fill: "#8e8eff"},//   {fill: "#7171ff"},//   {fill: "#5554ff"},//   {fill: "#3939ff"},//   {fill: "#1b1cff"},//   {fill: "#1500ff"}// ]breaksProperties: [{fill: "rgb(234,234,234)"},{fill: "rgb(140,246,130)"},{fill: "rgb(0,191,27)"},{fill: "rgb(62,185,255)"},{fill: "rgb(25,0,235)"},{fill: "rgb(255,0,255)"},{fill: "rgb(140,0,65)"}]
};
let levelV = [1, 10, 20, 30, 50, 70, 100];
let isobands = turf.isobands(grid,levelV,isobands_options
);
function sortArea(a,b)
{return turf.area(b)-turf.area(a);
}
//按照面积对图层进行排序,规避turf的一个bug
isobands.features.sort(sortArea)
//后面使用要求输入的参数为Feature<Polygon> ,而turf.isobands的是 MultiPolygon,需要先 flatten() 处理一下,同时去掉图形为空的记录
boundaries = turf.flatten(boundaries); //行政边界
isobands = turf.flatten(isobands);//等值面边界
//console.log('isobands:'+JSON.stringify(isobands));//统计图形坐标为顺序针和逆时针的数量
let clockwiseNum = 0; //顺时针图形数量
let notClockwiseNum = 0; //逆时针图形数量
let notClockwisePartNum = 0; //逆时针图形部件数量
let notClockwiseIndex = 0; //逆时针图形序号
isobands.features.forEach(function (feature, index) {let partNum = 0; //记录图形部件数let haveNotClockwise = false; //记录图形是否带逆时针部件feature.geometry.coordinates.forEach(function (coords) {let booleanClockwise = turf.booleanClockwise(coords);if(booleanClockwise)clockwiseNum++;else{notClockwiseNum++;haveNotClockwise = true;}partNum++;console.log('a'+partNum+':'+booleanClockwise);//console.log(coords);});//有逆时针图形时记录逆时针图形部件数量和逆时针图形序号if(haveNotClockwise){notClockwisePartNum = partNum;notClockwiseIndex = index;}//turf.isobands有点不符合业务预期,只有一个逆时针图形是镂空图形缺少外环的错误问题,写点程序补救下if(partNum==1&&haveNotClockwise){let coords=[];let gridBox = turf.bbox(grid);let gridBoxPolygon = [[gridBox[0],gridBox[1]],[gridBox[0],gridBox[3]],[gridBox[2],gridBox[3]],[gridBox[2],gridBox[1]],[gridBox[0],gridBox[1]]];coords.push(gridBoxPolygon);isobands.features.forEach(function (feature, index) {if(index!=notClockwiseIndex){feature.geometry.coordinates.forEach(function (item) {if(turf.booleanClockwise(coords))coords.push(item.reverse());elsecoords.push(item);});}});isobands.features[notClockwiseIndex].geometry.coordinates=coords;if(isobands.features.length==1){ //图层只有一个镂空图形时属性可能不对需要重新赋值let maxAttribute = getMaxAttribute(levelV,grid,isobands_options.breaksProperties);let value = maxAttribute[0];let fill = maxAttribute[1];if(value!=''&&fill!=''){isobands.features[notClockwiseIndex].properties.value = value;isobands.features[notClockwiseIndex].properties.fill = fill;}}}
});//turf.isobands有点不符合业务预期
// //if(isobands.features.length==2){//只有两个图形的情况下,一个图形包含另一个图形时,大图形缺少外环显示错误,写点程序补救下
// //  if(isobands.features[0].geometry.coordinates.length==1&&isobands.features[1].geometry.coordinates.length==1){
// //    if(turf.booleanClockwise(isobands.features[0].geometry.coordinates[0])){
// //     if(!turf.booleanClockwise(isobands.features[1].geometry.coordinates[0])){
// //         let gridBox = turf.bbox(grid);
// //         let gridBoxPolygon = [[gridBox[0],gridBox[1]],[gridBox[0],gridBox[3]],[gridBox[2],gridBox[3]],[gridBox[2],gridBox[1]],[gridBox[0],gridBox[1]]];
// //         isobands.features[1].geometry.coordinates.unshift(gridBoxPolygon);
// //       }
// //   }
// //   else{
// //       if(turf.booleanClockwise(isobands.features[1].geometry.coordinates[0])){
// //         let gridBox = turf.bbox(grid);
// //         let gridBoxPolygon = [[gridBox[0],gridBox[1]],[gridBox[0],gridBox[3]],[gridBox[2],gridBox[3]],[gridBox[2],gridBox[1]],[gridBox[0],gridBox[1]]];
// //         isobands.features[0].geometry.coordinates.unshift(gridBoxPolygon);
// //     }
// //   }
// //  }
// //}
// //else{
//   if(notClockwiseNum==1&&notClockwisePartNum==1){//有些镂空图形缺少外环显示错误,写点程序补救下
//    let coords=[];
//    let gridBox = turf.bbox(grid);
//    let gridBoxPolygon = [[gridBox[0],gridBox[1]],[gridBox[0],gridBox[3]],[gridBox[2],gridBox[3]],[gridBox[2],gridBox[1]],[gridBox[0],gridBox[1]]];
//    coords.push(gridBoxPolygon);
//    isobands.features.forEach(function (feature, index) {
//      if(index!=notClockwiseIndex){
//        feature.geometry.coordinates.forEach(function (item) {
//          coords.push(item.reverse());
//        });
//      }
//    });
//    isobands.features[notClockwiseIndex].geometry.coordinates=coords;
//     if(isobands.features.length==1){ //图层只有一个镂空图形时属性可能不对需要重新赋值
//      let maxAttribute = getMaxAttribute(levelV,grid,isobands_options.breaksProperties);
//      let value = maxAttribute[0];
//      let fill = maxAttribute[1];
//      if(value!=''&&fill!=''){
//        isobands.features[notClockwiseIndex].properties.value = value;
//        isobands.features[notClockwiseIndex].properties.fill = fill;
//      }
//     }
//   }
// //}//根据行政边界裁剪图形
let features = [];//裁剪后的结果集
isobands.features.forEach(function (feature1) {boundaries.features.forEach(function (feature2) {let intersection = null;try {intersection = turf.intersect(feature1, feature2);} catch (e) {try{//色斑图绘制之后,可能会生成一些非法 Polygon ,例如 在 hole 里存在一些形状(听不懂?去查一下 GeoJSON 的规范),//我遇到的一个意外情况大概是这样,这种 Polygon 在做 intersect() 操作的时候会报错,所以在代码中做了个容错操作。//解决的方法通常就是做一次 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);}});
});//turf.isobands有点不符合业务预期,只有一个等级时,结果集可能为空,无图形显示,写点程序(找出那一个等级,并添加进结果集)补救下
if(features.length == 0){let maxAttribute = getMaxAttribute(levelV,grid,isobands_options.breaksProperties);let value = maxAttribute[0];let fill = maxAttribute[1];if(value!=''&&fill!=''){//获取网格点Boxlet gridBox = turf.bbox(grid);//生成网格点范围的面let gridBoxPolygon = [[[gridBox[0],gridBox[1]],[gridBox[0],gridBox[3]],[gridBox[2],gridBox[3]],[gridBox[2],gridBox[1]],[gridBox[0],gridBox[1]]]];//获取网格范围的面与行政边界的交集 Polygonlet intersectPolygon = null;let gridoxFeature = {"type":"Feature","properties":{"fill-opacity":0.8},"geometry":{"type":"Polygon","coordinates":gridBoxPolygon},"id":10};try {intersectPolygon = turf.intersect(gridoxFeature, boundaries.features[0]);} catch (e) {try{//色斑图绘制之后,可能会生成一些非法 Polygon ,例如 在 hole 里存在一些形状(听不懂?去查一下 GeoJSON 的规范),//我遇到的一个意外情况大概是这样,这种 Polygon 在做 intersect() 操作的时候会报错,所以在代码中做了个容错操作。//解决的方法通常就是做一次 turf.buffer() 操作,这样可以把一些小的碎片 Polygon 清理掉。gridoxFeature = turf.buffer(gridoxFeature, 0);intersectPolygon = turf.intersect(gridoxFeature, boundaries.features[0]);} catch (e) {intersectPolygon = gridoxFeature;//实在裁剪不了就不裁剪了,根据业务需求自行决定}}//结果添加到结果数组if (intersectPolygon != null){features.push({"type":"Feature","properties":{"fill-opacity":0.8,"fill":fill,"value":value},"geometry":intersectPolygon.geometry,"id":0});}}
}//console.log('features:'+JSON.stringify(features));
let intersection = turf.featureCollection(features);// 可视化及交互部分
//图层
var baseLayer = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {attribution: '...',maxZoom: 18}
);
var map = new L.Map('map', {center: new L.LatLng(40.4865, 111.4085),//110.763, 41.376   39.62353145, 121.9937485zoom: 8, //4attributionControl:false, //是否去除右下角标志layers: [baseLayer]
});
map.bounds = turf.bbox(boundaries);// 逐个添加过程中的数据L.geoJSON(boundaries, {style: function (feature) {return {color: '#4264fb', weight:1, fillOpacity:0};}}).addTo(map);//由于leaflet中没有找到图层显示隐藏属性,建一个字符串记录leaflet地图中显示的图层let layerstr = "";var layerM = new Map(); //记录创建的图层列表//原始点图层var geojsonMarkerOptions = {  // geojson点的样式radius: 3,fillColor: "#ff7800",color: "#000",weight: 1,opacity: 1,fillOpacity: 0.8};var pointsLay = L.geoJSON(points, {  // 添加geojson数据pointToLayer: function (feature, latlng){return L.circleMarker(latlng, geojsonMarkerOptions);}}).addTo(map);var pointsTxtLay = L.geoJSON(points, {  // 添加geojson数据pointToLayer: function (feature, latlng){//marker的icon文字var myIcon = L.divIcon({html: "<div style='color:#000;margin-top:-5px'>"+feature.properties.value+"</div>",className: 'my-div-icon',iconSize: 30});return L.marker(latlng, { icon: myIcon});}}).addTo(map);layerstr = layerstr + "points,";layerM.set("points",pointsLay);layerM.set("pointsTxt",pointsTxtLay);//网格差值结果var gridLay = L.geoJSON(grid, {pointToLayer: function (feature, latlng){//marker的icon文字var myIcon = L.divIcon({html: "<div style='color:#FF0000'>"+feature.properties.value+"</div>",className: '',iconSize: 30});return L.marker(latlng, { icon: myIcon});}});//显示信息let identifyGrid = function (e) {if (e.value !== null) {//let v = e.value.toFixed(3);let v = e.layer.feature.properties.value;let html = `<span class="popupText">Surface currents velocity ${v} ml</span>`;let popup = L.popup().setLatLng(e.latlng).setContent(html).openOn(map);}};// Bilinear interpolationgridLay.interpolate = true;gridLay.on('click', identifyGrid);layerM.set("grid",gridLay);//差值结果分级var isobandsLay = L.geoJSON(isobands, {style: function (feature) {return {color: '#4264fb',fillColor:feature.properties.fill, weight:0.1, fillOpacity:0.2};}});layerM.set("isobands",isobandsLay);//差值分级后再根据行政区裁剪后的图层var intersectionLay = L.geoJSON(intersection, {style: function (feature) {return {color: '#ffffff',fillColor:feature.properties.fill, weight:0.1, fillOpacity:0.2};}}).addTo(map);//显示属性信息let identify = function (e) {if (e.value !== null) {//let v = e.layer.feature.properties.value;//获取的值为区间值let v = getPointValue(e.latlng.lat,e.latlng.lng);//获取的值为IDW差的值let html = `<span class="popupText">Surface currents velocity ${v} ml</span>`;let popup = L.popup().setLatLng(e.latlng).setContent(html).openOn(map);}};intersectionLay.on('click', identify);//定位到geojson数据上//map.fitBounds(intersectionLay.getBounds());layerstr = layerstr + "intersection,";layerM.set("intersection",intersectionLay);//根据网格点计算任意经纬度值function getPointValue(lat,lon){let latMin = 0.0, latMax = 0.0, lonMin = 0.0, lonMax = 0.0;let leftTopV = 0, rightTopV = 0, rightButtomV = 0, leftButtomV = 0;//先求任意经纬度点所在的网格坐标grid.features.forEach(function(item){if(item.geometry.coordinates[0]<=lon && item.geometry.coordinates[1]>=lat){//lonMin = item.geometry.coordinates[0];//latMax = item.geometry.coordinates[1];if(lonMin == 0.0){lonMin = item.geometry.coordinates[0];latMax = item.geometry.coordinates[1];}else{lonMin = ((lon-item.geometry.coordinates[0])<(lon-lonMin))?item.geometry.coordinates[0]:lonMin;latMax = ((item.geometry.coordinates[1]-lat)<(latMax-lat))?item.geometry.coordinates[1]:latMax;}//leftTopV = item.properties.value;}//if(item.geometry.coordinates[0]>=lon && item.geometry.coordinates[1]>=lat){//lonMax = item.geometry.coordinates[0];//latMax = item.geometry.coordinates[1];//lonMax = ((item.geometry.coordinates[0]-lon)<(lonMax-lon)?item.geometry.coordinates[0]:lonMax);//latMax = ((item.geometry.coordinates[1]-lat)<(latMax-lat))?item.geometry.coordinates[1]:latMax;//rightTopV = item.properties.value;//}if(item.geometry.coordinates[0]>=lon && item.geometry.coordinates[1]<=lat){//lonMax = item.geometry.coordinates[0];//latMin = item.geometry.coordinates[1];if(lonMax == 0.0){lonMax = item.geometry.coordinates[0];latMin = item.geometry.coordinates[1];}else{lonMax = ((item.geometry.coordinates[0]-lon)<(lonMax-lon))?item.geometry.coordinates[0]:lonMax;latMin = ((lat-item.geometry.coordinates[1])<(lat-latMin))?item.geometry.coordinates[1]:latMin;}//rightButtomV = item.properties.value;}//if(item.geometry.coordinates[0]<=lon && item.geometry.coordinates[1]<=lat){//lonMin = item.geometry.coordinates[0];//latMin = item.geometry.coordinates[1];//lonMin = ((lon-item.geometry.coordinates[0])<(lon-lonMin)?item.geometry.coordinates[0]:lonMin);//latMin = ((lat-item.geometry.coordinates[1])<(lat-latMin))?item.geometry.coordinates[1]:latMin;//leftButtomV = item.properties.value;//}});//再求任意经纬度点所在的网格上点的值grid.features.forEach(function(item){if(item.geometry.coordinates[0]==lonMin && item.geometry.coordinates[1]==latMax){leftTopV = item.properties.value;}if(item.geometry.coordinates[0]==lonMax && item.geometry.coordinates[1]==latMax){rightTopV = item.properties.value;}if(item.geometry.coordinates[0]==lonMax && item.geometry.coordinates[1]==latMin){rightButtomV = item.properties.value;}if(item.geometry.coordinates[0]==lonMin && item.geometry.coordinates[1]==latMin){leftButtomV = item.properties.value;}});//开始通过IDW算法计算网格上任意点的值let idwdatas = [{x:lonMin,y:latMax,v:leftTopV},{x:lonMax,y:latMax,v:rightTopV},{x:lonMax,y:latMin,v:rightButtomV},{x:lonMin,y:latMin,v:leftButtomV}];var idwresult = [{x:lon,y:lat,v:0}];idwcomputer(idwdatas,idwresult);//console.info(idwresult);//结束通过IDW算法计算网格上任意点的值let rValue = idwresult[0].v.toFixed(2);//获取任意经纬度点的值return rValue;}//idw算法function idwcomputer(datas,result){if(datas.lenght<3) return result;var m0=datas.length;var m1=result.length;//距离列表var r=[];for(var i=0;i<m1;i++){for(var j=0;j<m0;j++){var tmpDis = Math.sqrt(Math.pow(result[i].x - datas[j].x, 2) + Math.pow(result[i].y - datas[j].y, 2));r.push(tmpDis);}}//插值函数for (var i = 0; i < m1; i++){//查找重复var ifFind = false;for (var j = m0 * i; j < m0 * i + m0; j++){if (Math.abs(r[j]) < 0.0001){result[i].v = datas[j - m0 * i].v;ifFind = true;break;}}if (ifFind) continue;var numerator = 0;var denominator = 0;for (var j = m0 * i; j < m0 * i + m0; j++){numerator += datas[j - m0 * i].v / (r[j] * r[j]);denominator += 1 / (r[j] * r[j]);}result[i].v = numerator / denominator;}return result;}//取网格点中等级包含最多的点的等级属性function getMaxAttribute(inLevelV,inGrid,inBreaksProperties){//定义变量let levelArray = [];let levelLength = inLevelV.length;inLevelV.forEach(function (item, index) {if(index<levelLength-2)levelArray.push(0);});//统计每个等级中网格点数量inGrid.features.map((i) => {inLevelV.forEach(function (item, index) {if(index<levelLength-3){if(i.properties.value>=inLevelV[index]&&i.properties.value<inLevelV[index+1])levelArray[index]++;}if(index==levelLength-2){if(i.properties.value>=inLevelV[index])levelArray[index]++;}});});//取等级中网格点最多的值let maxIndex = -1;let maxV = 0;levelArray.forEach(function (item, index) {if(maxV<item){maxV = item; maxIndex = index;}});let value = '';let fill='';if(maxIndex != -1){value = inLevelV[maxIndex] + '-' + inLevelV[maxIndex+1];fill=inBreaksProperties[maxIndex].fill;}return [value,fill]}// 右上角的导航菜单var layers = document.getElementById("menu-ui");var toggleableLayerIds = ["points", "grid", "isobands", "intersection"];for (var i = 0; i < toggleableLayerIds.length; i++) {var id = toggleableLayerIds[i];var link = document.createElement("a");link.href = "#";link.className = layerstr.indexOf(id+",") == -1 ? "" : "active";link.textContent = id;link.onclick = function (e) {let clickedLayer = this.textContent;e.preventDefault();e.stopPropagation();let visibility = layerstr.indexOf(clickedLayer+",");if (visibility === -1) {this.className = "active";map.addLayer(layerM.get(clickedLayer));if(clickedLayer=="points"){map.addLayer(layerM.get(clickedLayer+"Txt"));}layerstr = layerstr + clickedLayer + ",";} else {map.removeLayer(layerM.get(clickedLayer));if(clickedLayer=="points"){map.removeLayer(layerM.get(clickedLayer+"Txt"));}this.className = "";layerstr = layerstr.replace(clickedLayer + ",","");}};layers.appendChild(link);}// var hoveredStateId = null;
// map.on("mousemove", "intersection", function (e) {
//   if (e.features.length > 0) {
//     if (hoveredStateId) {
//       map.setFeatureState(
//         { source: "intersection", id: hoveredStateId },
//         { hover: false }
//       );
//     }
//     hoveredStateId = e.features[0].id;
//     map.setFeatureState(
//       { source: "intersection", id: hoveredStateId },
//       { hover: true }
//     );
//   }
// });// var map = L.map("mapDiv").setView([36.55,117.32],13);
// L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{attribution:'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'}).addTo(map);
// L.marker([36.55,117.32]).addTo(map);
// L.polyline([[36.54,117.33],[36.55,117.33],[36.56,117.35],[36.55,117.36]]).addTo(map);
// L.polygon([[[36.53,117.32],[36.51,117.30],[36.51,117.33],[36.53,117.32]]]).addTo(map);
// L.circle([36.52,117.30],{radius:200}).addTo(map);
// L.circleMarker([36.54,117.29],{radius:20}).addTo(map);

style.css

body {margin: 0;padding: 0;
}
#map {position: absolute;top: 0;bottom: 0;width: 100%;
}
.menu-ui {background: #fff;position: absolute;top: 10px;right: 10px;z-index: 999;border-radius: 3px;width: 120px;border: 1px solid rgba(0, 0, 0, 0.4);
}
.menu-ui a {font-size: 13px;color: #404040;display: block;margin: 0;padding: 0;padding: 10px;text-decoration: none;border-bottom: 1px solid rgba(0, 0, 0, 0.25);text-align: center;
}
.menu-ui a:first-child {border-radius: 3px 3px 0 0;
}
.menu-ui a:last-child {border: none;border-radius: 0 0 3px 3px;
}
.menu-ui a:hover {background: #f8f8f8;color: #404040;
}
.menu-ui a.active {background: #3887be;color: #fff;
}
.menu-ui a.active:hover {background: #3074a4;
}

本文大部分参考:Javascript(turfjs)等值线图绘制 - SegmentFault 思否

Leaflet加turf生成色斑图并单击显示范围值或精准值-Javascript文档类资源-CSDN文库

Leaflet加turf生成等值线图(或色斑图)并单击显示值相关推荐

  1. 如何实现通过Leaflet加载dwg格式的CAD图

  2. echarts雷达图类目下显示值

    initRadar() {let chartDom = this.$refs.radar;let myChart = echarts.init(chartDom);let i = -1;// 获取数据 ...

  3. unity读取灰度图生成等值线图

    准备灰度图 grayTest.png,放置于Assets下StreamingAssets文件夹中. 在场景中添加RawImage用于显示最后的等值线图. 生成等值线的过程,使用Marching squ ...

  4. leaflet加载Geoq智图,4种形式切换(示例代码033)

    第033个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet加载Geoq智图,这里使用了control.layers进行多个底图间的自由切换. 直接复制下面的 vue+leafle ...

  5. leaflet加载百度地图(路网矢量图和卫星影像图)示例代码032

    第032个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet加载百度地图,这里使用了control.layers进行切换两种不同的百度底图.这里要引用proj4,proj4leaf ...

  6. openlayers加kriging出等值线图

    openlayers加kriging出等值线图 方法一 效果图 代码 <!DOCTYPE html> <html> <head><meta charset=& ...

  7. Python自动生成代码 - 通过tkinter图形化操作生成代码框架

    Python自动生成代码 - 通过tkinter图形化操作生成代码框架 背景 脚本代码 Demo_CodeGenerator.py display.py FileHandler.py: 脚本运行结果: ...

  8. GeoServer发布影像金字塔并leaflet加载

    如果是几百M的影像数据,我们直接用GeoServer发布就可以了.但如果是几十G的影像数据怎么办? 有经验的同学都知道,首选要先将影像数据构建成金字塔,才可以将数据发布浏览,要不然会卡死. 我们现在就 ...

  9. 使用FFmpeg生成高清gif图

    前言 使用FFmpeg能够很方便的给视频片段或GIF加水印,同时还能对选取的片段生成GIF图,但是在使用默认FFmpeg设置情况下,生成的GIF画质很差,有很明显的栅格化现象.如何生成高质量的GIF是 ...

  10. PHP使用HighChart生成股票K线图详解

    转自:http://blog.csdn.net/wangyuchun_799/article/details/50292315 HighChart是集合了各种常见的web图表的开源合集,其中产生股票K ...

最新文章

  1. R语言使用R基础安装中的glm函数构建乳腺癌二分类预测逻辑回归模型、分类预测器(分类变量)被自动替换为一组虚拟编码变量、summary函数查看检查模型、使用table函数计算混淆矩阵评估分类模型性能
  2. 2020年人工神经网络第二次作业-参考答案第八题
  3. AD域与外部网站域名相同处理办法
  4. 开课吧python小课值得么-好消息!今天,审计、会计、税务、财务主管彻底沸腾了……...
  5. excel常用公式整理
  6. 基于PyTorch框架的多层全连接神经网络实现MNIST手写数字分类
  7. 一个在校的普通前端小姐姐的2021
  8. Active Directory PowerShell模块收集AD信息
  9. 从程序员到项目经理(12):如何管理自己的时间(上)
  10. 一步一步写算法(之“数星星”)
  11. 如何清除以前连接到Mac的WiFi网络
  12. 内存管理之memblock探寻
  13. 海康摄像头SDK跨平台通用解决方案
  14. 软件工程案例学习-网上购书系统
  15. leetcode 904 水果成篮
  16. mui.ajax执行的次数,MUI 中使用 ajax下拉刷新时,数据怎么才能做到累加呢,谢谢...
  17. android 调取数字键盘,Android自定义键盘的实现(数字键盘和字母键盘)
  18. GDAL error: ‘NoneType‘ object has no attribute ‘GetGeoTransform‘
  19. 阿里巴巴Java开发手册github地址
  20. Web大学生网页作业成品 基于HTML+CSS+JavaScript-----苹果商城Apple商城 8页 三级带视频

热门文章

  1. 计算机系统保密检查整改情况函,保密工作整改情况汇报
  2. C#编写的一个SFTP工具类
  3. 基于二叉链表的二叉树最长路径的求解
  4. 微信小程序开发——字体样式设置
  5. linux 深度攻略 pdf,万字深度详细分析 全民主公深度攻略
  6. 我的世界服务器光影文件夹,我的世界光影怎么开?中国版介绍
  7. cmake安装到指定目录
  8. 一文弄清传统软件开发与互联网软件开发的异同
  9. 【11】MINST数据集的分类与效果验证
  10. python 离线安装numpy_Python本地安装numpy包