60 lines
1.8 KiB
JavaScript
60 lines
1.8 KiB
JavaScript
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
|
|
};
|