Merge pull request #3066 from tsauerwein/webgl-point-hasFeatureAtPixel
Introduce hasFeatureAtPixel
This commit is contained in:
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
|
|
||||||
<div class="span12">
|
<div class="span8">
|
||||||
<h4 id="title">Icon sprite with WebGL example</h4>
|
<h4 id="title">Icon sprite with WebGL example</h4>
|
||||||
<p id="shortdesc">Icon sprite with WebGL.</p>
|
<p id="shortdesc">Icon sprite with WebGL.</p>
|
||||||
<div id="docs">
|
<div id="docs">
|
||||||
@@ -39,6 +39,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="tags">webgl, icon, sprite, vector, point</div>
|
<div id="tags">webgl, icon, sprite, vector, point</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="span2 offset2">
|
||||||
|
<div id="info" class="alert alert-success">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -109,3 +109,31 @@ var featureOverlay = new ol.FeatureOverlay({
|
|||||||
}),
|
}),
|
||||||
features: overlayFeatures
|
features: overlayFeatures
|
||||||
});
|
});
|
||||||
|
|
||||||
|
map.on('click', function(evt) {
|
||||||
|
var info = document.getElementById('info');
|
||||||
|
info.innerHTML =
|
||||||
|
'Hold on a second, while I catch those butterflies for you ...';
|
||||||
|
|
||||||
|
window.setTimeout(function() {
|
||||||
|
var features = [];
|
||||||
|
map.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {
|
||||||
|
features.push(features);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (features.length === 1) {
|
||||||
|
info.innerHTML = 'Got one butterfly';
|
||||||
|
} else if (features.length > 1) {
|
||||||
|
info.innerHTML = 'Got ' + features.length + ' butterflies';
|
||||||
|
} else {
|
||||||
|
info.innerHTML = 'Couldn\'t catch a single butterfly';
|
||||||
|
}
|
||||||
|
}, 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(map.getViewport()).on('mousemove', function(evt) {
|
||||||
|
var pixel = map.getEventPixel(evt.originalEvent);
|
||||||
|
var hit = map.hasFeatureAtPixel(pixel);
|
||||||
|
map.getTarget().style.cursor = hit ? 'pointer' : '';
|
||||||
|
});
|
||||||
|
|||||||
+7
-10
@@ -5,7 +5,7 @@ goog.require('ol.View');
|
|||||||
goog.require('ol.geom.Point');
|
goog.require('ol.geom.Point');
|
||||||
goog.require('ol.layer.Tile');
|
goog.require('ol.layer.Tile');
|
||||||
goog.require('ol.layer.Vector');
|
goog.require('ol.layer.Vector');
|
||||||
goog.require('ol.source.OSM');
|
goog.require('ol.source.TileJSON');
|
||||||
goog.require('ol.source.Vector');
|
goog.require('ol.source.Vector');
|
||||||
goog.require('ol.style.Icon');
|
goog.require('ol.style.Icon');
|
||||||
goog.require('ol.style.Style');
|
goog.require('ol.style.Style');
|
||||||
@@ -39,7 +39,10 @@ var vectorLayer = new ol.layer.Vector({
|
|||||||
});
|
});
|
||||||
|
|
||||||
var rasterLayer = new ol.layer.Tile({
|
var rasterLayer = new ol.layer.Tile({
|
||||||
source: new ol.source.OSM()
|
source: new ol.source.TileJSON({
|
||||||
|
url: 'http://api.tiles.mapbox.com/v3/mapbox.geography-class.jsonp',
|
||||||
|
crossOrigin: ''
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
var map = new ol.Map({
|
var map = new ol.Map({
|
||||||
@@ -85,12 +88,6 @@ map.on('click', function(evt) {
|
|||||||
// change mouse cursor when over marker
|
// change mouse cursor when over marker
|
||||||
$(map.getViewport()).on('mousemove', function(e) {
|
$(map.getViewport()).on('mousemove', function(e) {
|
||||||
var pixel = map.getEventPixel(e.originalEvent);
|
var pixel = map.getEventPixel(e.originalEvent);
|
||||||
var hit = map.forEachFeatureAtPixel(pixel, function(feature, layer) {
|
var hit = map.hasFeatureAtPixel(pixel);
|
||||||
return true;
|
map.getTarget().style.cursor = hit ? 'pointer' : '';
|
||||||
});
|
|
||||||
if (hit) {
|
|
||||||
map.getTarget().style.cursor = 'pointer';
|
|
||||||
} else {
|
|
||||||
map.getTarget().style.cursor = '';
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -589,6 +589,34 @@ ol.Map.prototype.forEachFeatureAtPixel =
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect if features intersect a pixel on the viewport. Layers included in the
|
||||||
|
* detection can be configured through `opt_layerFilter`. Feature overlays will
|
||||||
|
* always be included in the detection.
|
||||||
|
* @param {ol.Pixel} pixel Pixel.
|
||||||
|
* @param {(function(this: U, ol.layer.Layer): boolean)=} opt_layerFilter Layer
|
||||||
|
* filter function, only layers which are visible and for which this
|
||||||
|
* function returns `true` will be tested for features. By default, all
|
||||||
|
* visible layers will be tested. Feature overlays will always be tested.
|
||||||
|
* @param {U=} opt_this2 Value to use as `this` when executing `layerFilter`.
|
||||||
|
* @return {boolean} Is there a feature at the given pixel?
|
||||||
|
* @template U
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
ol.Map.prototype.hasFeatureAtPixel =
|
||||||
|
function(pixel, opt_layerFilter, opt_this2) {
|
||||||
|
if (goog.isNull(this.frameState_)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var coordinate = this.getCoordinateFromPixel(pixel);
|
||||||
|
var layerFilter = goog.isDef(opt_layerFilter) ?
|
||||||
|
opt_layerFilter : goog.functions.TRUE;
|
||||||
|
var thisArg2 = goog.isDef(opt_this2) ? opt_this2 : null;
|
||||||
|
return this.renderer_.hasFeatureAtPixel(
|
||||||
|
coordinate, this.frameState_, layerFilter, thisArg2);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the geographical coordinate for a browser event.
|
* Returns the geographical coordinate for a browser event.
|
||||||
* @param {Event} event Event.
|
* @param {Event} event Event.
|
||||||
|
|||||||
@@ -557,6 +557,7 @@ ol.render.webgl.ImageReplay.prototype.createTextures_ =
|
|||||||
* @param {number} saturation Global saturation.
|
* @param {number} saturation Global saturation.
|
||||||
* @param {Object} skippedFeaturesHash Ids of features to skip.
|
* @param {Object} skippedFeaturesHash Ids of features to skip.
|
||||||
* @param {function(ol.Feature): T|undefined} featureCallback Feature callback.
|
* @param {function(ol.Feature): T|undefined} featureCallback Feature callback.
|
||||||
|
* @param {boolean} oneByOne Draw features one-by-one for the hit-detecion.
|
||||||
* @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
|
* @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
|
||||||
* this extent are checked.
|
* this extent are checked.
|
||||||
* @return {T|undefined} Callback result.
|
* @return {T|undefined} Callback result.
|
||||||
@@ -565,7 +566,7 @@ ol.render.webgl.ImageReplay.prototype.createTextures_ =
|
|||||||
ol.render.webgl.ImageReplay.prototype.replay = function(context,
|
ol.render.webgl.ImageReplay.prototype.replay = function(context,
|
||||||
center, resolution, rotation, size, pixelRatio,
|
center, resolution, rotation, size, pixelRatio,
|
||||||
opacity, brightness, contrast, hue, saturation, skippedFeaturesHash,
|
opacity, brightness, contrast, hue, saturation, skippedFeaturesHash,
|
||||||
featureCallback, opt_hitExtent) {
|
featureCallback, oneByOne, opt_hitExtent) {
|
||||||
var gl = context.getGL();
|
var gl = context.getGL();
|
||||||
|
|
||||||
// bind the vertices buffer
|
// bind the vertices buffer
|
||||||
@@ -672,7 +673,7 @@ ol.render.webgl.ImageReplay.prototype.replay = function(context,
|
|||||||
} else {
|
} else {
|
||||||
// draw feature by feature for the hit-detection
|
// draw feature by feature for the hit-detection
|
||||||
result = this.drawHitDetectionReplay_(gl, context, featureCallback,
|
result = this.drawHitDetectionReplay_(gl, context, featureCallback,
|
||||||
opt_hitExtent);
|
oneByOne, opt_hitExtent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// disable the vertex attrib arrays
|
// disable the vertex attrib arrays
|
||||||
@@ -715,21 +716,82 @@ ol.render.webgl.ImageReplay.prototype.drawReplay_ =
|
|||||||
* @param {WebGLRenderingContext} gl gl.
|
* @param {WebGLRenderingContext} gl gl.
|
||||||
* @param {ol.webgl.Context} context Context.
|
* @param {ol.webgl.Context} context Context.
|
||||||
* @param {function(ol.Feature): T|undefined} featureCallback Feature callback.
|
* @param {function(ol.Feature): T|undefined} featureCallback Feature callback.
|
||||||
|
* @param {boolean} oneByOne Draw features one-by-one for the hit-detecion.
|
||||||
* @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
|
* @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
|
||||||
* this extent are checked.
|
* this extent are checked.
|
||||||
* @return {T|undefined} Callback result.
|
* @return {T|undefined} Callback result.
|
||||||
* @template T
|
* @template T
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.ImageReplay.prototype.drawHitDetectionReplay_ =
|
ol.render.webgl.ImageReplay.prototype.drawHitDetectionReplay_ =
|
||||||
function(gl, context, featureCallback, opt_hitExtent) {
|
function(gl, context, featureCallback, oneByOne, opt_hitExtent) {
|
||||||
goog.asserts.assert(this.hitDetectionTextures_.length ===
|
goog.asserts.assert(this.hitDetectionTextures_.length ===
|
||||||
this.hitDetectionGroupIndices_.length);
|
this.hitDetectionGroupIndices_.length);
|
||||||
var elementType = context.hasOESElementIndexUint ?
|
var elementType = context.hasOESElementIndexUint ?
|
||||||
goog.webgl.UNSIGNED_INT : goog.webgl.UNSIGNED_SHORT;
|
goog.webgl.UNSIGNED_INT : goog.webgl.UNSIGNED_SHORT;
|
||||||
var elementSize = context.hasOESElementIndexUint ? 4 : 2;
|
var elementSize = context.hasOESElementIndexUint ? 4 : 2;
|
||||||
|
|
||||||
var i, groupStart, groupEnd, numItems, start, end, feature;
|
if (!oneByOne) {
|
||||||
|
// draw all hit-detection features in "once" (by texture group)
|
||||||
|
return this.drawHitDetectionReplayAll_(gl, context, featureCallback,
|
||||||
|
elementType, elementSize);
|
||||||
|
} else {
|
||||||
|
// draw hit-detection features one by one
|
||||||
|
return this.drawHitDetectionReplayOneByOne_(gl, context, featureCallback,
|
||||||
|
elementType, elementSize, opt_hitExtent);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @param {WebGLRenderingContext} gl gl.
|
||||||
|
* @param {ol.webgl.Context} context Context.
|
||||||
|
* @param {function(ol.Feature): T|undefined} featureCallback Feature callback.
|
||||||
|
* @param {number} elementType Element type.
|
||||||
|
* @param {number} elementSize Element size.
|
||||||
|
* @return {T|undefined} Callback result.
|
||||||
|
* @template T
|
||||||
|
*/
|
||||||
|
ol.render.webgl.ImageReplay.prototype.drawHitDetectionReplayAll_ =
|
||||||
|
function(gl, context, featureCallback, elementType, elementSize) {
|
||||||
|
var i, ii, start;
|
||||||
|
for (i = 0, ii = this.hitDetectionTextures_.length, start = 0; i < ii; ++i) {
|
||||||
|
gl.bindTexture(goog.webgl.TEXTURE_2D, this.hitDetectionTextures_[i]);
|
||||||
|
var end = this.hitDetectionGroupIndices_[i];
|
||||||
|
var numItems = end - start;
|
||||||
|
var offsetInBytes = start * elementSize;
|
||||||
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||||
|
gl.drawElements(goog.webgl.TRIANGLES, numItems, elementType, offsetInBytes);
|
||||||
|
start = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = featureCallback(null);
|
||||||
|
if (result) {
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @param {WebGLRenderingContext} gl gl.
|
||||||
|
* @param {ol.webgl.Context} context Context.
|
||||||
|
* @param {function(ol.Feature): T|undefined} featureCallback Feature callback.
|
||||||
|
* @param {number} elementType Element type.
|
||||||
|
* @param {number} elementSize Element size.
|
||||||
|
* @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
|
||||||
|
* this extent are checked.
|
||||||
|
* @return {T|undefined} Callback result.
|
||||||
|
* @template T
|
||||||
|
*/
|
||||||
|
ol.render.webgl.ImageReplay.prototype.drawHitDetectionReplayOneByOne_ =
|
||||||
|
function(gl, context, featureCallback, elementType, elementSize,
|
||||||
|
opt_hitExtent) {
|
||||||
|
var i, groupStart, numItems, start, end, feature;
|
||||||
var featureIndex = this.startIndices_.length - 1;
|
var featureIndex = this.startIndices_.length - 1;
|
||||||
|
|
||||||
for (i = this.hitDetectionTextures_.length - 1; i >= 0; --i) {
|
for (i = this.hitDetectionTextures_.length - 1; i >= 0; --i) {
|
||||||
gl.bindTexture(goog.webgl.TEXTURE_2D, this.hitDetectionTextures_[i]);
|
gl.bindTexture(goog.webgl.TEXTURE_2D, this.hitDetectionTextures_[i]);
|
||||||
groupStart = (i > 0) ? this.hitDetectionGroupIndices_[i - 1] : 0;
|
groupStart = (i > 0) ? this.hitDetectionGroupIndices_[i - 1] : 0;
|
||||||
@@ -957,7 +1019,7 @@ ol.render.webgl.ReplayGroup.prototype.replay = function(context,
|
|||||||
replay.replay(context,
|
replay.replay(context,
|
||||||
center, resolution, rotation, size, pixelRatio,
|
center, resolution, rotation, size, pixelRatio,
|
||||||
opacity, brightness, contrast, hue, saturation, skippedFeaturesHash,
|
opacity, brightness, contrast, hue, saturation, skippedFeaturesHash,
|
||||||
undefined);
|
undefined, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -978,6 +1040,7 @@ ol.render.webgl.ReplayGroup.prototype.replay = function(context,
|
|||||||
* @param {number} saturation Global saturation.
|
* @param {number} saturation Global saturation.
|
||||||
* @param {Object} skippedFeaturesHash Ids of features to skip.
|
* @param {Object} skippedFeaturesHash Ids of features to skip.
|
||||||
* @param {function(ol.Feature): T|undefined} featureCallback Feature callback.
|
* @param {function(ol.Feature): T|undefined} featureCallback Feature callback.
|
||||||
|
* @param {boolean} oneByOne Draw features one-by-one for the hit-detecion.
|
||||||
* @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
|
* @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
|
||||||
* this extent are checked.
|
* this extent are checked.
|
||||||
* @return {T|undefined} Callback result.
|
* @return {T|undefined} Callback result.
|
||||||
@@ -986,7 +1049,7 @@ ol.render.webgl.ReplayGroup.prototype.replay = function(context,
|
|||||||
ol.render.webgl.ReplayGroup.prototype.replayHitDetection_ = function(context,
|
ol.render.webgl.ReplayGroup.prototype.replayHitDetection_ = function(context,
|
||||||
center, resolution, rotation, size, pixelRatio,
|
center, resolution, rotation, size, pixelRatio,
|
||||||
opacity, brightness, contrast, hue, saturation, skippedFeaturesHash,
|
opacity, brightness, contrast, hue, saturation, skippedFeaturesHash,
|
||||||
featureCallback, opt_hitExtent) {
|
featureCallback, oneByOne, opt_hitExtent) {
|
||||||
var i, replay, result;
|
var i, replay, result;
|
||||||
for (i = ol.render.REPLAY_ORDER.length - 1; i >= 0; --i) {
|
for (i = ol.render.REPLAY_ORDER.length - 1; i >= 0; --i) {
|
||||||
replay = this.replays_[ol.render.REPLAY_ORDER[i]];
|
replay = this.replays_[ol.render.REPLAY_ORDER[i]];
|
||||||
@@ -994,7 +1057,7 @@ ol.render.webgl.ReplayGroup.prototype.replayHitDetection_ = function(context,
|
|||||||
result = replay.replay(context,
|
result = replay.replay(context,
|
||||||
center, resolution, rotation, size, pixelRatio,
|
center, resolution, rotation, size, pixelRatio,
|
||||||
opacity, brightness, contrast, hue, saturation,
|
opacity, brightness, contrast, hue, saturation,
|
||||||
skippedFeaturesHash, featureCallback, opt_hitExtent);
|
skippedFeaturesHash, featureCallback, oneByOne, opt_hitExtent);
|
||||||
if (result) {
|
if (result) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1061,7 +1124,49 @@ ol.render.webgl.ReplayGroup.prototype.forEachFeatureAtPixel = function(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, hitExtent);
|
}, true, hitExtent);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.webgl.Context} context Context.
|
||||||
|
* @param {ol.Coordinate} center Center.
|
||||||
|
* @param {number} resolution Resolution.
|
||||||
|
* @param {number} rotation Rotation.
|
||||||
|
* @param {ol.Size} size Size.
|
||||||
|
* @param {number} pixelRatio Pixel ratio.
|
||||||
|
* @param {number} opacity Global opacity.
|
||||||
|
* @param {number} brightness Global brightness.
|
||||||
|
* @param {number} contrast Global contrast.
|
||||||
|
* @param {number} hue Global hue.
|
||||||
|
* @param {number} saturation Global saturation.
|
||||||
|
* @param {Object} skippedFeaturesHash Ids of features to skip.
|
||||||
|
* @param {ol.Coordinate} coordinate Coordinate.
|
||||||
|
* @return {boolean} Is there a feature at the given pixel?
|
||||||
|
*/
|
||||||
|
ol.render.webgl.ReplayGroup.prototype.hasFeatureAtPixel = function(
|
||||||
|
context, center, resolution, rotation, size, pixelRatio,
|
||||||
|
opacity, brightness, contrast, hue, saturation, skippedFeaturesHash,
|
||||||
|
coordinate) {
|
||||||
|
var gl = context.getGL();
|
||||||
|
gl.bindFramebuffer(
|
||||||
|
gl.FRAMEBUFFER, context.getHitDetectionFramebuffer());
|
||||||
|
|
||||||
|
var hasFeature = this.replayHitDetection_(context,
|
||||||
|
coordinate, resolution, rotation, ol.render.webgl.HIT_DETECTION_SIZE_,
|
||||||
|
pixelRatio, opacity, brightness, contrast, hue, saturation,
|
||||||
|
skippedFeaturesHash,
|
||||||
|
/**
|
||||||
|
* @param {ol.Feature} feature Feature.
|
||||||
|
* @return {boolean} Is there a feature?
|
||||||
|
*/
|
||||||
|
function(feature) {
|
||||||
|
var imageData = new Uint8Array(4);
|
||||||
|
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, imageData);
|
||||||
|
return imageData[3] > 0;
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
return goog.isDef(hasFeature);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,14 @@ goog.inherits(ol.renderer.Layer, goog.Disposable);
|
|||||||
ol.renderer.Layer.prototype.forEachFeatureAtPixel = goog.nullFunction;
|
ol.renderer.Layer.prototype.forEachFeatureAtPixel = goog.nullFunction;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.Coordinate} coordinate Coordinate.
|
||||||
|
* @param {olx.FrameState} frameState Frame state.
|
||||||
|
* @return {boolean} Is there a feature at the given pixel?
|
||||||
|
*/
|
||||||
|
ol.renderer.Layer.prototype.hasFeatureAtPixel = goog.functions.FALSE;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @protected
|
* @protected
|
||||||
* @return {ol.layer.Layer} Layer.
|
* @return {ol.layer.Layer} Layer.
|
||||||
|
|||||||
@@ -169,6 +169,26 @@ ol.renderer.Map.prototype.forEachFeatureAtPixel =
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.Coordinate} coordinate Coordinate.
|
||||||
|
* @param {olx.FrameState} frameState FrameState.
|
||||||
|
* @param {function(this: U, ol.layer.Layer): boolean} layerFilter Layer filter
|
||||||
|
* function, only layers which are visible and for which this function
|
||||||
|
* returns `true` will be tested for features. By default, all visible
|
||||||
|
* layers will be tested.
|
||||||
|
* @param {U} thisArg Value to use as `this` when executing `layerFilter`.
|
||||||
|
* @return {boolean} Is there a feature at the given pixel?
|
||||||
|
* @template U
|
||||||
|
*/
|
||||||
|
ol.renderer.Map.prototype.hasFeatureAtPixel =
|
||||||
|
function(coordinate, frameState, layerFilter, thisArg) {
|
||||||
|
var hasFeature = this.forEachFeatureAtPixel(
|
||||||
|
coordinate, frameState, goog.functions.TRUE, this, layerFilter, thisArg);
|
||||||
|
|
||||||
|
return goog.isDef(hasFeature);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ol.layer.Layer} layer Layer.
|
* @param {ol.layer.Layer} layer Layer.
|
||||||
* @protected
|
* @protected
|
||||||
|
|||||||
@@ -601,8 +601,56 @@ ol.renderer.webgl.Map.prototype.forEachFeatureAtPixel =
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.Map.prototype.hasFeatureAtPixel =
|
||||||
|
function(coordinate, frameState, layerFilter, thisArg) {
|
||||||
|
var hasFeature = false;
|
||||||
|
|
||||||
|
if (this.getGL().isContextLost()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var context = this.getContext();
|
||||||
|
var viewState = frameState.viewState;
|
||||||
|
|
||||||
|
// do the hit-detection for the overlays first
|
||||||
|
if (!goog.isNull(this.replayGroup)) {
|
||||||
|
// use default color values
|
||||||
|
var d = ol.renderer.webgl.Map.DEFAULT_COLOR_VALUES_;
|
||||||
|
|
||||||
|
hasFeature = this.replayGroup.hasFeatureAtPixel(context,
|
||||||
|
viewState.center, viewState.resolution, viewState.rotation,
|
||||||
|
frameState.size, frameState.pixelRatio,
|
||||||
|
d.opacity, d.brightness, d.contrast, d.hue, d.saturation, {},
|
||||||
|
coordinate);
|
||||||
|
if (hasFeature) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var layerStates = this.getMap().getLayerGroup().getLayerStatesArray();
|
||||||
|
var numLayers = layerStates.length;
|
||||||
|
var i;
|
||||||
|
for (i = numLayers - 1; i >= 0; --i) {
|
||||||
|
var layerState = layerStates[i];
|
||||||
|
var layer = layerState.layer;
|
||||||
|
if (ol.layer.Layer.visibleAtResolution(layerState, viewState.resolution) &&
|
||||||
|
layerFilter.call(thisArg, layer)) {
|
||||||
|
var layerRenderer = this.getLayerRenderer(layer);
|
||||||
|
hasFeature = layerRenderer.hasFeatureAtPixel(coordinate, frameState);
|
||||||
|
if (hasFeature) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hasFeature;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
|
* @const
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.Map.DEFAULT_COLOR_VALUES_ = {
|
ol.renderer.webgl.Map.DEFAULT_COLOR_VALUES_ = {
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
|
|||||||
@@ -140,6 +140,28 @@ ol.renderer.webgl.VectorLayer.prototype.forEachFeatureAtPixel =
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.VectorLayer.prototype.hasFeatureAtPixel =
|
||||||
|
function(coordinate, frameState) {
|
||||||
|
if (goog.isNull(this.replayGroup_) || goog.isNull(this.layerState_)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
var mapRenderer = this.getWebGLMapRenderer();
|
||||||
|
var context = mapRenderer.getContext();
|
||||||
|
var viewState = frameState.viewState;
|
||||||
|
var layerState = this.layerState_;
|
||||||
|
return this.replayGroup_.hasFeatureAtPixel(context,
|
||||||
|
viewState.center, viewState.resolution, viewState.rotation,
|
||||||
|
frameState.size, frameState.pixelRatio,
|
||||||
|
layerState.opacity, layerState.brightness, layerState.contrast,
|
||||||
|
layerState.hue, layerState.saturation, frameState.skippedFeatureUids,
|
||||||
|
coordinate);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle changes in image style state.
|
* Handle changes in image style state.
|
||||||
* @param {goog.events.Event} event Image style change event.
|
* @param {goog.events.Event} event Image style change event.
|
||||||
|
|||||||
Reference in New Issue
Block a user