haversine-geolocation 2.0.0-alpha.1 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -14
- package/dist/browser.cjs +1 -1
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.mjs +3 -1
- package/dist/browser.mjs.map +1 -1
- package/dist/build.js +1 -1
- package/dist/build.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +16 -10
- package/dist/index.mjs.map +1 -1
- package/dist/legacy.cjs +1 -1
- package/dist/legacy.cjs.map +1 -1
- package/dist/legacy.mjs +1 -1
- package/dist/legacy.mjs.map +1 -1
- package/dist/types/legacy.d.ts +1 -1
- package/dist/types/utils/getHaversineEntity.d.ts +1 -1
- package/dist/types/utils/index.d.ts +1 -1
- package/dist/types/v2/browser.d.ts +1 -1
- package/dist/types/v2/distance.d.ts +1 -0
- package/dist/types/v2/index.d.ts +5 -5
- package/dist/types/v2/units.d.ts +1 -1
- package/package.json +9 -5
package/README.md
CHANGED
|
@@ -11,22 +11,32 @@ A small JavaScript/TypeScript geospatial library built around spherical Haversin
|
|
|
11
11
|
|
|
12
12
|
## Release status
|
|
13
13
|
|
|
14
|
-
There are currently two
|
|
14
|
+
There are currently two public release lines:
|
|
15
15
|
|
|
16
|
-
- **npm stable
|
|
17
|
-
- **
|
|
16
|
+
- **npm stable / `latest`:** `haversine-geolocation@1.6.0` — the historical V1 API;
|
|
17
|
+
- **npm prerelease / `next`:** `haversine-geolocation@2.0.0-alpha.1` — the first public V2 alpha.
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
If you run:
|
|
19
|
+
A normal install still receives stable V1:
|
|
22
20
|
|
|
23
21
|
```bash
|
|
24
22
|
npm install haversine-geolocation
|
|
25
23
|
```
|
|
26
24
|
|
|
27
|
-
|
|
25
|
+
To test V2 explicitly:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install haversine-geolocation@2.0.0-alpha.1
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
or:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install haversine-geolocation@next
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
V2 is public, but remains prerelease until stable `2.0.0`.
|
|
28
38
|
|
|
29
|
-
See [Migrating from V1 to V2](docs/migration/v1-to-v2.md) for the
|
|
39
|
+
See [Migrating from V1 to V2](docs/migration/v1-to-v2.md) for the upgrade path and the [Changelog](CHANGELOG.md) for release history.
|
|
30
40
|
|
|
31
41
|
## Published V1 usage
|
|
32
42
|
|
|
@@ -94,9 +104,9 @@ V1 couples browser geolocation to the historical singleton. That package design
|
|
|
94
104
|
|
|
95
105
|
---
|
|
96
106
|
|
|
97
|
-
## V2
|
|
107
|
+
## V2 alpha — public prerelease
|
|
98
108
|
|
|
99
|
-
The canonical V2 API is
|
|
109
|
+
The canonical V2 API is available in the public `2.0.0-alpha.1` prerelease and uses named exports.
|
|
100
110
|
|
|
101
111
|
### Distance
|
|
102
112
|
|
|
@@ -224,7 +234,7 @@ The legacy facade preserves historical V1 behavior where compatibility matters,
|
|
|
224
234
|
|
|
225
235
|
## V2 package architecture
|
|
226
236
|
|
|
227
|
-
The
|
|
237
|
+
The V2 package is designed around explicit entry points:
|
|
228
238
|
|
|
229
239
|
```text
|
|
230
240
|
haversine-geolocation
|
|
@@ -278,8 +288,9 @@ d = R * c
|
|
|
278
288
|
|
|
279
289
|
The V2 contract is documented in the accepted ADRs under [docs/architecture](docs/architecture/README.md).
|
|
280
290
|
|
|
281
|
-
The detailed migration and release guides are:
|
|
291
|
+
The detailed API, migration and release guides are:
|
|
282
292
|
|
|
293
|
+
- [V2 API Reference](docs/api-reference.md)
|
|
283
294
|
- [Migrating from Haversine V1 to V2](docs/migration/v1-to-v2.md)
|
|
284
295
|
- [Haversine V2 release runbook](docs/release/v2-release-runbook.md)
|
|
285
296
|
|
|
@@ -292,8 +303,8 @@ Historical behavior and compatibility findings are preserved in:
|
|
|
292
303
|
The repository currently validates:
|
|
293
304
|
|
|
294
305
|
- TypeScript source typechecking;
|
|
295
|
-
-
|
|
296
|
-
- production builds;
|
|
306
|
+
- Vitest unit and characterization tests;
|
|
307
|
+
- production builds through Vite library mode;
|
|
297
308
|
- Node runtime smoke tests;
|
|
298
309
|
- CommonJS and ESM package consumers;
|
|
299
310
|
- npm tarball contents;
|
package/dist/browser.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=()=>{if(typeof navigator
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=()=>{if(typeof navigator>`u`)return;let e=navigator.geolocation;return typeof e?.getCurrentPosition==`function`?e:void 0},t=()=>e()!==void 0,n=t=>new Promise((n,r)=>{let i=e();i===void 0?r(Error(`Geolocation API is not available in this environment`)):i.getCurrentPosition(n,r,t)});exports.getCurrentPosition=n,exports.isGeolocationSupported=t;
|
|
2
2
|
//# sourceMappingURL=browser.cjs.map
|
package/dist/browser.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.cjs","names":["getGeolocation","
|
|
1
|
+
{"version":3,"file":"browser.cjs","names":["getGeolocation","geolocation","isGeolocationSupported","getCurrentPosition","reject","resolve","options"],"sources":["../src/v2/browser.ts"],"sourcesContent":["const getGeolocation = (): Geolocation | undefined => {\n if (typeof navigator === 'undefined') {\n return undefined;\n }\n\n const geolocation = navigator.geolocation;\n return typeof geolocation?.getCurrentPosition === 'function' ? geolocation : undefined;\n};\n\nexport const isGeolocationSupported = (): boolean => getGeolocation() !== undefined;\n\nexport const getCurrentPosition = (options?: PositionOptions): Promise<GeolocationPosition> =>\n new Promise((resolve, reject) => {\n const geolocation = getGeolocation();\n\n if (geolocation === undefined) {\n reject(new Error('Geolocation API is not available in this environment'));\n return;\n }\n\n geolocation.getCurrentPosition(resolve, reject, options);\n });\n"],"mappings":"mEAAA,IAAMA,MAAgD,CAClD,GAAI,OAAO,UAAc,IACrB,OAGJ,IAAMC,EAAc,UAAU,YAC9B,OAAO,OAAOA,GAAa,oBAAuB,WAAaA,EAAc,IAAA,EACjF,EAEaC,MAAwCF,EAAe,IAAM,IAAA,GAE7DG,EAAsB,GAC/B,IAAI,SAAS,EAAS,IAAW,CAC7B,IAAMF,EAAcD,EAAe,EAE/BC,IAAgB,IAAA,GAChBG,EAAW,MAAM,sDAAsD,CAAC,EAI5EH,EAAY,mBAAmBI,EAASD,EAAQE,CAAO,CAC3D,CAAC"}
|
package/dist/browser.mjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
//#region src/v2/browser.ts
|
|
2
2
|
var e = () => {
|
|
3
|
-
if (typeof navigator
|
|
3
|
+
if (typeof navigator > "u") return;
|
|
4
|
+
let e = navigator.geolocation;
|
|
5
|
+
return typeof e?.getCurrentPosition == "function" ? e : void 0;
|
|
4
6
|
}, t = () => e() !== void 0, n = (t) => new Promise((n, r) => {
|
|
5
7
|
let i = e();
|
|
6
8
|
i === void 0 ? r(/* @__PURE__ */ Error("Geolocation API is not available in this environment")) : i.getCurrentPosition(n, r, t);
|
package/dist/browser.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.mjs","names":["getGeolocation","
|
|
1
|
+
{"version":3,"file":"browser.mjs","names":["getGeolocation","geolocation","isGeolocationSupported","getCurrentPosition","reject","resolve","options"],"sources":["../src/v2/browser.ts"],"sourcesContent":["const getGeolocation = (): Geolocation | undefined => {\n if (typeof navigator === 'undefined') {\n return undefined;\n }\n\n const geolocation = navigator.geolocation;\n return typeof geolocation?.getCurrentPosition === 'function' ? geolocation : undefined;\n};\n\nexport const isGeolocationSupported = (): boolean => getGeolocation() !== undefined;\n\nexport const getCurrentPosition = (options?: PositionOptions): Promise<GeolocationPosition> =>\n new Promise((resolve, reject) => {\n const geolocation = getGeolocation();\n\n if (geolocation === undefined) {\n reject(new Error('Geolocation API is not available in this environment'));\n return;\n }\n\n geolocation.getCurrentPosition(resolve, reject, options);\n });\n"],"mappings":";AAAA,IAAMA,UAAgD;CAClD,IAAI,OAAO,YAAc,KACrB;CAGJ,IAAMC,IAAc,UAAU;CAC9B,OAAO,OAAOA,GAAa,sBAAuB,aAAaA,IAAc,KAAA;AACjF,GAEaC,UAAwCF,EAAe,MAAM,KAAA,GAE7DG,KAAsB,MAC/B,IAAI,SAAS,GAAS,MAAW;CAC7B,IAAMF,IAAcD,EAAe;CAEnC,AAAIC,MAAgB,KAAA,IAChBG,EAAO,gBAAI,MAAM,sDAAsD,CAAC,IAI5EH,EAAY,mBAAmBI,GAASD,GAAQE,CAAO;AAC3D,CAAC"}
|
package/dist/build.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.HaversineGeolocation={}))})(this,function(e){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});var t=new class{_convertMeasurements(e,t=`km`){let n=``;switch(t.toLowerCase()){case`mi`:n=(e*.62137).toFixed(1);break;case`km`:n=e.toFixed(1);break;case`m`:n=(e*1e3).toFixed();break;default:n=e.toFixed(1)}return parseFloat(n)}_haversine(...e){let t=e.map(e=>e/180*Math.PI),n=t[0],r=t[1],i=t[2],a=t[3],o=i-n,s=a-r,c=Math.sin(o/2)*Math.sin(o/2)+Math.sin(s/2)*Math.sin(s/2)*Math.cos(n)*Math.cos(i);return 2*Math.asin(Math.sqrt(Math.min(1,Math.max(0,c))))*6372.8}isGeolocationAvailable(){return new Promise((e,t)=>{`geolocation`in navigator?navigator.geolocation.getCurrentPosition(t=>{e(t)},e=>{switch(e.code){case e.PERMISSION_DENIED:t(Error(`Error: Permission denied`));break;case e.POSITION_UNAVAILABLE:t(Error(`Error: Position unavailable`));break;case e.TIMEOUT:t(Error(`Error: Timeout`))}}):t(Error(`Error: Geolocation disabled in your browser`))})}getDistanceBetween(e,t,n){if(
|
|
1
|
+
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.HaversineGeolocation={}))})(this,function(e){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});var t=new class{_convertMeasurements(e,t=`km`){let n=``;switch(t.toLowerCase()){case`mi`:n=(e*.62137).toFixed(1);break;case`km`:n=e.toFixed(1);break;case`m`:n=(e*1e3).toFixed();break;default:n=e.toFixed(1)}return parseFloat(n)}_haversine(...e){let t=e.map(e=>e/180*Math.PI),n=t[0],r=t[1],i=t[2],a=t[3],o=i-n,s=a-r,c=Math.sin(o/2)*Math.sin(o/2)+Math.sin(s/2)*Math.sin(s/2)*Math.cos(n)*Math.cos(i);return 2*Math.asin(Math.sqrt(Math.min(1,Math.max(0,c))))*6372.8}isGeolocationAvailable(){return new Promise((e,t)=>{`geolocation`in navigator?navigator.geolocation.getCurrentPosition(t=>{e(t)},e=>{switch(e.code){case e.PERMISSION_DENIED:t(Error(`Error: Permission denied`));break;case e.POSITION_UNAVAILABLE:t(Error(`Error: Position unavailable`));break;case e.TIMEOUT:t(Error(`Error: Timeout`))}}):t(Error(`Error: Geolocation disabled in your browser`))})}getDistanceBetween(e,t,n){if(Object.prototype.hasOwnProperty.call(e,`latitude`)&&Object.prototype.hasOwnProperty.call(e,`longitude`)&&Object.prototype.hasOwnProperty.call(t,`latitude`)&&Object.prototype.hasOwnProperty.call(t,`longitude`)){let r=this._haversine(e.latitude,e.longitude,t.latitude,t.longitude);return this._convertMeasurements(r,n)}throw Error(`Error: Position latitude or longitude is not correct`)}getClosestPosition(e,t,n){let r=t.map(t=>this.getDistanceBetween(e,t,n)),i=r.indexOf(Math.min(...r));return{...t[i],haversine:{distance:r[i],measurement:n,accuracy:e.accuracy}}}},n=e=>typeof e==`number`&&Number.isFinite(e),r=e=>typeof e==`object`&&!!e&&`latitude`in e&&`longitude`in e;function i(e){if(!r(e))throw TypeError(`Coordinate must provide latitude and longitude`);if(!n(e.latitude)||!n(e.longitude))throw TypeError(`Coordinate latitude and longitude must be finite numbers`);if(e.latitude<-90||e.latitude>90)throw RangeError(`Coordinate latitude must be between -90 and 90`);if(e.longitude<-180||e.longitude>180)throw RangeError(`Coordinate longitude must be between -180 and 180`)}var a=e=>{try{return i(e),!0}catch{return!1}},o={m:1,km:1e3,mi:1609.344};function s(e){if(e!==`m`&&e!==`km`&&e!==`mi`)throw TypeError(`Distance unit must be one of: m, km, mi`)}var c=(e,t,n)=>{if(!Number.isFinite(e))throw TypeError(`Distance value must be a finite number`);return s(t),s(n),e*o[t]/o[n]},l=6371008.8,u=e=>e*Math.PI/180,d=e=>{if(!Number.isFinite(e))throw TypeError(`Radius must be a finite number`);if(e<=0)throw RangeError(`Radius must be greater than zero`)},f=(e={})=>{d(e.radius??6371008.8),s(e.unit??`km`)},p=(e,t,n={})=>{i(e),i(t);let r=n.unit??`km`,a=n.radius??6371008.8;d(a);let o=u(e.latitude),s=u(e.longitude),l=u(t.latitude),f=u(t.longitude),p=l-o,m=f-s,h=Math.sin(p/2),g=Math.sin(m/2),_=h*h+g*g*Math.cos(o)*Math.cos(l);return c(2*Math.asin(Math.sqrt(Math.min(1,Math.max(0,_))))*a,`m`,r)};e.EARTH_MEAN_RADIUS_M=l,e.assertCoordinate=i,e.assertDistanceUnit=s,e.convertDistance=c,e.default=t,e.distance=p,e.isCoordinate=a,e.nearest=(e,t,n={})=>{if(i(e),t.length===0){f(n);return}let r,a=1/0;for(let i of t){let t=p(e,i,n);t<a&&(r=i,a=t)}if(r!==void 0)return{point:r,distance:a}}});
|
|
2
2
|
//# sourceMappingURL=build.js.map
|
package/dist/build.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.js","names":["factory","global","exports","legacy_default","rawValue","measurement","distance","args","rad","deg","lat1","lon1","lat2","lon2","dLat","dLon","a","resolve","data","error","reject","p1","p2","distances","otherPoints","current","value","indexOfSmallest","isFiniteNumber","hasCoordinateShape","assertCoordinate","isCoordinate","METRES_PER_UNIT","assertDistanceUnit","convertDistance","from","to","EARTH_MEAN_RADIUS_M","degreesToRadians","degrees","assertRadius","radius","unit","options","latitude1","longitude1","latitude2","longitude2","latitudeDelta","longitudeDelta","latitudeHaversine","longitudeHaversine","closestPoint","closestDistance","candidate","candidates","candidateDistance","origin"],"sources":["../src/legacy.ts","../src/v2/coordinate.ts","../src/v2/units.ts","../src/v2/distance.ts","../src/v2/nearest.ts"],"sourcesContent":["import type { ILocationPoint } from \"./interfaces/ILocationPoint.js\";\n\nclass HaversineGeolocation {\n _convertMeasurements(distance: number, measurement: string = 'km'): number {\n let rawValue: string = '';\n switch (measurement.toLowerCase()) {\n case 'mi' :\n rawValue = (distance * 0.62137).toFixed(1);\n break;\n case 'km' :\n rawValue = distance.toFixed(1);\n break;\n case 'm' :\n rawValue = (distance * 1000).toFixed();\n break;\n default :\n rawValue = distance.toFixed(1);\n }\n return parseFloat(rawValue);\n }\n\n _haversine(...args: number[]): number {\n const rad: number[] = args.map((deg: number) => deg / 180.0 * Math.PI);\n const lat1: number = rad[0];\n const lon1: number = rad[1];\n const lat2: number = rad[2];\n const lon2: number = rad[3];\n const R: number = 6372.8;\n const dLat: number = lat2 - lat1;\n const dLon: number = lon2 - lon1;\n\n const a: number = Math.sin(dLat / 2) *\n Math.sin(dLat / 2) +\n Math.sin(dLon / 2) *\n Math.sin(dLon / 2) *\n Math.cos(lat1) *\n Math.cos(lat2);\n\n const safeA: number = Math.min(1, Math.max(0, a));\n const c: number = 2 * Math.asin(Math.sqrt(safeA));\n\n return R * c;\n };\n\n isGeolocationAvailable(): Promise<GeolocationPosition> {\n return new Promise((resolve, reject) => {\n if ('geolocation' in navigator) {\n navigator.geolocation.getCurrentPosition((data: GeolocationPosition) => {\n resolve(data);\n }, (error: GeolocationPositionError) => {\n switch (error.code) {\n case error.PERMISSION_DENIED:\n reject(new Error(\"Error: Permission denied\"));\n break;\n case error.POSITION_UNAVAILABLE:\n reject(new Error(\"Error: Position unavailable\"));\n break;\n case error.TIMEOUT:\n reject(new Error(\"Error: Timeout\"));\n break;\n }\n });\n } else {\n reject(new Error(\"Error: Geolocation disabled in your browser\"));\n }\n });\n };\n\n getDistanceBetween(p1: ILocationPoint, p2: ILocationPoint, measurement: string): number {\n if (p1.hasOwnProperty('latitude') && p1.hasOwnProperty('longitude') &&\n p2.hasOwnProperty('latitude') && p2.hasOwnProperty('longitude')) {\n const distance: number = this._haversine(\n p1.latitude,\n p1.longitude,\n p2.latitude,\n p2.longitude\n );\n\n return this._convertMeasurements(distance, measurement)\n\n } else {\n throw new Error(\"Error: Position latitude or longitude is not correct\");\n }\n }\n\n getClosestPosition(\n current: ILocationPoint,\n otherPoints: ILocationPoint[],\n measurement: string,\n ): ILocationPoint & {\n haversine: {\n distance: number;\n measurement: string;\n accuracy: number;\n };\n } {\n const distances: number[] = otherPoints.map((value: any) => this.getDistanceBetween(current, value, measurement));\n const indexOfSmallest: number = distances.indexOf(Math.min(...distances));\n\n return {\n ...otherPoints[indexOfSmallest],\n haversine: {\n distance: distances[indexOfSmallest],\n measurement,\n accuracy: current.accuracy\n },\n };\n };\n}\n\nexport default new HaversineGeolocation();\n","export interface Coordinate {\n latitude: number;\n longitude: number;\n}\n\nconst isFiniteNumber = (value: unknown): value is number =>\n typeof value === 'number' && Number.isFinite(value);\n\nconst hasCoordinateShape = (\n value: unknown,\n): value is { latitude: unknown; longitude: unknown } =>\n typeof value === 'object' &&\n value !== null &&\n 'latitude' in value &&\n 'longitude' in value;\n\nexport function assertCoordinate(\n value: unknown,\n): asserts value is Coordinate {\n if (!hasCoordinateShape(value)) {\n throw new TypeError('Coordinate must provide latitude and longitude');\n }\n\n if (!isFiniteNumber(value.latitude) || !isFiniteNumber(value.longitude)) {\n throw new TypeError('Coordinate latitude and longitude must be finite numbers');\n }\n\n if (value.latitude < -90 || value.latitude > 90) {\n throw new RangeError('Coordinate latitude must be between -90 and 90');\n }\n\n if (value.longitude < -180 || value.longitude > 180) {\n throw new RangeError('Coordinate longitude must be between -180 and 180');\n }\n}\n\nexport const isCoordinate = (value: unknown): value is Coordinate => {\n try {\n assertCoordinate(value);\n return true;\n } catch {\n return false;\n }\n};\n","export type DistanceUnit = 'm' | 'km' | 'mi';\n\nconst METRES_PER_UNIT: Record<DistanceUnit, number> = {\n m: 1,\n km: 1000,\n mi: 1609.344,\n};\n\nexport function assertDistanceUnit(\n value: unknown,\n): asserts value is DistanceUnit {\n if (value !== 'm' && value !== 'km' && value !== 'mi') {\n throw new TypeError('Distance unit must be one of: m, km, mi');\n }\n}\n\nexport const convertDistance = (\n value: number,\n from: DistanceUnit,\n to: DistanceUnit,\n): number => {\n if (!Number.isFinite(value)) {\n throw new TypeError('Distance value must be a finite number');\n }\n\n assertDistanceUnit(from);\n assertDistanceUnit(to);\n\n const metres = value * METRES_PER_UNIT[from];\n\n return metres / METRES_PER_UNIT[to];\n};\n","import { assertCoordinate } from './coordinate.js';\nimport type { Coordinate } from './coordinate.js';\nimport { convertDistance } from './units.js';\nimport type { DistanceUnit } from './units.js';\n\nexport const EARTH_MEAN_RADIUS_M = 6_371_008.8;\n\nexport interface DistanceOptions {\n unit?: DistanceUnit;\n radius?: number;\n}\n\nconst degreesToRadians = (degrees: number): number =>\n degrees * Math.PI / 180;\n\nconst assertRadius = (radius: number): void => {\n if (!Number.isFinite(radius)) {\n throw new TypeError('Radius must be a finite number');\n }\n\n if (radius <= 0) {\n throw new RangeError('Radius must be greater than zero');\n }\n};\n\nexport const distance = (\n from: Coordinate,\n to: Coordinate,\n options: DistanceOptions = {},\n): number => {\n assertCoordinate(from);\n assertCoordinate(to);\n\n const unit = options.unit ?? 'km';\n const radius = options.radius ?? EARTH_MEAN_RADIUS_M;\n\n assertRadius(radius);\n\n const latitude1 = degreesToRadians(from.latitude);\n const longitude1 = degreesToRadians(from.longitude);\n const latitude2 = degreesToRadians(to.latitude);\n const longitude2 = degreesToRadians(to.longitude);\n\n const latitudeDelta = latitude2 - latitude1;\n const longitudeDelta = longitude2 - longitude1;\n\n const latitudeHaversine = Math.sin(latitudeDelta / 2);\n const longitudeHaversine = Math.sin(longitudeDelta / 2);\n\n const a =\n latitudeHaversine * latitudeHaversine +\n longitudeHaversine * longitudeHaversine *\n Math.cos(latitude1) *\n Math.cos(latitude2);\n\n const safeA = Math.min(1, Math.max(0, a));\n const centralAngle = 2 * Math.asin(Math.sqrt(safeA));\n const metres = radius * centralAngle;\n\n return convertDistance(metres, 'm', unit);\n};\n","import type { Coordinate } from './coordinate.js';\nimport { distance } from './distance.js';\nimport type { DistanceOptions } from './distance.js';\n\nexport interface NearestResult<T> {\n point: T;\n distance: number;\n}\n\nexport const nearest = <T extends Coordinate>(\n origin: Coordinate,\n candidates: readonly T[],\n options: DistanceOptions = {},\n): NearestResult<T> | undefined => {\n let closestPoint: T | undefined;\n let closestDistance = Infinity;\n\n for (const candidate of candidates) {\n const candidateDistance = distance(origin, candidate, options);\n\n if (candidateDistance < closestDistance) {\n closestPoint = candidate;\n closestDistance = candidateDistance;\n }\n }\n\n if (closestPoint === undefined) {\n return undefined;\n }\n\n return {\n point: closestPoint,\n distance: closestDistance,\n };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"build.js","names":["factory","global","exports","legacy_default","rawValue","measurement","distance","args","rad","deg","lat1","lon1","lat2","lon2","dLat","dLon","a","resolve","data","error","reject","p1","p2","distances","otherPoints","current","value","indexOfSmallest","isFiniteNumber","hasCoordinateShape","assertCoordinate","isCoordinate","METRES_PER_UNIT","assertDistanceUnit","convertDistance","from","to","EARTH_MEAN_RADIUS_M","degreesToRadians","degrees","assertRadius","radius","assertDistanceOptions","options","unit","latitude1","longitude1","latitude2","longitude2","latitudeDelta","longitudeDelta","latitudeHaversine","longitudeHaversine","origin","candidates","closestPoint","closestDistance","candidate","candidateDistance"],"sources":["../src/legacy.ts","../src/v2/coordinate.ts","../src/v2/units.ts","../src/v2/distance.ts","../src/v2/nearest.ts"],"sourcesContent":["import type { ILocationPoint } from './interfaces/ILocationPoint.js';\n\nclass HaversineGeolocation {\n _convertMeasurements(distance: number, measurement: string = 'km'): number {\n let rawValue: string = '';\n switch (measurement.toLowerCase()) {\n case 'mi':\n rawValue = (distance * 0.62137).toFixed(1);\n break;\n case 'km':\n rawValue = distance.toFixed(1);\n break;\n case 'm':\n rawValue = (distance * 1000).toFixed();\n break;\n default:\n rawValue = distance.toFixed(1);\n }\n return parseFloat(rawValue);\n }\n\n _haversine(...args: number[]): number {\n const rad: number[] = args.map((deg: number) => (deg / 180.0) * Math.PI);\n const lat1: number = rad[0];\n const lon1: number = rad[1];\n const lat2: number = rad[2];\n const lon2: number = rad[3];\n const R: number = 6372.8;\n const dLat: number = lat2 - lat1;\n const dLon: number = lon2 - lon1;\n\n const a: number =\n Math.sin(dLat / 2) * Math.sin(dLat / 2) +\n Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);\n\n const safeA: number = Math.min(1, Math.max(0, a));\n const c: number = 2 * Math.asin(Math.sqrt(safeA));\n\n return R * c;\n }\n\n isGeolocationAvailable(): Promise<GeolocationPosition> {\n return new Promise((resolve, reject) => {\n if ('geolocation' in navigator) {\n navigator.geolocation.getCurrentPosition(\n (data: GeolocationPosition) => {\n resolve(data);\n },\n (error: GeolocationPositionError) => {\n switch (error.code) {\n case error.PERMISSION_DENIED:\n reject(new Error('Error: Permission denied'));\n break;\n case error.POSITION_UNAVAILABLE:\n reject(new Error('Error: Position unavailable'));\n break;\n case error.TIMEOUT:\n reject(new Error('Error: Timeout'));\n break;\n }\n },\n );\n } else {\n reject(new Error('Error: Geolocation disabled in your browser'));\n }\n });\n }\n\n getDistanceBetween(p1: ILocationPoint, p2: ILocationPoint, measurement: string): number {\n if (\n // biome-ignore lint/suspicious/noPrototypeBuiltins: Preserve ES2020-compatible V1 own-property checks without Object.hasOwn (ES2022).\n Object.prototype.hasOwnProperty.call(p1, 'latitude') &&\n // biome-ignore lint/suspicious/noPrototypeBuiltins: Preserve ES2020-compatible V1 own-property checks without Object.hasOwn (ES2022).\n Object.prototype.hasOwnProperty.call(p1, 'longitude') &&\n // biome-ignore lint/suspicious/noPrototypeBuiltins: Preserve ES2020-compatible V1 own-property checks without Object.hasOwn (ES2022).\n Object.prototype.hasOwnProperty.call(p2, 'latitude') &&\n // biome-ignore lint/suspicious/noPrototypeBuiltins: Preserve ES2020-compatible V1 own-property checks without Object.hasOwn (ES2022).\n Object.prototype.hasOwnProperty.call(p2, 'longitude')\n ) {\n const distance: number = this._haversine(\n p1.latitude,\n p1.longitude,\n p2.latitude,\n p2.longitude,\n );\n\n return this._convertMeasurements(distance, measurement);\n } else {\n throw new Error('Error: Position latitude or longitude is not correct');\n }\n }\n\n getClosestPosition(\n current: ILocationPoint,\n otherPoints: ILocationPoint[],\n measurement: string,\n ): ILocationPoint & {\n haversine: {\n distance: number;\n measurement: string;\n accuracy: number;\n };\n } {\n const distances: number[] = otherPoints.map((value) =>\n this.getDistanceBetween(current, value, measurement),\n );\n const indexOfSmallest: number = distances.indexOf(Math.min(...distances));\n\n return {\n ...otherPoints[indexOfSmallest],\n haversine: {\n distance: distances[indexOfSmallest],\n measurement,\n accuracy: current.accuracy,\n },\n };\n }\n}\n\nexport default new HaversineGeolocation();\n","export interface Coordinate {\n latitude: number;\n longitude: number;\n}\n\nconst isFiniteNumber = (value: unknown): value is number =>\n typeof value === 'number' && Number.isFinite(value);\n\nconst hasCoordinateShape = (value: unknown): value is { latitude: unknown; longitude: unknown } =>\n typeof value === 'object' && value !== null && 'latitude' in value && 'longitude' in value;\n\nexport function assertCoordinate(value: unknown): asserts value is Coordinate {\n if (!hasCoordinateShape(value)) {\n throw new TypeError('Coordinate must provide latitude and longitude');\n }\n\n if (!isFiniteNumber(value.latitude) || !isFiniteNumber(value.longitude)) {\n throw new TypeError('Coordinate latitude and longitude must be finite numbers');\n }\n\n if (value.latitude < -90 || value.latitude > 90) {\n throw new RangeError('Coordinate latitude must be between -90 and 90');\n }\n\n if (value.longitude < -180 || value.longitude > 180) {\n throw new RangeError('Coordinate longitude must be between -180 and 180');\n }\n}\n\nexport const isCoordinate = (value: unknown): value is Coordinate => {\n try {\n assertCoordinate(value);\n return true;\n } catch {\n return false;\n }\n};\n","export type DistanceUnit = 'm' | 'km' | 'mi';\n\nconst METRES_PER_UNIT: Record<DistanceUnit, number> = {\n m: 1,\n km: 1000,\n mi: 1609.344,\n};\n\nexport function assertDistanceUnit(value: unknown): asserts value is DistanceUnit {\n if (value !== 'm' && value !== 'km' && value !== 'mi') {\n throw new TypeError('Distance unit must be one of: m, km, mi');\n }\n}\n\nexport const convertDistance = (value: number, from: DistanceUnit, to: DistanceUnit): number => {\n if (!Number.isFinite(value)) {\n throw new TypeError('Distance value must be a finite number');\n }\n\n assertDistanceUnit(from);\n assertDistanceUnit(to);\n\n const metres = value * METRES_PER_UNIT[from];\n\n return metres / METRES_PER_UNIT[to];\n};\n","import { assertCoordinate } from './coordinate.js';\nimport type { Coordinate } from './coordinate.js';\nimport { assertDistanceUnit, convertDistance } from './units.js';\nimport type { DistanceUnit } from './units.js';\n\nexport const EARTH_MEAN_RADIUS_M = 6_371_008.8;\n\nexport interface DistanceOptions {\n unit?: DistanceUnit;\n radius?: number;\n}\n\nconst degreesToRadians = (degrees: number): number => (degrees * Math.PI) / 180;\n\nconst assertRadius = (radius: number): void => {\n if (!Number.isFinite(radius)) {\n throw new TypeError('Radius must be a finite number');\n }\n\n if (radius <= 0) {\n throw new RangeError('Radius must be greater than zero');\n }\n};\n\n// Validate options even when nearest() receives no candidates to measure.\nexport const assertDistanceOptions = (options: DistanceOptions = {}): void => {\n assertRadius(options.radius ?? EARTH_MEAN_RADIUS_M);\n assertDistanceUnit(options.unit ?? 'km');\n};\n\nexport const distance = (\n from: Coordinate,\n to: Coordinate,\n options: DistanceOptions = {},\n): number => {\n assertCoordinate(from);\n assertCoordinate(to);\n\n const unit = options.unit ?? 'km';\n const radius = options.radius ?? EARTH_MEAN_RADIUS_M;\n\n assertRadius(radius);\n\n const latitude1 = degreesToRadians(from.latitude);\n const longitude1 = degreesToRadians(from.longitude);\n const latitude2 = degreesToRadians(to.latitude);\n const longitude2 = degreesToRadians(to.longitude);\n\n const latitudeDelta = latitude2 - latitude1;\n const longitudeDelta = longitude2 - longitude1;\n\n const latitudeHaversine = Math.sin(latitudeDelta / 2);\n const longitudeHaversine = Math.sin(longitudeDelta / 2);\n\n const a =\n latitudeHaversine * latitudeHaversine +\n longitudeHaversine * longitudeHaversine * Math.cos(latitude1) * Math.cos(latitude2);\n\n const safeA = Math.min(1, Math.max(0, a));\n const centralAngle = 2 * Math.asin(Math.sqrt(safeA));\n const metres = radius * centralAngle;\n\n return convertDistance(metres, 'm', unit);\n};\n","import { assertCoordinate } from './coordinate.js';\nimport type { Coordinate } from './coordinate.js';\nimport { assertDistanceOptions, distance } from './distance.js';\nimport type { DistanceOptions } from './distance.js';\n\nexport interface NearestResult<T> {\n point: T;\n distance: number;\n}\n\nexport const nearest = <T extends Coordinate>(\n origin: Coordinate,\n candidates: readonly T[],\n options: DistanceOptions = {},\n): NearestResult<T> | undefined => {\n assertCoordinate(origin);\n\n if (candidates.length === 0) {\n assertDistanceOptions(options);\n return undefined;\n }\n\n let closestPoint: T | undefined;\n let closestDistance = Infinity;\n\n for (const candidate of candidates) {\n const candidateDistance = distance(origin, candidate, options);\n\n if (candidateDistance < closestDistance) {\n closestPoint = candidate;\n closestDistance = candidateDistance;\n }\n }\n\n if (closestPoint === undefined) {\n return undefined;\n }\n\n return {\n point: closestPoint,\n distance: closestDistance,\n };\n};\n"],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("./legacy.cjs");var t=e=>typeof e==`number`&&Number.isFinite(e),n=e=>typeof e==`object`&&!!e&&`latitude`in e&&`longitude`in e;function r(e){if(!n(e))throw TypeError(`Coordinate must provide latitude and longitude`);if(!t(e.latitude)||!t(e.longitude))throw TypeError(`Coordinate latitude and longitude must be finite numbers`);if(e.latitude<-90||e.latitude>90)throw RangeError(`Coordinate latitude must be between -90 and 90`);if(e.longitude<-180||e.longitude>180)throw RangeError(`Coordinate longitude must be between -180 and 180`)}var i=e=>{try{return r(e),!0}catch{return!1}},a={m:1,km:1e3,mi:1609.344};function o(e){if(e!==`m`&&e!==`km`&&e!==`mi`)throw TypeError(`Distance unit must be one of: m, km, mi`)}var s=(e,t,n)=>{if(!Number.isFinite(e))throw TypeError(`Distance value must be a finite number`);return o(t),o(n),e*a[t]/a[n]},c=6371008.8,l=e=>e*Math.PI/180,u=e=>{if(!Number.isFinite(e))throw TypeError(`Radius must be a finite number`);if(e<=0)throw RangeError(`Radius must be greater than zero`)},d=(e,t,n={})=>{r(e),r(t);let i=n.unit??`km`,a=n.radius??6371008.8;u(a);let o=l(e.latitude),c=l(e.longitude),d=l(t.latitude),f=l(t.longitude),p=d-o,m=f-c,h=Math.sin(p/2),g=Math.sin(m/2),_=h*h+g*g*Math.cos(o)*Math.cos(d);return s(2*Math.asin(Math.sqrt(Math.min(1,Math.max(0,_))))*a,`m`,i)},
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("./legacy.cjs");var t=e=>typeof e==`number`&&Number.isFinite(e),n=e=>typeof e==`object`&&!!e&&`latitude`in e&&`longitude`in e;function r(e){if(!n(e))throw TypeError(`Coordinate must provide latitude and longitude`);if(!t(e.latitude)||!t(e.longitude))throw TypeError(`Coordinate latitude and longitude must be finite numbers`);if(e.latitude<-90||e.latitude>90)throw RangeError(`Coordinate latitude must be between -90 and 90`);if(e.longitude<-180||e.longitude>180)throw RangeError(`Coordinate longitude must be between -180 and 180`)}var i=e=>{try{return r(e),!0}catch{return!1}},a={m:1,km:1e3,mi:1609.344};function o(e){if(e!==`m`&&e!==`km`&&e!==`mi`)throw TypeError(`Distance unit must be one of: m, km, mi`)}var s=(e,t,n)=>{if(!Number.isFinite(e))throw TypeError(`Distance value must be a finite number`);return o(t),o(n),e*a[t]/a[n]},c=6371008.8,l=e=>e*Math.PI/180,u=e=>{if(!Number.isFinite(e))throw TypeError(`Radius must be a finite number`);if(e<=0)throw RangeError(`Radius must be greater than zero`)},d=(e={})=>{u(e.radius??6371008.8),o(e.unit??`km`)},f=(e,t,n={})=>{r(e),r(t);let i=n.unit??`km`,a=n.radius??6371008.8;u(a);let o=l(e.latitude),c=l(e.longitude),d=l(t.latitude),f=l(t.longitude),p=d-o,m=f-c,h=Math.sin(p/2),g=Math.sin(m/2),_=h*h+g*g*Math.cos(o)*Math.cos(d);return s(2*Math.asin(Math.sqrt(Math.min(1,Math.max(0,_))))*a,`m`,i)},p=(e,t,n={})=>{if(r(e),t.length===0){d(n);return}let i,a=1/0;for(let r of t){let t=f(e,r,n);t<a&&(i=r,a=t)}if(i!==void 0)return{point:i,distance:a}};exports.EARTH_MEAN_RADIUS_M=c,exports.assertCoordinate=r,exports.assertDistanceUnit=o,exports.convertDistance=s,exports.default=e.default,exports.distance=f,exports.isCoordinate=i,exports.nearest=p;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["require_legacy","isFiniteNumber","value","hasCoordinateShape","assertCoordinate","isCoordinate","METRES_PER_UNIT","assertDistanceUnit","convertDistance","from","to","EARTH_MEAN_RADIUS_M","degreesToRadians","degrees","assertRadius","radius","
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["require_legacy","isFiniteNumber","value","hasCoordinateShape","assertCoordinate","isCoordinate","METRES_PER_UNIT","assertDistanceUnit","convertDistance","from","to","EARTH_MEAN_RADIUS_M","degreesToRadians","degrees","assertRadius","radius","assertDistanceOptions","options","distance","unit","latitude1","longitude1","latitude2","longitude2","latitudeDelta","longitudeDelta","latitudeHaversine","longitudeHaversine","a","nearest","origin","candidates","closestPoint","closestDistance","candidate","candidateDistance"],"sources":["../src/v2/coordinate.ts","../src/v2/units.ts","../src/v2/distance.ts","../src/v2/nearest.ts"],"sourcesContent":["export interface Coordinate {\n latitude: number;\n longitude: number;\n}\n\nconst isFiniteNumber = (value: unknown): value is number =>\n typeof value === 'number' && Number.isFinite(value);\n\nconst hasCoordinateShape = (value: unknown): value is { latitude: unknown; longitude: unknown } =>\n typeof value === 'object' && value !== null && 'latitude' in value && 'longitude' in value;\n\nexport function assertCoordinate(value: unknown): asserts value is Coordinate {\n if (!hasCoordinateShape(value)) {\n throw new TypeError('Coordinate must provide latitude and longitude');\n }\n\n if (!isFiniteNumber(value.latitude) || !isFiniteNumber(value.longitude)) {\n throw new TypeError('Coordinate latitude and longitude must be finite numbers');\n }\n\n if (value.latitude < -90 || value.latitude > 90) {\n throw new RangeError('Coordinate latitude must be between -90 and 90');\n }\n\n if (value.longitude < -180 || value.longitude > 180) {\n throw new RangeError('Coordinate longitude must be between -180 and 180');\n }\n}\n\nexport const isCoordinate = (value: unknown): value is Coordinate => {\n try {\n assertCoordinate(value);\n return true;\n } catch {\n return false;\n }\n};\n","export type DistanceUnit = 'm' | 'km' | 'mi';\n\nconst METRES_PER_UNIT: Record<DistanceUnit, number> = {\n m: 1,\n km: 1000,\n mi: 1609.344,\n};\n\nexport function assertDistanceUnit(value: unknown): asserts value is DistanceUnit {\n if (value !== 'm' && value !== 'km' && value !== 'mi') {\n throw new TypeError('Distance unit must be one of: m, km, mi');\n }\n}\n\nexport const convertDistance = (value: number, from: DistanceUnit, to: DistanceUnit): number => {\n if (!Number.isFinite(value)) {\n throw new TypeError('Distance value must be a finite number');\n }\n\n assertDistanceUnit(from);\n assertDistanceUnit(to);\n\n const metres = value * METRES_PER_UNIT[from];\n\n return metres / METRES_PER_UNIT[to];\n};\n","import { assertCoordinate } from './coordinate.js';\nimport type { Coordinate } from './coordinate.js';\nimport { assertDistanceUnit, convertDistance } from './units.js';\nimport type { DistanceUnit } from './units.js';\n\nexport const EARTH_MEAN_RADIUS_M = 6_371_008.8;\n\nexport interface DistanceOptions {\n unit?: DistanceUnit;\n radius?: number;\n}\n\nconst degreesToRadians = (degrees: number): number => (degrees * Math.PI) / 180;\n\nconst assertRadius = (radius: number): void => {\n if (!Number.isFinite(radius)) {\n throw new TypeError('Radius must be a finite number');\n }\n\n if (radius <= 0) {\n throw new RangeError('Radius must be greater than zero');\n }\n};\n\n// Validate options even when nearest() receives no candidates to measure.\nexport const assertDistanceOptions = (options: DistanceOptions = {}): void => {\n assertRadius(options.radius ?? EARTH_MEAN_RADIUS_M);\n assertDistanceUnit(options.unit ?? 'km');\n};\n\nexport const distance = (\n from: Coordinate,\n to: Coordinate,\n options: DistanceOptions = {},\n): number => {\n assertCoordinate(from);\n assertCoordinate(to);\n\n const unit = options.unit ?? 'km';\n const radius = options.radius ?? EARTH_MEAN_RADIUS_M;\n\n assertRadius(radius);\n\n const latitude1 = degreesToRadians(from.latitude);\n const longitude1 = degreesToRadians(from.longitude);\n const latitude2 = degreesToRadians(to.latitude);\n const longitude2 = degreesToRadians(to.longitude);\n\n const latitudeDelta = latitude2 - latitude1;\n const longitudeDelta = longitude2 - longitude1;\n\n const latitudeHaversine = Math.sin(latitudeDelta / 2);\n const longitudeHaversine = Math.sin(longitudeDelta / 2);\n\n const a =\n latitudeHaversine * latitudeHaversine +\n longitudeHaversine * longitudeHaversine * Math.cos(latitude1) * Math.cos(latitude2);\n\n const safeA = Math.min(1, Math.max(0, a));\n const centralAngle = 2 * Math.asin(Math.sqrt(safeA));\n const metres = radius * centralAngle;\n\n return convertDistance(metres, 'm', unit);\n};\n","import { assertCoordinate } from './coordinate.js';\nimport type { Coordinate } from './coordinate.js';\nimport { assertDistanceOptions, distance } from './distance.js';\nimport type { DistanceOptions } from './distance.js';\n\nexport interface NearestResult<T> {\n point: T;\n distance: number;\n}\n\nexport const nearest = <T extends Coordinate>(\n origin: Coordinate,\n candidates: readonly T[],\n options: DistanceOptions = {},\n): NearestResult<T> | undefined => {\n assertCoordinate(origin);\n\n if (candidates.length === 0) {\n assertDistanceOptions(options);\n return undefined;\n }\n\n let closestPoint: T | undefined;\n let closestDistance = Infinity;\n\n for (const candidate of candidates) {\n const candidateDistance = distance(origin, candidate, options);\n\n if (candidateDistance < closestDistance) {\n closestPoint = candidate;\n closestDistance = candidateDistance;\n }\n }\n\n if (closestPoint === undefined) {\n return undefined;\n }\n\n return {\n point: closestPoint,\n distance: closestDistance,\n };\n};\n"],"mappings":"+HAKA,IAAMC,EAAkB,GACpB,OAAOC,GAAU,UAAY,OAAO,SAASA,CAAK,EAEhDC,EAAsB,GACxB,OAAOD,GAAU,YAAYA,GAAkB,aAAcA,GAAS,cAAeA,EAEzF,SAAgBE,EAAiB,EAA6C,CAC1E,GAAI,CAACD,EAAmBD,CAAK,EACzB,MAAU,UAAU,gDAAgD,EAGxE,GAAI,CAACD,EAAeC,EAAM,QAAQ,GAAK,CAACD,EAAeC,EAAM,SAAS,EAClE,MAAU,UAAU,0DAA0D,EAGlF,GAAIA,EAAM,SAAW,KAAOA,EAAM,SAAW,GACzC,MAAU,WAAW,gDAAgD,EAGzE,GAAIA,EAAM,UAAY,MAAQA,EAAM,UAAY,IAC5C,MAAU,WAAW,mDAAmD,CAEhF,CAEA,IAAaG,EAAgB,GAAwC,CACjE,GAAI,CAEA,OADAD,EAAiBF,CAAK,EACf,EACX,MAAQ,CACJ,MAAO,EACX,CACJ,EClCMI,EAAgD,CAClD,EAAG,EACH,GAAI,IACJ,GAAI,QACR,EAEA,SAAgBC,EAAmB,EAA+C,CAC9E,GAAIL,IAAU,KAAOA,IAAU,MAAQA,IAAU,KAC7C,MAAU,UAAU,yCAAyC,CAErE,CAEA,IAAaM,GAAmB,EAAe,EAAoB,IAA6B,CAC5F,GAAI,CAAC,OAAO,SAASN,CAAK,EACtB,MAAU,UAAU,wCAAwC,EAQhE,OALAK,EAAmBE,CAAI,EACvBF,EAAmBG,CAAE,EAENR,EAAQI,EAAgBG,GAEvBH,EAAgBI,EACpC,ECpBaC,EAAsB,UAO7BC,EAAoB,GAA6BC,EAAU,KAAK,GAAM,IAEtEC,EAAgB,GAAyB,CAC3C,GAAI,CAAC,OAAO,SAASC,CAAM,EACvB,MAAU,UAAU,gCAAgC,EAGxD,GAAIA,GAAU,EACV,MAAU,WAAW,kCAAkC,CAE/D,EAGaC,GAAyB,EAA2B,CAAC,IAAY,CAC1EF,EAAaG,EAAQ,QAAA,SAA6B,EAClDV,EAAmBU,EAAQ,MAAQ,IAAI,CAC3C,EAEaC,GACT,EACA,EACA,EAA2B,CAAC,IACnB,CACTd,EAAiBK,CAAI,EACrBL,EAAiBM,CAAE,EAEnB,IAAMS,EAAOF,EAAQ,MAAQ,KACvBF,EAASE,EAAQ,QAAA,UAEvBH,EAAaC,CAAM,EAEnB,IAAMK,EAAYR,EAAiBH,EAAK,QAAQ,EAC1CY,EAAaT,EAAiBH,EAAK,SAAS,EAC5Ca,EAAYV,EAAiBF,EAAG,QAAQ,EACxCa,EAAaX,EAAiBF,EAAG,SAAS,EAE1Cc,EAAgBF,EAAYF,EAC5BK,EAAiBF,EAAaF,EAE9BK,EAAoB,KAAK,IAAIF,EAAgB,CAAC,EAC9CG,EAAqB,KAAK,IAAIF,EAAiB,CAAC,EAEhDG,EACFF,EAAoBA,EACpBC,EAAqBA,EAAqB,KAAK,IAAIP,CAAS,EAAI,KAAK,IAAIE,CAAS,EAMtF,OAAOd,EAHc,EAAI,KAAK,KAAK,KAAK,KAD1B,KAAK,IAAI,EAAG,KAAK,IAAI,EAAGoB,CAAC,CACM,CAAK,CAAC,EACpCb,EAEgB,IAAKI,CAAI,CAC5C,ECrDaU,GACT,EACA,EACA,EAA2B,CAAC,IACG,CAG/B,GAFAzB,EAAiB0B,CAAM,EAEnBC,EAAW,SAAW,EAAG,CACzBf,EAAsBC,CAAO,EAC7B,MACJ,CAEA,IAAIe,EACAC,EAAkB,IAEtB,IAAK,IAAMC,KAAaH,EAAY,CAChC,IAAMI,EAAoBjB,EAASY,EAAQI,EAAWjB,CAAO,EAEzDkB,EAAoBF,IACpB,EAAeC,EACf,EAAkBC,EAE1B,CAEA,GAAIH,IAAiB,IAAA,GAIrB,MAAO,CACH,MAAOA,EACP,SAAUC,CACd,CACJ"}
|
package/dist/index.mjs
CHANGED
|
@@ -27,24 +27,30 @@ var s = (e, t, n) => {
|
|
|
27
27
|
}, c = 6371008.8, l = (e) => e * Math.PI / 180, u = (e) => {
|
|
28
28
|
if (!Number.isFinite(e)) throw TypeError("Radius must be a finite number");
|
|
29
29
|
if (e <= 0) throw RangeError("Radius must be greater than zero");
|
|
30
|
-
}, d = (e
|
|
30
|
+
}, d = (e = {}) => {
|
|
31
|
+
u(e.radius ?? 6371008.8), o(e.unit ?? "km");
|
|
32
|
+
}, f = (e, t, n = {}) => {
|
|
31
33
|
r(e), r(t);
|
|
32
34
|
let i = n.unit ?? "km", a = n.radius ?? 6371008.8;
|
|
33
35
|
u(a);
|
|
34
36
|
let o = l(e.latitude), c = l(e.longitude), d = l(t.latitude), f = l(t.longitude), p = d - o, m = f - c, h = Math.sin(p / 2), g = Math.sin(m / 2), _ = h * h + g * g * Math.cos(o) * Math.cos(d);
|
|
35
37
|
return s(2 * Math.asin(Math.sqrt(Math.min(1, Math.max(0, _)))) * a, "m", i);
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
}, p = (e, t, n = {}) => {
|
|
39
|
+
if (r(e), t.length === 0) {
|
|
40
|
+
d(n);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
let i, a = Infinity;
|
|
44
|
+
for (let r of t) {
|
|
45
|
+
let t = f(e, r, n);
|
|
46
|
+
t < a && (i = r, a = t);
|
|
41
47
|
}
|
|
42
|
-
if (
|
|
43
|
-
point:
|
|
44
|
-
distance:
|
|
48
|
+
if (i !== void 0) return {
|
|
49
|
+
point: i,
|
|
50
|
+
distance: a
|
|
45
51
|
};
|
|
46
52
|
};
|
|
47
53
|
//#endregion
|
|
48
|
-
export { c as EARTH_MEAN_RADIUS_M, r as assertCoordinate, o as assertDistanceUnit, s as convertDistance, e as default,
|
|
54
|
+
export { c as EARTH_MEAN_RADIUS_M, r as assertCoordinate, o as assertDistanceUnit, s as convertDistance, e as default, f as distance, i as isCoordinate, p as nearest };
|
|
49
55
|
|
|
50
56
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["legacy_default","isFiniteNumber","value","hasCoordinateShape","assertCoordinate","isCoordinate","METRES_PER_UNIT","assertDistanceUnit","convertDistance","from","to","EARTH_MEAN_RADIUS_M","degreesToRadians","degrees","assertRadius","radius","
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["legacy_default","isFiniteNumber","value","hasCoordinateShape","assertCoordinate","isCoordinate","METRES_PER_UNIT","assertDistanceUnit","convertDistance","from","to","EARTH_MEAN_RADIUS_M","degreesToRadians","degrees","assertRadius","radius","assertDistanceOptions","options","distance","unit","latitude1","longitude1","latitude2","longitude2","latitudeDelta","longitudeDelta","latitudeHaversine","longitudeHaversine","a","nearest","origin","candidates","closestPoint","closestDistance","candidate","candidateDistance"],"sources":["../src/v2/coordinate.ts","../src/v2/units.ts","../src/v2/distance.ts","../src/v2/nearest.ts"],"sourcesContent":["export interface Coordinate {\n latitude: number;\n longitude: number;\n}\n\nconst isFiniteNumber = (value: unknown): value is number =>\n typeof value === 'number' && Number.isFinite(value);\n\nconst hasCoordinateShape = (value: unknown): value is { latitude: unknown; longitude: unknown } =>\n typeof value === 'object' && value !== null && 'latitude' in value && 'longitude' in value;\n\nexport function assertCoordinate(value: unknown): asserts value is Coordinate {\n if (!hasCoordinateShape(value)) {\n throw new TypeError('Coordinate must provide latitude and longitude');\n }\n\n if (!isFiniteNumber(value.latitude) || !isFiniteNumber(value.longitude)) {\n throw new TypeError('Coordinate latitude and longitude must be finite numbers');\n }\n\n if (value.latitude < -90 || value.latitude > 90) {\n throw new RangeError('Coordinate latitude must be between -90 and 90');\n }\n\n if (value.longitude < -180 || value.longitude > 180) {\n throw new RangeError('Coordinate longitude must be between -180 and 180');\n }\n}\n\nexport const isCoordinate = (value: unknown): value is Coordinate => {\n try {\n assertCoordinate(value);\n return true;\n } catch {\n return false;\n }\n};\n","export type DistanceUnit = 'm' | 'km' | 'mi';\n\nconst METRES_PER_UNIT: Record<DistanceUnit, number> = {\n m: 1,\n km: 1000,\n mi: 1609.344,\n};\n\nexport function assertDistanceUnit(value: unknown): asserts value is DistanceUnit {\n if (value !== 'm' && value !== 'km' && value !== 'mi') {\n throw new TypeError('Distance unit must be one of: m, km, mi');\n }\n}\n\nexport const convertDistance = (value: number, from: DistanceUnit, to: DistanceUnit): number => {\n if (!Number.isFinite(value)) {\n throw new TypeError('Distance value must be a finite number');\n }\n\n assertDistanceUnit(from);\n assertDistanceUnit(to);\n\n const metres = value * METRES_PER_UNIT[from];\n\n return metres / METRES_PER_UNIT[to];\n};\n","import { assertCoordinate } from './coordinate.js';\nimport type { Coordinate } from './coordinate.js';\nimport { assertDistanceUnit, convertDistance } from './units.js';\nimport type { DistanceUnit } from './units.js';\n\nexport const EARTH_MEAN_RADIUS_M = 6_371_008.8;\n\nexport interface DistanceOptions {\n unit?: DistanceUnit;\n radius?: number;\n}\n\nconst degreesToRadians = (degrees: number): number => (degrees * Math.PI) / 180;\n\nconst assertRadius = (radius: number): void => {\n if (!Number.isFinite(radius)) {\n throw new TypeError('Radius must be a finite number');\n }\n\n if (radius <= 0) {\n throw new RangeError('Radius must be greater than zero');\n }\n};\n\n// Validate options even when nearest() receives no candidates to measure.\nexport const assertDistanceOptions = (options: DistanceOptions = {}): void => {\n assertRadius(options.radius ?? EARTH_MEAN_RADIUS_M);\n assertDistanceUnit(options.unit ?? 'km');\n};\n\nexport const distance = (\n from: Coordinate,\n to: Coordinate,\n options: DistanceOptions = {},\n): number => {\n assertCoordinate(from);\n assertCoordinate(to);\n\n const unit = options.unit ?? 'km';\n const radius = options.radius ?? EARTH_MEAN_RADIUS_M;\n\n assertRadius(radius);\n\n const latitude1 = degreesToRadians(from.latitude);\n const longitude1 = degreesToRadians(from.longitude);\n const latitude2 = degreesToRadians(to.latitude);\n const longitude2 = degreesToRadians(to.longitude);\n\n const latitudeDelta = latitude2 - latitude1;\n const longitudeDelta = longitude2 - longitude1;\n\n const latitudeHaversine = Math.sin(latitudeDelta / 2);\n const longitudeHaversine = Math.sin(longitudeDelta / 2);\n\n const a =\n latitudeHaversine * latitudeHaversine +\n longitudeHaversine * longitudeHaversine * Math.cos(latitude1) * Math.cos(latitude2);\n\n const safeA = Math.min(1, Math.max(0, a));\n const centralAngle = 2 * Math.asin(Math.sqrt(safeA));\n const metres = radius * centralAngle;\n\n return convertDistance(metres, 'm', unit);\n};\n","import { assertCoordinate } from './coordinate.js';\nimport type { Coordinate } from './coordinate.js';\nimport { assertDistanceOptions, distance } from './distance.js';\nimport type { DistanceOptions } from './distance.js';\n\nexport interface NearestResult<T> {\n point: T;\n distance: number;\n}\n\nexport const nearest = <T extends Coordinate>(\n origin: Coordinate,\n candidates: readonly T[],\n options: DistanceOptions = {},\n): NearestResult<T> | undefined => {\n assertCoordinate(origin);\n\n if (candidates.length === 0) {\n assertDistanceOptions(options);\n return undefined;\n }\n\n let closestPoint: T | undefined;\n let closestDistance = Infinity;\n\n for (const candidate of candidates) {\n const candidateDistance = distance(origin, candidate, options);\n\n if (candidateDistance < closestDistance) {\n closestPoint = candidate;\n closestDistance = candidateDistance;\n }\n }\n\n if (closestPoint === undefined) {\n return undefined;\n }\n\n return {\n point: closestPoint,\n distance: closestDistance,\n };\n};\n"],"mappings":";;AAKA,IAAMC,KAAkB,MACpB,OAAOC,KAAU,YAAY,OAAO,SAASA,CAAK,GAEhDC,KAAsB,MACxB,OAAOD,KAAU,cAAYA,KAAkB,cAAcA,KAAS,eAAeA;AAEzF,SAAgBE,EAAiB,GAA6C;CAC1E,IAAI,CAACD,EAAmBD,CAAK,GACzB,MAAU,UAAU,gDAAgD;CAGxE,IAAI,CAACD,EAAeC,EAAM,QAAQ,KAAK,CAACD,EAAeC,EAAM,SAAS,GAClE,MAAU,UAAU,0DAA0D;CAGlF,IAAIA,EAAM,WAAW,OAAOA,EAAM,WAAW,IACzC,MAAU,WAAW,gDAAgD;CAGzE,IAAIA,EAAM,YAAY,QAAQA,EAAM,YAAY,KAC5C,MAAU,WAAW,mDAAmD;AAEhF;AAEA,IAAaG,KAAgB,MAAwC;CACjE,IAAI;EAEA,OADAD,EAAiBF,CAAK,GACf;CACX,QAAQ;EACJ,OAAO;CACX;AACJ,GClCMI,IAAgD;CAClD,GAAG;CACH,IAAI;CACJ,IAAI;AACR;AAEA,SAAgBC,EAAmB,GAA+C;CAC9E,IAAIL,MAAU,OAAOA,MAAU,QAAQA,MAAU,MAC7C,MAAU,UAAU,yCAAyC;AAErE;AAEA,IAAaM,KAAmB,GAAe,GAAoB,MAA6B;CAC5F,IAAI,CAAC,OAAO,SAASN,CAAK,GACtB,MAAU,UAAU,wCAAwC;CAQhE,OALAK,EAAmBE,CAAI,GACvBF,EAAmBG,CAAE,GAENR,IAAQI,EAAgBG,KAEvBH,EAAgBI;AACpC,GCpBaC,IAAsB,WAO7BC,KAAoB,MAA6BC,IAAU,KAAK,KAAM,KAEtEC,KAAgB,MAAyB;CAC3C,IAAI,CAAC,OAAO,SAASC,CAAM,GACvB,MAAU,UAAU,gCAAgC;CAGxD,IAAIA,KAAU,GACV,MAAU,WAAW,kCAAkC;AAE/D,GAGaC,KAAyB,IAA2B,CAAC,MAAY;CAE1E,AADAF,EAAaG,EAAQ,UAAA,SAA6B,GAClDV,EAAmBU,EAAQ,QAAQ,IAAI;AAC3C,GAEaC,KACT,GACA,GACA,IAA2B,CAAC,MACnB;CAET,AADAd,EAAiBK,CAAI,GACrBL,EAAiBM,CAAE;CAEnB,IAAMS,IAAOF,EAAQ,QAAQ,MACvBF,IAASE,EAAQ,UAAA;CAEvB,EAAaF,CAAM;CAEnB,IAAMK,IAAYR,EAAiBH,EAAK,QAAQ,GAC1CY,IAAaT,EAAiBH,EAAK,SAAS,GAC5Ca,IAAYV,EAAiBF,EAAG,QAAQ,GACxCa,IAAaX,EAAiBF,EAAG,SAAS,GAE1Cc,IAAgBF,IAAYF,GAC5BK,IAAiBF,IAAaF,GAE9BK,IAAoB,KAAK,IAAIF,IAAgB,CAAC,GAC9CG,IAAqB,KAAK,IAAIF,IAAiB,CAAC,GAEhDG,IACFF,IAAoBA,IACpBC,IAAqBA,IAAqB,KAAK,IAAIP,CAAS,IAAI,KAAK,IAAIE,CAAS;CAMtF,OAAOd,EAHc,IAAI,KAAK,KAAK,KAAK,KAD1B,KAAK,IAAI,GAAG,KAAK,IAAI,GAAGoB,CAAC,CACM,CAAK,CAAC,IACpCb,GAEgB,KAAKI,CAAI;AAC5C,GCrDaU,KACT,GACA,GACA,IAA2B,CAAC,MACG;CAG/B,IAFAzB,EAAiB0B,CAAM,GAEnBC,EAAW,WAAW,GAAG;EACzB,EAAsBd,CAAO;EAC7B;CACJ;CAEA,IAAIe,GACAC,IAAkB;CAEtB,KAAK,IAAMC,KAAaH,GAAY;EAChC,IAAMI,IAAoBjB,EAASY,GAAQI,GAAWjB,CAAO;EAE7D,AAAIkB,IAAoBF,MACpB,IAAeC,GACf,IAAkBC;CAE1B;CAEA,IAAIH,MAAiB,KAAA,GAIrB,OAAO;EACH,OAAOA;EACP,UAAUC;CACd;AACJ"}
|
package/dist/legacy.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});var e=new class{_convertMeasurements(e,t=`km`){let n=``;switch(t.toLowerCase()){case`mi`:n=(e*.62137).toFixed(1);break;case`km`:n=e.toFixed(1);break;case`m`:n=(e*1e3).toFixed();break;default:n=e.toFixed(1)}return parseFloat(n)}_haversine(...e){let t=e.map(e=>e/180*Math.PI),n=t[0],r=t[1],i=t[2],a=t[3],o=i-n,s=a-r,c=Math.sin(o/2)*Math.sin(o/2)+Math.sin(s/2)*Math.sin(s/2)*Math.cos(n)*Math.cos(i);return 2*Math.asin(Math.sqrt(Math.min(1,Math.max(0,c))))*6372.8}isGeolocationAvailable(){return new Promise((e,t)=>{`geolocation`in navigator?navigator.geolocation.getCurrentPosition(t=>{e(t)},e=>{switch(e.code){case e.PERMISSION_DENIED:t(Error(`Error: Permission denied`));break;case e.POSITION_UNAVAILABLE:t(Error(`Error: Position unavailable`));break;case e.TIMEOUT:t(Error(`Error: Timeout`))}}):t(Error(`Error: Geolocation disabled in your browser`))})}getDistanceBetween(e,t,n){if(
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});var e=new class{_convertMeasurements(e,t=`km`){let n=``;switch(t.toLowerCase()){case`mi`:n=(e*.62137).toFixed(1);break;case`km`:n=e.toFixed(1);break;case`m`:n=(e*1e3).toFixed();break;default:n=e.toFixed(1)}return parseFloat(n)}_haversine(...e){let t=e.map(e=>e/180*Math.PI),n=t[0],r=t[1],i=t[2],a=t[3],o=i-n,s=a-r,c=Math.sin(o/2)*Math.sin(o/2)+Math.sin(s/2)*Math.sin(s/2)*Math.cos(n)*Math.cos(i);return 2*Math.asin(Math.sqrt(Math.min(1,Math.max(0,c))))*6372.8}isGeolocationAvailable(){return new Promise((e,t)=>{`geolocation`in navigator?navigator.geolocation.getCurrentPosition(t=>{e(t)},e=>{switch(e.code){case e.PERMISSION_DENIED:t(Error(`Error: Permission denied`));break;case e.POSITION_UNAVAILABLE:t(Error(`Error: Position unavailable`));break;case e.TIMEOUT:t(Error(`Error: Timeout`))}}):t(Error(`Error: Geolocation disabled in your browser`))})}getDistanceBetween(e,t,n){if(Object.prototype.hasOwnProperty.call(e,`latitude`)&&Object.prototype.hasOwnProperty.call(e,`longitude`)&&Object.prototype.hasOwnProperty.call(t,`latitude`)&&Object.prototype.hasOwnProperty.call(t,`longitude`)){let r=this._haversine(e.latitude,e.longitude,t.latitude,t.longitude);return this._convertMeasurements(r,n)}throw Error(`Error: Position latitude or longitude is not correct`)}getClosestPosition(e,t,n){let r=t.map(t=>this.getDistanceBetween(e,t,n)),i=r.indexOf(Math.min(...r));return{...t[i],haversine:{distance:r[i],measurement:n,accuracy:e.accuracy}}}};exports.default=e;
|
|
2
2
|
//# sourceMappingURL=legacy.cjs.map
|
package/dist/legacy.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"legacy.cjs","names":["legacy_default","rawValue","measurement","distance","args","rad","deg","lat1","lon1","lat2","lon2","dLat","dLon","a","resolve","data","error","reject","p1","p2","distances","otherPoints","current","value","indexOfSmallest"],"sources":["../src/legacy.ts"],"sourcesContent":["import type { ILocationPoint } from
|
|
1
|
+
{"version":3,"file":"legacy.cjs","names":["legacy_default","rawValue","measurement","distance","args","rad","deg","lat1","lon1","lat2","lon2","dLat","dLon","a","resolve","data","error","reject","p1","p2","distances","otherPoints","current","value","indexOfSmallest"],"sources":["../src/legacy.ts"],"sourcesContent":["import type { ILocationPoint } from './interfaces/ILocationPoint.js';\n\nclass HaversineGeolocation {\n _convertMeasurements(distance: number, measurement: string = 'km'): number {\n let rawValue: string = '';\n switch (measurement.toLowerCase()) {\n case 'mi':\n rawValue = (distance * 0.62137).toFixed(1);\n break;\n case 'km':\n rawValue = distance.toFixed(1);\n break;\n case 'm':\n rawValue = (distance * 1000).toFixed();\n break;\n default:\n rawValue = distance.toFixed(1);\n }\n return parseFloat(rawValue);\n }\n\n _haversine(...args: number[]): number {\n const rad: number[] = args.map((deg: number) => (deg / 180.0) * Math.PI);\n const lat1: number = rad[0];\n const lon1: number = rad[1];\n const lat2: number = rad[2];\n const lon2: number = rad[3];\n const R: number = 6372.8;\n const dLat: number = lat2 - lat1;\n const dLon: number = lon2 - lon1;\n\n const a: number =\n Math.sin(dLat / 2) * Math.sin(dLat / 2) +\n Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);\n\n const safeA: number = Math.min(1, Math.max(0, a));\n const c: number = 2 * Math.asin(Math.sqrt(safeA));\n\n return R * c;\n }\n\n isGeolocationAvailable(): Promise<GeolocationPosition> {\n return new Promise((resolve, reject) => {\n if ('geolocation' in navigator) {\n navigator.geolocation.getCurrentPosition(\n (data: GeolocationPosition) => {\n resolve(data);\n },\n (error: GeolocationPositionError) => {\n switch (error.code) {\n case error.PERMISSION_DENIED:\n reject(new Error('Error: Permission denied'));\n break;\n case error.POSITION_UNAVAILABLE:\n reject(new Error('Error: Position unavailable'));\n break;\n case error.TIMEOUT:\n reject(new Error('Error: Timeout'));\n break;\n }\n },\n );\n } else {\n reject(new Error('Error: Geolocation disabled in your browser'));\n }\n });\n }\n\n getDistanceBetween(p1: ILocationPoint, p2: ILocationPoint, measurement: string): number {\n if (\n // biome-ignore lint/suspicious/noPrototypeBuiltins: Preserve ES2020-compatible V1 own-property checks without Object.hasOwn (ES2022).\n Object.prototype.hasOwnProperty.call(p1, 'latitude') &&\n // biome-ignore lint/suspicious/noPrototypeBuiltins: Preserve ES2020-compatible V1 own-property checks without Object.hasOwn (ES2022).\n Object.prototype.hasOwnProperty.call(p1, 'longitude') &&\n // biome-ignore lint/suspicious/noPrototypeBuiltins: Preserve ES2020-compatible V1 own-property checks without Object.hasOwn (ES2022).\n Object.prototype.hasOwnProperty.call(p2, 'latitude') &&\n // biome-ignore lint/suspicious/noPrototypeBuiltins: Preserve ES2020-compatible V1 own-property checks without Object.hasOwn (ES2022).\n Object.prototype.hasOwnProperty.call(p2, 'longitude')\n ) {\n const distance: number = this._haversine(\n p1.latitude,\n p1.longitude,\n p2.latitude,\n p2.longitude,\n );\n\n return this._convertMeasurements(distance, measurement);\n } else {\n throw new Error('Error: Position latitude or longitude is not correct');\n }\n }\n\n getClosestPosition(\n current: ILocationPoint,\n otherPoints: ILocationPoint[],\n measurement: string,\n ): ILocationPoint & {\n haversine: {\n distance: number;\n measurement: string;\n accuracy: number;\n };\n } {\n const distances: number[] = otherPoints.map((value) =>\n this.getDistanceBetween(current, value, measurement),\n );\n const indexOfSmallest: number = distances.indexOf(Math.min(...distances));\n\n return {\n ...otherPoints[indexOfSmallest],\n haversine: {\n distance: distances[indexOfSmallest],\n measurement,\n accuracy: current.accuracy,\n },\n };\n }\n}\n\nexport default new HaversineGeolocation();\n"],"mappings":"+FAuHA,IAAAA,EAAe,IAAI,KArHQ,CACvB,qBAAqB,EAAkB,EAAsB,KAAc,CACvE,IAAIC,EAAmB,GACvB,OAAQC,EAAY,YAAY,EAAhC,CACI,IAAK,KACD,GAAYC,EAAW,OAAA,CAAS,QAAQ,CAAC,EACzC,MACJ,IAAK,KACD,EAAWA,EAAS,QAAQ,CAAC,EAC7B,MACJ,IAAK,IACD,GAAYA,EAAW,IAAA,CAAM,QAAQ,EACrC,MACJ,QACI,EAAWA,EAAS,QAAQ,CAAC,CACrC,CACA,OAAO,WAAWF,CAAQ,CAC9B,CAEA,WAAW,GAAGG,EAAwB,CAClC,IAAMC,EAAgBD,EAAK,IAAK,GAAiBE,EAAM,IAAS,KAAK,EAAE,EACjEC,EAAeF,EAAI,GACnBG,EAAeH,EAAI,GACnBI,EAAeJ,EAAI,GACnBK,EAAeL,EAAI,GAEnBM,EAAeF,EAAOF,EACtBK,EAAeF,EAAOF,EAEtBK,EACF,KAAK,IAAIF,EAAO,CAAC,EAAI,KAAK,IAAIA,EAAO,CAAC,EACtC,KAAK,IAAIC,EAAO,CAAC,EAAI,KAAK,IAAIA,EAAO,CAAC,EAAI,KAAK,IAAIL,CAAI,EAAI,KAAK,IAAIE,CAAI,EAK5E,MAFkB,GAAI,KAAK,KAAK,KAAK,KADf,KAAK,IAAI,EAAG,KAAK,IAAI,EAAGI,CAAC,CACL,CAAK,CAAC,EAEzC,MACX,CAEA,wBAAuD,CACnD,OAAO,IAAI,SAAS,EAAS,IAAW,CAChC,gBAAiB,UACjB,UAAU,YAAY,mBACjB,GAA8B,CAC3BC,EAAQC,CAAI,CAChB,EACC,GAAoC,CACjC,OAAQC,EAAM,KAAd,CACI,KAAKA,EAAM,kBACPC,EAAW,MAAM,0BAA0B,CAAC,EAC5C,MACJ,KAAKD,EAAM,qBACPC,EAAW,MAAM,6BAA6B,CAAC,EAC/C,MACJ,KAAKD,EAAM,QACPC,EAAW,MAAM,gBAAgB,CAAC,CAE1C,CACJ,CACJ,EAEAA,EAAW,MAAM,6CAA6C,CAAC,CAEvE,CAAC,CACL,CAEA,mBAAmB,EAAoB,EAAoB,EAA6B,CACpF,GAEI,OAAO,UAAU,eAAe,KAAKC,EAAI,UAAU,GAEnD,OAAO,UAAU,eAAe,KAAKA,EAAI,WAAW,GAEpD,OAAO,UAAU,eAAe,KAAKC,EAAI,UAAU,GAEnD,OAAO,UAAU,eAAe,KAAKA,EAAI,WAAW,EACtD,CACE,IAAMhB,EAAmB,KAAK,WAC1Be,EAAG,SACHA,EAAG,UACHC,EAAG,SACHA,EAAG,SACP,EAEA,OAAO,KAAK,qBAAqBhB,EAAUD,CAAW,CAC1D,CACI,MAAU,MAAM,sDAAsD,CAE9E,CAEA,mBACI,EACA,EACA,EAOF,CACE,IAAMkB,EAAsBC,EAAY,IAAK,GACzC,KAAK,mBAAmBC,EAASC,EAAOrB,CAAW,CACvD,EACMsB,EAA0BJ,EAAU,QAAQ,KAAK,IAAI,GAAGA,CAAS,CAAC,EAExE,MAAO,CACH,GAAGC,EAAYG,GACf,UAAW,CACP,SAAUJ,EAAUI,GACpB,cACA,SAAUF,EAAQ,QACtB,CACJ,CACJ,CACJ"}
|
package/dist/legacy.mjs
CHANGED
|
@@ -37,7 +37,7 @@ var e = new class {
|
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
39
|
getDistanceBetween(e, t, n) {
|
|
40
|
-
if (
|
|
40
|
+
if (Object.prototype.hasOwnProperty.call(e, "latitude") && Object.prototype.hasOwnProperty.call(e, "longitude") && Object.prototype.hasOwnProperty.call(t, "latitude") && Object.prototype.hasOwnProperty.call(t, "longitude")) {
|
|
41
41
|
let r = this._haversine(e.latitude, e.longitude, t.latitude, t.longitude);
|
|
42
42
|
return this._convertMeasurements(r, n);
|
|
43
43
|
}
|
package/dist/legacy.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"legacy.mjs","names":["legacy_default","rawValue","measurement","distance","args","rad","deg","lat1","lon1","lat2","lon2","dLat","dLon","a","data","error","reject","p1","p2","distances","otherPoints","current","value","indexOfSmallest"],"sources":["../src/legacy.ts"],"sourcesContent":["import type { ILocationPoint } from
|
|
1
|
+
{"version":3,"file":"legacy.mjs","names":["legacy_default","rawValue","measurement","distance","args","rad","deg","lat1","lon1","lat2","lon2","dLat","dLon","a","data","error","reject","p1","p2","distances","otherPoints","current","value","indexOfSmallest"],"sources":["../src/legacy.ts"],"sourcesContent":["import type { ILocationPoint } from './interfaces/ILocationPoint.js';\n\nclass HaversineGeolocation {\n _convertMeasurements(distance: number, measurement: string = 'km'): number {\n let rawValue: string = '';\n switch (measurement.toLowerCase()) {\n case 'mi':\n rawValue = (distance * 0.62137).toFixed(1);\n break;\n case 'km':\n rawValue = distance.toFixed(1);\n break;\n case 'm':\n rawValue = (distance * 1000).toFixed();\n break;\n default:\n rawValue = distance.toFixed(1);\n }\n return parseFloat(rawValue);\n }\n\n _haversine(...args: number[]): number {\n const rad: number[] = args.map((deg: number) => (deg / 180.0) * Math.PI);\n const lat1: number = rad[0];\n const lon1: number = rad[1];\n const lat2: number = rad[2];\n const lon2: number = rad[3];\n const R: number = 6372.8;\n const dLat: number = lat2 - lat1;\n const dLon: number = lon2 - lon1;\n\n const a: number =\n Math.sin(dLat / 2) * Math.sin(dLat / 2) +\n Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);\n\n const safeA: number = Math.min(1, Math.max(0, a));\n const c: number = 2 * Math.asin(Math.sqrt(safeA));\n\n return R * c;\n }\n\n isGeolocationAvailable(): Promise<GeolocationPosition> {\n return new Promise((resolve, reject) => {\n if ('geolocation' in navigator) {\n navigator.geolocation.getCurrentPosition(\n (data: GeolocationPosition) => {\n resolve(data);\n },\n (error: GeolocationPositionError) => {\n switch (error.code) {\n case error.PERMISSION_DENIED:\n reject(new Error('Error: Permission denied'));\n break;\n case error.POSITION_UNAVAILABLE:\n reject(new Error('Error: Position unavailable'));\n break;\n case error.TIMEOUT:\n reject(new Error('Error: Timeout'));\n break;\n }\n },\n );\n } else {\n reject(new Error('Error: Geolocation disabled in your browser'));\n }\n });\n }\n\n getDistanceBetween(p1: ILocationPoint, p2: ILocationPoint, measurement: string): number {\n if (\n // biome-ignore lint/suspicious/noPrototypeBuiltins: Preserve ES2020-compatible V1 own-property checks without Object.hasOwn (ES2022).\n Object.prototype.hasOwnProperty.call(p1, 'latitude') &&\n // biome-ignore lint/suspicious/noPrototypeBuiltins: Preserve ES2020-compatible V1 own-property checks without Object.hasOwn (ES2022).\n Object.prototype.hasOwnProperty.call(p1, 'longitude') &&\n // biome-ignore lint/suspicious/noPrototypeBuiltins: Preserve ES2020-compatible V1 own-property checks without Object.hasOwn (ES2022).\n Object.prototype.hasOwnProperty.call(p2, 'latitude') &&\n // biome-ignore lint/suspicious/noPrototypeBuiltins: Preserve ES2020-compatible V1 own-property checks without Object.hasOwn (ES2022).\n Object.prototype.hasOwnProperty.call(p2, 'longitude')\n ) {\n const distance: number = this._haversine(\n p1.latitude,\n p1.longitude,\n p2.latitude,\n p2.longitude,\n );\n\n return this._convertMeasurements(distance, measurement);\n } else {\n throw new Error('Error: Position latitude or longitude is not correct');\n }\n }\n\n getClosestPosition(\n current: ILocationPoint,\n otherPoints: ILocationPoint[],\n measurement: string,\n ): ILocationPoint & {\n haversine: {\n distance: number;\n measurement: string;\n accuracy: number;\n };\n } {\n const distances: number[] = otherPoints.map((value) =>\n this.getDistanceBetween(current, value, measurement),\n );\n const indexOfSmallest: number = distances.indexOf(Math.min(...distances));\n\n return {\n ...otherPoints[indexOfSmallest],\n haversine: {\n distance: distances[indexOfSmallest],\n measurement,\n accuracy: current.accuracy,\n },\n };\n }\n}\n\nexport default new HaversineGeolocation();\n"],"mappings":"AAuHA,IAAAA,IAAe,IAAI,MArHQ;CACvB,qBAAqB,GAAkB,IAAsB,MAAc;EACvE,IAAIC,IAAmB;EACvB,QAAQC,EAAY,YAAY,GAAhC;GACI,KAAK;IACD,KAAYC,IAAW,OAAA,CAAS,QAAQ,CAAC;IACzC;GACJ,KAAK;IACD,IAAWA,EAAS,QAAQ,CAAC;IAC7B;GACJ,KAAK;IACD,KAAYA,IAAW,IAAA,CAAM,QAAQ;IACrC;GACJ,SACI,IAAWA,EAAS,QAAQ,CAAC;EACrC;EACA,OAAO,WAAWF,CAAQ;CAC9B;CAEA,WAAW,GAAGG,GAAwB;EAClC,IAAMC,IAAgBD,EAAK,KAAK,MAAiBE,IAAM,MAAS,KAAK,EAAE,GACjEC,IAAeF,EAAI,IACnBG,IAAeH,EAAI,IACnBI,IAAeJ,EAAI,IACnBK,IAAeL,EAAI,IAEnBM,IAAeF,IAAOF,GACtBK,IAAeF,IAAOF,GAEtBK,IACF,KAAK,IAAIF,IAAO,CAAC,IAAI,KAAK,IAAIA,IAAO,CAAC,IACtC,KAAK,IAAIC,IAAO,CAAC,IAAI,KAAK,IAAIA,IAAO,CAAC,IAAI,KAAK,IAAIL,CAAI,IAAI,KAAK,IAAIE,CAAI;EAK5E,OAFkB,IAAI,KAAK,KAAK,KAAK,KADf,KAAK,IAAI,GAAG,KAAK,IAAI,GAAGI,CAAC,CACL,CAAK,CAAC,IAEzC;CACX;CAEA,yBAAuD;EACnD,OAAO,IAAI,SAAS,GAAS,MAAW;GACpC,AAAI,iBAAiB,YACjB,UAAU,YAAY,oBACjB,MAA8B;IAC3B,EAAQC,CAAI;GAChB,IACC,MAAoC;IACjC,QAAQC,EAAM,MAAd;KACI,KAAKA,EAAM;MACP,EAAO,gBAAI,MAAM,0BAA0B,CAAC;MAC5C;KACJ,KAAKA,EAAM;MACP,EAAO,gBAAI,MAAM,6BAA6B,CAAC;MAC/C;KACJ,KAAKA,EAAM,SACP,EAAO,gBAAI,MAAM,gBAAgB,CAAC;IAE1C;GACJ,CACJ,IAEAC,EAAO,gBAAI,MAAM,6CAA6C,CAAC;EAEvE,CAAC;CACL;CAEA,mBAAmB,GAAoB,GAAoB,GAA6B;EACpF,IAEI,OAAO,UAAU,eAAe,KAAKC,GAAI,UAAU,KAEnD,OAAO,UAAU,eAAe,KAAKA,GAAI,WAAW,KAEpD,OAAO,UAAU,eAAe,KAAKC,GAAI,UAAU,KAEnD,OAAO,UAAU,eAAe,KAAKA,GAAI,WAAW,GACtD;GACE,IAAMf,IAAmB,KAAK,WAC1Bc,EAAG,UACHA,EAAG,WACHC,EAAG,UACHA,EAAG,SACP;GAEA,OAAO,KAAK,qBAAqBf,GAAUD,CAAW;EAC1D;EACI,MAAU,MAAM,sDAAsD;CAE9E;CAEA,mBACI,GACA,GACA,GAOF;EACE,IAAMiB,IAAsBC,EAAY,KAAK,MACzC,KAAK,mBAAmBC,GAASC,GAAOpB,CAAW,CACvD,GACMqB,IAA0BJ,EAAU,QAAQ,KAAK,IAAI,GAAGA,CAAS,CAAC;EAExE,OAAO;GACH,GAAGC,EAAYG;GACf,WAAW;IACP,UAAUJ,EAAUI;IACpB;IACA,UAAUF,EAAQ;GACtB;EACJ;CACJ;AACJ,EAEwC"}
|
package/dist/types/legacy.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ILocationPoint } from
|
|
1
|
+
import type { ILocationPoint } from './interfaces/ILocationPoint.js';
|
|
2
2
|
declare class HaversineGeolocation {
|
|
3
3
|
_convertMeasurements(distance: number, measurement?: string): number;
|
|
4
4
|
_haversine(...args: number[]): number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const getHaversineEntity: (HaversineGeolocation:
|
|
1
|
+
export declare const getHaversineEntity: <T>(HaversineGeolocation: new () => T) => T | Record<string, never>;
|
|
@@ -4,4 +4,4 @@ import { getHaversineEntity } from './getHaversineEntity';
|
|
|
4
4
|
import { isNodeJs } from './isNodeJs';
|
|
5
5
|
import { showError } from './showError';
|
|
6
6
|
import { showGeolocationError } from './showGeolocationError';
|
|
7
|
-
export { calculateHaversine, convertMeasurement, getHaversineEntity, isNodeJs, showError, showGeolocationError };
|
|
7
|
+
export { calculateHaversine, convertMeasurement, getHaversineEntity, isNodeJs, showError, showGeolocationError, };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const isGeolocationSupported: () => boolean;
|
|
2
|
-
export declare const getCurrentPosition: (options?: PositionOptions
|
|
2
|
+
export declare const getCurrentPosition: (options?: PositionOptions) => Promise<GeolocationPosition>;
|
package/dist/types/v2/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { assertCoordinate, isCoordinate, } from './coordinate.js';
|
|
2
|
-
export type { Coordinate
|
|
2
|
+
export type { Coordinate } from './coordinate.js';
|
|
3
3
|
export { assertDistanceUnit, convertDistance, } from './units.js';
|
|
4
|
-
export type { DistanceUnit
|
|
4
|
+
export type { DistanceUnit } from './units.js';
|
|
5
5
|
export { distance, EARTH_MEAN_RADIUS_M, } from './distance.js';
|
|
6
|
-
export type { DistanceOptions
|
|
7
|
-
export { nearest
|
|
8
|
-
export type { NearestResult
|
|
6
|
+
export type { DistanceOptions } from './distance.js';
|
|
7
|
+
export { nearest } from './nearest.js';
|
|
8
|
+
export type { NearestResult } from './nearest.js';
|
package/dist/types/v2/units.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type DistanceUnit = 'm' | 'km' | 'mi';
|
|
2
2
|
export declare function assertDistanceUnit(value: unknown): asserts value is DistanceUnit;
|
|
3
3
|
export declare const convertDistance: (value: number, from: DistanceUnit, to: DistanceUnit) => number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "haversine-geolocation",
|
|
3
|
-
"version": "2.0.0-
|
|
3
|
+
"version": "2.0.0-beta.1",
|
|
4
4
|
"description": "Get distances between two points or get closest position to current point. Based on the Haversine Formula",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"scripts": {
|
|
@@ -11,7 +11,10 @@
|
|
|
11
11
|
"typecheck": "tsc --noEmit",
|
|
12
12
|
"build:types": "tsc -p tsconfig.types.json",
|
|
13
13
|
"build:umd": "vite build --config vite.umd.config.ts",
|
|
14
|
-
"build:runtime": "vite build --config vite.lib.config.ts"
|
|
14
|
+
"build:runtime": "vite build --config vite.lib.config.ts",
|
|
15
|
+
"size:check": "node scripts/check-package-size.mjs",
|
|
16
|
+
"quality": "biome check src spec scripts vite.lib.config.ts vite.umd.config.ts vitest.config.ts",
|
|
17
|
+
"quality:fix": "biome check --write src spec scripts vite.lib.config.ts vite.umd.config.ts vitest.config.ts"
|
|
15
18
|
},
|
|
16
19
|
"keywords": [
|
|
17
20
|
"geolocation",
|
|
@@ -24,13 +27,14 @@
|
|
|
24
27
|
"author": "Daniil Sydorenko <daniildeveloper@gmail.com>",
|
|
25
28
|
"repository": {
|
|
26
29
|
"type": "git",
|
|
27
|
-
"url": "https://github.com/DaniilSydorenko/haversine-geolocation.git"
|
|
30
|
+
"url": "git+https://github.com/DaniilSydorenko/haversine-geolocation.git"
|
|
28
31
|
},
|
|
29
32
|
"license": "MIT",
|
|
30
33
|
"devDependencies": {
|
|
31
|
-
"typescript": "
|
|
34
|
+
"typescript": "7.0.2",
|
|
32
35
|
"vite": "8.3.4",
|
|
33
|
-
"vitest": "5.0.3"
|
|
36
|
+
"vitest": "5.0.3",
|
|
37
|
+
"@biomejs/biome": "2.5.15"
|
|
34
38
|
},
|
|
35
39
|
"files": [
|
|
36
40
|
"dist"
|