基于js的idw算法的气象插值图

基于js气象IDW反向权重插值法

居中的图片: 在这里插入图片描述])

##cs代码

//
 <style>
			.frame {
				fill: none;
				stroke: #000;
			}
			
			.axis text {
				font: 10px sans-serif;
			}
			
			.axis line,
			.axis circle {
				fill: none;
				stroke: steelblue;
				stroke-dasharray: 4;
			}
			
			.axis:last-of-type circle {
				stroke: steelblue;
				stroke-dasharray: none;
			}
			
			.line {
				fill: none;
				stroke: orange;
				stroke-width: 3px;
			}
			
			svg {
				opacity: 1;
				filter: alpha(opacity=100);
			}
		</style>
//
##js代码
<div class="zuobiao">
			<canvas id="canvas" style="z-index: -1; opacity:1; position: absolute;  ">  </canvas>
			<canvas id="canvas1" height="400px" width="600px" style=" z-index: -1; position: absolute;  ">  </canvas>
		</div>

		<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

		<script>
			var width = 380,  //图形的宽度
				height = 300; //图形的高度
		</script>
		<script src="js/weathermapIDW.js"></script>

		<script>
			var colorarray = ["#0000FF", "#006EFF", "#00DDFF", "#2AFFFF", "#68FFFF", "#8BFFE8", "#06FF0B", "#49FF7A", "#49FF00", "#9BFF00", "#D2FF00", "#E3FF00", "#F3FF00", "#FFF200", "#FFCB00", "#FFA300", "#FF7D00", "#FF5300", "#FF5300", "#FF0000"];
			var namearray = [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000];
			var table = [{
				"WS": [1.0, 4.0, 2.0, 1.0, 3.0, 3.0, 3.0, 2.0, 2.0, 1.0, 1.0, 1.0, 3.0, 3.0, 3.0, 2.0, 5.0, 4.0, 6.0, 4.0, 2.0, 1.0, 2.0, 3.0, 3.0, 3.0, 4.0, 3.0, 3.0, 7.0, 6.0, 7.0, 4.0, 8.0, 6.0, 6.0, 7.0, 7.0, 6.0, 8.0, 8.0, 8.0, 7.0, 5.0, 4.0, 3.0, 3.0, 1.0, 2.0, 2.0, 2.0, 2.0],
				"WD": [335.0, 350.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 170.0, 135.0, 135.0, 135.0, 90.0, 90.0, 90.0, 90.0, 100.0, 80.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 10.0, 0.0, 20.0, 30.0, 45.0, 45.0, 45.0, 80.0, 45.0, 45.0, 75.0, 45.0, 45.0, 45.0, 60.0, 45.0, 70.0, 80.0, 90.0, 225.0, 270.0, 260.0, 225.0],
				"PM10": [183.2, 173.4, 194.0, 175.75, 203.6, 161.2, 142.0, 163.0, 175.5, 208.4, 205.0, 171.2, 143.6, 116.0, 110.6, 93.2, 98.2, 91.8, 83.6, 88.4, 81.4, 77.0, 81.8, 89.4, 115.8, 131.2, 166.4, 174.0, 170.2, 152.4, 184.4, 203.8, 212.6, 627.8, 1290.4, 1581.25, 1711.525, 1841.8, 2128.4, 2406.8, 2576.8, 2035.6, 1615.0, 1286.8, 1202.4, 1015.2, 733.8, 635.6, 339.2, 331.4, 303.2, 282.6]
			}]

			$(document).ready(function() {
				parm("canvas", width, height);
				wwDrawpolygon(table);
				
				var Legend = {
					"DistanceLeft": width,
					"With": 20,
					"Height": height,
					"Colorarray": colorarray,
					"Namearray": namearray
				};
				zzb("canvas1", Legend);
				//纵坐标
				/**
				 * Name:纵坐标的名称
				 * DistanceTop:距离顶部距离
				 * DistanceLeft:距离左边距距离
				 */
				var OrdinateName = {
					"Name": "风速(m/s)",
					"DistanceTop": 30,
					"DistanceLeft": 10
				};
				/**Scale对象纵坐标标线与刻度
				 * Min:最小值
				 * Max:最大值
				 * Stepnumber:取多少个刻度(步数)
				 * height:圆的高度
				 * DistanceTop:坐标轴距离顶部的距离
				 * DistanceLeft:坐标轴距离左边的距离
				 * FontLeft:坐标轴的字体与纵坐标标线的距离
				 */

				var Scale = {
					"Min": -maxvalue,
					"Max": maxvalue,
					"Stepnumber": 10,
					"height": height,
					"DistanceTop": 30,
					"DistanceLeft": 40,
					"FontLeft": 10
				};
				xzb("canvas1", OrdinateName, Scale);

			});
		</script>

