diff --git a/debug/vector/vector-canvas.html b/debug/vector/vector-canvas.html index 6b2f69bb..cee5461d 100644 --- a/debug/vector/vector-canvas.html +++ b/debug/vector/vector-canvas.html @@ -69,6 +69,8 @@ weight: 20 }); map.addLayer(polygon); + + polygon.bindPopup('I am a polygon'); diff --git a/src/layer/vector/canvas/Polygon.Canvas.js b/src/layer/vector/canvas/Polygon.Canvas.js index 3db3f8a3..5be4f01a 100644 --- a/src/layer/vector/canvas/Polygon.Canvas.js +++ b/src/layer/vector/canvas/Polygon.Canvas.js @@ -1,6 +1,48 @@ L.Polygon.include(L.Path.SVG || !L.Path.CANVAS ? {} : { _initEvents: function() { - // TODO polygon events (through http://en.wikipedia.org/wiki/Point_in_polygon) + if (this.options.clickable) { + // TODO hand cursor + // TODO mouseover, mouseout, dblclick + this._map.on('click', this._onClick, this); + } + }, + + _containsPoint: function(p) { + var inside = false, + part, p1, p2, + i, j, k, + len, len2; + + // TODO optimization: check if within bounds first + + if (L.Polyline.prototype._containsPoint.call(this, p)) { + // click on polygon border + return true; + } + + // ray casting algorithm for detecting if point is in polygon + + for (i = 0, len = this._parts.length; i < len; i++) { + part = this._parts[i]; + + for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) { + p1 = part[j]; + p2 = part[k]; + + if (((p1.y > p.y) != (p2.y > p.y)) && + (p.x < (p2.x - p1.x) * (p.y - p1.y) / (p2.y - p1.y) + p1.x)) { + inside = !inside; + } + } + } + + return inside; + }, + + _onClick: function(e) { + if (this._containsPoint(e.layerPoint)) { + this.fire('click', e); + } } }); \ No newline at end of file diff --git a/src/layer/vector/canvas/Polyline.Canvas.js b/src/layer/vector/canvas/Polyline.Canvas.js index 021eca53..059baa54 100644 --- a/src/layer/vector/canvas/Polyline.Canvas.js +++ b/src/layer/vector/canvas/Polyline.Canvas.js @@ -8,22 +8,25 @@ L.Polyline.include(L.Path.SVG || !L.Path.CANVAS ? {} : { } }, - _onClick: function(e) { - var p1 = this._point, - p2 = e.layerPoint; - + _containsPoint: function(p) { var i, j, len, len2, dist, part; - + for (i = 0, len = this._parts.length; i < len; i++) { part = this._parts[i]; for (j = 0, len2 = part.length; j < len2 - 1; j++) { - dist = L.LineUtil.pointToSegmentDistance(e.layerPoint, part[j], part[j+1]); + dist = L.LineUtil.pointToSegmentDistance(p, part[j], part[j+1]); if (dist <= this.options.weight / 2) { - this.fire('click', e); - return; + return true; } } } + return false; + }, + + _onClick: function(e) { + if (this._containsPoint(e.layerPoint)) { + this.fire('click', e); + } } }); \ No newline at end of file