Hull.js examples

View project on GitHub

Ukrainian border

To receive concave hull (polygon) by the set of points just call hull function:

var pointset = [[168, 180], [168, 178], [168, 179], ...];
var pts = hull(pointset, 10);
// ... draw pts

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

var pointset = [[168, 180], [168, 178], [168, 179], ...];
var pts = hull(pointset, 80);
// ... draw pts

Big horse

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

Chars

If you want to get hulls of the point set that looks like a multipolygon, then you need to call hull function for the 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 the several groups, after that we recive hulls for each of them:

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 receive something like that:

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

Geo points

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 on the globe

All calculations in hull.js based on the cartesian coordinate system. If you use it for the calculation and data visualization on the global map please don't forget that globe has the shape of geoid, latitude and longitude are angles (not points with X and Y), and after projection we have some map distortion. So, for the better accuracy you need to 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