Расчет средних ЗРВ
This commit is contained in:
+33
@@ -57,4 +57,37 @@ class RvaRestController(
|
||||
@PathVariable duration: Long,
|
||||
@RequestBody stations: List<StationDTO>
|
||||
) = slotService.rvaMergeOnRev(satelliteId, duration, stations)
|
||||
|
||||
@PostMapping("/average/{satelliteId}/{duration}")
|
||||
@ResponseBody
|
||||
fun rvaAverage(
|
||||
@PathVariable satelliteId: Long,
|
||||
@PathVariable duration: Long,
|
||||
@RequestBody stations: List<StationDTO>
|
||||
): List<RvaAverageDTO> {
|
||||
val days = duration.coerceAtLeast(1).toDouble()
|
||||
val zonesByStation = slotService.rvaCommon(satelliteId, duration, stations)
|
||||
.groupBy { it.stationId }
|
||||
|
||||
return stations
|
||||
.sortedBy { it.number }
|
||||
.map { station ->
|
||||
val zones = zonesByStation[station.number.toLong()].orEmpty()
|
||||
val zoneCount = zones.size
|
||||
val totalDurationSec = zones.sumOf { it.duration }
|
||||
RvaAverageDTO(
|
||||
ppiNumber = station.number.toLong(),
|
||||
ppiLatitude = station.position.lat,
|
||||
averageCount = zoneCount / days,
|
||||
averageDurationSec = if (zoneCount == 0) 0.0 else totalDurationSec / zoneCount
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class RvaAverageDTO(
|
||||
val ppiNumber: Long,
|
||||
val ppiLatitude: Double,
|
||||
val averageCount: Double,
|
||||
val averageDurationSec: Double
|
||||
)
|
||||
|
||||
@@ -30,6 +30,17 @@
|
||||
return date.toLocaleString('ru-RU');
|
||||
}
|
||||
|
||||
function formatNumber(value, digits = 3) {
|
||||
const number = Number(value);
|
||||
if (!Number.isFinite(number)) {
|
||||
return '';
|
||||
}
|
||||
return number.toLocaleString('ru-RU', {
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: digits
|
||||
});
|
||||
}
|
||||
|
||||
function selectedMode() {
|
||||
return document.querySelector('input[name="rva-mode"]:checked')?.value || 'common';
|
||||
}
|
||||
@@ -113,7 +124,7 @@
|
||||
<td>${row.durationSec}</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
} else {
|
||||
} else if (resultState.mode === 'merge-on-rev') {
|
||||
head.innerHTML = `
|
||||
<tr>
|
||||
<th>Виток</th>
|
||||
@@ -123,7 +134,24 @@
|
||||
body.innerHTML = resultState.rows.map(row => `
|
||||
<tr>
|
||||
<td>${row.revolution}</td>
|
||||
<td>${row.durationSec}</td>
|
||||
<td>${formatNumber(row.durationSec, 1)}</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
} else if (resultState.mode === 'average') {
|
||||
head.innerHTML = `
|
||||
<tr>
|
||||
<th>№ППИ</th>
|
||||
<th>Широта ППИ</th>
|
||||
<th>Сред.кол-во</th>
|
||||
<th>Сред.длит., с</th>
|
||||
</tr>
|
||||
`;
|
||||
body.innerHTML = resultState.rows.map(row => `
|
||||
<tr>
|
||||
<td>${row.ppiNumber}</td>
|
||||
<td>${formatNumber(row.ppiLatitude, 6)}</td>
|
||||
<td>${formatNumber(row.averageCount, 3)}</td>
|
||||
<td>${formatNumber(row.averageDurationSec, 1)}</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
}
|
||||
@@ -145,8 +173,9 @@
|
||||
return;
|
||||
}
|
||||
|
||||
const lines = resultState.mode === 'common'
|
||||
? [
|
||||
let lines;
|
||||
if (resultState.mode === 'common') {
|
||||
lines = [
|
||||
['stationId', 'revolution', 'onStart', 'onMaximum', 'onStop', 'duration'],
|
||||
...resultState.rows.map(row => [
|
||||
row.stationId,
|
||||
@@ -156,23 +185,35 @@
|
||||
row.onStop.time,
|
||||
row.duration
|
||||
])
|
||||
]
|
||||
: resultState.mode === 'merge'
|
||||
? [
|
||||
];
|
||||
} else if (resultState.mode === 'merge') {
|
||||
lines = [
|
||||
['begin', 'end', 'durationSec'],
|
||||
...resultState.rows.map(row => [
|
||||
row.begin,
|
||||
row.end,
|
||||
row.durationSec
|
||||
])
|
||||
]
|
||||
: [
|
||||
];
|
||||
} else if (resultState.mode === 'merge-on-rev') {
|
||||
lines = [
|
||||
['revolution', 'durationSec'],
|
||||
...resultState.rows.map(row => [
|
||||
row.revolution,
|
||||
row.durationSec
|
||||
])
|
||||
];
|
||||
} else {
|
||||
lines = [
|
||||
['ppiNumber', 'ppiLatitude', 'averageCount', 'averageDurationSec'],
|
||||
...resultState.rows.map(row => [
|
||||
row.ppiNumber,
|
||||
row.ppiLatitude,
|
||||
row.averageCount,
|
||||
row.averageDurationSec
|
||||
])
|
||||
];
|
||||
}
|
||||
|
||||
const csv = lines.map(line => line.map(csvEscape).join(';')).join('\n');
|
||||
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
|
||||
|
||||
@@ -56,6 +56,10 @@
|
||||
<input class="form-check-input" type="radio" name="rva-mode" id="rva-mode-merge-on-rev" value="merge-on-rev">
|
||||
<label class="form-check-label" for="rva-mode-merge-on-rev">Суммарная длительность на витке</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="rva-mode" id="rva-mode-average" value="average">
|
||||
<label class="form-check-label" for="rva-mode-average">Средняя длительность</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user