Расчет средних ЗРВ
This commit is contained in:
+33
@@ -57,4 +57,37 @@ class RvaRestController(
|
|||||||
@PathVariable duration: Long,
|
@PathVariable duration: Long,
|
||||||
@RequestBody stations: List<StationDTO>
|
@RequestBody stations: List<StationDTO>
|
||||||
) = slotService.rvaMergeOnRev(satelliteId, duration, stations)
|
) = 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');
|
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() {
|
function selectedMode() {
|
||||||
return document.querySelector('input[name="rva-mode"]:checked')?.value || 'common';
|
return document.querySelector('input[name="rva-mode"]:checked')?.value || 'common';
|
||||||
}
|
}
|
||||||
@@ -113,7 +124,7 @@
|
|||||||
<td>${row.durationSec}</td>
|
<td>${row.durationSec}</td>
|
||||||
</tr>
|
</tr>
|
||||||
`).join('');
|
`).join('');
|
||||||
} else {
|
} else if (resultState.mode === 'merge-on-rev') {
|
||||||
head.innerHTML = `
|
head.innerHTML = `
|
||||||
<tr>
|
<tr>
|
||||||
<th>Виток</th>
|
<th>Виток</th>
|
||||||
@@ -123,7 +134,24 @@
|
|||||||
body.innerHTML = resultState.rows.map(row => `
|
body.innerHTML = resultState.rows.map(row => `
|
||||||
<tr>
|
<tr>
|
||||||
<td>${row.revolution}</td>
|
<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>
|
</tr>
|
||||||
`).join('');
|
`).join('');
|
||||||
}
|
}
|
||||||
@@ -145,8 +173,9 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lines = resultState.mode === 'common'
|
let lines;
|
||||||
? [
|
if (resultState.mode === 'common') {
|
||||||
|
lines = [
|
||||||
['stationId', 'revolution', 'onStart', 'onMaximum', 'onStop', 'duration'],
|
['stationId', 'revolution', 'onStart', 'onMaximum', 'onStop', 'duration'],
|
||||||
...resultState.rows.map(row => [
|
...resultState.rows.map(row => [
|
||||||
row.stationId,
|
row.stationId,
|
||||||
@@ -156,23 +185,35 @@
|
|||||||
row.onStop.time,
|
row.onStop.time,
|
||||||
row.duration
|
row.duration
|
||||||
])
|
])
|
||||||
]
|
];
|
||||||
: resultState.mode === 'merge'
|
} else if (resultState.mode === 'merge') {
|
||||||
? [
|
lines = [
|
||||||
['begin', 'end', 'durationSec'],
|
['begin', 'end', 'durationSec'],
|
||||||
...resultState.rows.map(row => [
|
...resultState.rows.map(row => [
|
||||||
row.begin,
|
row.begin,
|
||||||
row.end,
|
row.end,
|
||||||
row.durationSec
|
row.durationSec
|
||||||
])
|
])
|
||||||
]
|
];
|
||||||
: [
|
} else if (resultState.mode === 'merge-on-rev') {
|
||||||
|
lines = [
|
||||||
['revolution', 'durationSec'],
|
['revolution', 'durationSec'],
|
||||||
...resultState.rows.map(row => [
|
...resultState.rows.map(row => [
|
||||||
row.revolution,
|
row.revolution,
|
||||||
row.durationSec
|
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 csv = lines.map(line => line.map(csvEscape).join(';')).join('\n');
|
||||||
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
|
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">
|
<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>
|
<label class="form-check-label" for="rva-mode-merge-on-rev">Суммарная длительность на витке</label>
|
||||||
</div>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user