raain-model 3.0.36 → 3.0.37
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/CHANGELOG.md +9 -0
- package/bpInfo.js +1 -1
- package/package.json +2 -2
- package/rain/RainSpeedMap.d.ts +23 -1
- package/rain/RainSpeedMap.js +66 -59
- package/rain/RainSpeedMap.js.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- RainSpeedMap.getTrustRatio: returns the trustRatio of the RainSpeed found for a given point, with support for
|
|
13
|
+
`inEarthMap` and `strictContaining` options.
|
|
14
|
+
When no point is provided, returns the average trustRatio of all RainSpeeds in the map.
|
|
15
|
+
As fallback returns 0 when no RainSpeeds exist.
|
|
16
|
+
|
|
17
|
+
## [3.0.36] - 2025-10-27
|
|
18
|
+
|
|
10
19
|
### Changed
|
|
11
20
|
|
|
12
21
|
- RainSpeedMap.getRainSpeed and .transpose: using Haversine distance when `strictContaining`, and Earth map when
|
package/bpInfo.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "raain-model",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.37",
|
|
4
4
|
"author": "contact@radartorain.com",
|
|
5
5
|
"homepage": "https://github.com/raainio/raain-model",
|
|
6
6
|
"description": "radartorain.com api model",
|
|
@@ -56,4 +56,4 @@
|
|
|
56
56
|
"typedoc": "^0.25.12",
|
|
57
57
|
"typescript": "^5.0.4"
|
|
58
58
|
}
|
|
59
|
-
}
|
|
59
|
+
}
|
package/rain/RainSpeedMap.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RainSpeed } from './RainSpeed';
|
|
2
|
-
import { CartesianValue, LatLng } from '../cartesian';
|
|
2
|
+
import { CartesianTools, CartesianValue, LatLng } from '../cartesian';
|
|
3
3
|
/**
|
|
4
4
|
* api/rains/:rainId/computations/:rainHistoryId/speeds => RainSpeedMap.map => RainSpeed[]
|
|
5
5
|
*/
|
|
@@ -20,8 +20,30 @@ export declare class RainSpeedMap {
|
|
|
20
20
|
inEarthMap?: boolean;
|
|
21
21
|
strictContaining?: boolean;
|
|
22
22
|
}): RainSpeed | undefined;
|
|
23
|
+
getTrustRatio(point?: LatLng | {
|
|
24
|
+
latitude: number;
|
|
25
|
+
longitude: number;
|
|
26
|
+
} | {
|
|
27
|
+
lat: number;
|
|
28
|
+
lng: number;
|
|
29
|
+
}, options?: {
|
|
30
|
+
inEarthMap?: boolean;
|
|
31
|
+
strictContaining?: boolean;
|
|
32
|
+
}): number;
|
|
23
33
|
transpose(cartesianValue: CartesianValue, diffInMinutes: number, options?: {
|
|
24
34
|
inEarthMap?: boolean;
|
|
25
35
|
strictContaining?: boolean;
|
|
26
36
|
}): CartesianValue;
|
|
37
|
+
protected normalizePoint(point: LatLng | {
|
|
38
|
+
latitude: number;
|
|
39
|
+
longitude: number;
|
|
40
|
+
} | {
|
|
41
|
+
lat: number;
|
|
42
|
+
lng: number;
|
|
43
|
+
}): {
|
|
44
|
+
lat: number;
|
|
45
|
+
lng: number;
|
|
46
|
+
} | undefined;
|
|
47
|
+
protected roundRectangles(rects: [LatLng, LatLng][], cartesianTools: CartesianTools): [LatLng, LatLng][];
|
|
48
|
+
protected findClosestRainSpeed(lat: number, lng: number): RainSpeed | undefined;
|
|
27
49
|
}
|
package/rain/RainSpeedMap.js
CHANGED
|
@@ -16,25 +16,11 @@ class RainSpeedMap {
|
|
|
16
16
|
getRainSpeed(point, options) {
|
|
17
17
|
var _a, _b;
|
|
18
18
|
// normalize input to numbers
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (point instanceof cartesian_1.LatLng) {
|
|
22
|
-
lat = point.lat;
|
|
23
|
-
lng = point.lng;
|
|
24
|
-
}
|
|
25
|
-
else if (typeof (point === null || point === void 0 ? void 0 : point.lat) === 'number' &&
|
|
26
|
-
typeof (point === null || point === void 0 ? void 0 : point.lng) === 'number') {
|
|
27
|
-
lat = point.lat;
|
|
28
|
-
lng = point.lng;
|
|
29
|
-
}
|
|
30
|
-
else if (typeof (point === null || point === void 0 ? void 0 : point.latitude) === 'number' &&
|
|
31
|
-
typeof (point === null || point === void 0 ? void 0 : point.longitude) === 'number') {
|
|
32
|
-
lat = point.latitude;
|
|
33
|
-
lng = point.longitude;
|
|
34
|
-
}
|
|
35
|
-
if (typeof lat !== 'number' || typeof lng !== 'number') {
|
|
19
|
+
const normalized = this.normalizePoint(point);
|
|
20
|
+
if (!normalized) {
|
|
36
21
|
return undefined;
|
|
37
22
|
}
|
|
23
|
+
let { lat, lng } = normalized;
|
|
38
24
|
// Apply earth map rounding if requested
|
|
39
25
|
const cartesianTools = new cartesian_1.CartesianTools();
|
|
40
26
|
if (options === null || options === void 0 ? void 0 : options.inEarthMap) {
|
|
@@ -45,64 +31,44 @@ class RainSpeedMap {
|
|
|
45
31
|
// retrieve the first RainSpeed whose area contains the point
|
|
46
32
|
for (const rs of (_a = this.rainSpeeds) !== null && _a !== void 0 ? _a : []) {
|
|
47
33
|
const rects = (_b = rs === null || rs === void 0 ? void 0 : rs.latLngs) !== null && _b !== void 0 ? _b : [];
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const r0 = cartesianTools.getLatLngFromEarthMap(r[0]);
|
|
52
|
-
const r1 = cartesianTools.getLatLngFromEarthMap(r[1]);
|
|
53
|
-
return [r0, r1];
|
|
54
|
-
});
|
|
55
|
-
}
|
|
34
|
+
const roundedRects = (options === null || options === void 0 ? void 0 : options.inEarthMap)
|
|
35
|
+
? this.roundRectangles(rects, cartesianTools)
|
|
36
|
+
: rects;
|
|
56
37
|
if (cartesian_1.CartesianTools.IsPointInAnyRect(lat, lng, roundedRects)) {
|
|
57
38
|
return rs;
|
|
58
39
|
}
|
|
59
40
|
}
|
|
60
|
-
// If no containing area found and strictContaining is not true, find closest by center distance
|
|
41
|
+
// If no containing area found and strictContaining is not true, find the closest by center distance
|
|
61
42
|
if ((options === null || options === void 0 ? void 0 : options.strictContaining) !== true) {
|
|
62
|
-
return this.
|
|
63
|
-
if (!closest) {
|
|
64
|
-
return current;
|
|
65
|
-
}
|
|
66
|
-
const currentCenter = current.getCenter();
|
|
67
|
-
const closestCenter = closest.getCenter();
|
|
68
|
-
const currentDistance = cartesian_1.CartesianTools.GetDistanceFromLatLngInKm(new cartesian_1.LatLng({ lat, lng }), currentCenter);
|
|
69
|
-
const closestDistance = cartesian_1.CartesianTools.GetDistanceFromLatLngInKm(new cartesian_1.LatLng({ lat, lng }), closestCenter);
|
|
70
|
-
return currentDistance < closestDistance ? current : closest;
|
|
71
|
-
}, undefined);
|
|
43
|
+
return this.findClosestRainSpeed(lat, lng);
|
|
72
44
|
}
|
|
73
45
|
return undefined;
|
|
74
46
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
// find matching RainSpeed areas that contain the point
|
|
82
|
-
const matches = this.rainSpeeds.filter((rs) => { var _a; return cartesian_1.CartesianTools.IsPointInAnyRect(lat, lng, (_a = rs === null || rs === void 0 ? void 0 : rs.latLngs) !== null && _a !== void 0 ? _a : []); });
|
|
83
|
-
if (matches.length >= 1) {
|
|
84
|
-
rainSpeed = matches[0];
|
|
47
|
+
getTrustRatio(point, options) {
|
|
48
|
+
var _a;
|
|
49
|
+
// When no point is provided, return average trustRatio of all RainSpeeds
|
|
50
|
+
if (point === undefined) {
|
|
51
|
+
if (!this.rainSpeeds || this.rainSpeeds.length === 0) {
|
|
52
|
+
return 0;
|
|
85
53
|
}
|
|
54
|
+
const sum = this.rainSpeeds.reduce((acc, rs) => { var _a; return acc + ((_a = rs.trustRatio) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
55
|
+
return sum / this.rainSpeeds.length;
|
|
86
56
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const closestCenter = closest.getCenter();
|
|
95
|
-
const currentDistance = cartesian_1.CartesianTools.GetDistanceFromLatLngInKm(new cartesian_1.LatLng({ lat, lng }), currentCenter);
|
|
96
|
-
const closestDistance = cartesian_1.CartesianTools.GetDistanceFromLatLngInKm(new cartesian_1.LatLng({ lat, lng }), closestCenter);
|
|
97
|
-
return currentDistance < closestDistance ? current : closest;
|
|
98
|
-
}, undefined);
|
|
99
|
-
}
|
|
57
|
+
// When point is provided, use existing logic
|
|
58
|
+
const rainSpeed = this.getRainSpeed(point, options);
|
|
59
|
+
return (_a = rainSpeed === null || rainSpeed === void 0 ? void 0 : rainSpeed.trustRatio) !== null && _a !== void 0 ? _a : 0;
|
|
60
|
+
}
|
|
61
|
+
transpose(cartesianValue, diffInMinutes, options) {
|
|
62
|
+
// Use getRainSpeed to find the appropriate RainSpeed for this point
|
|
63
|
+
const rainSpeed = this.getRainSpeed(cartesianValue, options);
|
|
100
64
|
if (rainSpeed) {
|
|
101
65
|
return rainSpeed.transpose(cartesianValue, diffInMinutes, options);
|
|
102
66
|
}
|
|
67
|
+
// No RainSpeed found - handle fallback based on inEarthMap option
|
|
103
68
|
if (!(options === null || options === void 0 ? void 0 : options.inEarthMap)) {
|
|
104
69
|
return cartesianValue;
|
|
105
70
|
}
|
|
71
|
+
const cartesianTools = new cartesian_1.CartesianTools();
|
|
106
72
|
const newLatLng = cartesianTools.getLatLngFromEarthMap(cartesianValue);
|
|
107
73
|
return new cartesian_1.CartesianValue({
|
|
108
74
|
value: cartesianValue.value,
|
|
@@ -110,6 +76,47 @@ class RainSpeedMap {
|
|
|
110
76
|
lng: newLatLng.lng,
|
|
111
77
|
});
|
|
112
78
|
}
|
|
79
|
+
normalizePoint(point) {
|
|
80
|
+
let lat;
|
|
81
|
+
let lng;
|
|
82
|
+
if (point instanceof cartesian_1.LatLng) {
|
|
83
|
+
lat = point.lat;
|
|
84
|
+
lng = point.lng;
|
|
85
|
+
}
|
|
86
|
+
else if (typeof (point === null || point === void 0 ? void 0 : point.lat) === 'number' &&
|
|
87
|
+
typeof (point === null || point === void 0 ? void 0 : point.lng) === 'number') {
|
|
88
|
+
lat = point.lat;
|
|
89
|
+
lng = point.lng;
|
|
90
|
+
}
|
|
91
|
+
else if (typeof (point === null || point === void 0 ? void 0 : point.latitude) === 'number' &&
|
|
92
|
+
typeof (point === null || point === void 0 ? void 0 : point.longitude) === 'number') {
|
|
93
|
+
lat = point.latitude;
|
|
94
|
+
lng = point.longitude;
|
|
95
|
+
}
|
|
96
|
+
if (typeof lat !== 'number' || typeof lng !== 'number') {
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
return { lat, lng };
|
|
100
|
+
}
|
|
101
|
+
roundRectangles(rects, cartesianTools) {
|
|
102
|
+
return rects.map((r) => {
|
|
103
|
+
const r0 = cartesianTools.getLatLngFromEarthMap(r[0]);
|
|
104
|
+
const r1 = cartesianTools.getLatLngFromEarthMap(r[1]);
|
|
105
|
+
return [r0, r1];
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
findClosestRainSpeed(lat, lng) {
|
|
109
|
+
return this.rainSpeeds.reduce((closest, current) => {
|
|
110
|
+
if (!closest) {
|
|
111
|
+
return current;
|
|
112
|
+
}
|
|
113
|
+
const currentCenter = current.getCenter();
|
|
114
|
+
const closestCenter = closest.getCenter();
|
|
115
|
+
const currentDistance = cartesian_1.CartesianTools.GetDistanceFromLatLngInKm(new cartesian_1.LatLng({ lat, lng }), currentCenter);
|
|
116
|
+
const closestDistance = cartesian_1.CartesianTools.GetDistanceFromLatLngInKm(new cartesian_1.LatLng({ lat, lng }), closestCenter);
|
|
117
|
+
return currentDistance < closestDistance ? current : closest;
|
|
118
|
+
}, undefined);
|
|
119
|
+
}
|
|
113
120
|
}
|
|
114
121
|
exports.RainSpeedMap = RainSpeedMap;
|
|
115
122
|
//# sourceMappingURL=RainSpeedMap.js.map
|
package/rain/RainSpeedMap.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RainSpeedMap.js","sourceRoot":"","sources":["../../src/rain/RainSpeedMap.ts"],"names":[],"mappings":";;;AAAA,2CAAsC;AACtC,4CAAoE;AAEpE;;GAEG;AACH,MAAa,YAAY;IAIrB,YAAY,IAA4C;QACpD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,qBAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/D,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACZ,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;IACL,CAAC;
|
|
1
|
+
{"version":3,"file":"RainSpeedMap.js","sourceRoot":"","sources":["../../src/rain/RainSpeedMap.ts"],"names":[],"mappings":"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"}
|