##js代码  weathermapIDW.js


var radius = Math.min(width, height) / 2 - 30;
var canvas;

var canvasID;

var width ;
var	height ;
 var maxvalue = 0;
function parm(id, w, h) {
	canvas = document.getElementById(id);
	canvasID = id;
	//		var context = canvas.getContext("2d");
	width = w;
	height = h;
	radius = Math.min(width, height) / 2 - 30;
//	$("#" + id).height(Math.sqrt(((h - 60) / 2) * ((h - 60) / 2) * 2));
//	$("#" + id).width(Math.sqrt(((h - 60) / 2) * ((h - 60) / 2) * 2));
	
//	var w = ((h - 60) - Math.sqrt(((h - 60) / 2) * ((h - 60) / 2) * 2)) / 2 + 30;
//	$("#" + id).css({
//		"margin-top": w + "px"
//	});
//	var w = (width - Math.sqrt(((h - 60) / 2) * ((h - 60) / 2) * 2)) / 2;
//	$("#" + id).css({
//		"margin-left": w + "px"
//	});
	
	$("#" + id).height(h - 60);
	$("#" + id).width(h - 60);
	$("#" + id).css({
		"margin-top": 30 + "px"
	});
	var w = (width - (h - 60) ) / 2 ;
	$("#" + id).css({
		"margin-left": w  + "px"
	});
	
}
/**
 * canvas1:canvas的id
 * @param {Object} Legend
 *  DistanceLeft:距离左边的距离
 *  With:单位图例高度
 *  Height:单位图例高度
 *  Colorarray:颜色设定值 数据类型 -数组(Array)
 *  Namearray:颜色块儿对应的名称 数据类型 -数组(Array)
 */
function zzb(canvas1, Legend) {

	Legend.Height = (Legend.Height / (Legend.Colorarray.length + 2));
	Legend.DistanceLeft = Legend.DistanceLeft - 30
	var canvas1 = document.getElementById(canvas1);
	var canvasWidth1 = canvas1.width;
	var canvasHeight1 = canvas1.height;
	var context1 = canvas1.getContext("2d");

	for(var i = 0; i < Legend.Colorarray.length; i++) {
		var my_gradient = context1.createLinearGradient(0, 0, 0, Legend.Height);
		if(i != 0) {
			my_gradient.addColorStop(0, Legend.Colorarray[Legend.Colorarray.length - i]);
			my_gradient.addColorStop(1, Legend.Colorarray[Legend.Colorarray.length - i - 1]);
			context1.fillStyle = my_gradient;
			context1.fillRect(Legend.DistanceLeft * 1, Legend.Height * (i + 1), Legend.With, Legend.Height);
			context1.strokeStyle = "#000000";
			context1.strokeRect(Legend.DistanceLeft * 1, Legend.Height * (i + 1), Legend.With, Legend.Height);
			context1.fillStyle = "#000000";
			context1.font = "11px Arial";
			context1.fillText(Legend.Namearray[Legend.Namearray.length - i - 1], Legend.DistanceLeft + Legend.With + 5, Legend.Height * (i + 1) + Legend.Height * 2 / 3);

		} else {
			my_gradient.addColorStop(0, Legend.Colorarray[Legend.Colorarray.length - i - 1]);
			my_gradient.addColorStop(1, Legend.Colorarray[Legend.Colorarray.length - i - 1]);
			context1.fillStyle = my_gradient;
			context1.fillRect(Legend.DistanceLeft, Legend.Height * (i + 1), Legend.With, Legend.Height);
			context1.strokeStyle = "#000000";
			context1.lineHeight = Legend.Height;
			context1.strokeRect(Legend.DistanceLeft, Legend.Height * (i + 1), Legend.With, Legend.Height);
			context1.fillStyle = "#000000";
			context1.font = "11px Arial";
			context1.fillText(Legend.Namearray[Legend.Namearray.length - 1], Legend.DistanceLeft + Legend.With + 5, Legend.Height * (i + 1) + Legend.Height * 2 / 3);

		}
	}

}
/**
 * @param {Object} OrdinateName 纵坐标标题
 * Name:纵坐标的名称
 * DistanceTop:距离顶部距离
 * DistanceLeft:距离左边距距离
 * @param {Object} Scale 纵坐标刻度
 * Min:最小值
 * Max:最大值
 * Stepnumber:取多少个刻度(步数)
 * Step:单位刻度的长度(步长)
 * DistanceTop:坐标轴距离顶部的距离
 * DistanceLeft:坐标轴距离左边的距离
 * DistanceLeft:坐标轴距离左边的距离
 */
