openlayers 聚类分析中预警marker 的位置在缩放过程中出现偏移

问题:在做疫情分析时,疫情点采用cluster动态聚集,对于有肺炎患者的地方,通过overlay的方式显示动态闪烁点,但是由于疫情点是动态聚集的,在不同的级别,聚集点不同,下一次聚集时,有肺炎患者的点被聚集到另一个聚集点中,但是预警闪烁点的位置还在原地,这样就造成预警点不在有肺炎患者的聚集点中。

解决办法:当新出现肺炎患者点,将其加入到聚集图层中,同时添加overlay 预警点,并将肺炎患者点的实际id和位置保存到overlay的属性中。

1、新出现肺炎患者点,将其加入到聚集图层中(这是是加入到数据中,情况图层数据,再统一加载新的数据)

for (var i = 0; i < rows.length; i++) {
			var row = rows[i];
			var id = row.resourceid;
			var val = row.temperature;
			var region = row.retrievalRegion;
			var pnt = [ row.channelLongitude, row.channelLatitude];
			var fea = new ol.Feature(new ol.geom.Point(pnt))
			fea.setId(id);
			fea.setProperties(row);
			feas.push(fea);
		}
		var sr = this.clusterLyr.getSource().getSource();
		sr.clear();
		sr.addFeatures(feas);//聚类要素展示数据
		sr.refresh();

2、同时添加overlay 预警点,并将肺炎患者点的实际id和位置保存到overlay的属性中

var id = "n_alert" + this.refNum;
		var css = "n_alert active";
		var msg = "";
		var showClose = false;
		var autoClose = 4000;
		var str = "发现【1】例新冠肺炎患者";
		var center = [ d1[0].channelLongitude, d1[0].channelLatitude ];
		if (true) {
			var div = document.createElement('div');
			div.className = css;
			div.id = id;
			var indiv = document.createElement('div');
			div.appendChild(indiv);
			var p = document.createElement('p');
			var span = document.createElement('span');
			indiv.appendChild(p);
			indiv.appendChild(span);
			var mkId = this.alertId;
			var cFea = this.clusterLyr.getSource().getClosestFeatureToCoordinate(center);
			var newPos = center;
			if (cFea) {
				var feas = cFea.get("features");
				if (feas && feas.length > 0) {
					for (var i = 0; i < feas.length; i++) {
						var coord = feas[i].getGeometry().getCoordinates();
						if (feas[i].getId() == d1[0].resourceid) {
							newPos = cFea.getGeometry().getCoordinates();
							break;
						}
					}
				}
			}
			var marker = new ol.Overlay({
				element : div,
				id : mkId,
				position : newPos,
				positioning : 'center-center'
			});
			// 记录要素的id
			marker.setProperties({
				center : center,
				isAlert : true,
				resourceid : d1[0].resourceid
			});
			map.addOverlay(marker);

3、在样式函数中添加聚类处理,在聚类函数中添加预警点

styleFunction : function(feature, resolution, isHover) {
		if (resolution != this.currentRes) {
			this.calCluster(resolution);
			this.currentRes = resolution;
		} else {
			if (this.refresh == true) {
				this.calCluster(resolution);
				this.refresh = false;
			}
		}

3、在聚类函数中,添加预警点处理(每一次重新聚类后,就会重新处理预警点的位置)

		var this_ = this;
		setTimeout(function() {
			this_.calAlert();//处理预警marker
		}, 300);

即基于预警的要素的center利用函数getClosestFeatureToCoordinate(注意,这里要用回调函数,在函数中通过预警的要素的resourceid过滤返回离center最近且包含resourceid要素的聚集点)得到该预警点预警的要素当前所在的聚集点,然后获得此聚集点的中心位置,将中心位置赋给预警的overlay,并根据次聚集点的大小,重新计算预警overlay的半径

//计算预警marker
	calAlert : function() {
		var s = map.getOverlays();
		if (s && s.getArray()) {
			var all = s.getArray();
			if (all && all.length > 0) {
				for (var i = 0; i < all.length; i++) {
					if (all[i].get("isAlert") == true) {
						var center = all[i].get("center");
						var id = all[i].get("resourceid");
						var cFea = this.clusterLyr.getSource().getClosestFeatureToCoordinate(center, function(e) {
							var temps = e.get("features");
							var flag = false;
							for (var t = 0; t < temps.length; t++) {
								if (id == temps[t].getId()) {
									flag = true;
									return e;
								}
							}
						});

						if (cFea) {
							var feas = cFea.get("features");
							if (feas && feas.length > 0) {
								for (var j = 0; j < feas.length; j++) {
									if (id == feas[j].getId()) {
										var pos = cFea.getGeometry().getCoordinates();
										all[i].setPosition(pos);
										var ele = all[i].getElement();
										if (ele) {
											var l = feas.length;
											if (l > 20) {
												$(ele).removeClass("alert_1").removeClass("alert_2").removeClass("alert_3").addClass("alert_3");
											} else if (l > 10) {
												$(ele).removeClass("alert_1").removeClass("alert_2").removeClass("alert_3").addClass("alert_2");
											} else if (l > 5) {
												$(ele).removeClass("alert_1").removeClass("alert_2").removeClass("alert_3").addClass("alert_2");
											} else {
												$(ele).removeClass("alert_1").removeClass("alert_2").removeClass("alert_3");
											}
										}
										break;
									}
								}

							}

						}
					}
				}
			}

		}

	},

 

你可能感兴趣的:(webgis)