canvas polygon clicks through ray casting (yay!), refactoring

This commit is contained in:
Mourner 2011-06-21 14:37:34 +03:00
parent b257c022e3
commit 436915617a
3 changed files with 56 additions and 9 deletions

View File

@ -69,6 +69,8 @@
weight: 20
});
map.addLayer(polygon);
polygon.bindPopup('I am a polygon');
</script>
</body>

View File

@ -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);
}
}
});

View File

@ -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);
}
}
});