forEachFeatureAtPixel无法正常工作

时间:2017-01-07 09:41:57

标签: openlayers-3

我有以下代码, 基本上我有两层一个osm laryer,一个矢量图层,首先我通过使用ol.interaction.draw在地图上的两个随机位置单击将两个id为id和id 2的特征节点添加到矢量图层中,然后切换到交互通过选择“拖动点”来拖动' (左上角),想法是当两个节点中的一个节点拖过另一个节点时,被拖动的节点将变成绿色节点,我可以通过将节点id 1轻松地拖动到节点id 2来实现这一点,但是当我尝试将节点ID 2拖到节点ID 1,它要求更高的精度,反之亦然。两个节点之间的唯一区别是在节点id 2之前创建节点id 1。 我在这里看到的问题是在forEachFeatureAtPixel中,当在节点id 1上拖动节点id 2时,它很少检测到(或回调很少返回节点id 1)特征节点id 1。 我在这个问题上花了很长时间。仍然无法弄清楚为什么。真的很感激任何帮助。 感谢



<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE HTML>
<html>
  <head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Draw and Modify Features</title>
    <link rel="stylesheet" href="https://openlayers.org/en/v3.20.1/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/v3.20.1/build/ol-debug.js"></script>
  </head>
  <body>
   <form class="form-inline">
        <select id="type">
        <option value="DrawPoint">Draw Point</option>
        <option value="DragPoint">Drag Point</option>
      </select>
    </form>
    <div id="map" class="map"></div>
   
   <script>
   var raster = new ol.layer.Tile({
		source: new ol.source.OSM()
	});

var map = new ol.Map({
		layers: [raster],
		target: 'map',
		view: new ol.View({
			center: [-11000000, 4600000],
			zoom: 4
		})
	});
var circle_style = new ol.style.Style({
		image: new ol.style.Circle({
			radius: 5,
			fill: new ol.style.Fill({
				color: 'rgba(255, 0, 0, 2)'
			})
		})
	});
var overlap_style = new ol.style.Style({
					image: new ol.style.Circle({
						radius: 8,
						fill: new ol.style.Fill({
							color: 'rgba(0, 255, 0, 2)'
						})
					})
				});
var features = new ol.Collection();
var featureOverlay = new ol.layer.Vector({
		source: new ol.source.Vector({
			features: features
		}),
		style: circle_style
	});
featureOverlay.setMap(map);

window.app = {};
var app = window.app;

/**
 * @constructor
 * @extends {ol.interaction.Pointer}
 */
app.Drag = function () {

	ol.interaction.Pointer.call(this, {
		handleDownEvent: app.Drag.prototype.handleDownEvent,
		handleDragEvent: app.Drag.prototype.handleDragEvent,
		handleMoveEvent: app.Drag.prototype.handleMoveEvent,
		handleUpEvent: app.Drag.prototype.handleUpEvent
	});


	this.coordinate12_ = null;

	
	this.cursor_ = 'pointer';

	
	this.feature_ = null;

	
	this.previousCursor_ = undefined;

};
ol.inherits(app.Drag, ol.interaction.Pointer);
app.Drag.prototype.handleDownEvent = function (evt) {
	var map = evt.map;
	
	var feature = map.forEachFeatureAtPixel(evt.pixel,
			function (feature, layer) {
			return feature;
		});

	if (feature) {
		console.log("down: node_id: " + feature.getProperties()['id']);
		this.coordinate12_ = evt.coordinate;
		this.feature_ = feature;
	}

	return !!feature;
};

