By default, the map.forEachFeatureAtPixel() function only considers features that are directly under the provided pixel. This can make it difficult to interact with features on touch devices. To consider features within some distance of the provided pixel, use the hitTolerance option. For example, map.forEachFeatureAtPixel(pixel, callback, {hitTolerance: 3}) will call the callback with all features that are within three pixels of the provided pixel.
默认情况下,map.forEachFeatureAtPixel()函数只考虑在给定的像素下面的要素,这会使在触摸设备上与要素进行交互变得困难。为了考虑到在给定的像素一定距离内的要素,使用hitTolerance选项。例如,map.forEachFeatureAtPixel(pixel, callback, {hitTolerance: 3})函数将会调用在给定的3个像素以内的所有要素的回调函数。
代码:
默认情况下,map.forEachFeatureAtPixel()函数只考虑在给定的像素下面的要素,这会使在触摸设备上与要素进行交互变得困难。为了考虑到在给定的像素一定距离内的要素,使用hitTolerance选项。例如,map.forEachFeatureAtPixel(pixel, callback, {hitTolerance: 3})函数将会调用在给定的3个像素以内的所有要素的回调函数。
代码:
<!DOCTYPE html>
<html>
<head>
<title>Hit Tolerance</title>
<link rel="stylesheet" href="https://openlayers.org/en/v4.2.0/css/ol.css" type="text/css">
<!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
<script src="https://openlayers.org/en/v4.2.0/build/ol.js"></script>
</head>
<body>
<div id="map" class="map"></div>
<form class="form-inline">
<span id="status"> No feature got hit.</span>
<br />
<label>Hit tolerance for selecting features </label>
<select id="hitTolerance" class="form-control">
<option value="0" selected>0 Pixels</option>
<option value="5">5 Pixels</option>
<option value="10">10 Pixels</option>
</select>
<br />
Area: <canvas id="circle" style="vertical-align: middle"/>
</form>
<script>
var raster = new ol.layer.Tile({
source: new ol.source.OSM()
});
// 样式
var style = new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'black',
width: 1
})
});
// 线要素
var feature = new ol.Feature(new ol.geom.LineString([[-4000000, 0], [4000000, 0]]));
// 矢量图层
var vector = new ol.layer.Vector({
source: new ol.source.Vector({
features: [feature]
}),
style: style
});
var map = new ol.Map({
layers: [raster, vector],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
var hitTolerance;
var statusElement = document.getElementById('status');
// 在地图上单击的时候,如果有要素则改变要素的样式并给出提示
map.on('singleclick', function(e) {
var hit = false;
map.forEachFeatureAtPixel(e.pixel, function() {
hit = true;
}, {
hitTolerance: hitTolerance
});
if (hit) {
style.getStroke().setColor('green');
statusElement.innerHTML = ' A feature got hit!';
} else {
style.getStroke().setColor('black');
statusElement.innerHTML = ' No feature got hit.';
}
feature.changed();
});
var selectHitToleranceElement = document.getElementById('hitTolerance');
var circleCanvas = document.getElementById('circle');
// 当HitTolerance改变时绘制圆形
var changeHitTolerance = function() {
// 获取下拉列表中的值
hitTolerance = parseInt(selectHitToleranceElement.value, 10);
// 大小
var size = 2 * hitTolerance + 2;
// 设置circleCanvas的宽高
circleCanvas.width = size;
circleCanvas.height = size;
// canvas画布
var ctx = circleCanvas.getContext('2d');
// 清除矩形
ctx.clearRect(0, 0, size, size);
// 开始绘制
ctx.beginPath();
// 绘制圆形
ctx.arc(hitTolerance + 1, hitTolerance + 1, hitTolerance + 0.5, 0, 2 * Math.PI);
// 填充
ctx.fill();
// 完成绘制
ctx.stroke();
};
selectHitToleranceElement.onchange = changeHitTolerance;
changeHitTolerance();
</script>
</body>
</html>