Skip to content

Latest commit

 

History

History
280 lines (254 loc) · 7.59 KB

09-04.md

File metadata and controls

280 lines (254 loc) · 7.59 KB

Feature选取之条件过滤

涉及到选取,自然会有各种条件用于过滤,比如是鼠标左键单击,还是双击,是可以选取地图上的任意feature,还是某一类的feature。 对于这些需求,ol.interaction.Select都能满足,在API的文档里面就有相关的参数设置,下面就是一些简单的使用示例。

改变默认的单击选取方式

默认情况下,是支持鼠标左键单击选取feature的,在地图上其他地方点击一下,就取消选取了,但这并不是定死的选取方式,你完全可以自定义。 比如鼠标移动到feature上,就选取了,试试:

<script type="text/javascript" src="../src/ol3.13.1/ol.js" charset="utf-8"></script>
<script type="text/javascript"> var layer = new ol.layer.Vector({ source: new ol.source.Vector(), style: new ol.style.Style({ image: new ol.style.Circle({ radius: 10, fill: new ol.style.Fill({ color: 'red' }) }) }) }); var map = new ol.Map({ layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }), layer ], target: 'map', view: new ol.View({ center: ol.proj.transform( [104, 30], 'EPSG:4326', 'EPSG:3857'), zoom: 10 }) });
// 在地图上添加一个圆
var circle = new ol.Feature({
	geometry: new ol.geom.Point(ol.proj.transform(
	      [104, 30], 'EPSG:4326', 'EPSG:3857'))
})
layer.getSource().addFeature(circle);

// 添加一个用于选择Feature的交互方式
map.addInteraction(new ol.interaction.Select({
	condition: ol.events.condition.pointerMove, 	// 唯一的不同之处,设置鼠标移到feature上就选取
	style: new ol.style.Style({
		image: new ol.style.Circle({
			radius: 10,
			fill: new ol.style.Fill({
				color: 'blue'
			})
		})
	})
}));
</script>

代码同之前的例子只有一个地方不同:

<div id="map" style="width: 100%"></div>
<script type="text/javascript">
	var layer = new ol.layer.Vector({
		source: new ol.source.Vector(),
		style: new ol.style.Style({
			image: new ol.style.Circle({
				radius: 10,
				fill: new ol.style.Fill({
					color: 'red'
				})
			})
		})
	});
	var map = new ol.Map({
		layers: [
		  new ol.layer.Tile({
		    source: new ol.source.OSM()
		  }), 
		  layer
		],
		target: 'map',
		view: new ol.View({
		  center: ol.proj.transform(
		      [104, 30], 'EPSG:4326', 'EPSG:3857'),
		  zoom: 10
		})
	});

	// 在地图上添加一个圆
	var circle = new ol.Feature({
		geometry: new ol.geom.Point(ol.proj.transform(
		      [104, 30], 'EPSG:4326', 'EPSG:3857'))
	})
	layer.getSource().addFeature(circle);

	// 添加一个用于选择Feature的交互方式
	map.addInteraction(new ol.interaction.Select({
		condition: ol.events.condition.pointerMove, 	// 唯一的不同之处,设置鼠标移到feature上就选取
		style: new ol.style.Style({
			image: new ol.style.Circle({
				radius: 10,
				fill: new ol.style.Fill({
					color: 'blue'
				})
			})
		})
	}));
</script>

ol.events.condition里面有很多内置的条件过滤函数,可以在官网API查询,如果内置方式没有,也可以自己写一个类似的函数,比如:

ol.events.condition.singleClick = function(mapBrowserEvent) {
  return mapBrowserEvent.type == ol.MapBrowserEvent.EventType.SINGLECLICK;
};

就只是一个类型判断而已,是否非常的简单,任何人都可以自定义一个这种条件过滤函数。

直接对feature过滤

除了可以自定义选取的交互方式之外,我们还可以对feature进行过滤,如果当前选取的并不是我们需要的feature,我们可以决定不选取。 比如我们只希望用户能选取圆形,而不能选取五星,选取方式为默认的单击:

<script type="text/javascript"> var circleLayer = new ol.layer.Vector({ source: new ol.source.Vector(), style: new ol.style.Style({ image: new ol.style.Circle({ radius: 10, fill: new ol.style.Fill({ color: 'red' }) }) }) });
var starLayer = new ol.layer.Vector({
	source: new ol.source.Vector(),
	style: new ol.style.Style({
		image: new ol.style.RegularShape({
			points: 5,
			radius1: 20,
			radius2: 10,
			fill: new ol.style.Fill({
				color: 'red'
			})
		})
	})
});

var map2 = new ol.Map({
	layers: [
	  new ol.layer.Tile({
	    source: new ol.source.OSM()
	  }), 
	  circleLayer, starLayer
	],
	target: 'map2',
	view: new ol.View({
	  center: ol.proj.transform(
	      [104, 30], 'EPSG:4326', 'EPSG:3857'),
	  zoom: 10
	})
});

// 在地图上添加一个圆
var circle1 = new ol.Feature({
	geometry: new ol.geom.Point(ol.proj.transform(
	      [104, 30], 'EPSG:4326', 'EPSG:3857'))
})
circleLayer.getSource().addFeature(circle1);

// 在地图上添加一个五星
var star = new ol.Feature({
	geometry: new ol.geom.Point(ol.proj.transform(
	      [104.06, 30.05], 'EPSG:4326', 'EPSG:3857'))
})
starLayer.getSource().addFeature(star);

// 添加一个用于选择Feature的交互方式
map2.addInteraction(new ol.interaction.Select({
	style: new ol.style.Style({
		image: new ol.style.Circle({
			radius: 10,
			fill: new ol.style.Fill({
				color: 'blue'
			})
		})
	}),
	filter: function(feature, layer){
		return layer === circleLayer;
	}
}));
</script>

代码其实也是非常简单,前面大部分代码都是一样的,关键在最后:

<div id="map2" style="width: 100%"></div>
<script type="text/javascript">
	// 创建一个用于存放circle的layer
	var circleLayer = new ol.layer.Vector({
		source: new ol.source.Vector(),
		style: new ol.style.Style({
			image: new ol.style.Circle({
				radius: 10,
				fill: new ol.style.Fill({
					color: 'red'
				})
			})
		})
	});

	// 创建一个用于存放star的layer
	var starLayer = new ol.layer.Vector({
		source: new ol.source.Vector(),
		style: new ol.style.Style({
			image: new ol.style.RegularShape({
				points: 5,
				radius1: 20,
				radius2: 10,
				fill: new ol.style.Fill({
					color: 'red'
				})
			})
		})
	});

	var map2 = new ol.Map({
		layers: [
		  new ol.layer.Tile({
		    source: new ol.source.OSM()
		  }), 
		  circleLayer, starLayer
		],
		target: 'map2',
		view: new ol.View({
		  center: ol.proj.transform(
		      [104, 30], 'EPSG:4326', 'EPSG:3857'),
		  zoom: 10
		})
	});

	// 在地图上添加一个圆
	var circle1 = new ol.Feature({
		geometry: new ol.geom.Point(ol.proj.transform(
		      [104, 30], 'EPSG:4326', 'EPSG:3857'))
	})
	circleLayer.getSource().addFeature(circle1);

	// 在地图上添加一个五星
	var star = new ol.Feature({
		geometry: new ol.geom.Point(ol.proj.transform(
		      [104.06, 30.05], 'EPSG:4326', 'EPSG:3857'))
	})
	starLayer.getSource().addFeature(star);

	// 添加一个用于选择Feature的交互方式
	map2.addInteraction(new ol.interaction.Select({
		style: new ol.style.Style({
			image: new ol.style.Circle({
				radius: 10,
				fill: new ol.style.Fill({
					color: 'blue'
				})
			})
		}),
		// 关键: 设置过了条件,可以用feature来写过滤,也可以用layer来写过滤
		filter: function(feature, layer){
			return layer === circleLayer;
		}
	}));
</script>

选取多个feature

前面的例子都只是一个feature的情况,在实际应用中,肯定是不止一个的,如果要能同时选择多个,只需要设置一下构造函数的参数multi: true,默认情况下,只能选取一个feature。 仿照上面的代码,可自行尝试。