const proj4 = require('proj4'), turf = require('@turf/turf'), jsts = require('jsts'), utils = require('./utils'); /** * Convert a line buffer to a polygon coordinates * @param {*} lineGeoCoors buffer line coordinates * @param {*} width in meters */ function lineBuffer(lineGeoCoors, width) { let dBufCoors = []; if (!utils.isEmptyArray(lineGeoCoors)) { const _width = width || 10; // default is 10 meter try { // 1. Transform to Earth Azimuthal Equidistant projection centered by the centeroid of the geometry's bounds const line = turf.lineString(lineGeoCoors); const bbox = turf.bbox(line); const bboxPolygon = turf.bboxPolygon(bbox); const centroid = turf.centroid(bboxPolygon); proj4.defs([ [ 'EPSG:4326', '+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees'], ]); const aeqdProjection = `+proj=aeqd +lat_0=${centroid.geometry.coordinates[1]} +lon_0=${centroid.geometry.coordinates[0]} +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs`; const projectedCoors = lineGeoCoors.map(co => { return proj4(aeqdProjection, co); }); // 2. Do the buffer using JSTS geolib const pathCoords = projectedCoors.map(coor => { return new jsts.geom.Coordinate(coor[0], coor[1]); }); const geometryFactory = new jsts.geom.GeometryFactory(); const shell = geometryFactory.createLineString(pathCoords); const meters = _width * .5; const polygon = shell.buffer(meters, 16, 2); // 16: quadrants point for arc, 2: flat endStyle const polygonCoords = polygon.getCoordinates(); // 3. Transform back to WGS84 latlon dBufCoors = polygonCoords.map(co => { const proj = proj4(aeqdProjection, proj4('EPSG:4326'), co); return [proj.x, proj.y]; }); } catch (error) { // debug(error); return []; } } return dBufCoors; }; module.exports = { lineBuffer };