app.Drag.prototype.handleDragEvent = function (evt) {

	var map = evt.map;
	fs = featureOverlay.getSource().getFeatures();
	
	var feature = map.forEachFeatureAtPixel(evt.pixel,
			function (feature, layer) {
			return feature;
		});
	
	if (!(feature === undefined)) {
		console.log("drag: node_id: " + feature.getProperties()['id']);
		// console.log("this:" + this.feature_.getId()+ " o: " +  feature.getId());
		if (this.feature_.getProperties()['id'] != feature.getProperties()['id']) {
			console.log("green: node_id: " + feature.getProperties()['id']);
			this.feature_.setStyle(overlap_style);
		} else {
			this.feature_.setStyle(circle_style);
		}
	}

	var deltaX = evt.coordinate[0] - this.coordinate12_[0];
	var deltaY = evt.coordinate[1] - this.coordinate12_[1];

	var geometry = /** @type {ol.geom.SimpleGeometry} */
		(this.feature_.getGeometry());
	geometry.translate(deltaX, deltaY);

	this.coordinate12_[0] = evt.coordinate[0];
	this.coordinate12_[1] = evt.coordinate[1];
};
app.Drag.prototype.handleMoveEvent = function (evt) {
	if (this.cursor_) {
		var map = evt.map;
		var feature = map.forEachFeatureAtPixel(evt.pixel,
				function (feature, layer) {
				if (this.feature_ != null) 
				{
					console.log("move forEachFeatureAtPixel: node_id: " + feature.getProperties()['id']);
				}
				return feature;
			});
		var element = evt.map.getTargetElement();
		if (feature) {
		    if (this.feature_ != null) 
				{
					console.log("move forEachFeatureAtPixel: node_id: " + feature.getProperties()['id']);
				}
			if (element.style.cursor != this.cursor_) {
				this.previousCursor_ = element.style.cursor;
				element.style.cursor = this.cursor_;
			}
		} else if (this.previousCursor_ !== undefined) {
			element.style.cursor = this.previousCursor_;
			this.previousCursor_ = undefined;
		}
	}
};

/**
 * @param {ol.MapBrowserEvent} evt Map browser event.
 * @return {boolean} `false` to stop the drag sequence.
 */
app.Drag.prototype.handleUpEvent = function (evt) {
	this.coordinate12_ = null;
	this.feature_ = null;
	return false;
};
var draw = new ol.interaction.Draw({
		features: features,
		type: ('Point')
	});
var drag = new app.Drag();
var id_count = 0;
draw.on('drawend', function(e) {
  e.feature.setProperties({
    'id': ++id_count
  })
  console.log(e.feature, e.feature.getProperties());
});
map.addInteraction(draw);

var typeSelect = document.getElementById('type');
typeSelect.value = 'DrawPoint';
typeSelect.onchange = function () {
	if (typeSelect.value == 'DrawPoint')
	{
		map.removeInteraction(drag);
		map.addInteraction(draw);
	}else
	{
		map.removeInteraction(draw);
		map.addInteraction(drag);
	}
};
   </script>
  </body>
</html>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

防止从map.forEachFeatureAtPixel方法返回的要素(第1或第2个)。 请参阅以下工作代码段。

