archive, bug fixes
This commit is contained in:
@ -40,7 +40,7 @@
|
||||
<a href="/live">
|
||||
<div><img src="../img/waves.svg">Трансляция</div>
|
||||
</a>
|
||||
<a href="/">
|
||||
<a href="/videos">
|
||||
<div><img src="../img/play.svg">Записи</div>
|
||||
</a>
|
||||
<a class="settings" href="/">
|
||||
|
@ -40,7 +40,7 @@
|
||||
<a href="/live">
|
||||
<div><img src="../img/waves.svg">Трансляция</div>
|
||||
</a>
|
||||
<a href="/">
|
||||
<a href="/videos">
|
||||
<div><img src="../img/play.svg">Записи</div>
|
||||
</a>
|
||||
<a class="settings" href="/">
|
||||
|
@ -40,7 +40,7 @@
|
||||
<a href="/live">
|
||||
<div><img src="../img/waves.svg">Трансляция</div>
|
||||
</a>
|
||||
<a href="/">
|
||||
<a href="/videos">
|
||||
<div><img src="../img/play.svg">Записи</div>
|
||||
</a>
|
||||
<a class="settings" href="/">
|
||||
|
@ -42,7 +42,7 @@
|
||||
<a href="/live">
|
||||
<div><img src="../img/waves.svg">Трансляция</div>
|
||||
</a>
|
||||
<a href="/">
|
||||
<a href="/videos">
|
||||
<div><img src="../img/play.svg">Записи</div>
|
||||
</a>
|
||||
<a class="settings" href="/">
|
||||
|
@ -45,7 +45,7 @@
|
||||
<a href="/live">
|
||||
<div class="selected"><img src="../img/waves.svg">Трансляция</div>
|
||||
</a>
|
||||
<a href="/">
|
||||
<a href="/videos">
|
||||
<div><img src="../img/play.svg">Записи</div>
|
||||
</a>
|
||||
<a class="settings" href="/">
|
||||
@ -115,6 +115,15 @@
|
||||
|
||||
</section>
|
||||
|
||||
<div id="video-popup" class="video-popup">
|
||||
<div id="video-popup-content" class="video-popup-content">
|
||||
<span class="close-popup" id="close-popup">×</span>
|
||||
<div id="popup-video-container" class="popup-video-container">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<section class="table" style="position: relative;">
|
||||
@ -128,7 +137,8 @@
|
||||
<ul id="list">
|
||||
{{#each Alarms}}
|
||||
<li>
|
||||
<input type="radio" name="signal" id="signal-{{this.id}}" hidden>
|
||||
<!-- <input type="radio" name="signal" id="signal-{{this.id}}" hidden> -->
|
||||
<a style="color:rgba(0, 0, 0, 0.7);" href="/reports/{{this.id}}" target="_blank">
|
||||
<label for="signal-{{this.id}}">
|
||||
<h2>{{this.type}}</h2>
|
||||
<span>ID {{this.id}}</span>
|
||||
@ -149,6 +159,7 @@
|
||||
<path fill="#000" fill-opacity=".75" d="M10.38 14c1.25 0 2.07-.336 2.792-1.15.057-.056.114-.12.164-.178.428-.478.628-.95.628-1.4 0-.513-.3-.992-.935-1.434l-2.077-1.442c-.643-.443-1.393-.493-1.992.1l-.55.55c-.164.164-.307.17-.464.07-.386-.242-1.164-.92-1.692-1.448-.557-.55-1.092-1.164-1.378-1.614-.093-.164-.086-.3.079-.464l.542-.55c.6-.6.55-1.356.107-1.992L4.162.971C3.72.336 3.242.043 2.727.036c-.45-.007-.92.2-1.4.628-.063.057-.12.107-.178.157C.336 1.549 0 2.371 0 3.605c0 2.042 1.256 4.527 3.562 6.832C5.854 12.73 8.346 14 10.38 14Zm.008-1.1c-1.82.036-4.155-1.363-6.005-3.205-1.863-1.856-3.326-4.27-3.29-6.09.014-.785.292-1.463.849-1.949.05-.043.086-.078.136-.114.214-.186.442-.285.65-.285.206 0 .392.078.527.292L4.64 3.627c.15.221.165.47-.057.692l-.628.628c-.492.493-.457 1.093-.1 1.571.407.55 1.114 1.35 1.664 1.892.542.55 1.406 1.32 1.963 1.735.478.357 1.078.393 1.57-.1l.629-.628c.221-.222.464-.207.692-.065l2.078 1.385a.6.6 0 0 1 .292.536c0 .207-.1.435-.285.65l-.114.135c-.486.557-1.164.828-1.956.843Z"/>
|
||||
</svg></p> -->
|
||||
</label>
|
||||
</a>
|
||||
</li>
|
||||
{{/each}}
|
||||
|
||||
@ -156,7 +167,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div class="map">
|
||||
<div class="stream-map">
|
||||
<div id="properties" class="properties" style="display: none;">
|
||||
<div class="propert"><h1>Группа</h1><br><h2 id="propert-group">Автобусы</h2></div>
|
||||
<div class="propert"><h1>Скорость</h1><br><h2 id="propert-speed"> км/ч</h2></div>
|
||||
@ -166,11 +177,11 @@
|
||||
<div id="map"></div>
|
||||
</div>
|
||||
|
||||
<div class="cameras">
|
||||
<div class="stream-cameras">
|
||||
<div class="cameras-swipe"><svg xmlns="http://www.w3.org/2000/svg" width="17" height="11" fill="none" viewBox="0 0 17 11">
|
||||
<path fill="#000" fill-opacity=".5" d="M8.486 10.4a.88.88 0 0 0 .655-.283l7.558-7.744a.871.871 0 0 0 .264-.625.876.876 0 0 0-.889-.898.927.927 0 0 0-.635.254L7.96 8.75h1.045l-7.48-7.646A.892.892 0 0 0 .888.85.876.876 0 0 0 0 1.748a.91.91 0 0 0 .264.635l7.558 7.734c.186.186.41.283.664.283Z"/>
|
||||
</svg></div>
|
||||
<div class="video-container">
|
||||
<div class="stream-video-container">
|
||||
<!-- <video id="camera-1"></video> -->
|
||||
<video id="camera-2"></video>
|
||||
<video id="camera-3"></video>
|
||||
@ -178,8 +189,8 @@
|
||||
<video id="camera-5"></video>
|
||||
<!-- <video id="camera-6"></video>
|
||||
<video id="camera-7"></video>
|
||||
<video id="camera-8"></video> -->
|
||||
<!-- <video id="camera-9"></video>
|
||||
<video id="camera-8"></video>
|
||||
<video id="camera-9"></video>
|
||||
<video id="camera-10"></video>
|
||||
<video id="camera-11"></video>
|
||||
<video id="camera-12"></video>
|
||||
@ -348,6 +359,19 @@
|
||||
zoom: 10
|
||||
})
|
||||
});
|
||||
// Скрыть кнопки приближения/отдаления
|
||||
map.getControls().forEach(function(control) {
|
||||
if (control instanceof ol.control.Zoom) {
|
||||
map.removeControl(control);
|
||||
}
|
||||
});
|
||||
|
||||
// Скрыть информационную панель
|
||||
map.getControls().forEach(function(control) {
|
||||
if (control instanceof ol.control.Attribution) {
|
||||
map.removeControl(control);
|
||||
}
|
||||
});
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "../scripts/style.json", true);
|
||||
@ -366,9 +390,21 @@
|
||||
{{#if ifDBError}}
|
||||
{{else}}
|
||||
|
||||
const selectedDevices = Array.from(checkboxes)
|
||||
.filter(checkbox => checkbox.checked && checkbox.value !== 'on')
|
||||
.map(checkbox => checkbox.value);
|
||||
const selectedDevices = Array.from(checkboxes)
|
||||
.filter(checkbox => checkbox.checked && checkbox.value !== 'on')
|
||||
.map(checkbox => checkbox.value);
|
||||
|
||||
checkboxes.forEach(checkbox => {
|
||||
checkbox.addEventListener('change', function() {
|
||||
selectedDevices.length = 0; // Очищаем массив
|
||||
selectedDevices.push(...Array.from(checkboxes)
|
||||
.filter(checkbox => checkbox.checked && checkbox.value !== 'on')
|
||||
.map(checkbox => checkbox.value));
|
||||
|
||||
console.log(selectedDevices); // Вывести выбранные устройства в консоль
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function addMarker(device) {
|
||||
const { serial, status, longitude, latitude, direction, speed } = device;
|
||||
@ -410,6 +446,7 @@
|
||||
}
|
||||
|
||||
function fetchAndShowMarkers() {
|
||||
console.log(selectedDevices);
|
||||
fetch('/devices-geo', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@ -436,8 +473,9 @@
|
||||
|
||||
const propertiesDiv = document.getElementById('properties');
|
||||
|
||||
console.log(selectedDevice);
|
||||
|
||||
if (selectedDevice) {
|
||||
// Вывод нужных свойств устройства в консоль
|
||||
// groupElement.textContent = selectedDevice.group;
|
||||
speedElement.textContent = selectedDevice.speed + ' км/ч';
|
||||
plateElement.textContent = selectedDevice.plate;
|
||||
@ -574,6 +612,80 @@ for (var i = 0; i < tableCheckboxes.length; i++) {
|
||||
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// Получаем ссылки на элементы
|
||||
const videoContainers = document.querySelectorAll('.stream-video-container video');
|
||||
const popup = document.getElementById('video-popup');
|
||||
const popupVideo = document.getElementById('popup-video');
|
||||
const closePopup = document.getElementById('close-popup');
|
||||
const popupVideoContainer = document.getElementById('popup-video-container');
|
||||
const popupContainer = document.getElementById('video-popup-content');
|
||||
|
||||
let originalVideo = null; // Сохраняем оригинальное видео элемент
|
||||
|
||||
// Функция для открытия попапа с видео
|
||||
function openVideoPopup(video) {
|
||||
// Сохраняем оригинальное видео
|
||||
originalVideo = video;
|
||||
|
||||
// Меняем стили видео
|
||||
video.style.position = 'fixed';
|
||||
video.style.top = '10%';
|
||||
video.style.left = '0';
|
||||
video.style.width = '100%';
|
||||
video.style.height = '80%';
|
||||
video.style.zIndex = '1000';
|
||||
|
||||
popup.style.display = 'block';
|
||||
popupContainer.style.width = '100%';
|
||||
popupContainer.style.height = '80%';
|
||||
}
|
||||
|
||||
// Функция для закрытия попапа с видео
|
||||
function closeVideoPopup() {
|
||||
// Восстанавливаем оригинальные стили видео
|
||||
if (originalVideo) {
|
||||
originalVideo.style.position = '';
|
||||
originalVideo.style.top = '';
|
||||
originalVideo.style.left = '';
|
||||
originalVideo.style.width = '';
|
||||
originalVideo.style.height = '';
|
||||
originalVideo.style.zIndex = '';
|
||||
|
||||
// Очищаем контейнер попапа
|
||||
popup.style.display = 'none';
|
||||
|
||||
// Сбрасываем оригинальное видео
|
||||
originalVideo = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Добавляем обработчики событий для клика на видео и кнопку закрытия
|
||||
videoContainers.forEach((video) => {
|
||||
video.addEventListener('click', () => {
|
||||
openVideoPopup(video);
|
||||
});
|
||||
});
|
||||
|
||||
closePopup.addEventListener('click', () => {
|
||||
closeVideoPopup();
|
||||
});
|
||||
|
||||
// Закрыть попап при клике вне его области
|
||||
window.addEventListener('click', (event) => {
|
||||
if (event.target === popup) {
|
||||
closeVideoPopup();
|
||||
}
|
||||
});
|
||||
|
||||
// Закрыть попап при нажатии на клавишу Esc
|
||||
window.addEventListener('keydown', (event) => {
|
||||
if (event.key === 'Escape') {
|
||||
closeVideoPopup();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
|
@ -40,7 +40,7 @@
|
||||
<a href="/live">
|
||||
<div><img src="../img/waves.svg">Трансляция</div>
|
||||
</a>
|
||||
<a href="/">
|
||||
<a href="/videos">
|
||||
<div><img src="../img/play.svg">Записи</div>
|
||||
</a>
|
||||
<a class="settings" href="/">
|
||||
|
@ -43,7 +43,7 @@
|
||||
<a href="/live">
|
||||
<div><img src="../img/waves.svg">Трансляция</div>
|
||||
</a>
|
||||
<a href="/">
|
||||
<a href="/videos">
|
||||
<div><img src="../img/play.svg">Записи</div>
|
||||
</a>
|
||||
<a class="settings" href="/">
|
||||
@ -168,14 +168,18 @@
|
||||
|
||||
<video id="my-video" src="../test_video.MP4"></video>
|
||||
|
||||
<div class="map">
|
||||
<div class="stream-map">
|
||||
<div id="map"></div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
.map {
|
||||
.stream-map {
|
||||
width: calc(100% - 450px - 514px);
|
||||
height: calc(100% - 62px);
|
||||
float: right;
|
||||
}
|
||||
</style>
|
||||
@ -253,7 +257,7 @@ var map = new ol.Map({
|
||||
],
|
||||
view: new ol.View({
|
||||
center: ol.proj.fromLonLat([prevLongitude, prevLatitude]),
|
||||
zoom: 17
|
||||
zoom: 14
|
||||
})
|
||||
});
|
||||
|
||||
|
760
static/templates/videos/see.html
Normal file
760
static/templates/videos/see.html
Normal file
@ -0,0 +1,760 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Записи</title>
|
||||
<link rel="stylesheet" href="../styles/main.css" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ol3/4.6.5/ol.css" type="text/css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ol3/4.6.5/ol.js"></script>
|
||||
<script src="https://unpkg.com/ol-mapbox-style@9.4.0/dist/olms.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<header>
|
||||
<h1>Аргус</h1>
|
||||
<h2><span>/</span> {{Organisation}}</h2>
|
||||
</header>
|
||||
|
||||
<section class="account-info">
|
||||
<div id="account-main">
|
||||
<img id="person" src="../img/person.svg">
|
||||
<span>{{User}}</span>
|
||||
<img id="down" src="../img/down.svg">
|
||||
<img id="up" src="../img/up.svg">
|
||||
</div>
|
||||
<a href="/login"><div id="account-additional" class="additional">Выйти</div></a>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<section class="navigation">
|
||||
<a href="/">
|
||||
<div><img src="../img/chart.svg">Главная</div>
|
||||
</a>
|
||||
<a href="/devices">
|
||||
<div><img src="../img/cloud.svg">Устройства</div>
|
||||
</a>
|
||||
<a href="/reports">
|
||||
<div><img src="../img/bubble.svg">Отчёты</div>
|
||||
</a>
|
||||
<a href="/live">
|
||||
<div><img src="../img/waves.svg">Трансляция</div>
|
||||
</a>
|
||||
<a href="/videos">
|
||||
<div class="selected"><img src="../img/play.svg">Записи</div>
|
||||
</a>
|
||||
<a class="settings" href="/">
|
||||
<div><img src="../img/gear.svg">Настройки</div>
|
||||
</a>
|
||||
</section>
|
||||
|
||||
<section class="main">
|
||||
{{#if ifDBError}}
|
||||
<section class="dberror">
|
||||
<div class="erorr-container">
|
||||
<img src="../img/warning.svg"> <br>
|
||||
<h1>Ошибка </h1> <br>
|
||||
<span>Не удалось получить данные из БД</span>
|
||||
<button type="button" onclick="location.reload();">Повторить попытку</button>
|
||||
</div>
|
||||
</section>
|
||||
{{/if}}
|
||||
<div class="name">
|
||||
<span>Управление записями</span>
|
||||
</div>
|
||||
<nav>
|
||||
<a class="selected" href="/videos">Воспроизведение</a>
|
||||
<a href="/videos">Экспорт</a>
|
||||
</nav>
|
||||
<section class="bg">
|
||||
<section class="content">
|
||||
<section class="for-table">
|
||||
|
||||
<section class="organisation">
|
||||
<h1>Организация</h1>
|
||||
|
||||
<ul class="area">
|
||||
<li class="area-name"><img src="../img/ul.svg"><input type="checkbox" id="name-1" class="checkbox-input" hidden checked><label for="name-1" class="checkbox-label">Группа 1</label>
|
||||
<ul class="area-devices" id="devices-1">
|
||||
{{#each Registrars}}
|
||||
<li class="device">
|
||||
<img>
|
||||
<input type="radio" name="camera-serial" id="radio-{{this.serial}}" class="radio-input" value="{{this.serial}}" hidden>
|
||||
<label for="radio-{{this.serial}}" class="radio-label">
|
||||
{{this.serial}}
|
||||
</label>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
<section class="table" style="position: relative;">
|
||||
|
||||
<div class="map">
|
||||
<div id="properties" class="properties" style="display: none;">
|
||||
<div class="propert"><h1>Группа</h1><br><h2 id="propert-group">Автобусы</h2></div>
|
||||
<div class="propert"><h1>Скорость</h1><br><h2 id="propert-speed"> км/ч</h2></div>
|
||||
<div class="propert"><h1>Номерной знак</h1><br><h2 id="propert-plate"></h2></div>
|
||||
<div class="propert"><h1>Геопозиция</h1><br><h2 id="propert-geo"></h2></div>
|
||||
</div>
|
||||
<div id="map"></div>
|
||||
</div>
|
||||
|
||||
<div class="cameras">
|
||||
<div class="video-container">
|
||||
<div id="camera-1" onclick="playVideo(1);">
|
||||
<img src="../../img/play-circle.svg">
|
||||
<span>Запустить 1 камеру</span>
|
||||
</div>
|
||||
<div id="camera-2" onclick="playVideo(2);">
|
||||
<img src="../../img/play-circle.svg">
|
||||
<span>Запустить 2 камеру</span>
|
||||
</div>
|
||||
<div id="camera-3" onclick="playVideo(3);">
|
||||
<img src="../../img/play-circle.svg">
|
||||
<span>Запустить 3 камеру</span>
|
||||
</div>
|
||||
<div id="camera-4" onclick="playVideo(4);">
|
||||
<img src="../../img/play-circle.svg">
|
||||
<span>Запустить 4 камеру</span>
|
||||
</div>
|
||||
<div id="camera-5" onclick="playVideo(5);">
|
||||
<img src="../../img/play-circle.svg">
|
||||
<span>Запустить 5 камеру</span>
|
||||
</div>
|
||||
<div id="camera-6" onclick="playVideo(6);">
|
||||
<img src="../../img/play-circle.svg">
|
||||
<span>Запустить 6 камеру</span>
|
||||
</div>
|
||||
<div id="camera-7" onclick="playVideo(7);">
|
||||
<img src="../../img/play-circle.svg">
|
||||
<span>Запустить 7 камеру</span>
|
||||
</div>
|
||||
<div id="camera-8" onclick="playVideo(8);">
|
||||
<img src="../../img/play-circle.svg">
|
||||
<span>Запустить 8 камеру</span>
|
||||
</div>
|
||||
<div id="camera-9" onclick="playVideo(9);">
|
||||
<img src="../../img/play-circle.svg">
|
||||
<span>Запустить 9 камеру</span>
|
||||
</div>
|
||||
<div id="camera-10" onclick="playVideo(10);">
|
||||
<img src="../../img/play-circle.svg">
|
||||
<span>Запустить 10 камеру</span>
|
||||
</div>
|
||||
<div id="camera-11" onclick="playVideo(11);">
|
||||
<img src="../../img/play-circle.svg">
|
||||
<span>Запустить 11 камеру</span>
|
||||
</div>
|
||||
<div id="camera-12" onclick="playVideo(12);">
|
||||
<img src="../../img/play-circle.svg">
|
||||
<span>Запустить 12 камеру</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="video-container-right">
|
||||
<div id="camera-13" onclick="playVideo(13);">
|
||||
<img src="../../img/play-circle.svg">
|
||||
<span>Запустить 13 камеру</span>
|
||||
</div>
|
||||
<div id="camera-14" onclick="playVideo(14);">
|
||||
<img src="../../img/play-circle.svg">
|
||||
<span>Запустить 14 камеру</span>
|
||||
</div>
|
||||
<div id="camera-15" onclick="playVideo(15);">
|
||||
<img src="../../img/play-circle.svg">
|
||||
<span>Запустить 15 камеру</span>
|
||||
</div>
|
||||
<div id="camera-16" onclick="playVideo(16);">
|
||||
<img src="../../img/play-circle.svg">
|
||||
<span>Запустить 16 камеру</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="calendar">
|
||||
<div class="calendar-header">
|
||||
<button id="prevMonth"></button>
|
||||
<h2 id="monthYear"></h2>
|
||||
<button id="nextMonth"></button>
|
||||
</div>
|
||||
<div class="daysOfWeek">
|
||||
<div>Пн</div>
|
||||
<div>Вт</div>
|
||||
<div>Ср</div>
|
||||
<div>Чт</div>
|
||||
<div>Пт</div>
|
||||
<div>Сб</div>
|
||||
<div>Вс</div>
|
||||
</div>
|
||||
<div class="dates" id="dates">
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" id="selectedDate" name="selectedDate" hidden>
|
||||
|
||||
<div class="speedometr">
|
||||
<h1>Скорость</h1>
|
||||
<span>км/ч</span>
|
||||
<span style="float: right; font-size: 18px;">1 ч</span>
|
||||
<div>
|
||||
<canvas id="speed"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="video-time">
|
||||
<input name="videoTime" type="time" id="video-time" step="1">
|
||||
</div>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
.table {
|
||||
background-color:rgba(0, 0, 0, 0.02) !important;
|
||||
}
|
||||
|
||||
.speedometr {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 62px;
|
||||
width: calc(75% - 300px - 10px - 32px);
|
||||
height: 220px;
|
||||
border-radius: 15px;
|
||||
background-color: white;
|
||||
padding-right: 32px;
|
||||
}
|
||||
|
||||
.speedometr div {
|
||||
height: 200px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="../scripts/jquery.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
|
||||
<script>
|
||||
function combineDateTime(dateString, timeString) {
|
||||
const date = new Date(dateString);
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(date.getDate()).padStart(2, "0");
|
||||
|
||||
// Разбиение времени на часы, минуты и секунды
|
||||
const timeParts = timeString.split(":");
|
||||
const hours = timeParts[0].padStart(2, "0");
|
||||
const minutes = timeParts[1].padStart(2, "0");
|
||||
const seconds = timeParts[2].padStart(2, "0");
|
||||
|
||||
// Собираем дату и время в нужном формате
|
||||
const combinedDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
|
||||
return combinedDateTime;
|
||||
}
|
||||
|
||||
function sendPostRequest() {
|
||||
// Получение данных из полей ввода
|
||||
const selectedDate = document.getElementById("selectedDate").value;
|
||||
const videoTime = document.getElementById("video-time").value;
|
||||
const selectedSerial = document.querySelector('input[name="camera-serial"]:checked').value;
|
||||
|
||||
// Объединяем дату и время и преобразуем в нужный формат
|
||||
const combinedDateTime = combineDateTime(selectedDate, videoTime);
|
||||
|
||||
const requestData = {
|
||||
serial: selectedSerial,
|
||||
datetime: combinedDateTime,
|
||||
};
|
||||
|
||||
fetch("/getspeedarchive", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(requestData),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
|
||||
const existingChart = Chart.getChart("speed");
|
||||
|
||||
if (existingChart) {
|
||||
existingChart.destroy();
|
||||
}
|
||||
|
||||
const numberOfLabels = data.speeds.length;
|
||||
const labels = Array.from({ length: numberOfLabels }, () => "");
|
||||
|
||||
// Обновление данных графика
|
||||
const chart = new Chart("speed", {
|
||||
type: "line",
|
||||
data: {
|
||||
labels: labels,
|
||||
datasets: [
|
||||
{
|
||||
label: "Скорость",
|
||||
borderColor: "#8086F9",
|
||||
fill: false,
|
||||
data: data.speeds,
|
||||
pointStyle: false,
|
||||
pointRadius: 25,
|
||||
pointHoverRadius: 25,
|
||||
tension: 0.1,
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
},
|
||||
labelStep: "3",
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
y: {
|
||||
stacked: true,
|
||||
grid: {
|
||||
display: true,
|
||||
color: "#D9D9D9",
|
||||
},
|
||||
ticks: {
|
||||
stepSize: 10,
|
||||
},
|
||||
},
|
||||
x: {
|
||||
grid: {
|
||||
display: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
routeLayer.getSource().clear();
|
||||
markerLayer.getSource().clear();
|
||||
|
||||
const geoData = data.geo;
|
||||
|
||||
const routePoints = geoData.map((point) => {
|
||||
return ol.proj.fromLonLat([point.longitude, point.latitude]);
|
||||
});
|
||||
|
||||
const routeFeature = new ol.Feature({
|
||||
geometry: new ol.geom.LineString(routePoints),
|
||||
});
|
||||
routeFeature.setStyle(routeStyle);
|
||||
|
||||
routeLayer.getSource().addFeature(routeFeature);
|
||||
|
||||
const startMarker = new ol.Feature({
|
||||
geometry: new ol.geom.Point(routePoints[0]),
|
||||
});
|
||||
startMarker.setStyle(markerStyle);
|
||||
|
||||
const endMarker = new ol.Feature({
|
||||
geometry: new ol.geom.Point(routePoints[routePoints.length - 1]),
|
||||
});
|
||||
endMarker.setStyle(markerStyle);
|
||||
|
||||
markerLayer.getSource().addFeatures([startMarker, endMarker]);
|
||||
|
||||
const mapElement = document.getElementById("map");
|
||||
|
||||
const map = new ol.Map({
|
||||
target: null,
|
||||
layers: [
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM(),
|
||||
}),
|
||||
markerLayer,
|
||||
routeLayer,
|
||||
],
|
||||
view: new ol.View({
|
||||
center: ol.proj.fromLonLat([30.282995, 59.855198]),
|
||||
zoom: 10
|
||||
}),
|
||||
});
|
||||
|
||||
map.getLayers().clear();
|
||||
|
||||
map.setTarget(mapElement);
|
||||
|
||||
// Скрыть кнопки приближения/отдаления
|
||||
map.getControls().forEach(function (control) {
|
||||
if (control instanceof ol.control.Zoom) {
|
||||
map.removeControl(control);
|
||||
}
|
||||
});
|
||||
|
||||
// Скрыть информационную панель
|
||||
map.getControls().forEach(function (control) {
|
||||
if (control instanceof ol.control.Attribution) {
|
||||
map.removeControl(control);
|
||||
}
|
||||
});
|
||||
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Ошибка при отправке запроса:", error);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const radioInputs = document.querySelectorAll(".radio-input");
|
||||
radioInputs.forEach((input) => {
|
||||
input.addEventListener("change", sendPostRequest);
|
||||
});
|
||||
|
||||
const selectedDateInput = document.getElementById("selectedDate");
|
||||
selectedDateInput.addEventListener("change", sendPostRequest);
|
||||
|
||||
const videoTimeInput = document.getElementById("video-time");
|
||||
videoTimeInput.addEventListener("change", sendPostRequest);
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<script>
|
||||
var now = new Date();
|
||||
now.setHours(now.getHours() - 1);
|
||||
var formattedTime = now.toISOString().substr(11, 8);
|
||||
document.getElementById("video-time").value = formattedTime;
|
||||
</script>
|
||||
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const prevMonthBtn = document.getElementById("prevMonth");
|
||||
const nextMonthBtn = document.getElementById("nextMonth");
|
||||
const monthYear = document.getElementById("monthYear");
|
||||
const datesContainer = document.getElementById("dates");
|
||||
const dateForm = document.getElementById("dateForm");
|
||||
const selectedDateInput = document.getElementById("selectedDate");
|
||||
|
||||
let currentDate = new Date();
|
||||
let selectedDate = currentDate;
|
||||
selectedDateInput.value = selectedDate.toISOString();
|
||||
function renderCalendar() {
|
||||
// Очистить предыдущий календарь
|
||||
datesContainer.innerHTML = "";
|
||||
|
||||
// Установить заголовок с месяцем и годом
|
||||
const options = { year: "numeric", month: "long" };
|
||||
const formattedDate = currentDate.toLocaleDateString("ru-RU", options);
|
||||
const formattedMonthYear = formattedDate.charAt(0).toUpperCase() + formattedDate.slice(1);
|
||||
monthYear.textContent = formattedMonthYear.replace('г.', '');
|
||||
|
||||
// Найти первый день текущего месяца
|
||||
const firstDayOfMonth = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1);
|
||||
|
||||
// Определить день недели, с которого начнется месяц
|
||||
const startingDay = firstDayOfMonth.getDay() - 1;
|
||||
|
||||
// Определить количество дней в текущем месяце
|
||||
const daysInMonth = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 0).getDate();
|
||||
|
||||
// Создать дни месяца
|
||||
for (let i = 0; i < startingDay; i++) {
|
||||
const emptyDay = document.createElement("div");
|
||||
emptyDay.classList.add("empty-day");
|
||||
datesContainer.appendChild(emptyDay);
|
||||
}
|
||||
|
||||
for (let day = 1; day <= daysInMonth; day++) {
|
||||
const dateCell = document.createElement("div");
|
||||
dateCell.textContent = day;
|
||||
dateCell.classList.add("date");
|
||||
if (selectedDate.getDate() === day && selectedDate.getMonth() === currentDate.getMonth() && selectedDate.getFullYear() === currentDate.getFullYear()) {
|
||||
dateCell.classList.add("selected");
|
||||
}
|
||||
dateCell.addEventListener("click", () => {
|
||||
selectedDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), day);
|
||||
renderCalendar();
|
||||
selectedDateInput.value = selectedDate.toISOString();
|
||||
});
|
||||
datesContainer.appendChild(dateCell);
|
||||
}
|
||||
sendPostRequest();
|
||||
}
|
||||
|
||||
// Перейти на предыдущий месяц
|
||||
prevMonthBtn.addEventListener("click", () => {
|
||||
currentDate = new Date(currentDate.getFullYear(), currentDate.getMonth() - 1, 1);
|
||||
renderCalendar();
|
||||
});
|
||||
|
||||
// Перейти на следующий месяц
|
||||
nextMonthBtn.addEventListener("click", () => {
|
||||
currentDate = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 1);
|
||||
renderCalendar();
|
||||
});
|
||||
|
||||
// Инициализировать календарь
|
||||
renderCalendar();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<script>
|
||||
function formatDate(selectedDate) {
|
||||
const date = new Date(selectedDate);
|
||||
const year = date.getFullYear();
|
||||
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
||||
const day = date.getDate().toString().padStart(2, '0');
|
||||
return `${year}${month}${day}`;
|
||||
}
|
||||
|
||||
function formatTime(videoTime) {
|
||||
const parts = videoTime.split(':');
|
||||
const hours = parts[0].toString().padStart(2, '0');
|
||||
const minutes = parts[1].toString().padStart(2, '0');
|
||||
const seconds = parts[2].toString().padStart(2, '0');
|
||||
return `${hours}${minutes}${seconds}`;
|
||||
}
|
||||
|
||||
function playVideo(channel) {
|
||||
const selectedDevice = document.querySelector('input[name="camera-serial"]:checked');
|
||||
if (!selectedDevice) {
|
||||
alert('Пожалуйста, выберите устройство из списка.');
|
||||
return;
|
||||
}
|
||||
|
||||
const startTimeInput = document.getElementById('video-time');
|
||||
const selectedDateInput = document.getElementById('selectedDate');
|
||||
const startTime = formatTime(startTimeInput.value);
|
||||
const selectedDate = formatDate(selectedDateInput.value);
|
||||
const serial = selectedDevice.value;
|
||||
|
||||
const url = `http://localhost:8081/?url=http%3A%2F%2Fkrbl.ru%3A8080%2Fhttp%2Fplayback.flv%3Fserial%3D${serial}%26channel%3D${channel}%26quality%3D1%26queryTime%3D${selectedDate}%26startTime%3D${startTime}%26endTime%3D130000`;
|
||||
|
||||
fetch(url)
|
||||
.then(response => {
|
||||
if (response.status === 200) {
|
||||
console.log('Запрос выполнен успешно.');
|
||||
} else {
|
||||
console.error('Произошла ошибка при выполнении запроса.');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Произошла ошибка при выполнении запроса:', error);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<script>
|
||||
window.addEventListener('DOMContentLoaded', function() {
|
||||
var mapContainer = document.querySelector('.map');
|
||||
var mapArea = document.getElementById('map');
|
||||
|
||||
mapArea.style.height = (mapContainer.clientHeight) + 'px';
|
||||
mapArea.style.width = (mapContainer.clientWidth) + 'px';
|
||||
});
|
||||
|
||||
window.addEventListener("resize", function (event) {
|
||||
var mapContainer = document.querySelector('.map');
|
||||
var mapArea = document.getElementById('map');
|
||||
|
||||
mapArea.style.height = (mapContainer.clientHeight) + 'px';
|
||||
mapArea.style.width = (mapContainer.clientWidth) + 'px';
|
||||
});
|
||||
|
||||
var startPoint = ol.proj.fromLonLat([0, 0]);
|
||||
var endPoint = ol.proj.fromLonLat([0, 0]);
|
||||
|
||||
var routeStyle = new ol.style.Style({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: 'red',
|
||||
width: 6
|
||||
})
|
||||
});
|
||||
|
||||
var markerStyle = new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
radius: 7,
|
||||
fill: new ol.style.Fill({
|
||||
color: 'red'
|
||||
}),
|
||||
stroke: new ol.style.Stroke({
|
||||
color: 'white',
|
||||
width: 2
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
var routeSource = new ol.source.Vector({
|
||||
features: [
|
||||
new ol.Feature({
|
||||
geometry: new ol.geom.LineString([startPoint, endPoint])
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
var routeLayer = new ol.layer.Vector({
|
||||
source: routeSource,
|
||||
style: routeStyle
|
||||
});
|
||||
|
||||
var startMarker = new ol.Feature({
|
||||
geometry: new ol.geom.Point(startPoint)
|
||||
});
|
||||
startMarker.setStyle(markerStyle);
|
||||
|
||||
var endMarker = new ol.Feature({
|
||||
geometry: new ol.geom.Point(endPoint)
|
||||
});
|
||||
endMarker.setStyle(markerStyle);
|
||||
|
||||
var markerSource = new ol.source.Vector({
|
||||
features: [startMarker, endMarker]
|
||||
});
|
||||
|
||||
var markerLayer = new ol.layer.Vector({
|
||||
source: markerSource
|
||||
});
|
||||
var map = new ol.Map({
|
||||
target: 'map',
|
||||
layers: [
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
}),
|
||||
markerLayer,
|
||||
routeLayer,
|
||||
],
|
||||
view: new ol.View({
|
||||
center: ol.proj.fromLonLat([30.282995, 59.855198]),
|
||||
zoom: 10
|
||||
})
|
||||
});
|
||||
|
||||
// Скрыть кнопки приближения/отдаления
|
||||
map.getControls().forEach(function(control) {
|
||||
if (control instanceof ol.control.Zoom) {
|
||||
map.removeControl(control);
|
||||
}
|
||||
});
|
||||
|
||||
// Скрыть информационную панель
|
||||
map.getControls().forEach(function(control) {
|
||||
if (control instanceof ol.control.Attribution) {
|
||||
map.removeControl(control);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// Скрытие/Показ дополнительных меню аккаунта
|
||||
const accountMain = document.getElementById('account-main');
|
||||
const accountAdditional = document.getElementById('account-additional');
|
||||
const accountUp = document.getElementById('up');
|
||||
const accountDown = document.getElementById('down');
|
||||
accountAdditional.style.display = 'none';
|
||||
accountUp.style.display = 'none';
|
||||
|
||||
accountMain.addEventListener('click', () => {
|
||||
if (accountAdditional.style.display === 'none') {
|
||||
accountAdditional.style.display = 'flex';
|
||||
accountUp.style.display = 'unset';
|
||||
accountDown.style.display = 'none';
|
||||
} else {
|
||||
accountAdditional.style.display = 'none';
|
||||
accountUp.style.display = 'none';
|
||||
accountDown.style.display = 'unset';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Chart.defaults.color = "rgba(0, 0, 0, 0.4)";
|
||||
Chart.defaults.font.size = 15;
|
||||
Chart.defaults.font.weight = 400;
|
||||
var speedData = {
|
||||
labels: [
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
],
|
||||
datasets: [
|
||||
{
|
||||
label: "Скорость",
|
||||
borderColor: "#8086F9",
|
||||
fill: false,
|
||||
data: [
|
||||
{{Speeds}}
|
||||
],
|
||||
pointStyle: false,
|
||||
pointRadius: 25,
|
||||
pointHoverRadius: 25,
|
||||
tension: 0.1,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
var speedOptions = {
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
},
|
||||
labelStep: "3",
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
y: {
|
||||
stacked: true,
|
||||
grid: {
|
||||
display: true,
|
||||
color: "#D9D9D9",
|
||||
},
|
||||
ticks: {
|
||||
stepSize: 10,
|
||||
},
|
||||
},
|
||||
x: {
|
||||
grid: {
|
||||
display: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
new Chart("speed", {
|
||||
type: "line",
|
||||
data: speedData,
|
||||
options: speedOptions,
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user