/*
Copyright (c) 2017 Jean-Marc VIGLINO,
released under the CeCILL-B license (http://www.cecill.info/).
ol.coordinate.convexHull compute a convex hull using Andrew's Monotone Chain Algorithm.
@see https://en.wikipedia.org/wiki/Convex_hull_algorithms
*/
import ol_geom_Geometry from 'ol/geom/Geometry.js';
var ol_coordinate_convexHull;
(function(){
/** Tests if a point is left or right of line (a,b).
* @param {ol.coordinate} a point on the line
* @param {ol.coordinate} b point on the line
* @param {ol.coordinate} o
* @return {bool} true if (a,b,o) turns clockwise
*/
var clockwise = function (a, b, o) {
return ((a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]) <= 0);
};
/** Compute a convex hull using Andrew's Monotone Chain Algorithm
* @param {Array
} points an array of 2D points
* @return {Array} the convex hull vertices
*/
ol_coordinate_convexHull = function (points) { // Sort by increasing x and then y coordinate
var i;
points.sort(function(a, b) {
return a[0] == b[0] ? a[1] - b[1] : a[0] - b[0];
});
// Compute the lower hull
var lower = [];
for (i = 0; i < points.length; i++) {
while (lower.length >= 2 && clockwise(lower[lower.length - 2], lower[lower.length - 1], points[i])) {
lower.pop();
}
lower.push(points[i]);
}
// Compute the upper hull
var upper = [];
for (i = points.length - 1; i >= 0; i--) {
while (upper.length >= 2 && clockwise(upper[upper.length - 2], upper[upper.length - 1], points[i])) {
upper.pop();
}
upper.push(points[i]);
}
upper.pop();
lower.pop();
return lower.concat(upper);
};
/* Get coordinates of a geometry */
var getCoordinates = function (geom) {
var i, p
var h = [];
switch (geom.getType()) {
case "Point":h.push(geom.getCoordinates());
break;
case "LineString":
case "LinearRing":
case "MultiPoint":h = geom.getCoordinates();
break;
case "MultiLineString":
p = geom.getLineStrings();
for (i = 0; i < p.length; i++) h.concat(getCoordinates(p[i]));
break;
case "Polygon":
h = getCoordinates(geom.getLinearRing(0));
break;
case "MultiPolygon":
p = geom.getPolygons();
for (i = 0; i < p.length; i++) h.concat(getCoordinates(p[i]));
break;
case "GeometryCollection":
p = geom.getGeometries();
for (i = 0; i < p.length; i++) h.concat(getCoordinates(p[i]));
break;
default:break;
}
return h;
};
/** Compute a convex hull on a geometry using Andrew's Monotone Chain Algorithm
* @return {Array} the convex hull vertices
*/
ol_geom_Geometry.prototype.convexHull = function() {
return ol_coordinate_convexHull(getCoordinates(this));
};
})();
export default ol_coordinate_convexHull;