diff --git a/package.json b/package.json index 6bf136f..41a0ee9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@flyingeek/lidojs", - "version": "1.2.4", + "version": "1.2.5", "description": "convert Lido OFP text files", "publishConfig": { "registry": "https://npm.pkg.github.com/" diff --git a/src/modules/geopoint.js b/src/modules/geopoint.js index adfa706..0422063 100644 --- a/src/modules/geopoint.js +++ b/src/modules/geopoint.js @@ -13,6 +13,7 @@ const nm_to_rad = (nm) => nm * NM / R; const km_to_rad = (km) => km * 1000.0 / R; const km_to_nm = (km) => km * 1000.0 / NM; +const fmod = (a, b) => Number((a - (Math.floor(a / b) * b)).toPrecision(8)); /** * convert geo coordinates in degrees, minutes in signed fixed value * N5500.0 => 55.00000000 @@ -273,7 +274,6 @@ class GeoPoint { const phi1 = this.latphi.phi; const rlat2 = other.latphi.rlat; const phi2 = other.latphi.phi; - const fmod = (a, b) => Number((a - (Math.floor(a / b) * b)).toPrecision(8)); return fmod( Math.atan2( Math.sin(phi1 - phi2) * Math.cos(rlat2), @@ -324,6 +324,31 @@ class GeoPoint { return new GeoPoint(new LatPhi(rlat, phi).asLatLng); } + /** + * Return points forming a circle around current points + * @param {int} radius distance in radians + * @param {int} steps number of points in the circle + * @param {function} converter converter to use for the radius + */ + circle(radius, steps=64, converter=nm_to_rad) { + if (converter) radius = converter(radius); + const destination = (d, tc) => { + const lat1 = this.latphi.rlat; + const lon1 = this.latphi.phi; + const rlat = Math.asin(Math.sin(lat1) * Math.cos(d) + Math.cos(lat1) *Math.sin(d) * Math.cos(tc)); + let phi = lon1; + if (Math.cos(rlat) !== 0) { + phi = fmod(lon1 - Math.asin(Math.sin(tc) * Math.sin(d) / Math.cos(rlat)) +Math.PI, 2 * Math.PI) - Math.PI; + } + return new GeoPoint(new LatPhi(rlat, phi).asLatLng); + } + const points = []; + for (let i = 0; i < steps; i += 1) { + points.push(destination(radius, i * 2 * Math.PI / steps)); + } + return points; + } + equals(other){ return (this.latitude.toFixed(6) === other.latitude.toFixed(6) && this.longitude.toFixed(6) === other.longitude.toFixed(6)) diff --git a/test/geopoint.test.js b/test/geopoint.test.js index 190069c..c7e576c 100644 --- a/test/geopoint.test.js +++ b/test/geopoint.test.js @@ -172,3 +172,8 @@ test("getCenter", () => { center = GeoPoint.getCenter([g1, g2, g3]); expect(center.equals(new GeoPoint([45.5, 0]))); }); + +test("circle", () => { + const g = new GeoPoint([0, 90]); + expect(g.circle(420).length).toEqual(64); +})