diff --git a/examples/vector-layer.html b/examples/vector-layer.html
index c34ff9cde5..6cea238384 100644
--- a/examples/vector-layer.html
+++ b/examples/vector-layer.html
@@ -37,7 +37,7 @@
Vector layer example
-
Example of a vector layer.
+
Example of a countries vector layer with country information on hover.
diff --git a/src/ol/geom/base.js b/src/ol/geom/base.js
index 1b8d3e4a04..24c2ee75fe 100644
--- a/src/ol/geom/base.js
+++ b/src/ol/geom/base.js
@@ -42,31 +42,3 @@ ol.geom.squaredDistanceToSegment = function(coordinate, segment) {
return ol.coordinate.squaredDistance(coordinate,
[v[0] + t * (w[0] - v[0]), v[1] + t * (w[1] - v[1])]);
};
-
-
-/**
- * Calculate whether a point falls inside a polygon.
- *
- * @param {ol.Coordinate} coordinate Coordinate of the point.
- * @param {Array.
} vertices Vertices of the polygon.
- * @return {boolean} Whether the point falls inside the polygon.
- */
-ol.geom.pointInPolygon = function(coordinate, vertices) {
- // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
- var x = coordinate[0], y = coordinate[1];
- var inside = false;
- var xi, yi, xj, yj, intersect;
- var numVertices = vertices.length;
- for (var i = 0, j = numVertices - 1; i < numVertices; j = i++) {
- xi = vertices[i][0];
- yi = vertices[i][1];
- xj = vertices[j][0];
- yj = vertices[j][1];
- intersect = ((yi > y) != (yj > y)) &&
- (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
- if (intersect) {
- inside = !inside;
- }
- }
- return inside;
-};
diff --git a/src/ol/geom/linearring.js b/src/ol/geom/linearring.js
index 0d2180be87..8437fd8543 100644
--- a/src/ol/geom/linearring.js
+++ b/src/ol/geom/linearring.js
@@ -33,3 +33,33 @@ goog.inherits(ol.geom.LinearRing, ol.geom.LineString);
ol.geom.LinearRing.prototype.getType = function() {
return ol.geom.GeometryType.LINEARRING;
};
+
+
+/**
+ * Check whether a given coordinate is inside this ring. Note that this is a
+ * fast and simple check - points on an edge or vertex of the ring are either
+ * classified inside or outside.
+ *
+ * @param {ol.Coordinate} coordinate Coordinate.
+ * @return {boolean} Whether the coordinate is inside the ring.
+ */
+ol.geom.LinearRing.prototype.containsCoordinate = function(coordinate) {
+ // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
+ var x = coordinate[0], y = coordinate[1];
+ var vertices = this.getCoordinates();
+ var inside = false;
+ var xi, yi, xj, yj, intersect;
+ var numVertices = vertices.length;
+ for (var i = 0, j = numVertices - 1; i < numVertices; j = i++) {
+ xi = vertices[i][0];
+ yi = vertices[i][1];
+ xj = vertices[j][0];
+ yj = vertices[j][1];
+ intersect = ((yi > y) != (yj > y)) &&
+ (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
+ if (intersect) {
+ inside = !inside;
+ }
+ }
+ return inside;
+};
diff --git a/src/ol/geom/polygon.js b/src/ol/geom/polygon.js
index 383cdebd98..57fd12ffd8 100644
--- a/src/ol/geom/polygon.js
+++ b/src/ol/geom/polygon.js
@@ -91,22 +91,24 @@ ol.geom.Polygon.prototype.getType = function() {
/**
- * Check whether a given coordinate is inside this polygon.
+ * Check whether a given coordinate is inside this polygon. Note that this is a
+ * fast and simple check - points on an edge or vertex of the polygon or one of
+ * its inner rings are either classified inside or outside.
*
* @param {ol.Coordinate} coordinate Coordinate.
* @return {boolean} Whether the coordinate is inside the polygon.
*/
ol.geom.Polygon.prototype.containsCoordinate = function(coordinate) {
var rings = this.rings;
- var containsCoordinate = ol.geom.pointInPolygon(coordinate,
- rings[0].getCoordinates());
- if (containsCoordinate) {
- // if inner ring contains point, polygon does not contain it
- for (var i = 1, ii = rings.length; i < ii; ++i) {
- if (ol.geom.pointInPolygon(coordinate, rings[i].getCoordinates())) {
- containsCoordinate = false;
- break;
- }
+ var containsCoordinate;
+ for (var i = 0, ii = rings.length; i < ii; ++i) {
+ containsCoordinate = rings[i].containsCoordinate(coordinate);
+ // if inner ring (i > 0) contains coordinate, polygon does not contain it
+ if (i > 0) {
+ containsCoordinate = !containsCoordinate;
+ }
+ if (!containsCoordinate) {
+ break;
}
}
return containsCoordinate;
diff --git a/test/spec/ol/geom/linearring.test.js b/test/spec/ol/geom/linearring.test.js
index 402dfbf874..1c3380deff 100644
--- a/test/spec/ol/geom/linearring.test.js
+++ b/test/spec/ol/geom/linearring.test.js
@@ -40,6 +40,72 @@ describe('ol.geom.LinearRing', function() {
});
+ describe('#containsCoordinate()', function() {
+
+ it('knows when a point coordinate is inside a ring', function() {
+ /**
+ * The ring:
+ * edge 3
+ * (5, 10) __________ (15, 10)
+ * / /
+ * edge 4 / / edge 2
+ * / /
+ * (0, 0) /_________/ (10, 0)
+ * edge 1
+ */
+ var ring = new ol.geom.LinearRing(
+ [[0, 0], [10, 0], [15, 10], [5, 10]]);
+
+ // contains: 1 (touches - not implemented), true (within), false (outside)
+ var cases = [{
+ point: [5, 5], contains: true
+ }, {
+ point: [20, 20], contains: false
+ }, {
+ point: [15, 15], contains: false
+ }/*, {
+ point: [0, 0], contains: 1 // lower left corner
+ }, {
+ point: [10, 0], contains: 1 // lower right corner
+ }, {
+ point: [15, 10], contains: 1 // upper right corner
+ }, {
+ point: [5, 10], contains: 1 // upper left corner
+ }, {
+ point: [5, 0], contains: 1 // on edge 1
+ }*/, {
+ point: [5, -0.1], contains: false // below edge 1
+ }, {
+ point: [5, 0.1], contains: true // above edge 1
+ }/*, {
+ point: [12.5, 5], contains: 1 // on edge 2
+ }*/, {
+ point: [12.4, 5], contains: true // left of edge 2
+ }, {
+ point: [12.6, 5], contains: false // right of edge 2
+ }/*, {
+ point: [10, 10], contains: 1 // on edge 3
+ }*/, {
+ point: [10, 9.9], contains: true // below edge 3
+ }, {
+ point: [10, 10.1], contains: false // above edge 3
+ }/*, {
+ point: [2.5, 5], contains: 1 // on edge 4
+ }*/, {
+ point: [2.4, 5], contains: false // left of edge 4
+ }, {
+ point: [2.6, 5], contains: true // right of edge 4
+ }];
+
+ var len = cases.length;
+ var c;
+ for (var i=0; i