raain-model 2.6.8 → 2.6.10
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/.cursorignore +10 -0
- package/.github/workflows/ci.yml +29 -0
- package/CHANGELOG.md +166 -0
- package/LICENSE +21 -0
- package/README.md +5 -3
- package/RELEASE_PROCESS.md +111 -0
- package/package.json +1 -1
- package/specs/REQUIREMENTS.md +42 -0
- package/specs/TECHNICAL.md +57 -0
- package/specs/cartesian/Cartesian.spec.ts +82 -0
- package/specs/cartesian/CartesianTools.spec.ts +121 -0
- package/specs/gauge/Gauge.spec.ts +39 -0
- package/specs/organization/Organization.spec.ts +38 -0
- package/specs/polar/Polar.spec.ts +267 -0
- package/specs/quality/Position.spec.ts +18 -0
- package/specs/quality/QualityPointEdgeCases.spec.ts +215 -0
- package/specs/quality/QualityTools.spec.ts +67 -0
- package/specs/quality/SpeedMatrix.spec.ts +214 -0
- package/specs/radar/Radar.spec.ts +129 -0
- package/specs/rain/Rain.spec.ts +334 -0
- package/specs/tsconfig.json +12 -0
- package/{cartesian/CartesianMeasureValue.js → src/cartesian/CartesianMeasureValue.ts} +73 -41
- package/{cartesian/CartesianTools.js → src/cartesian/CartesianTools.ts} +130 -69
- package/src/cartesian/CartesianValue.ts +26 -0
- package/src/cartesian/EarthMap.ts +5 -0
- package/src/cartesian/ICartesianMeasureValue.ts +22 -0
- package/src/cartesian/LatLng.ts +43 -0
- package/src/cartesian/RadarCartesianMeasureValue.ts +32 -0
- package/src/cartesian/RainCartesianMeasureValue.ts +32 -0
- package/src/gauge/GaugeMeasure.ts +42 -0
- package/{gauge/GaugeNode.js → src/gauge/GaugeNode.ts} +48 -20
- package/src/gauge/GaugeNodeMap.ts +55 -0
- package/src/organization/EventNode.ts +43 -0
- package/{organization/Link.js → src/organization/Link.ts} +15 -15
- package/src/organization/Measure.ts +61 -0
- package/{organization/PeopleNode.js → src/organization/PeopleNode.ts} +20 -10
- package/{organization/RaainNode.js → src/organization/RaainNode.ts} +91 -58
- package/{organization/TeamNode.js → src/organization/TeamNode.ts} +36 -13
- package/{polar/AbstractPolarMeasureValue.js → src/polar/AbstractPolarMeasureValue.ts} +58 -32
- package/src/polar/IPolarMeasureValue.ts +21 -0
- package/{polar/MeasureValuePolarContainer.js → src/polar/MeasureValuePolarContainer.ts} +29 -13
- package/src/polar/PolarFilter.ts +46 -0
- package/{polar/PolarMeasureValue.js → src/polar/PolarMeasureValue.ts} +125 -62
- package/{polar/PolarMeasureValueMap.js → src/polar/PolarMeasureValueMap.ts} +165 -88
- package/src/polar/PolarValue.ts +16 -0
- package/{polar/RadarPolarMeasureValue.js → src/polar/RadarPolarMeasureValue.ts} +34 -21
- package/src/polar/RainPolarMeasureValue.ts +57 -0
- package/{quality/QualityPoint.js → src/quality/QualityPoint.ts} +62 -34
- package/{quality/SpeedMatrix.js → src/quality/SpeedMatrix.ts} +117 -76
- package/{quality/SpeedMatrixContainer.js → src/quality/SpeedMatrixContainer.ts} +210 -103
- package/src/quality/history/CartesianGaugeHistory.ts +23 -0
- package/src/quality/history/CartesianRainHistory.ts +15 -0
- package/src/quality/history/PositionHistory.ts +31 -0
- package/{quality/index.d.ts → src/quality/index.ts} +3 -0
- package/src/quality/position/Position.ts +59 -0
- package/src/quality/position/PositionValue.ts +15 -0
- package/{quality/tools/QualityTools.js → src/quality/tools/QualityTools.ts} +18 -17
- package/src/radar/RadarMeasure.ts +41 -0
- package/{radar/RadarNode.js → src/radar/RadarNode.ts} +41 -19
- package/src/radar/RadarNodeMap.ts +61 -0
- package/src/rain/MergeStrategy.ts +15 -0
- package/src/rain/RainComputation.ts +96 -0
- package/{rain/RainComputationAbstract.js → src/rain/RainComputationAbstract.ts} +135 -69
- package/{rain/RainComputationMap.js → src/rain/RainComputationMap.ts} +55 -22
- package/{rain/RainComputationQuality.js → src/rain/RainComputationQuality.ts} +82 -44
- package/src/rain/RainMeasure.ts +25 -0
- package/{rain/RainNode.js → src/rain/RainNode.ts} +117 -72
- package/tsconfig.json +17 -0
- package/tslint.json +79 -0
- package/typedoc.json +31 -0
- package/cartesian/CartesianMeasureValue.d.ts +0 -40
- package/cartesian/CartesianMeasureValue.js.map +0 -1
- package/cartesian/CartesianTools.d.ts +0 -32
- package/cartesian/CartesianTools.js.map +0 -1
- package/cartesian/CartesianValue.d.ts +0 -14
- package/cartesian/CartesianValue.js +0 -17
- package/cartesian/CartesianValue.js.map +0 -1
- package/cartesian/EarthMap.d.ts +0 -5
- package/cartesian/EarthMap.js +0 -3
- package/cartesian/EarthMap.js.map +0 -1
- package/cartesian/ICartesianMeasureValue.d.ts +0 -23
- package/cartesian/ICartesianMeasureValue.js +0 -3
- package/cartesian/ICartesianMeasureValue.js.map +0 -1
- package/cartesian/LatLng.d.ts +0 -16
- package/cartesian/LatLng.js +0 -34
- package/cartesian/LatLng.js.map +0 -1
- package/cartesian/RadarCartesianMeasureValue.d.ts +0 -17
- package/cartesian/RadarCartesianMeasureValue.js +0 -22
- package/cartesian/RadarCartesianMeasureValue.js.map +0 -1
- package/cartesian/RainCartesianMeasureValue.d.ts +0 -17
- package/cartesian/RainCartesianMeasureValue.js +0 -23
- package/cartesian/RainCartesianMeasureValue.js.map +0 -1
- package/cartesian/index.js +0 -25
- package/cartesian/index.js.map +0 -1
- package/gauge/GaugeMeasure.d.ts +0 -20
- package/gauge/GaugeMeasure.js +0 -30
- package/gauge/GaugeMeasure.js.map +0 -1
- package/gauge/GaugeNode.d.ts +0 -85
- package/gauge/GaugeNode.js.map +0 -1
- package/gauge/GaugeNodeMap.d.ts +0 -24
- package/gauge/GaugeNodeMap.js +0 -40
- package/gauge/GaugeNodeMap.js.map +0 -1
- package/gauge/index.js +0 -20
- package/gauge/index.js.map +0 -1
- package/index.js +0 -24
- package/index.js.map +0 -1
- package/organization/EventNode.d.ts +0 -22
- package/organization/EventNode.js +0 -30
- package/organization/EventNode.js.map +0 -1
- package/organization/IVersion.js +0 -3
- package/organization/IVersion.js.map +0 -1
- package/organization/Link.d.ts +0 -16
- package/organization/Link.js.map +0 -1
- package/organization/Measure.d.ts +0 -22
- package/organization/Measure.js +0 -45
- package/organization/Measure.js.map +0 -1
- package/organization/PeopleNode.d.ts +0 -18
- package/organization/PeopleNode.js.map +0 -1
- package/organization/RaainNode.d.ts +0 -96
- package/organization/RaainNode.js.map +0 -1
- package/organization/TeamNode.d.ts +0 -63
- package/organization/TeamNode.js.map +0 -1
- package/organization/index.js +0 -24
- package/organization/index.js.map +0 -1
- package/polar/AbstractPolarMeasureValue.d.ts +0 -29
- package/polar/AbstractPolarMeasureValue.js.map +0 -1
- package/polar/IPolarMeasureValue.d.ts +0 -19
- package/polar/IPolarMeasureValue.js +0 -3
- package/polar/IPolarMeasureValue.js.map +0 -1
- package/polar/MeasureValuePolarContainer.d.ts +0 -19
- package/polar/MeasureValuePolarContainer.js.map +0 -1
- package/polar/PolarFilter.d.ts +0 -16
- package/polar/PolarFilter.js +0 -45
- package/polar/PolarFilter.js.map +0 -1
- package/polar/PolarMeasureValue.d.ts +0 -51
- package/polar/PolarMeasureValue.js.map +0 -1
- package/polar/PolarMeasureValueMap.d.ts +0 -45
- package/polar/PolarMeasureValueMap.js.map +0 -1
- package/polar/PolarValue.d.ts +0 -10
- package/polar/PolarValue.js +0 -12
- package/polar/PolarValue.js.map +0 -1
- package/polar/RadarPolarMeasureValue.d.ts +0 -27
- package/polar/RadarPolarMeasureValue.js.map +0 -1
- package/polar/RainPolarMeasureValue.d.ts +0 -20
- package/polar/RainPolarMeasureValue.js +0 -42
- package/polar/RainPolarMeasureValue.js.map +0 -1
- package/polar/index.js +0 -25
- package/polar/index.js.map +0 -1
- package/quality/QualityPoint.d.ts +0 -37
- package/quality/QualityPoint.js.map +0 -1
- package/quality/SpeedMatrix.d.ts +0 -83
- package/quality/SpeedMatrix.js.map +0 -1
- package/quality/SpeedMatrixContainer.d.ts +0 -102
- package/quality/SpeedMatrixContainer.js.map +0 -1
- package/quality/history/CartesianGaugeHistory.d.ts +0 -15
- package/quality/history/CartesianGaugeHistory.js +0 -14
- package/quality/history/CartesianGaugeHistory.js.map +0 -1
- package/quality/history/CartesianRainHistory.d.ts +0 -9
- package/quality/history/CartesianRainHistory.js +0 -11
- package/quality/history/CartesianRainHistory.js.map +0 -1
- package/quality/history/PositionHistory.d.ts +0 -20
- package/quality/history/PositionHistory.js +0 -17
- package/quality/history/PositionHistory.js.map +0 -1
- package/quality/index.js +0 -26
- package/quality/index.js.map +0 -1
- package/quality/position/Position.d.ts +0 -22
- package/quality/position/Position.js +0 -50
- package/quality/position/Position.js.map +0 -1
- package/quality/position/PositionValue.d.ts +0 -9
- package/quality/position/PositionValue.js +0 -12
- package/quality/position/PositionValue.js.map +0 -1
- package/quality/tools/QualityTools.d.ts +0 -9
- package/quality/tools/QualityTools.js.map +0 -1
- package/radar/RadarMeasure.d.ts +0 -19
- package/radar/RadarMeasure.js +0 -30
- package/radar/RadarMeasure.js.map +0 -1
- package/radar/RadarNode.d.ts +0 -30
- package/radar/RadarNode.js.map +0 -1
- package/radar/RadarNodeMap.d.ts +0 -26
- package/radar/RadarNodeMap.js +0 -44
- package/radar/RadarNodeMap.js.map +0 -1
- package/radar/index.js +0 -20
- package/radar/index.js.map +0 -1
- package/rain/MergeStrategy.d.ts +0 -13
- package/rain/MergeStrategy.js +0 -11
- package/rain/MergeStrategy.js.map +0 -1
- package/rain/RainComputation.d.ts +0 -42
- package/rain/RainComputation.js +0 -65
- package/rain/RainComputation.js.map +0 -1
- package/rain/RainComputationAbstract.d.ts +0 -73
- package/rain/RainComputationAbstract.js.map +0 -1
- package/rain/RainComputationMap.d.ts +0 -97
- package/rain/RainComputationMap.js.map +0 -1
- package/rain/RainComputationQuality.d.ts +0 -40
- package/rain/RainComputationQuality.js.map +0 -1
- package/rain/RainMeasure.d.ts +0 -17
- package/rain/RainMeasure.js +0 -18
- package/rain/RainMeasure.js.map +0 -1
- package/rain/RainNode.d.ts +0 -46
- package/rain/RainNode.js.map +0 -1
- package/rain/index.js +0 -23
- package/rain/index.js.map +0 -1
- /package/{cartesian/index.d.ts → src/cartesian/index.ts} +0 -0
- /package/{gauge/index.d.ts → src/gauge/index.ts} +0 -0
- /package/{index.d.ts → src/index.ts} +0 -0
- /package/{organization/IVersion.d.ts → src/organization/IVersion.ts} +0 -0
- /package/{organization/index.d.ts → src/organization/index.ts} +0 -0
- /package/{polar/index.d.ts → src/polar/index.ts} +0 -0
- /package/{radar/index.d.ts → src/radar/index.ts} +0 -0
- /package/{rain/index.d.ts → src/rain/index.ts} +0 -0
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class CartesianTools {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import {LatLng} from './LatLng';
|
|
2
|
+
import {CartesianValue} from './CartesianValue';
|
|
3
|
+
import {EarthMap} from './EarthMap';
|
|
4
|
+
|
|
5
|
+
export class CartesianTools {
|
|
6
|
+
|
|
7
|
+
// scale of Pixel regarding LatLng : Approx. 1 => 100km, 0.01 => 1km, 0.005 => 500m
|
|
8
|
+
public static DEFAULT_SCALE = 0.01;
|
|
9
|
+
|
|
10
|
+
constructor(public scale = CartesianTools.DEFAULT_SCALE,
|
|
11
|
+
public earthMap: EarthMap = undefined) {
|
|
9
12
|
}
|
|
10
|
-
|
|
13
|
+
|
|
14
|
+
public static RoundLatLng(latOrLng: number, scale = CartesianTools.DEFAULT_SCALE, needPrecision = false): number {
|
|
15
|
+
|
|
11
16
|
const result = Math.round(latOrLng / scale) * scale;
|
|
12
17
|
if (!needPrecision) {
|
|
13
18
|
return result;
|
|
14
19
|
}
|
|
15
20
|
return parseFloat(parseFloat('' + result).toPrecision(12));
|
|
21
|
+
|
|
16
22
|
// alternative ?
|
|
17
23
|
// let decimalPlaces = 0;
|
|
18
24
|
// if (('' + scale).indexOf('0.') === 0) {
|
|
@@ -24,20 +30,27 @@ class CartesianTools {
|
|
|
24
30
|
// const n = (latOrLng * p) * (1 + Number.EPSILON);
|
|
25
31
|
// return Math.round(n) / p;
|
|
26
32
|
}
|
|
27
|
-
|
|
28
|
-
|
|
33
|
+
|
|
34
|
+
public static CreateLatLng(latLng: { lat: number, lng: number }) {
|
|
35
|
+
const created = new LatLng(latLng);
|
|
29
36
|
created.setPrecision();
|
|
30
37
|
return created;
|
|
31
38
|
}
|
|
32
|
-
|
|
39
|
+
|
|
40
|
+
public static LimitWithPrecision(latOrLng: number, precision = 12): number {
|
|
33
41
|
return parseFloat(parseFloat('' + latOrLng).toPrecision(precision));
|
|
34
42
|
}
|
|
35
|
-
|
|
43
|
+
|
|
44
|
+
public static IsEqualsLatLng(latOrLng1: number, latOrLng2: number, cartesianStep = CartesianTools.DEFAULT_SCALE): boolean {
|
|
36
45
|
return CartesianTools.RoundLatLng(latOrLng1, cartesianStep, true) === CartesianTools.RoundLatLng(latOrLng2, cartesianStep, true);
|
|
37
46
|
}
|
|
38
|
-
|
|
47
|
+
|
|
48
|
+
public static IsAroundLatLng(latLngCenter: LatLng, latLngAround: LatLng, stepRange: number,
|
|
49
|
+
cartesianStep = CartesianTools.DEFAULT_SCALE): boolean {
|
|
50
|
+
|
|
39
51
|
let isAround = false;
|
|
40
|
-
const min = -stepRange * cartesianStep,
|
|
52
|
+
const min = -stepRange * cartesianStep,
|
|
53
|
+
max = stepRange * cartesianStep;
|
|
41
54
|
for (let lat = min; !isAround && lat <= max; lat += cartesianStep) {
|
|
42
55
|
for (let lng = min; !isAround && lng <= max; lng += cartesianStep) {
|
|
43
56
|
isAround = CartesianTools.RoundLatLng(latLngCenter.lat, cartesianStep, true)
|
|
@@ -48,54 +61,70 @@ class CartesianTools {
|
|
|
48
61
|
}
|
|
49
62
|
}
|
|
50
63
|
}
|
|
64
|
+
|
|
51
65
|
return isAround;
|
|
52
66
|
}
|
|
53
|
-
|
|
67
|
+
|
|
68
|
+
public static IsNotAroundLatLng(latLngCenter: LatLng, latLngAround: LatLng, stepRange: number,
|
|
69
|
+
cartesianStep = CartesianTools.DEFAULT_SCALE): boolean {
|
|
70
|
+
|
|
54
71
|
const max = (stepRange * cartesianStep) + Number.EPSILON;
|
|
72
|
+
|
|
55
73
|
let isOut = CartesianTools.RoundLatLng(latLngCenter.lat, cartesianStep)
|
|
56
74
|
> CartesianTools.RoundLatLng(latLngAround.lat + max, cartesianStep)
|
|
57
75
|
|| CartesianTools.RoundLatLng(latLngCenter.lat, cartesianStep)
|
|
58
|
-
|
|
76
|
+
< CartesianTools.RoundLatLng(latLngAround.lat - max, cartesianStep);
|
|
59
77
|
if (!isOut) {
|
|
60
78
|
isOut = CartesianTools.RoundLatLng(latLngCenter.lng, cartesianStep)
|
|
61
79
|
> CartesianTools.RoundLatLng(latLngAround.lng + max, cartesianStep)
|
|
62
80
|
|| CartesianTools.RoundLatLng(latLngCenter.lng, cartesianStep)
|
|
63
|
-
|
|
81
|
+
< CartesianTools.RoundLatLng(latLngAround.lng - max, cartesianStep);
|
|
64
82
|
}
|
|
83
|
+
|
|
65
84
|
return isOut;
|
|
66
85
|
}
|
|
67
|
-
|
|
86
|
+
|
|
87
|
+
public static DegToRad(azimuthInDegrees: number) {
|
|
68
88
|
return azimuthInDegrees * Math.PI / 180;
|
|
69
89
|
}
|
|
70
|
-
|
|
90
|
+
|
|
91
|
+
public static GetAzimuthRad(angleInDegrees: number): number {
|
|
71
92
|
return CartesianTools.DegToRad(-angleInDegrees + 90);
|
|
72
93
|
}
|
|
73
|
-
|
|
94
|
+
|
|
95
|
+
public static ComputeLatSteps(cartesianValues: CartesianValue[]): number[] {
|
|
74
96
|
const lats = cartesianValues.map(c => c.lat).sort((a, b) => a - b);
|
|
75
97
|
return CartesianTools.UniqNum(lats);
|
|
76
98
|
}
|
|
77
|
-
|
|
99
|
+
|
|
100
|
+
public static ComputeLngSteps(cartesianValues: CartesianValue[]): number[] {
|
|
78
101
|
const lngs = cartesianValues.map(c => c.lng).sort((a, b) => a - b);
|
|
79
102
|
return CartesianTools.UniqNum(lngs);
|
|
80
103
|
}
|
|
81
|
-
|
|
82
|
-
|
|
104
|
+
|
|
105
|
+
public static LogCartesianValues(cartesianValues: CartesianValue[],
|
|
106
|
+
logger = console) {
|
|
107
|
+
logger?.log('>> raain-quality ### logCartesianValues with', cartesianValues.length,
|
|
108
|
+
CartesianTools.DEFAULT_SCALE, ' in progress...');
|
|
83
109
|
const pointsToShow = {};
|
|
84
110
|
const latSteps = CartesianTools.ComputeLatSteps(cartesianValues);
|
|
85
111
|
const lngSteps = CartesianTools.ComputeLngSteps(cartesianValues);
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
112
|
+
|
|
113
|
+
const labelX = (v: number) => {
|
|
114
|
+
return CartesianTools.LabelWithSign(v)
|
|
115
|
+
}
|
|
116
|
+
const labelY = (v: number) => {
|
|
117
|
+
return CartesianTools.LabelWithSign(v)
|
|
118
|
+
}
|
|
92
119
|
const valueDisplay = (v) => {
|
|
93
120
|
return '' + Math.round(v * 100) / 100;
|
|
94
|
-
}
|
|
121
|
+
}
|
|
122
|
+
|
|
95
123
|
for (let lat of latSteps) {
|
|
96
124
|
const xObject = {};
|
|
97
125
|
for (let lng of lngSteps) {
|
|
98
|
-
|
|
126
|
+
|
|
127
|
+
const latLng = new LatLng({lat, lng});
|
|
99
128
|
latLng.setPrecision(12);
|
|
100
129
|
lat = latLng.lat;
|
|
101
130
|
lng = latLng.lng;
|
|
@@ -103,35 +132,44 @@ class CartesianTools {
|
|
|
103
132
|
}
|
|
104
133
|
pointsToShow[labelY(lat)] = xObject;
|
|
105
134
|
}
|
|
135
|
+
|
|
106
136
|
for (const [index, point] of cartesianValues.entries()) {
|
|
107
|
-
let value = valueDisplay(point.value)
|
|
137
|
+
let value = valueDisplay(point.value)
|
|
108
138
|
if (pointsToShow[labelY(point.lat)][labelX(point.lng)] !== '0') {
|
|
109
139
|
value = '' + value + '?' + pointsToShow[labelY(point.lat)][labelX(point.lng)];
|
|
110
140
|
}
|
|
141
|
+
|
|
111
142
|
pointsToShow[labelY(point.lat)][labelX(point.lng)] = value;
|
|
112
143
|
}
|
|
113
|
-
|
|
144
|
+
|
|
145
|
+
logger?.table(pointsToShow);
|
|
114
146
|
}
|
|
115
|
-
|
|
147
|
+
|
|
148
|
+
public static UniqNum(a: number[]) {
|
|
116
149
|
return [...new Set(a)];
|
|
117
150
|
}
|
|
118
|
-
|
|
151
|
+
|
|
152
|
+
public static UniqStr(a: number[]) {
|
|
119
153
|
return [...new Set(a)];
|
|
120
154
|
}
|
|
121
|
-
|
|
155
|
+
|
|
156
|
+
public static GetDistanceFromLatLngInKm(latLng1: LatLng, latLng2: LatLng) {
|
|
122
157
|
const R = 6371; // Radius of the earth in km
|
|
123
158
|
const dLat = CartesianTools.DegToRad(latLng2.lat - latLng1.lat);
|
|
124
159
|
const dLon = CartesianTools.DegToRad(latLng2.lng - latLng1.lng);
|
|
125
|
-
const a =
|
|
160
|
+
const a =
|
|
161
|
+
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
|
|
126
162
|
Math.cos(CartesianTools.DegToRad(latLng1.lat)) * Math.cos(CartesianTools.DegToRad(latLng2.lat)) *
|
|
127
|
-
|
|
163
|
+
Math.sin(dLon / 2) * Math.sin(dLon / 2);
|
|
128
164
|
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
|
129
165
|
return R * c; // Distance in km
|
|
130
166
|
}
|
|
131
|
-
|
|
167
|
+
|
|
168
|
+
public static VincentyDistance(latLng1: LatLng, latLng2: LatLng) {
|
|
132
169
|
const a = 6378137.0; // WGS84 ellipsoid semi-major axis
|
|
133
170
|
const f = 1 / 298.257223563; // WGS84 ellipsoid flattening
|
|
134
171
|
const b = 6356752.314245; // derived semi-minor axis
|
|
172
|
+
|
|
135
173
|
const L = CartesianTools.DegToRad(latLng2.lng - latLng1.lng);
|
|
136
174
|
const U1 = Math.atan((1 - f) * Math.tan(CartesianTools.DegToRad(latLng1.lat)));
|
|
137
175
|
const U2 = Math.atan((1 - f) * Math.tan(CartesianTools.DegToRad(latLng2.lat)));
|
|
@@ -139,103 +177,129 @@ class CartesianTools {
|
|
|
139
177
|
const cosU1 = Math.cos(U1);
|
|
140
178
|
const sinU2 = Math.sin(U2);
|
|
141
179
|
const cosU2 = Math.cos(U2);
|
|
180
|
+
|
|
142
181
|
let lambda = L;
|
|
143
|
-
let lambdaP;
|
|
182
|
+
let lambdaP: number;
|
|
144
183
|
let iterLimit = 100;
|
|
145
|
-
let cosSqAlpha, sinSigma, cos2SigmaM, cosSigma, sigma, sinLambda, cosLambda,
|
|
184
|
+
let cosSqAlpha: number, sinSigma: number, cos2SigmaM: number, cosSigma: number, sigma: number, sinLambda: number, cosLambda: number,
|
|
185
|
+
sinAlpha: number;
|
|
186
|
+
|
|
146
187
|
do {
|
|
147
188
|
sinLambda = Math.sin(lambda);
|
|
148
189
|
cosLambda = Math.cos(lambda);
|
|
149
190
|
sinSigma = Math.sqrt((cosU2 * sinLambda) * (cosU2 * sinLambda) +
|
|
150
191
|
(cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda));
|
|
151
|
-
|
|
152
|
-
|
|
192
|
+
|
|
193
|
+
if (sinSigma === 0) return 0; // co-incident points
|
|
194
|
+
|
|
153
195
|
cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
|
|
154
196
|
sigma = Math.atan2(sinSigma, cosSigma);
|
|
155
197
|
sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
|
|
156
198
|
cosSqAlpha = 1 - sinAlpha * sinAlpha;
|
|
157
199
|
cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;
|
|
158
|
-
|
|
159
|
-
|
|
200
|
+
|
|
201
|
+
if (isNaN(cos2SigmaM)) cos2SigmaM = 0; // equatorial line
|
|
202
|
+
|
|
160
203
|
const C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
|
|
161
204
|
lambdaP = lambda;
|
|
162
205
|
lambda = L + (1 - C) * f * sinAlpha *
|
|
163
206
|
(sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));
|
|
207
|
+
|
|
164
208
|
} while (Math.abs(lambda - lambdaP) > 1e-12 && --iterLimit > 0);
|
|
165
|
-
|
|
166
|
-
|
|
209
|
+
|
|
210
|
+
if (iterLimit === 0) return NaN; // formula failed to converge
|
|
211
|
+
|
|
167
212
|
const uSq = cosSqAlpha * (a * a - b * b) / (b * b);
|
|
168
213
|
const A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
|
|
169
214
|
const B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
|
|
215
|
+
|
|
170
216
|
const deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 *
|
|
171
217
|
(cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) -
|
|
172
218
|
B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM)));
|
|
219
|
+
|
|
173
220
|
const s = b * A * (sigma - deltaSigma);
|
|
221
|
+
|
|
174
222
|
return s / 1000; // distance in kilometers
|
|
175
223
|
}
|
|
176
|
-
|
|
224
|
+
|
|
225
|
+
protected static LabelWithSign(val: number) {
|
|
177
226
|
const value = val;
|
|
178
227
|
if (value < 0) {
|
|
179
228
|
return '' + value;
|
|
180
|
-
}
|
|
181
|
-
else if (value === 0) {
|
|
229
|
+
} else if (value === 0) {
|
|
182
230
|
return ' ' + 0;
|
|
183
231
|
}
|
|
184
232
|
return '+' + value;
|
|
185
233
|
}
|
|
186
|
-
|
|
234
|
+
|
|
235
|
+
public getScaleLatLng(latLng: LatLng, latDirection = 1): LatLng {
|
|
236
|
+
|
|
187
237
|
let lat2 = latLng.lat + this.scale;
|
|
188
238
|
if (latDirection < 0) {
|
|
189
239
|
lat2 = latLng.lat - this.scale;
|
|
190
240
|
}
|
|
191
|
-
const latDist = CartesianTools.VincentyDistance(new
|
|
241
|
+
const latDist = CartesianTools.VincentyDistance(new LatLng({lat: latLng.lat, lng: 0}),
|
|
242
|
+
new LatLng({lat: lat2, lng: 0}));
|
|
192
243
|
let lngScale = this.scale;
|
|
193
|
-
let minDiff;
|
|
244
|
+
let minDiff: number;
|
|
194
245
|
for (let scale = 0; scale <= this.scale * 100; scale += this.scale / 10) {
|
|
195
246
|
scale = CartesianTools.LimitWithPrecision(scale);
|
|
196
|
-
const lngDist = CartesianTools.VincentyDistance(new
|
|
247
|
+
const lngDist = CartesianTools.VincentyDistance(new LatLng({lat: lat2, lng: 0}),
|
|
248
|
+
new LatLng({lat: lat2, lng: scale}));
|
|
197
249
|
const diff2 = Math.abs(latDist - lngDist);
|
|
198
250
|
if (!minDiff || Math.min(minDiff, diff2) === diff2) {
|
|
199
251
|
minDiff = diff2;
|
|
200
252
|
lngScale = scale;
|
|
201
|
-
}
|
|
202
|
-
else {
|
|
253
|
+
} else {
|
|
203
254
|
break;
|
|
204
255
|
}
|
|
205
256
|
}
|
|
257
|
+
|
|
206
258
|
const lat = CartesianTools.LimitWithPrecision(this.scale);
|
|
207
259
|
const lng = CartesianTools.LimitWithPrecision(lngScale);
|
|
208
|
-
return new
|
|
260
|
+
return new LatLng({lat, lng});
|
|
209
261
|
}
|
|
210
|
-
|
|
262
|
+
|
|
263
|
+
public getScaleLatLngFromEarth(fromLatLng: LatLng): LatLng {
|
|
264
|
+
|
|
211
265
|
if (!this.earthMap) {
|
|
212
266
|
return null;
|
|
213
267
|
}
|
|
268
|
+
|
|
214
269
|
const posLat = Math.round((90 + fromLatLng.lat) / this.scale);
|
|
215
270
|
const latitudeLongitudeScale = this.earthMap.latitudeLongitudeScales[posLat];
|
|
216
|
-
return new
|
|
271
|
+
return new LatLng({lat: this.scale, lng: latitudeLongitudeScale});
|
|
217
272
|
}
|
|
218
|
-
|
|
273
|
+
|
|
274
|
+
public getLatLngFromEarthMap(fromLatLng: LatLng): LatLng {
|
|
275
|
+
|
|
219
276
|
if (!this.earthMap) {
|
|
220
277
|
return null;
|
|
221
278
|
}
|
|
279
|
+
|
|
222
280
|
const posLat = Math.round((90 + fromLatLng.lat) / this.scale);
|
|
223
281
|
const lat = this.earthMap.latitudes[posLat];
|
|
224
282
|
const latitudeLongitudeScale = this.earthMap.latitudeLongitudeScales[posLat];
|
|
283
|
+
|
|
225
284
|
const lngPos = Math.round(fromLatLng.lng / latitudeLongitudeScale);
|
|
226
285
|
const lng = CartesianTools.LimitWithPrecision(lngPos * latitudeLongitudeScale);
|
|
227
|
-
|
|
286
|
+
|
|
287
|
+
return new LatLng({lat, lng})
|
|
228
288
|
}
|
|
229
|
-
|
|
289
|
+
|
|
290
|
+
public buildLatLngEarthMap(): EarthMap {
|
|
291
|
+
|
|
230
292
|
if (this.earthMap) {
|
|
231
293
|
delete this.earthMap;
|
|
232
294
|
}
|
|
233
295
|
this.earthMap = undefined;
|
|
234
|
-
|
|
296
|
+
|
|
297
|
+
const earthMap: EarthMap = {
|
|
235
298
|
latitudes: [],
|
|
236
299
|
latitudeScale: this.scale,
|
|
237
300
|
latitudeLongitudeScales: []
|
|
238
301
|
};
|
|
302
|
+
|
|
239
303
|
for (let lat = -90; lat <= 90; lat += this.scale) {
|
|
240
304
|
lat = CartesianTools.LimitWithPrecision(lat);
|
|
241
305
|
earthMap.latitudes.push(lat);
|
|
@@ -243,13 +307,10 @@ class CartesianTools {
|
|
|
243
307
|
if (lat > 0) {
|
|
244
308
|
direction = -1;
|
|
245
309
|
}
|
|
246
|
-
earthMap.latitudeLongitudeScales.push(this.getScaleLatLng(new
|
|
310
|
+
earthMap.latitudeLongitudeScales.push(this.getScaleLatLng(new LatLng({lat, lng: 0}), direction).lng);
|
|
247
311
|
}
|
|
312
|
+
|
|
248
313
|
this.earthMap = earthMap;
|
|
249
314
|
return earthMap;
|
|
250
315
|
}
|
|
251
316
|
}
|
|
252
|
-
exports.CartesianTools = CartesianTools;
|
|
253
|
-
// scale of Pixel regarding LatLng : Approx. 1 => 100km, 0.01 => 1km, 0.005 => 500m
|
|
254
|
-
CartesianTools.DEFAULT_SCALE = 0.01;
|
|
255
|
-
//# sourceMappingURL=CartesianTools.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {LatLng} from './LatLng';
|
|
2
|
+
|
|
3
|
+
export class CartesianValue extends LatLng {
|
|
4
|
+
|
|
5
|
+
public value: number;
|
|
6
|
+
|
|
7
|
+
constructor(json: {
|
|
8
|
+
value: number,
|
|
9
|
+
lat: number,
|
|
10
|
+
lng: number
|
|
11
|
+
}
|
|
12
|
+
) {
|
|
13
|
+
super(json);
|
|
14
|
+
this.value = json.value;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
toJSON(): {
|
|
18
|
+
value: number,
|
|
19
|
+
lat: number,
|
|
20
|
+
lng: number
|
|
21
|
+
} {
|
|
22
|
+
const json = super.toJSON() as any;
|
|
23
|
+
json.value = this.value;
|
|
24
|
+
return json;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {CartesianValue} from './CartesianValue';
|
|
2
|
+
import {LatLng} from './LatLng';
|
|
3
|
+
|
|
4
|
+
export interface ICartesianMeasureValue {
|
|
5
|
+
|
|
6
|
+
getLimitPoints(): [LatLng, LatLng];
|
|
7
|
+
|
|
8
|
+
getCartesianValuesStringified(): string;
|
|
9
|
+
|
|
10
|
+
getCartesianValues(): CartesianValue[];
|
|
11
|
+
|
|
12
|
+
toJSON(): any;
|
|
13
|
+
|
|
14
|
+
toJSONWithCartesianValuesStringified(): any;
|
|
15
|
+
|
|
16
|
+
getCartesianValue(json: { lat: number, lng: number }): CartesianValue;
|
|
17
|
+
|
|
18
|
+
getCartesianValueRounded(json: { lat: number, lng: number, scale: LatLng }): CartesianValue;
|
|
19
|
+
|
|
20
|
+
setCartesianValue(json: { lat: number, lng: number, value: number }): void;
|
|
21
|
+
|
|
22
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {CartesianTools} from './CartesianTools';
|
|
2
|
+
|
|
3
|
+
export class LatLng {
|
|
4
|
+
|
|
5
|
+
public lat: number;
|
|
6
|
+
public lng: number;
|
|
7
|
+
|
|
8
|
+
constructor(json: {
|
|
9
|
+
lat: number,
|
|
10
|
+
lng: number,
|
|
11
|
+
}) {
|
|
12
|
+
if (typeof json?.lat === 'undefined' || typeof json?.lng === 'undefined') {
|
|
13
|
+
throw new Error('LatLng needs valid latitude && longitude');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
this.lat = json.lat;
|
|
17
|
+
this.lng = json.lng;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public equals(v: LatLng) {
|
|
21
|
+
return this.lat === v.lat && this.lng === v.lng;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
setPrecision(precision: number = 12) {
|
|
25
|
+
const tenPower = Math.pow(10, precision);
|
|
26
|
+
this.lat = Math.round(this.lat * tenPower) / tenPower;
|
|
27
|
+
this.lng = Math.round(this.lng * tenPower) / tenPower;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
rounded(scale: LatLng) {
|
|
31
|
+
this.lat = CartesianTools.RoundLatLng(this.lat, scale.lat, true);
|
|
32
|
+
this.lng = CartesianTools.RoundLatLng(this.lng, scale.lng, true);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
limitPrecision(precision = 12) {
|
|
36
|
+
this.lat = CartesianTools.LimitWithPrecision(this.lat, precision);
|
|
37
|
+
this.lng = CartesianTools.LimitWithPrecision(this.lng, precision);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
toJSON() {
|
|
41
|
+
return {lat: this.lat, lng: this.lng};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {CartesianValue} from './CartesianValue';
|
|
2
|
+
import {CartesianMeasureValue} from './CartesianMeasureValue';
|
|
3
|
+
import {LatLng} from './LatLng';
|
|
4
|
+
|
|
5
|
+
export class RadarCartesianMeasureValue extends CartesianMeasureValue {
|
|
6
|
+
|
|
7
|
+
public angle: number; // In degrees. Radar incidence angle, from 0° to 90°, from the ground to the top
|
|
8
|
+
public axis: number; // In degrees. Polarization angle 0° = horizontal, 90°= vertical.
|
|
9
|
+
|
|
10
|
+
constructor(json: {
|
|
11
|
+
cartesianValues: string | CartesianValue[],
|
|
12
|
+
angle: number,
|
|
13
|
+
axis: number,
|
|
14
|
+
limitPoints: [LatLng, LatLng],
|
|
15
|
+
}) {
|
|
16
|
+
|
|
17
|
+
super(json);
|
|
18
|
+
this.angle = json.angle;
|
|
19
|
+
this.axis = json.axis;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
toJSON(options = {stringify: false}): any {
|
|
23
|
+
const json: any = super.toJSON(options);
|
|
24
|
+
json.angle = this.angle;
|
|
25
|
+
json.axis = this.axis;
|
|
26
|
+
return json;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
toJSONWithCartesianValuesStringified(): any {
|
|
30
|
+
return this.toJSON({stringify: true});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {IVersion} from '../organization';
|
|
2
|
+
import {CartesianValue} from './CartesianValue';
|
|
3
|
+
import {CartesianMeasureValue} from './CartesianMeasureValue';
|
|
4
|
+
import {LatLng} from './LatLng';
|
|
5
|
+
|
|
6
|
+
export class RainCartesianMeasureValue extends CartesianMeasureValue implements IVersion {
|
|
7
|
+
|
|
8
|
+
private readonly version: string;
|
|
9
|
+
|
|
10
|
+
constructor(json: {
|
|
11
|
+
cartesianValues: string | CartesianValue[],
|
|
12
|
+
limitPoints: [LatLng, LatLng],
|
|
13
|
+
version: string,
|
|
14
|
+
}) {
|
|
15
|
+
super(json);
|
|
16
|
+
this.version = json.version;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
getVersion(): string {
|
|
20
|
+
return this.version;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
toJSON(options = {stringify: false}): any {
|
|
24
|
+
const json: any = super.toJSON(options);
|
|
25
|
+
json.version = this.getVersion();
|
|
26
|
+
return json;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
toJSONWithCartesianValuesStringified(): any {
|
|
30
|
+
return this.toJSON({stringify: true});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import {Measure} from '../organization';
|
|
2
|
+
import {IPolarMeasureValue} from '../polar';
|
|
3
|
+
import {ICartesianMeasureValue} from '../cartesian';
|
|
4
|
+
import {GaugeNode} from './GaugeNode';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* api/gauges/:id/measures/:id
|
|
8
|
+
*/
|
|
9
|
+
export class GaugeMeasure extends Measure {
|
|
10
|
+
|
|
11
|
+
public static TYPE = 'gauge-measure';
|
|
12
|
+
|
|
13
|
+
public gauge: string;
|
|
14
|
+
|
|
15
|
+
constructor(json: {
|
|
16
|
+
id: string,
|
|
17
|
+
values: IPolarMeasureValue[] | ICartesianMeasureValue[] | number[],
|
|
18
|
+
date?: Date,
|
|
19
|
+
validity?: number,
|
|
20
|
+
configurationAsJSON?: string,
|
|
21
|
+
gauge?: string
|
|
22
|
+
}
|
|
23
|
+
) {
|
|
24
|
+
super(json);
|
|
25
|
+
if (json.gauge) {
|
|
26
|
+
this.addLinks([new GaugeNode({id: json.gauge, latitude: NaN, longitude: NaN, team: null, name: null})]);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public toJSON(options?: any): any {
|
|
31
|
+
const json = super.toJSON(options);
|
|
32
|
+
const gaugeLink = this.getLink(GaugeNode.TYPE);
|
|
33
|
+
if (gaugeLink) {
|
|
34
|
+
json['gauge'] = gaugeLink.getId();
|
|
35
|
+
}
|
|
36
|
+
return json;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
protected getLinkType(): string {
|
|
40
|
+
return GaugeMeasure.TYPE;
|
|
41
|
+
}
|
|
42
|
+
}
|