&#13;
&#13;
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE HTML>
<html>
  <head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Draw and Modify Features</title>
    <link rel="stylesheet" href="https://openlayers.org/en/v3.20.1/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/v3.20.1/build/ol-debug.js"></script>
  </head>
  <body>
   <form class="form-inline">
        <select id="type">
        <option value="DrawPoint">Draw Point</option>
        <option value="DragPoint">Drag Point</option>
      </select>
    </form>
    <div id="map" class="map"></div>
   
   <script>
    var raster = new ol.layer.Tile({
		source: new ol.source.OSM()
	});

	var map = new ol.Map({
		layers: [raster],
		target: 'map',
		view: new ol.View({
			center: [-11000000, 4600000],
			zoom: 4
		})
	});
	var circle_style = new ol.style.Style({
		image: new ol.style.Circle({
			radius: 5,
			fill: new ol.style.Fill({
				color: 'rgba(255, 0, 0, 2)'
			})
		})
	});
	
	var overlap_style = new ol.style.Style({
		image: new ol.style.Circle({
			radius: 8,
			fill: new ol.style.Fill({
				color: 'rgba(0, 255, 0, 2)'
			})
		})
	});
	var features = new ol.Collection();
	var featureOverlay = new ol.layer.Vector({
		source: new ol.source.Vector({
			features: features
		}),
		style: circle_style
	});
	featureOverlay.setMap(map);

	window.app = {};
	var app = window.app;

	/**
	 * @constructor
	 * @extends {ol.interaction.Pointer}
	 */
	var dragFeature;
	app.Drag = function () {

		ol.interaction.Pointer.call(this, {
			handleDownEvent: app.Drag.prototype.handleDownEvent,
			handleDragEvent: app.Drag.prototype.handleDragEvent,
			handleMoveEvent: app.Drag.prototype.handleMoveEvent,
			handleUpEvent: app.Drag.prototype.handleUpEvent
		});


		this.coordinate12_ = null;
		this.cursor_ = 'pointer';
		this.previousCursor_ = undefined;

	};
	ol.inherits(app.Drag, ol.interaction.Pointer);
	app.Drag.prototype.handleDownEvent = function (evt) {
		var map = evt.map;
		
		var feature = map.forEachFeatureAtPixel(evt.pixel,
				function (feature, layer) {
				return feature;
			});

		if (feature) {
			//console.log("down: node_id: " + feature.getProperties()['id']);
			this.coordinate12_ = evt.coordinate;
			//this.feature_ = feature;
			dragFeature = feature;
		}

		return !!feature;
	};

	app.Drag.prototype.handleDragEvent = function (evt) {

		var map = evt.map;
		fs = featureOverlay.getSource().getFeatures();
		
		// Filter the feature 
		var feature = map.forEachFeatureAtPixel(evt.pixel,
				function (feature, layer) {
				if ( feature.getProperties()['id'] != dragFeature.getProperties()['id'] ) {
					return feature;
				}
			});
		
		if (!(feature === undefined)) {
			console.log("------------------- drag: node_id: " + feature.getProperties()['id']);
			// console.log("this:" + this.feature_.getId()+ " o: " +  feature.getId());
			if (dragFeature.getProperties()['id'] != feature.getProperties()['id']) {
				console.log("green: node_id: " + feature.getProperties()['id']);
				dragFeature.setStyle(overlap_style);
			}
		}
		else {
				dragFeature.setStyle(circle_style);
			}

		var deltaX = evt.coordinate[0] - this.coordinate12_[0];
		var deltaY = evt.coordinate[1] - this.coordinate12_[1];

		var geometry = /** @type {ol.geom.SimpleGeometry} */
			(dragFeature.getGeometry());
		geometry.translate(deltaX, deltaY);

		this.coordinate12_[0] = evt.coordinate[0];
		this.coordinate12_[1] = evt.coordinate[1];
	};
	app.Drag.prototype.handleMoveEvent = function (evt) {
		if (this.cursor_) {
			var map = evt.map;
			var feature = map.forEachFeatureAtPixel(evt.pixel,
					function (feature, layer) {
					if (dragFeature != null) 
					{
						//console.log("move forEachFeatureAtPixel: node_id: " + feature.getProperties()['id']);
					}
					return feature;
				});
			var element = evt.map.getTargetElement();
			if (feature) {
				if (dragFeature != null) 
					{
						//console.log("move forEachFeatureAtPixel: node_id: " + feature.getProperties()['id']);
					}
				if (element.style.cursor != this.cursor_) {
					this.previousCursor_ = element.style.cursor;
					element.style.cursor = this.cursor_;
				}
			} else if (this.previousCursor_ !== undefined) {
				element.style.cursor = this.previousCursor_;
				this.previousCursor_ = undefined;
			}
		}
	};

	/**
	 * @param {ol.MapBrowserEvent} evt Map browser event.
	 * @return {boolean} `false` to stop the drag sequence.
	 */
	app.Drag.prototype.handleUpEvent = function (evt) {
		this.coordinate12_ = null;
		//this.feature_ = null;
		dragFeature = null;
		return false;
	};
	var draw = new ol.interaction.Draw({
			features: features,
			type: ('Point')
		});
	var drag = new app.Drag();
	var id_count = 0;
	draw.on('drawend', function(e) {
	  e.feature.setProperties({
		'id': ++id_count
	  })
	  //console.log(e.feature, e.feature.getProperties());
	});
	map.addInteraction(draw);

	var typeSelect = document.getElementById('type');
	typeSelect.value = 'DrawPoint';
	typeSelect.onchange = function () {
		if (typeSelect.value == 'DrawPoint')
		{
			map.removeInteraction(drag);
			map.addInteraction(draw);
		}else
		{
			map.removeInteraction(draw);
			map.addInteraction(drag);
		}
	};
   </script>
  </body>
</html>
&#13;
&#13;
&#13;