Account for icon offsets when doing feature hit detection

This commit is contained in:
Tim Schaub
2013-08-26 19:54:03 -06:00
parent efeb00e4a5
commit 6b625e368b
2 changed files with 36 additions and 9 deletions

View File

@@ -249,6 +249,7 @@ ol.renderer.canvas.VectorLayer.prototype.getFeaturesForPixel =
var cachedTile = this.tileCache_.get(key);
var symbolSizes = cachedTile[1];
var maxSymbolSize = cachedTile[2];
var symbolOffsets = cachedTile[3];
var halfMaxWidth = maxSymbolSize[0] / 2;
var halfMaxHeight = maxSymbolSize[1] / 2;
var locationMin = [location[0] - halfMaxWidth, location[1] - halfMaxHeight];
@@ -264,8 +265,8 @@ ol.renderer.canvas.VectorLayer.prototype.getFeaturesForPixel =
return;
}
var candidate, geom, type, symbolBounds, symbolSize, halfWidth, halfHeight,
coordinates, j;
var candidate, geom, type, symbolBounds, symbolSize, symbolOffset,
halfWidth, halfHeight, coordinates, j;
for (var id in candidates) {
candidate = candidates[id];
geom = candidate.getGeometry();
@@ -275,11 +276,15 @@ ol.renderer.canvas.VectorLayer.prototype.getFeaturesForPixel =
// For points, check if the pixel coordinate is inside the candidate's
// symbol
symbolSize = symbolSizes[goog.getUid(candidate)];
symbolOffset = symbolOffsets[goog.getUid(candidate)];
halfWidth = symbolSize[0] / 2;
halfHeight = symbolSize[1] / 2;
symbolBounds = ol.extent.boundingExtent(
[[location[0] - halfWidth, location[1] - halfHeight],
[location[0] + halfWidth, location[1] + halfHeight]]);
symbolBounds = ol.extent.boundingExtent([
[location[0] - halfWidth - symbolOffset[0],
location[1] - halfHeight + symbolOffset[1]],
[location[0] + halfWidth - symbolOffset[0],
location[1] + halfHeight + symbolOffset[1]]
]);
coordinates = geom.getCoordinates();
if (!goog.isArray(coordinates[0])) {
coordinates = [coordinates];
@@ -519,7 +524,8 @@ ol.renderer.canvas.VectorLayer.prototype.renderFrame =
}
var symbolSizes = sketchCanvasRenderer.getSymbolSizes(),
maxSymbolSize = sketchCanvasRenderer.getMaxSymbolSize();
maxSymbolSize = sketchCanvasRenderer.getMaxSymbolSize(),
symbolOffsets = sketchCanvasRenderer.getSymbolOffsets();
for (key in tilesToRender) {
tileCoord = tilesToRender[key];
if (this.tileCache_.containsKey(key)) {
@@ -531,7 +537,8 @@ ol.renderer.canvas.VectorLayer.prototype.renderFrame =
(tileRange.minX - tileCoord.x) * tileSize[0],
(tileCoord.y - tileRange.maxY) * tileSize[1]);
// TODO: Create an ol.VectorTile subclass of ol.Tile
this.tileCache_.set(key, [tile, symbolSizes, maxSymbolSize]);
this.tileCache_.set(key,
[tile, symbolSizes, maxSymbolSize, symbolOffsets]);
}
finalContext.drawImage(tile,
tileSize[0] * (tileCoord.x - tileRange.minX),

View File

@@ -73,6 +73,12 @@ ol.renderer.canvas.VectorRenderer =
*/
this.symbolSizes_ = {};
/**
* @type {Object.<number, Array.<number>>}
* @private
*/
this.symbolOffsets_ = {};
/**
* @type {Array.<number>}
* @private
@@ -90,6 +96,14 @@ ol.renderer.canvas.VectorRenderer.prototype.getSymbolSizes = function() {
};
/**
* @return {Object.<number, Array.<number>>} Symbolizer offsets.
*/
ol.renderer.canvas.VectorRenderer.prototype.getSymbolOffsets = function() {
return this.symbolOffsets_;
};
/**
* @return {Array.<number>} Maximum symbolizer size.
*/
@@ -232,6 +246,8 @@ ol.renderer.canvas.VectorRenderer.prototype.renderPointFeatures_ =
var midHeight = content.height / 2;
var contentWidth = content.width * this.inverseScale_;
var contentHeight = content.height * this.inverseScale_;
var contentXOffset = xOffset * this.inverseScale_;
var contentYOffset = yOffset * this.inverseScale_;
context.save();
context.setTransform(1, 0, 0, 1, -midWidth, -midHeight);
context.globalAlpha = alpha;
@@ -242,9 +258,13 @@ ol.renderer.canvas.VectorRenderer.prototype.renderPointFeatures_ =
this.symbolSizes_[id] = goog.isDef(size) ?
[Math.max(size[0], contentWidth), Math.max(size[1], contentHeight)] :
[contentWidth, contentHeight];
this.symbolOffsets_[id] =
[xOffset * this.inverseScale_, yOffset * this.inverseScale_];
this.maxSymbolSize_ =
[Math.max(this.maxSymbolSize_[0], this.symbolSizes_[id][0]),
Math.max(this.maxSymbolSize_[1], this.symbolSizes_[id][1])];
[Math.max(this.maxSymbolSize_[0],
this.symbolSizes_[id][0] + 2 * Math.abs(contentXOffset)),
Math.max(this.maxSymbolSize_[1],
this.symbolSizes_[id][1] + 2 * Math.abs(contentYOffset))];
geometry = feature.getGeometry();
if (geometry instanceof ol.geom.Point) {
components = [geometry];