function xzb(canvas1, OrdinateName, Scale) {
	var Step = (Scale.height - 60) / Scale.Stepnumber;
	var canvas1 = document.getElementById(canvas1);
	var canvasWidth1 = canvas1.width;
	var canvasHeight1 = canvas1.height;
	var context1 = canvas1.getContext("2d");
	if((OrdinateName == "") && (OrdinateName == null))
		OrdinateName = {
			"Name": "风速(m/s)",
			"DistanceTop": 200,
			"DistanceLeft": 10
		};
	if((Scale == "") && (Scale == null))
		Scale = {
			"Min": -10,
			"Max": 10,
			"Stepnumber": 20,
			"Step": 17,
			"DistanceTop": 30,
			"DistanceLeft": 40,
			"FontLeft": 10
		};

	var Stepname = ((Scale.Max - Scale.Min) / Scale.Stepnumber).toFixed();
	context1.fillStyle = "#000000";

	for(var i = 0; i < (Scale.Stepnumber + 1); i++) {

		if(i != 0) {
			context1.fillRect(Scale.DistanceLeft, Step * (i + 1) + (Scale.DistanceTop - Step), 7, 1);
			context1.font = "11px Arial";
			context1.textAlign = "right";
			context1.fillText(Scale.Min + (Scale.Stepnumber - i) * Stepname, Scale.DistanceLeft - Scale.FontLeft, Step * (i + 1) + (Scale.DistanceTop + 5 - Step));
		} else {
			context1.fillRect(Scale.DistanceLeft, Step * (i + 1) + (Scale.DistanceTop - Step), 7, 1);
			context1.font = "11px Arial";
			context1.textAlign = "right";
			context1.fillText(Scale.Min + (Scale.Stepnumber - i) * Stepname, Scale.DistanceLeft - Scale.FontLeft, Step * (i + 1) + (Scale.DistanceTop + 5 - Step));
		}
	}
	context1.fillRect(Scale.DistanceLeft, Scale.DistanceTop, 1, Step * Scale.Stepnumber);
	context1.font = "12px Arial";
	context1.textAlign = "center";

	var DistanceTop = (Scale.height - 60) / 2;
	context1.translate(OrdinateName.DistanceLeft, DistanceTop + OrdinateName.DistanceTop);
	context1.rotate(270 * Math.PI / 180) 
	context1.fillText(OrdinateName.Name, 0, 0);

}
var zuobiaoname = ['北', '东北', '东', '东南', '南', '西南', '西', '西北', ]

// console.log($(".zuobiao").Width))

var data = [
	[24, 100]
]

var y = _.map(data, _.last);
var max = Math.max.apply(null, y);
max = Math.ceil(max * 10) / 10;

var angle = d3.scale.linear()
	.domain([0, 24])
	.range([0, 2 * Math.PI]);

var r = d3.scale.linear()
	.domain([0, max])
	.range([0, radius]);

var svg = d3.select(".zuobiao").append("svg")
	.attr("width", width)
	.attr("height", height)
	.append("g")
	.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

var gr = svg.append("g")
	.attr("class", "r axis")
	.selectAll("g")
	.data(r.ticks(max * 0.1).slice(1))
	.enter().append("g");

gr.append("circle")
	.attr("r", r);

gr.append("text")
	.attr("y", function(d) {
		return -r(d) - 4 ;
	})
	.attr("transform", "rotate(20)")
	.style("text-anchor", "middle")
	.text(function(d) {
		return d+"%";
	});

var ga = svg.append("g")
	.attr("class", "a axis")
	.selectAll("g")
	.data(d3.range(-90, 270, 45))
	.enter().append("g")
	.attr("transform", function(d) {
		return "rotate(" + d + ")";
	});

ga.append("line")
	.attr("x2", radius);

