Hull.js examples

View project on GitHub

Basic Usage

To get concave hull (polygon) by a set of points just call hull function:

var pointset = [[251, 275], [248, 276], [255, 272], [246,278], ...];
var pts = hull(pointset, 10);
// ... draw pts

You can adjust concavity of a hull via the 2nd param:

var pointset = [[251, 275], [248, 276], [255, 272], [246,278], ...];
var pts = hull(pointset, 80);
// ... draw pts

Performance

Hull.js also works well with large data sets. This example has more than 52K points, concavity = 20. Execution time in your browser: ms.

Multiple Shapes

If you want to get hulls of a point set that looks like a multipolygon, then you need to call hull function for each subset (for each polygon). In this example we use LukaszKrawczyk's density based clustering library (but you can use any other implementation) to split one large point set to several groups, after that we get hulls for each one:

var clusters,
    dbscan = new DBSCAN(),
    pointset = [[14, 18], [22, 19], [23, 20], ...];

// get clusters
clusters = dbscan.run(pointset, 250, 50);
clusters = clusters.map(function(cluster) {
    return cluster.map(function(i) {
        return pointset[i]; // map index to point
    });
});

// get hulls
clusters.forEach(function(pointset) {
    var pts = hull(pointset, 30);
    // ... draw pts
});

Otherwise (without clustering) you'll get something like this:

var pts = hull(pointset, 30);
// ... draw pts

Point Format

If your point format differs from the [x, y] then you can provide a custom format pattern:

var pointset = [
    { lng: -0.2067, lat: 51.4911 },
    { lng: -0.2070, lat: 51.4915 },
    { lng: -0.2074, lat: 51.4912 },
    ...
];

var pts = hull(pointset, 0.0011, ['.lng', '.lat']);
// ... show pts on map

Geo Points

hull.js is a general-purpose geometrical library, not a geospatial library. All calculations in hull.js are based on cartesian coordinate system. If you use it for cartographic tasks then don't forget that Earth has a shape of geoid, latitude and longitude are angles (and not points with X and Y), and projecting sphere to a plane results in distortion. For better accuracy, convert latitudes and longitudes to cartesian coordinates, calculate concave hull and then convert points back to the geo points. For example (using Leaflet library):

var pointset = [
    { lng:-20, lat:90 },
    { lng:-20, lat:80 },
    { lng:-20, lat:70 },
    ...
];

var pts = pointset.map(map.latLngToContainerPoint.bind(map));
pts = hull(pts, 58, ['.x', '.y']);
pts = pts.map(function(pt) {
    return map.containerPointToLatLng(L.point(pt.x, pt.y));
});
// ... show pts on map