ga.append("text")
	.attr("x", radius + 6)
	.attr("dy", ".35em")
	.style("text-anchor", function(d) {
		return d < 270 && d > 90 ? "end" : null;
		
	})
	.attr("transform", function(d) {
		console.log(d)
		if(d < 270 && d > 90)
		return d < 270 && d > 90 ? "rotate(180 " + (radius + 6) + ",0)" : null;
		if(d == 90)
		return "rotate(270 " + (radius + 6) + ",5)";   
		if(d == -90)
		return "rotate(90 " + (radius + 6) + ",-5)";
	})
	.attr("y", function(d) {
		if(d == 90)
		return "12";
		if(d == -90)
		return "-12";
	})
	
	.text(function(d, i) {
		return zuobiaoname[i]
	});

var color = d3.scale.category20();

function windrose2polar(a) {

	var d = [];
	for(var i = 0; i < a.length; i++) {
		var r = 360 - a[i] + 90;
		if(r > 360) {
			r = r - 360;
		}
		d.push(r)
	}
	return d;
}

function linspace(a, b, c) { //生成等差数列
	var d = (b - a) / (c - 1);
	var e = ((b - a) / d) + 1;
	var f = [];
	for(var i = 0; i < e; i++) {
		f.push(a + (d * i));
	}
	return f;
}

function radians(a) { //将角度转换为弧度
	var d = [];
	for(var i = 0; i < a.length; i++) {
		var rwd = (a[i] * Math.PI) / 180;
		d.push(rwd)
	}
	return d;
}

function degrees(a) {
	var d = [];
	for(var i = 0; i < a.length; i++) {
		var dwdbins = (a[i] * 180) / Math.PI;
		d.push(dwdbins)
	}
	return d;
}

function histogram(a, wdbins) {
	var numarry = [];
	for(var i = 0; i < wdbins.length - 1; i++) {
		var num = 0;
		for(var y = 0; y < a.length; y++) {
			if((a[y] > wdbins[i]) && (a[y] < wdbins[i + 1])) {
				num++;
			}
		}
		numarry.push(num);
	}
	return numarry;
}

function pol2cartcos(rwd, ws) {
	var cos = [];
	for(var i = 0; i < rwd.length; i++) {
		cos.push(ws[i] * Math.cos(rwd[i]))

		//					cos.push(Math.sqrt(rwd[i]*rwd[i] + ws[i]*ws[i] ));
	}
	return cos;
}

function pol2cartsin(rwd, ws) {
	var sin = [];
	for(var i = 0; i < rwd.length; i++) {
		sin.push(ws[i] * Math.sin(rwd[i]))
	}
	return sin;

}

// 可以借助cos a 在0-180之间,单调递减!!!
// 这里用的是叉积,正弦的判断
function multiply(p0, p1, p2) {
	return((p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y));
}

function distance_no_sqrt(p1, p2) {
	//return(sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))); 
	return((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}

function Graham_scan(pointSet, ch, n) {
	// 这里会修改pointSet
	var i, j, k = 0,
		top = 2;
	var tmp = new Object();
	// 找到一个基点,基本就是保证最下面最左面的点
	for(i = 1; i < n; i++) {
		if((pointSet[i].y < pointSet[k].y) ||
			((pointSet[i].y == pointSet[k].y) && (pointSet[i].x < pointSet[k].x))
		) {
			k = i;
		}
	}

	tmp = pointSet[0];
	pointSet[0] = pointSet[k];
	pointSet[k] = tmp;

	var use = n;
	for(i = 1; i < use - 1; i++) {
		k = i;
		for(j = i + 1; j < use; j++) {
			var direct = multiply(pointSet[0], pointSet[k], pointSet[j]);
			if(direct > 0) {
				k = j;
			} else if(direct == 0) {
				// k j 同方向
				var dis = distance_no_sqrt(pointSet[0], pointSet[j]) - distance_no_sqrt(pointSet[0], pointSet[k]);
				use--; // 也就是不要了
				if(dis > 0) {
					// 保留j
					// 把 k 就不要了
					pointSet[k] = pointSet[j];
					pointSet[j] = pointSet[use];
					j--;
				} else {
					tmp = pointSet[use];
					pointSet[use] = pointSet[j];
					pointSet[j] = tmp;
				}
			}
		}
		tmp = pointSet[i];
		pointSet[i] = pointSet[k];
		pointSet[k] = tmp;
	}

	ch.push(pointSet[0]);
	ch.push(pointSet[1]);
	ch.push(pointSet[2]);
	for(i = 3; i < use; i++) {
		while(!(multiply(pointSet[i], ch[top - 1], ch[top]) < 0)) {
			top--;
			ch.pop();
		}
		top++;
		ch.push(pointSet[i]);
	}

}

function drawCities(p) {
	for(var i = 0; i < p.length; i++) {
		// console.log(p[i].x + "-----" + p[i].y)

	}
}

function convexhull(rwdc, wsc) {
	var n = rwdc.length; // 用100个例子
	var p = new Array(n);
	for(var i = 0; i < rwdc.length; i++) {
		p[i] = new Object();
		//					p[i].x = rwdc[i] * (1) * 10 + 50;
		//					p[i].y = wsc[i] * (1) * (10) + 50;

		p[i].x = rwdc[i];
		p[i].y = wsc[i];
		//p[i].tj = false
	}
	var res = new Array();
	Graham_scan(p, res, n);
	drawCities(res);
	return res;

}

function sortNumber(a, b) {
	return a - b
}
var ws = [];
var wd = [];
var pm10 = [];
var N = 0;


function wwDrawpolygon(table) {
	            ws = table[0].WS;
				wd = table[0].WD;
				pm10 = table[0].PM10;
				N = ws.length;

				var rwd = windrose2polar(wd); //从风玫瑰坐标转换为极坐标
				rwd = radians(rwd) //将角度转换为弧度

				var wdbins = linspace(0.0, Math.PI * 2, 9); //生成等差数列	
				var dwdbins = degrees(wdbins) // 将弧度转换成角度
				dwdbins = windrose2polar(dwdbins);
				var rwdbins = radians(dwdbins);
				var wdN = wdbins.length - 1;
				var theta = [];
				theta = rwdbins;
				theta[wdN] = theta[0];

				for(var i = 0; i < wd.length; i++) {
					wd[i] = wd[i] + (360 / wdN) / 2;
				}
				for(var i = 0; i < wd.length; i++) {
					if(wd[i] > 360) {
						wd[i] = wd[i] - 360;
					}
				}
				var wdhist = histogram(radians(wd), wdbins);
				for(var i = 0; i < wdhist.length; i++) {
					wdhist[i] = wdhist[i] / N;
				}
				var nwdhist = wdhist;
				nwdhist.push(nwdhist[0]);
				var rwdc = pol2cartcos(rwd, ws); //极坐标转换为笛卡尔坐标
				var wwrwdc = rwdc;
				var wsc = pol2cartsin(rwd, ws);
				var wwwsc = wsc;
				var poly = convexhull(rwdc, wsc) //计算凸包
				var dd = 0.5;
				
				var minX = 0,
					maxX = 0,
					minY = 0,
					maxY = 0;
					
				for(var i = 0; i < rwdc.length ; i++){
					if(minX > rwdc[i]){
						minX  = rwdc[i];
					}
					if(maxX < rwdc[i]){
						maxX  = rwdc[i];
					}
				}
				for(var i = 0; i < wsc.length ; i++){
					if(minY > wsc[i]){
						minY  = wsc[i];
					}
					if(maxY < wsc[i]){
						maxY  = wsc[i];
					}
				}
				
				var fn = new MapIDW();
				var datas = [];
				
			 for(var i = 0; i < rwdc.length; i++) {
					datas.push({		
						"x": wwrwdc[i]  * 1,
						"y": wwwsc[i]  * 1,
						"v": pm10[i],
					})

				}
			 
   
    if(maxvalue < Math.abs(minX)){
    	maxvalue = Math.abs(minX);
    }
    if(maxvalue < Math.abs(minY)){
    	maxvalue = Math.abs(minY);
    }
    if(maxvalue < Math.abs(maxX)){
    	maxvalue = Math.abs(maxX);
    }
    if(maxvalue < Math.abs(maxY)){
    	maxvalue = Math.abs(maxY);
    }
   var num =  parseInt(maxvalue / 5); 
   var numol =  maxvalue % 5; 
   
   if(numol > 0){
   	maxvalue = num*5 + 5;
   }else{
   	maxvalue =  num*5 ;
   }
   
 console.log(maxvalue);
	$("#" + canvasID).height((height - 60)* ((maxY - minY)/(maxvalue*2)));
	$("#" + canvasID).width((height - 60) * ((maxX - minX)/(maxvalue*2)));
	var top = (height - 60 )/2 * ((10 - maxY)/maxvalue)
	$("#" + canvasID).css({
		"margin-top": (30 + top) + "px"
	});
	var w = (width - (height - 60) ) / 2 ;
	var left = (height - 60 )/2 * ((minX + maxvalue )/maxvalue)
	$("#" + canvasID).css({
		"margin-left": (w +left) + "px"
	});
	
	
                var points = fn.getTrainPonits(datas, 500,minX, maxX,minY ,maxY,  25000, poly);
				fn.draw(canvas, points,colorarray, namearray,function(v) {
					
					for(var i = 0; i < colorarray.length ; i++){
						if(i == 0){
							if(v < namearray[i]) {
						         return colorarray[i];
					         }
						}else if((i < (colorarray.length - 2))&&(i != 0)){
							if((v >  namearray[i - 1]) && (v <  namearray[i])) {
						     return colorarray[i];
					         }
						}else if( i == (colorarray.length - 1)){
							if((v > namearray[i])) {
						      return  colorarray[i];
					        }
						}
					};

				});

}

//worker 内容
function MapIDW() {

	/**
	 * 反向距离权重法模拟点位
	 * @param {Object} datas 原始数据
	 * @param {Object} minlon 经度边界
	 * @param {Object} maxlon 经度边界
	 * @param {Object} minlat 纬度边界
	 * @param {Object} maxlat 纬度边界
	 * @param {Object} num 生成点数
	 * @param {Object} isRange 判断点是否在范围内,在则显示,否则抛弃
	 */
	this.getTrainPonits = function(datas,weight, minlon, maxlon, minlat, maxlat, num, polygon) {
		var deltx = maxlon - minlon;
		var delty = maxlat - minlat;

		var b = deltx / delty;
		var numy = Math.floor(Math.sqrt(num / b), 0)
		var numx = Math.floor(b * Math.sqrt(num / b), 0)

		var wx = deltx / numx;
		var wy = delty / numy;
		var result = [];
		for(var j = 0; j < numy; j++) {
			for(var i = 0; i < numx; i++) {
				var tempx = minlon + i * wx;
				var tempy = minlat + j * wy;
					if(!isRange(tempx,tempy,polygon)) {
						continue;
					}
				result.push({
					x: tempx,
					y: tempy,
					v: 0,
					id: i + ":" + j
				})
			}
		}
		var isallOffline = true; //站点如果全部离线,值都置为-1,地图用灰色显示
		datas.forEach(function(d, index) {
			if(!d.v) {
				return;
			}
			isallOffline = false;
		})
		if(isallOffline) {
			console.log("无值!");
		}

		var maxdis = Math.sqrt(Math.pow(Math.abs(maxlon - minlon), 2) + Math.pow(Math.abs(maxlat - minlat), 2));
		result = result.map(function(r) {
			if(isallOffline) {
				r.v = -1
				return r;
			}
			var v = 0;
			var n = 0;
			var disLimit = maxdis / 20;
			var blog = false; // r.id == "6:4";
			if(blog) {
				//	console.log(r)
			}
			var fenmu = 0;
			datas.forEach(function(d, index) {
				if(!d.v) { //站点无值,则不参与运算
					return;
				}
				var dis = Math.sqrt(Math.pow(Math.abs(r.x - d.x)*weight,  2) + Math.pow(Math.abs(d.y - r.y)*weight, 2 ));
				d.dis = dis;
				fenmu += Math.pow((1 / dis), 2);
			})
			r.v = 0;
			for(var i = 0; i < datas.length; i++) {
				var d = datas[i]
				if(!d.v) {
					continue;
				}
				d.weight = Math.pow((1 / d.dis), 2) / fenmu;
				r.v += d.v * d.weight;
				
			//	console.log(r.v);
			}

			if(blog) {
				console.log(r);
			}
			return r
		})

		this.numy = numy;
		this.numx = numx;
		this.deltx = deltx;
		this.delty = delty;
		this.minlon = minlon;
		this.minlat = minlat;
		this.maxlon = maxlon;
		this.maxlat = maxlat;
		this.resultPoints = result;
		return result;
	}

	this.draw = function(canvas, points,Colorarray, Namearray, getColorFuc) {
		var ctx = canvas.getContext("2d");
		ctx.clearRect(0, 0, canvas.width, canvas.height);
		ctx.globalAlpha = 1;
		var wx = canvas.width / this.numx;
		var wy = canvas.height / this.numy;
		for(var i = 0; i < points.length; i++) {
			var x = (points[i].x - this.minlon) * canvas.width / this.deltx;
			var y = canvas.height - (points[i].y - this.minlat) * canvas.height / this.delty;
			var temp = points[i].v;
			ctx.fillStyle = getColorFuc(temp);
			ctx.fillRect(x - wx / 2, y - wy / 2, wx, wy);
		}
	}

	this.drawSelf = function(canvas, getColorFuc) {
		this.draw(canvas, this.resultPoints, getColorFuc);
	}

	this.getDataUrlSelf = function(getColorFuc) {
		var canvas = document.createElement("canvas");
		canvas.style.background = "transparent";
		canvas.width = 500;
		canvas.height = 500 * (this.maxlat - this.minlat) / (this.maxlon - this.minlon) * 1.13;
		this.drawSelf(canvas, getColorFuc);
		//图片展示的 data URI
		var dataUrl = canvas.toDataURL();
		return dataUrl;
	}

	this.getDataUrl = function(points, getColorFuc) {
		var canvas = document.createElement("canvas");
		canvas.style.background = "transparent";
		canvas.width = 500;
		canvas.height = 500 * (this.maxlat - this.minlat) / (this.maxlon - this.minlon) * 1.13;
		this.draw(canvas, points, getColorFuc);
		//图片展示的 data URI
		var dataUrl = canvas.toDataURL();
		return dataUrl;
	}

	//定义点的结构体
	function Point(x, y) {
		this.y = y;
		this.x = x;
	}
	//计算一个点是否在多边形里,参数:点,多边形数组

		function PointInPoly(pt, poly) {
		for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
			((poly[i].x <= pt.x && pt.x < poly[j].x) || (poly[j].x <= pt.x && pt.x < poly[i].x)) &&
			(pt.y < (poly[j].y - poly[i].y) * (pt.x - poly[i].x) / (poly[j].x - poly[i].x) + poly[i].y) &&
			(c = !c);
		return c;
	}

	function isRange(x, y, polygon) {
		
		var p = new Point(x, y)
		return PointInPoly(p, polygon);
	}
}

var colorArray = ["#00e400", "#ffff00", "#ff7e00", "#ff0000", "#99004c", "#7e0023"];
var colorchild = {
	"1": ['#2be900', '#55ed00', '#80f200', '#aaf600', '#d5fb00', "#ffff00"],
	"2": ['#ffea00', '#ffd400', '#ffbf00', '#ffa900', '#ff9400', "#ff7e00"],
	"3": ['#ff6900', '#ff5400', '#ff3f00', '#ff2a00', '#ff1500', "#ff0000"],
	"4": ['#ee000d', '#dd0019', '#cc0026', '#bb0033', '#aa003f', "#99004c"],
	"5": ['#950045', '#90003e', '#8c0038', '#870031', '#83002a', "#7e0023"]
}

var paraLevelRange = {
	'PM25': [0, 35, 75, 115, 150, 250, 500],
	'PM10': [0, 50, 150, 250, 350, 420, 600],
	'PM2.5': [0, 35, 75, 115, 150, 250, 500],
	'SO2': [0, 150, 500, 650, 800],
	'NO2': [0, 100, 200, 700, 1200, 2340, 3840],
	'CO': [0, 5, 10, 35, 60, 90, 150],
	'O3': [0, 160, 200, 300, 400, 800, 1200],
	'AQI': [0, 50, 100, 150, 200, 300, 500],
	'AQI': [0, 50, 100, 150, 200, 300, 500],
	'TVOC': [0, 60, 100, 200, 300, 500]
};

function getColorFuc(value) {
	if(value < 0) {
		return "gray";
	}
	let id = 0;
	var paraname = "NO2"
	for(let i = 1; i < paraLevelRange[paraname].length; i++) {
		if(value < paraLevelRange[paraname][i]) {
			id = i - 1;
			break;
		}
		if(i == paraLevelRange[paraname].length - 1) {
			id = i - 1;
		}
	}
	if(id > 0) {
		let max = paraLevelRange[paraname][id + 1];
		let min = paraLevelRange[paraname][id];
		let childColor = colorchild['' + id];
		let ci = Math.floor((value - min) * 6 / (max - min));
		return childColor[ci];
	}
	return colorArray[id];
}

var idw = new MapIDW();


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值