update alerts and live
This commit is contained in:
		
							
								
								
									
										133
									
								
								server.js
									
									
									
									
									
								
							
							
						
						
									
										133
									
								
								server.js
									
									
									
									
									
								
							| @@ -8,10 +8,9 @@ require("dotenv").config(); | |||||||
| const multer = require("multer"); | const multer = require("multer"); | ||||||
| const http = require("http"); | const http = require("http"); | ||||||
|  |  | ||||||
| // Для сохранения загруженных фотографий |  | ||||||
| const storage = multer.diskStorage({ | const storage = multer.diskStorage({ | ||||||
|   destination: function (req, file, cb) { |   destination: function (req, file, cb) { | ||||||
|     cb(null, "uploads"); // Папка для сохранения фотографий |     cb(null, "uploads");  | ||||||
|   }, |   }, | ||||||
|   filename: function (req, file, cb) { |   filename: function (req, file, cb) { | ||||||
|     cb(null, Date.now() + "-" + file.originalname); |     cb(null, Date.now() + "-" + file.originalname); | ||||||
| @@ -33,17 +32,17 @@ app.get("/devices/drivers", drivers); | |||||||
| app.get("/devices/update", update); | app.get("/devices/update", update); | ||||||
|  |  | ||||||
|  |  | ||||||
| // const DB_User = process.env.DB_USER; | const DB_User = process.env.DB_USER; | ||||||
| // const DB_Password = process.env.DB_PASSWORD; | const DB_Password = process.env.DB_PASSWORD; | ||||||
| // const DB_Host = process.env.DB_HOST; | const DB_Host = process.env.DB_HOST; | ||||||
| // const DB_Port = process.env.DB_PORT; | const DB_Port = process.env.DB_PORT; | ||||||
| // const DB_Name = process.env.DB_NAME; | const DB_Name = process.env.DB_NAME; | ||||||
|  |  | ||||||
| const DB_User = "postgres"; | // const DB_User = "postgres"; | ||||||
| const DB_Password = process.env.POSTGRES_PASSWORD; | // const DB_Password = process.env.POSTGRES_PASSWORD; | ||||||
| const DB_Host = "postgres"; | // const DB_Host = "postgres"; | ||||||
| const DB_Port = "5432"; | // const DB_Port = "5432"; | ||||||
| const DB_Name = "postgres"; | // const DB_Name = "postgres"; | ||||||
|  |  | ||||||
| async function index(req, res) { | async function index(req, res) { | ||||||
|   var templateData = { |   var templateData = { | ||||||
| @@ -87,7 +86,6 @@ async function index(req, res) { | |||||||
|     const resultT = template(templateData); |     const resultT = template(templateData); | ||||||
|     res.send(resultT); |     res.send(resultT); | ||||||
|   } |   } | ||||||
|   // res.sendFile(path.join(__dirname, "static/templates/index.html")); |  | ||||||
| } | } | ||||||
| function login(req, res) { | function login(req, res) { | ||||||
|   res.sendFile(path.join(__dirname, "static/templates/login.html")); |   res.sendFile(path.join(__dirname, "static/templates/login.html")); | ||||||
| @@ -130,12 +128,12 @@ async function live(req, res) { | |||||||
|     })); |     })); | ||||||
|  |  | ||||||
|     const subquery = ` |     const subquery = ` | ||||||
|       SELECT a.id, a.cmdno, a.time, a.serial, a.st, r.plate, g.latitude, g.longitude |     SELECT a.evtuuid, a.id, a.cmdno, a.time, a.serial, a.st, r.plate, g.latitude, g.longitude | ||||||
|     FROM ( |     FROM ( | ||||||
|         SELECT id, cmdno, time, serial, st |       SELECT DISTINCT ON (evtuuid) evtuuid, id, cmdno, time, serial, st | ||||||
|       FROM alarms |       FROM alarms | ||||||
|       WHERE alarmtype = 56 |       WHERE alarmtype = 56 | ||||||
|         ORDER BY time DESC  |       ORDER BY evtuuid, time DESC  | ||||||
|       LIMIT 100 |       LIMIT 100 | ||||||
|     ) AS a |     ) AS a | ||||||
|     LEFT JOIN registrars AS r ON a.serial = r.serial |     LEFT JOIN registrars AS r ON a.serial = r.serial | ||||||
| @@ -146,7 +144,7 @@ async function live(req, res) { | |||||||
|     ) AS g ON a.serial = g.serial AND g.row_num = 1 |     ) AS g ON a.serial = g.serial AND g.row_num = 1 | ||||||
|     ORDER BY a.time DESC; |     ORDER BY a.time DESC; | ||||||
|     `; |     `; | ||||||
|     const alarms = await client.query(subquery, [new Date()]); // Pass current date/time to the query for finding the nearest geoposition. |     const alarms = await client.query(subquery, [new Date()]);  | ||||||
|  |  | ||||||
|     function formatDate(date) { |     function formatDate(date) { | ||||||
|       const options = { |       const options = { | ||||||
| @@ -156,7 +154,10 @@ async function live(req, res) { | |||||||
|         hour: "2-digit", |         hour: "2-digit", | ||||||
|         minute: "2-digit", |         minute: "2-digit", | ||||||
|       }; |       }; | ||||||
|       const formattedDate = new Date(date).toLocaleString("ru-RU", options); |       const adjustedDate = new Date(date); | ||||||
|  |       adjustedDate.setHours(adjustedDate.getHours() - 3);  | ||||||
|  |      | ||||||
|  |       const formattedDate = adjustedDate.toLocaleString("ru-RU", options); | ||||||
|       return formattedDate.replace(",", ""); |       return formattedDate.replace(",", ""); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -304,8 +305,6 @@ app.post("/devices-geo", async (req, res) => { | |||||||
|     port: DB_Port, |     port: DB_Port, | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   // console.log(selectedDevices); |  | ||||||
|  |  | ||||||
|   const placeholders = selectedDevices |   const placeholders = selectedDevices | ||||||
|   .map((_, index) => `$${index + 1}`) |   .map((_, index) => `$${index + 1}`) | ||||||
|   .join(","); |   .join(","); | ||||||
| @@ -334,7 +333,6 @@ pool.query(subquery, selectedDevices, (err, result) => { | |||||||
|  |  | ||||||
|   const minuteInMillis = 60000; |   const minuteInMillis = 60000; | ||||||
|  |  | ||||||
|   // Process the result to include lastkeepalive information |  | ||||||
|   const devicesData = result.rows.map((row) => ({ |   const devicesData = result.rows.map((row) => ({ | ||||||
|     serial: row.serial, |     serial: row.serial, | ||||||
|     longitude: row.longitude, |     longitude: row.longitude, | ||||||
| @@ -344,11 +342,6 @@ pool.query(subquery, selectedDevices, (err, result) => { | |||||||
|     status: Date.now() - Date.parse(row.lastkeepalive) <= minuteInMillis, |     status: Date.now() - Date.parse(row.lastkeepalive) <= minuteInMillis, | ||||||
|   })); |   })); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     // console.log(result.rows); |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     res.json({ devicesData }); |     res.json({ devicesData }); | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
| @@ -369,14 +362,14 @@ async function reports(req, res) { | |||||||
|       port: DB_Port, |       port: DB_Port, | ||||||
|     }); |     }); | ||||||
|     const client = await pool.connect(); |     const client = await pool.connect(); | ||||||
|     // Выполняем запрос и получаем результат |  | ||||||
|     const query = ` |     const query = ` | ||||||
|       SELECT a.id, a.cmdno, a.time, a.serial, a.st, r.plate, g.latitude, g.longitude |     SELECT a.evtuuid, a.id, a.cmdno, a.time, a.serial, a.st, r.plate, g.latitude, g.longitude | ||||||
|     FROM ( |     FROM ( | ||||||
|         SELECT id, cmdno, time, serial, st |       SELECT DISTINCT ON (evtuuid) evtuuid, id, cmdno, time, serial, st | ||||||
|       FROM alarms |       FROM alarms | ||||||
|       WHERE alarmtype = 56 |       WHERE alarmtype = 56 | ||||||
|         ORDER BY time DESC  |       ORDER BY evtuuid, time DESC  | ||||||
|       LIMIT 100 |       LIMIT 100 | ||||||
|     ) AS a |     ) AS a | ||||||
|     LEFT JOIN registrars AS r ON a.serial = r.serial |     LEFT JOIN registrars AS r ON a.serial = r.serial | ||||||
| @@ -387,7 +380,7 @@ async function reports(req, res) { | |||||||
|     ) AS g ON a.serial = g.serial AND g.row_num = 1 |     ) AS g ON a.serial = g.serial AND g.row_num = 1 | ||||||
|     ORDER BY a.time DESC; |     ORDER BY a.time DESC; | ||||||
|     `; |     `; | ||||||
|     const alarms = await client.query(query, [new Date()]); // Pass current date/time to the query for finding the nearest geoposition. |     const alarms = await client.query(query, [new Date()]);  | ||||||
|  |  | ||||||
|     function formatDate(date) { |     function formatDate(date) { | ||||||
|       const options = { |       const options = { | ||||||
| @@ -397,7 +390,10 @@ async function reports(req, res) { | |||||||
|         hour: "2-digit", |         hour: "2-digit", | ||||||
|         minute: "2-digit", |         minute: "2-digit", | ||||||
|       }; |       }; | ||||||
|       const formattedDate = new Date(date).toLocaleString("ru-RU", options); |       const adjustedDate = new Date(date); | ||||||
|  |       adjustedDate.setHours(adjustedDate.getHours() - 3);  | ||||||
|  |      | ||||||
|  |       const formattedDate = adjustedDate.toLocaleString("ru-RU", options); | ||||||
|       return formattedDate.replace(",", ""); |       return formattedDate.replace(",", ""); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -537,6 +533,7 @@ async function reports(req, res) { | |||||||
|     res.send(resultT); |     res.send(resultT); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| app.get("/api/devices", async (req, res) => { | app.get("/api/devices", async (req, res) => { | ||||||
|   try { |   try { | ||||||
|     const pool = new Pool({ |     const pool = new Pool({ | ||||||
| @@ -575,7 +572,10 @@ app.get("/api/devices", async (req, res) => { | |||||||
|         hour: "2-digit", |         hour: "2-digit", | ||||||
|         minute: "2-digit", |         minute: "2-digit", | ||||||
|       }; |       }; | ||||||
|       const formattedDate = new Date(date).toLocaleString("ru-RU", options); |       const adjustedDate = new Date(date); | ||||||
|  |       adjustedDate.setHours(adjustedDate.getHours() - 3);  | ||||||
|  |      | ||||||
|  |       const formattedDate = adjustedDate.toLocaleString("ru-RU", options); | ||||||
|       return formattedDate.replace(",", ""); |       return formattedDate.replace(",", ""); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -636,10 +636,19 @@ app.get('/reports/:id', async (req, res) => { | |||||||
|     Date: "", |     Date: "", | ||||||
|     Serial: "", |     Serial: "", | ||||||
|     Geo: "", |     Geo: "", | ||||||
|  |     Latitude: "", | ||||||
|  |     Longitude: "", | ||||||
|  |      | ||||||
|     DriverName: "", |     DriverName: "", | ||||||
|     DriverPhone: "", |     DriverPhone: "", | ||||||
|     DriverEmail: "", |     DriverEmail: "", | ||||||
|     DriverLicense: "", |     DriverLicense: "", | ||||||
|  |  | ||||||
|  |     PrevLatitude: "", | ||||||
|  |     PrevLongitude: "", | ||||||
|  |     NextLatitude: "", | ||||||
|  |     NextLongitude: "", | ||||||
|  |     Speeds: "", | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   try { |   try { | ||||||
| @@ -654,15 +663,46 @@ app.get('/reports/:id', async (req, res) => { | |||||||
|    |    | ||||||
|     const minuteInMillis = 90 * 1000;  |     const minuteInMillis = 90 * 1000;  | ||||||
|    |    | ||||||
|     // Выполняем запрос, чтобы получить все данные из таблицы registrars |  | ||||||
|     const query = ` |     const query = ` | ||||||
|     SELECT a.serial, a.st, a.time, a.geoid, g.longitude, g.latitude, g.speed, |     WITH PrevNextGeo AS ( | ||||||
|     d.name, d.surname, d.card, d.phone, d.email |       SELECT | ||||||
|  |         a.serial, | ||||||
|  |         a.st, | ||||||
|  |         a.time, | ||||||
|  |         a.geoid, | ||||||
|  |         (SELECT g1.latitude FROM alarms a1 LEFT JOIN geo g1 ON a1.geoid = g1.id WHERE a1.evtuuid = a.evtuuid ORDER BY a1.time ASC LIMIT 1) AS prev_latitude, | ||||||
|  |         (SELECT g2.longitude FROM alarms a2 LEFT JOIN geo g2 ON a2.geoid = g2.id WHERE a2.evtuuid = a.evtuuid ORDER BY a2.time ASC LIMIT 1) AS prev_longitude, | ||||||
|  |         (SELECT g3.latitude FROM alarms a3 LEFT JOIN geo g3 ON a3.geoid = g3.id WHERE a3.evtuuid = a.evtuuid ORDER BY a3.time DESC LIMIT 1) AS next_latitude, | ||||||
|  |         (SELECT g4.longitude FROM alarms a4 LEFT JOIN geo g4 ON a4.geoid = g4.id WHERE a4.evtuuid = a.evtuuid ORDER BY a4.time DESC LIMIT 1) AS next_longitude, | ||||||
|  |         g.longitude, | ||||||
|  |         g.latitude, | ||||||
|  |         g.speed, | ||||||
|  |         d.name, | ||||||
|  |         d.surname, | ||||||
|  |         d.card, | ||||||
|  |         d.phone, | ||||||
|  |         d.email | ||||||
|       FROM alarms a |       FROM alarms a | ||||||
|       LEFT JOIN geo g ON a.geoid = g.id |       LEFT JOIN geo g ON a.geoid = g.id | ||||||
|       LEFT JOIN drivers d ON a.serial = d.transport |       LEFT JOIN drivers d ON a.serial = d.transport | ||||||
|       WHERE a.id = ${id} |       WHERE a.id = ${id} | ||||||
|     LIMIT 1; |       LIMIT 1 | ||||||
|  |     ), | ||||||
|  |     Speeds AS ( | ||||||
|  |       SELECT | ||||||
|  |         g.speed, | ||||||
|  |         ROW_NUMBER() OVER (ORDER BY ABS(EXTRACT(EPOCH FROM (a.time - (SELECT time FROM PrevNextGeo)))) ASC) AS row_number | ||||||
|  |       FROM alarms a | ||||||
|  |       LEFT JOIN geo g ON a.geoid = g.id | ||||||
|  |       WHERE g.serial = (SELECT serial FROM PrevNextGeo) -- Ограничиваем результаты только записями с тем же serial | ||||||
|  |     ) | ||||||
|  |     SELECT | ||||||
|  |       *, | ||||||
|  |       ( | ||||||
|  |         SELECT array_agg(speed) FROM Speeds | ||||||
|  |         WHERE row_number <= 11 | ||||||
|  |       ) AS nearest_speeds | ||||||
|  |     FROM PrevNextGeo; | ||||||
|     `; |     `; | ||||||
|  |  | ||||||
|     const alarm = (await client.query(query)).rows[0]; |     const alarm = (await client.query(query)).rows[0]; | ||||||
| @@ -676,7 +716,10 @@ app.get('/reports/:id', async (req, res) => { | |||||||
|         hour: "2-digit", |         hour: "2-digit", | ||||||
|         minute: "2-digit", |         minute: "2-digit", | ||||||
|       }; |       }; | ||||||
|       const formattedDate = new Date(date).toLocaleString("ru-RU", options); |       const adjustedDate = new Date(date); | ||||||
|  |       adjustedDate.setHours(adjustedDate.getHours() - 3);  | ||||||
|  |      | ||||||
|  |       const formattedDate = adjustedDate.toLocaleString("ru-RU", options); | ||||||
|       return formattedDate.replace(",", ""); |       return formattedDate.replace(",", ""); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -784,12 +827,21 @@ app.get('/reports/:id', async (req, res) => { | |||||||
|       templateData.Date = formatDate(alarm.time); |       templateData.Date = formatDate(alarm.time); | ||||||
|       templateData.Serial = alarm.serial; |       templateData.Serial = alarm.serial; | ||||||
|       templateData.Geo = alarm.latitude + "," + alarm.longitude; |       templateData.Geo = alarm.latitude + "," + alarm.longitude; | ||||||
|  |       templateData.Latitude = alarm.latitude | ||||||
|  |       templateData.Longitude = alarm.longitude | ||||||
|  |  | ||||||
|       templateData.DriverName = alarm.name + " " + alarm.surname; |       templateData.DriverName = alarm.name + " " + alarm.surname; | ||||||
|       templateData.DriverPhone = alarm.phone; |       templateData.DriverPhone = alarm.phone; | ||||||
|       templateData.DriverEmail = alarm.email; |       templateData.DriverEmail = alarm.email; | ||||||
|       templateData.DriverLicense = alarm.card; |       templateData.DriverLicense = alarm.card; | ||||||
|  |  | ||||||
|  |       templateData.PrevLatitude = alarm.prev_latitude;    | ||||||
|  |       templateData.PrevLongitude = alarm.prev_longitude;  | ||||||
|  |       templateData.NextLatitude = alarm.next_latitude;    | ||||||
|  |       templateData.NextLongitude = alarm.next_longitude;  | ||||||
|  |  | ||||||
|  |       templateData.Speeds = alarm.nearest_speeds; | ||||||
|  |        | ||||||
|     console.log(templateData); |     console.log(templateData); | ||||||
|    |    | ||||||
|     const source = fs.readFileSync("static/templates/reports/report.html", "utf8"); |     const source = fs.readFileSync("static/templates/reports/report.html", "utf8"); | ||||||
| @@ -810,7 +862,6 @@ app.get('/reports/:id', async (req, res) => { | |||||||
|     const resultT = template(templateData); |     const resultT = template(templateData); | ||||||
|     res.send(resultT); |     res.send(resultT); | ||||||
|   } |   } | ||||||
|   // res.sendFile(path.join(__dirname, "static/templates/reports/report.html")); |  | ||||||
| }); | }); | ||||||
|  |  | ||||||
| async function devices(req, res) { | async function devices(req, res) { | ||||||
| @@ -890,11 +941,9 @@ app.post("/devicedata", async (req, res) => { | |||||||
|   const client = await pool.connect(); |   const client = await pool.connect(); | ||||||
|  |  | ||||||
|   try { |   try { | ||||||
|     // Выполняем запрос и получаем результат |  | ||||||
|     const query = "SELECT * FROM registrars WHERE id = $1;"; |     const query = "SELECT * FROM registrars WHERE id = $1;"; | ||||||
|     const devicedata = await client.query(query, [id]); |     const devicedata = await client.query(query, [id]); | ||||||
|  |  | ||||||
|     // Формирование и отправка ответа |  | ||||||
|     const response = devicedata.rows[0]; |     const response = devicedata.rows[0]; | ||||||
|     res.json(response); |     res.json(response); | ||||||
|   } finally { |   } finally { | ||||||
| @@ -947,7 +996,7 @@ app.post("/updatedevice", async (req, res) => { | |||||||
|   } = req.body; |   } = req.body; | ||||||
|  |  | ||||||
|   try { |   try { | ||||||
|     // Обновление строки в таблице registrars |  | ||||||
|     const query = ` |     const query = ` | ||||||
|       UPDATE registrars |       UPDATE registrars | ||||||
|       SET |       SET | ||||||
|   | |||||||
| @@ -1627,6 +1627,18 @@ video { | |||||||
|   border-radius: 29px; |   border-radius: 29px; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .marker-name { | ||||||
|  |   width: 100%; | ||||||
|  |   background: white; | ||||||
|  |   border-radius: 5px; | ||||||
|  |   padding-left: 7px; | ||||||
|  |   padding-top: 4px; | ||||||
|  |   padding-bottom: 2px; | ||||||
|  |   margin-left: -40%; | ||||||
|  |   margin-bottom: 3px; | ||||||
|  |   font-weight: bold; | ||||||
|  | } | ||||||
|  |  | ||||||
| .cameras { | .cameras { | ||||||
|   background: #F5F5FA; |   background: #F5F5FA; | ||||||
|   position: absolute; |   position: absolute; | ||||||
|   | |||||||
| @@ -6,11 +6,9 @@ | |||||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0"> |     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||||
|     <title>Трансляция</title> |     <title>Трансляция</title> | ||||||
|     <link rel="stylesheet" href="../styles/main.css" /> |     <link rel="stylesheet" href="../styles/main.css" /> | ||||||
|     <!-- <link href="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.css" rel="stylesheet" /> |  | ||||||
|     <script src="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.js"></script> --> |  | ||||||
|     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ol3/4.6.5/ol.css" type="text/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://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> | </head> | ||||||
| <body> | <body> | ||||||
|  |  | ||||||
| @@ -121,7 +119,7 @@ | |||||||
|  |  | ||||||
|                     <section class="table" style="position: relative;"> |                     <section class="table" style="position: relative;"> | ||||||
|                       <div id="signals-list" class="signals-list"> |                       <div id="signals-list" class="signals-list"> | ||||||
|                         <h1>Сигналы ТС - {{Count}}</h1> |                         <h1>Сигналы ТС</h1> | ||||||
|                         <svg id="left-slider" class="left-slider" xmlns="http://www.w3.org/2000/svg" width="19" height="19" fill="none" viewBox="0 0 11 19"> |                         <svg id="left-slider" class="left-slider" xmlns="http://www.w3.org/2000/svg" width="19" height="19" fill="none" viewBox="0 0 11 19"> | ||||||
|                           <path fill="#000" fill-opacity=".75" d="M0 9.495c0 .273.101.514.315.722l8.92 8.477a.981.981 0 0 0 .73.295c.585 0 1.035-.427 1.035-.995 0-.285-.124-.525-.304-.711L2.508 9.495l8.188-7.789c.18-.186.304-.437.304-.71C11 .425 10.55 0 9.965 0c-.292 0-.54.098-.73.284L.314 8.773A.955.955 0 0 0 0 9.495Z"/> |                           <path fill="#000" fill-opacity=".75" d="M0 9.495c0 .273.101.514.315.722l8.92 8.477a.981.981 0 0 0 .73.295c.585 0 1.035-.427 1.035-.995 0-.285-.124-.525-.304-.711L2.508 9.495l8.188-7.789c.18-.186.304-.437.304-.71C11 .425 10.55 0 9.965 0c-.292 0-.54.098-.73.284L.314 8.773A.955.955 0 0 0 0 9.495Z"/> | ||||||
|                         </svg> |                         </svg> | ||||||
| @@ -199,19 +197,6 @@ | |||||||
|     </section> |     </section> | ||||||
|  |  | ||||||
|     <script src="../scripts/jquery.min.js"></script> |     <script src="../scripts/jquery.min.js"></script> | ||||||
|  |  | ||||||
|     <!-- <script> |  | ||||||
|       var serial; |  | ||||||
|       document.addEventListener("DOMContentLoaded", function () { |  | ||||||
|       const radioInputs = document.querySelectorAll(".radio-input"); |  | ||||||
|  |  | ||||||
|       if (radioInputs.length > 0) { |  | ||||||
|         radioInputs[0].checked = true; |  | ||||||
|       } |  | ||||||
|       serial = $("input[name=camera-serial]:checked").val() |  | ||||||
|       playflv(); |  | ||||||
|     }); |  | ||||||
|     </script> --> |  | ||||||
|     <script src="https://cdnjs.cloudflare.com/ajax/libs/flv.js/1.5.0/flv.min.js"></script> |     <script src="https://cdnjs.cloudflare.com/ajax/libs/flv.js/1.5.0/flv.min.js"></script> | ||||||
|               <script> |               <script> | ||||||
|                 let flvPlayers = []; |                 let flvPlayers = []; | ||||||
| @@ -243,19 +228,8 @@ | |||||||
|                 const baseURL = "http://45.9.42.252:8080/http/live.flv"; |                 const baseURL = "http://45.9.42.252:8080/http/live.flv"; | ||||||
|                 let currentCamera = 2; |                 let currentCamera = 2; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|                  |  | ||||||
|  |  | ||||||
|                 // stopAllCameras(); |  | ||||||
|  |  | ||||||
|                 function playNextCamera(i) { |                 function playNextCamera(i) { | ||||||
|                    console.log(flvPlayers) |                    console.log(flvPlayers) | ||||||
|                     // if (i > cameras) { |  | ||||||
|                     //     return; // Stop when all cameras have been played |  | ||||||
|                     // } |  | ||||||
|  |  | ||||||
|                     // stopAllCameras(); // Stop all previous connections before opening a new one |  | ||||||
|  |  | ||||||
|                     const videoElement = document.getElementById(`camera-${i}`); |                     const videoElement = document.getElementById(`camera-${i}`); | ||||||
|                     const flvPlayer = flvjs.createPlayer({ |                     const flvPlayer = flvjs.createPlayer({ | ||||||
| @@ -273,7 +247,7 @@ | |||||||
|                     flvPlayer.load(); |                     flvPlayer.load(); | ||||||
|                     flvPlayer.play(); |                     flvPlayer.play(); | ||||||
|  |  | ||||||
|                     flvPlayers.push(flvPlayer); // Add the current player to the array |                     flvPlayers.push(flvPlayer);  | ||||||
|  |  | ||||||
|                     setTimeout(() => { |                     setTimeout(() => { | ||||||
|                         playNextCamera(i + 1); |                         playNextCamera(i + 1); | ||||||
| @@ -284,7 +258,6 @@ | |||||||
|             } |             } | ||||||
|  |  | ||||||
|  |  | ||||||
|               // document.addEventListener('DOMContentLoaded', playflv); |  | ||||||
|  |  | ||||||
|               </script> |               </script> | ||||||
|  |  | ||||||
| @@ -344,56 +317,45 @@ | |||||||
|       }); |       }); | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
|     <!-- <script src="../scripts/table-reports.js"></script> --> |  | ||||||
|      |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     <script> |     <script> | ||||||
|  |  | ||||||
|       var checkboxes = document.querySelectorAll('.checkbox-input'); |       var checkboxes = document.querySelectorAll('.checkbox-input'); | ||||||
|       const form = document.getElementById('devices-1'); |       const form = document.getElementById('devices-1'); | ||||||
|  |  | ||||||
|       form.addEventListener('change', () => { |       form.addEventListener('change', () => { | ||||||
|         // const selectedDevices = Array.from(checkboxes) |  | ||||||
|         //   .filter(checkbox => checkbox.checked && checkbox.value !== 'on') |  | ||||||
|         //   .map(checkbox => checkbox.value); |  | ||||||
|  |  | ||||||
|         //   console.log(selectedDevices); |  | ||||||
|  |  | ||||||
|         // fetch('/devices-geo', { |  | ||||||
|         //   method: 'POST', |  | ||||||
|         //   headers: { |  | ||||||
|         //     'Content-Type': 'application/json', |  | ||||||
|         //   }, |  | ||||||
|         //   body: JSON.stringify({ devices: selectedDevices }), |  | ||||||
|         // }) |  | ||||||
|         //   .then(response => response.json()) |  | ||||||
|         //   .then(data => { |  | ||||||
|         //     console.log(data.devicesData); |  | ||||||
|         //     updateMapMarkers(data.devicesData); |  | ||||||
|         //   }) |  | ||||||
|         //   .catch(error => { |  | ||||||
|         //     console.error('Ошибка при отправке запроса:', error); |  | ||||||
|         //   }); |  | ||||||
|         fetchAndShowMarkers(); |         fetchAndShowMarkers(); | ||||||
|       }); |       }); | ||||||
|  |  | ||||||
|     </script> |     </script> | ||||||
|  |  | ||||||
| <script> | <script> | ||||||
|   const map = new ol.Map({ |    | ||||||
|  |   var map = new ol.Map({ | ||||||
|       target: 'map', |       target: 'map', | ||||||
|       layers: [ |       layers: [ | ||||||
|         new ol.layer.Tile({ |         new ol.layer.Tile({ | ||||||
|         source: new ol.source.OSM() // Источник OpenStreetMap |           source: new ol.source.OSM()  | ||||||
|         }) |         }) | ||||||
|       ], |       ], | ||||||
|       view: new ol.View({ |       view: new ol.View({ | ||||||
|       center: ol.proj.fromLonLat([30.282995, 59.855198]), // Преобразование координат в EPSG:3857 |         center: ol.proj.fromLonLat([30.282995, 59.855198]), | ||||||
|         zoom: 10  |         zoom: 10  | ||||||
|       }) |       }) | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|  |     var xhr = new XMLHttpRequest(); | ||||||
|  |     xhr.open("GET", "../scripts/style.json", true); | ||||||
|  |     xhr.onreadystatechange = function () { | ||||||
|  |       if (xhr.readyState === 4 && xhr.status === 200) { | ||||||
|  |         var customStyle = JSON.parse(xhr.responseText); | ||||||
|  |  | ||||||
|  |         map.getLayers().forEach(function(layer) { | ||||||
|  |           layer.setStyle(customStyle.layers[0].paint); | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |     xhr.send(); | ||||||
|  |  | ||||||
|   const markers = []; |   const markers = []; | ||||||
|   {{#if ifDBError}} |   {{#if ifDBError}} | ||||||
| {{else}} | {{else}} | ||||||
| @@ -409,17 +371,19 @@ | |||||||
|     markerElement.className = 'marker'; |     markerElement.className = 'marker'; | ||||||
|     if (serial === $("input[name=camera-serial]:checked").val()) { |     if (serial === $("input[name=camera-serial]:checked").val()) { | ||||||
|       markerElement.innerHTML = ` |       markerElement.innerHTML = ` | ||||||
|  |       <div class="marker-name active-${status}">${serial}</div> | ||||||
|     <svg class="active-${status}" id="marker-${serial}" style="transform: rotate(${direction}deg)" xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26" fill="none"> |     <svg class="active-${status}" id="marker-${serial}" style="transform: rotate(${direction}deg)" xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26" fill="none"> | ||||||
|       <path fill="#FF6A4B" d="M12.669 24.673c6.565 0 12-5.435 12-12 0-6.553-5.447-12-12.012-12C6.104.673.67 6.12.67 12.673c0 6.565 5.447 12 12 12Z"/> |       <path fill="#FF6A4B" d="M12.669 24.673c6.565 0 12-5.435 12-12 0-6.553-5.447-12-12.012-12C6.104.673.67 6.12.67 12.673c0 6.565 5.447 12 12 12Z"/> | ||||||
|       <path fill="#fff" fill-opacity=".85" d="m7.104 17.92 4.683-11.93c.33-.823 1.423-.846 1.753-.023l4.682 11.953c.318.788-.553 1.47-1.294.73l-3.953-3.953c-.188-.2-.424-.2-.612 0L8.41 18.65c-.753.74-1.623.059-1.306-.73Z"/> |       <path fill="#fff" fill-opacity=".85" d="m7.104 17.92 4.683-11.93c.33-.823 1.423-.846 1.753-.023l4.682 11.953c.318.788-.553 1.47-1.294.73l-3.953-3.953c-.188-.2-.424-.2-.612 0L8.41 18.65c-.753.74-1.623.059-1.306-.73Z"/> | ||||||
| </svg><br><span class="speed active-${status}">${speed} км/ч</span> | </svg> | ||||||
|     `; |     `; | ||||||
|     } else { |     } else { | ||||||
|     markerElement.innerHTML = ` |     markerElement.innerHTML = ` | ||||||
|  |     <div class="marker-name active-${status}">${serial}</div> | ||||||
|     <svg class="active-${status}" id="marker-${serial}" style="transform: rotate(${direction}deg)" xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26" fill="none"> |     <svg class="active-${status}" id="marker-${serial}" style="transform: rotate(${direction}deg)" xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26" fill="none"> | ||||||
|   <path d="M12.9815 25.0195C19.5462 25.0336 24.9931 19.6101 25.0073 13.0454C25.0214 6.49253 19.5861 1.03375 13.0214 1.01961C6.46848 1.00549 1.02147 6.44081 1.00735 12.9937C0.993201 19.5584 6.42852 25.0054 12.9815 25.0195Z" fill="#8086F9"/> |   <path d="M12.9815 25.0195C19.5462 25.0336 24.9931 19.6101 25.0073 13.0454C25.0214 6.49253 19.5861 1.03375 13.0214 1.01961C6.46848 1.00549 1.02147 6.44081 1.00735 12.9937C0.993201 19.5584 6.42852 25.0054 12.9815 25.0195Z" fill="#8086F9"/> | ||||||
|   <path d="M7.43175 18.2547L12.1398 6.33536C12.471 5.51254 13.5652 5.49137 13.8928 6.31561L18.5493 18.2786C18.8653 19.0675 17.9932 19.748 17.2537 19.0052L13.3092 15.0438C13.1215 14.8434 12.8862 14.8429 12.6975 15.0425L8.73605 18.9868C7.98152 19.7264 7.1124 19.0422 7.43175 18.2547Z" fill="white" fill-opacity="0.85"/> |   <path d="M7.43175 18.2547L12.1398 6.33536C12.471 5.51254 13.5652 5.49137 13.8928 6.31561L18.5493 18.2786C18.8653 19.0675 17.9932 19.748 17.2537 19.0052L13.3092 15.0438C13.1215 14.8434 12.8862 14.8429 12.6975 15.0425L8.73605 18.9868C7.98152 19.7264 7.1124 19.0422 7.43175 18.2547Z" fill="white" fill-opacity="0.85"/> | ||||||
| </svg><br><span class="speed active-${status}">${speed} км/ч</span> | </svg> | ||||||
|     `; |     `; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -471,135 +435,6 @@ | |||||||
| </script> | </script> | ||||||
|  |  | ||||||
|  |  | ||||||
|     <!-- <script> |  | ||||||
|       mapboxgl.accessToken = 'pk.eyJ1IjoicHBlY2hlbmtvbyIsImEiOiJjbGs3Y3dkc3AwNmN1M2dudzRtd3gwNjl4In0.oEFhSBTsaiyBx1uOqHdrZQ'; |  | ||||||
| const map = new mapboxgl.Map({ |  | ||||||
|   container: 'map', |  | ||||||
|   style: 'mapbox://styles/ppechenkoo/clkwfa6wu00ck01qgcrm93msr', |  | ||||||
|   center: [30.282995, 59.855198], // Задайте начальные координаты карты |  | ||||||
|   zoom: 10, // Задайте начальный уровень масштабирования карты |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| // Хранение текущих маркеров на карте |  | ||||||
| const markers = []; |  | ||||||
| {{#if ifDBError}} |  | ||||||
| {{else}} |  | ||||||
|  |  | ||||||
|  |  | ||||||
| const selectedDevices = Array.from(checkboxes) |  | ||||||
|           .filter(checkbox => checkbox.checked && checkbox.value !== 'on') |  | ||||||
|           .map(checkbox => checkbox.value); |  | ||||||
|  |  | ||||||
|           console.log(selectedDevices); |  | ||||||
|  |  | ||||||
|         fetch('/devices-geo', { |  | ||||||
|           method: 'POST', |  | ||||||
|           headers: { |  | ||||||
|             'Content-Type': 'application/json', |  | ||||||
|           }, |  | ||||||
|           body: JSON.stringify({ devices: selectedDevices }), |  | ||||||
|         }) |  | ||||||
|           .then(response => response.json()) |  | ||||||
|           .then(data => { |  | ||||||
|             console.log(data.devicesData); |  | ||||||
|             data.devicesData.forEach(device => { |  | ||||||
|     const { serial, status, longitude, latitude, direction, speed } = device; |  | ||||||
|     var newDirection = direction + 90 |  | ||||||
|     console.log(newDirection); |  | ||||||
|      |  | ||||||
|     // Создание HTML-элемента для маркера |  | ||||||
|     const el = document.createElement('div'); |  | ||||||
|     el.className = 'marker'; |  | ||||||
|     // el.style.transform = `rotate(${direction / 100}deg)`; |  | ||||||
|     el.innerHTML = `<svg class="active-${status}" id="marker-${serial}" style="transform: rotate(${direction}deg)" xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26" fill="none"> |  | ||||||
|   <path d="M12.9815 25.0195C19.5462 25.0336 24.9931 19.6101 25.0073 13.0454C25.0214 6.49253 19.5861 1.03375 13.0214 1.01961C6.46848 1.00549 1.02147 6.44081 1.00735 12.9937C0.993201 19.5584 6.42852 25.0054 12.9815 25.0195Z" fill="#8086F9"/> |  | ||||||
|   <path d="M7.43175 18.2547L12.1398 6.33536C12.471 5.51254 13.5652 5.49137 13.8928 6.31561L18.5493 18.2786C18.8653 19.0675 17.9932 19.748 17.2537 19.0052L13.3092 15.0438C13.1215 14.8434 12.8862 14.8429 12.6975 15.0425L8.73605 18.9868C7.98152 19.7264 7.1124 19.0422 7.43175 18.2547Z" fill="white" fill-opacity="0.85"/> |  | ||||||
| </svg><br><span class="speed active-${status}">${speed} км/ч</span>`; |  | ||||||
|  |  | ||||||
|     // Создание нового маркера на карте |  | ||||||
|     const marker = new mapboxgl.Marker(el) |  | ||||||
|       .setLngLat([longitude, latitude]) |  | ||||||
|       .addTo(map); |  | ||||||
|  |  | ||||||
|     // Добавление маркера в массив markers |  | ||||||
|     markers.push(marker); |  | ||||||
|   }); |  | ||||||
|           }) |  | ||||||
|           .catch(error => { |  | ||||||
|             console.error('Ошибка при отправке запроса:', error); |  | ||||||
|           }); |  | ||||||
|  |  | ||||||
| // Функция для обновления маркеров на карте |  | ||||||
| function updateMapMarkers(devicesData) { |  | ||||||
|   // Очистка существующих маркеров на карте |  | ||||||
|   markers.forEach(marker => marker.remove()); |  | ||||||
|   markers.length = 0; |  | ||||||
|  |  | ||||||
|   // Создание новых маркеров на карте на основе полученных данных |  | ||||||
|   devicesData.forEach(device => { |  | ||||||
|     const { serial, status, longitude, latitude, direction, speed } = device; |  | ||||||
|     var newDirection = direction + 90 |  | ||||||
|     console.log(newDirection); |  | ||||||
|      |  | ||||||
|     // Создание HTML-элемента для маркера |  | ||||||
|     const el = document.createElement('div'); |  | ||||||
|     el.className = 'marker'; |  | ||||||
|     // el.style.transform = `rotate(${direction}deg)`; |  | ||||||
|     el.innerHTML = `<svg class="active-${status}" id="marker-${serial}" style="transform: rotate(${direction}deg)" xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26" fill="none"> |  | ||||||
|   <path d="M12.9815 25.0195C19.5462 25.0336 24.9931 19.6101 25.0073 13.0454C25.0214 6.49253 19.5861 1.03375 13.0214 1.01961C6.46848 1.00549 1.02147 6.44081 1.00735 12.9937C0.993201 19.5584 6.42852 25.0054 12.9815 25.0195Z" fill="#8086F9"/> |  | ||||||
|   <path d="M7.43175 18.2547L12.1398 6.33536C12.471 5.51254 13.5652 5.49137 13.8928 6.31561L18.5493 18.2786C18.8653 19.0675 17.9932 19.748 17.2537 19.0052L13.3092 15.0438C13.1215 14.8434 12.8862 14.8429 12.6975 15.0425L8.73605 18.9868C7.98152 19.7264 7.1124 19.0422 7.43175 18.2547Z" fill="white" fill-opacity="0.85"/> |  | ||||||
| </svg><br><span class="speed active-${status}">${speed} км/ч</span>`; |  | ||||||
|  |  | ||||||
|     // Создание нового маркера на карте |  | ||||||
|     const marker = new mapboxgl.Marker(el) |  | ||||||
|       .setLngLat([longitude, latitude]) |  | ||||||
|       .addTo(map); |  | ||||||
|  |  | ||||||
|     // Добавление маркера в массив markers |  | ||||||
|     markers.push(marker); |  | ||||||
|   }); |  | ||||||
|   serial = $("input[name=camera-serial]:checked").val() |  | ||||||
|  |  | ||||||
|                     var svgId = "marker-" + serial; |  | ||||||
|                     var svgElement = document.getElementById(svgId); |  | ||||||
|                     if (svgElement) { |  | ||||||
|                       svgElement.innerHTML = ` |  | ||||||
|                         <path fill="#FF6A4B" d="M12.669 24.673c6.565 0 12-5.435 12-12 0-6.553-5.447-12-12.012-12C6.104.673.67 6.12.67 12.673c0 6.565 5.447 12 12 12Z"/> |  | ||||||
|                         <path fill="#fff" fill-opacity=".85" d="m7.104 17.92 4.683-11.93c.33-.823 1.423-.846 1.753-.023l4.682 11.953c.318.788-.553 1.47-1.294.73l-3.953-3.953c-.188-.2-.424-.2-.612 0L8.41 18.65c-.753.74-1.623.059-1.306-.73Z"/> |  | ||||||
|                       `; |  | ||||||
|                     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| setInterval(() => { |  | ||||||
|   fetch('/devices-geo', { |  | ||||||
|           method: 'POST', |  | ||||||
|           headers: { |  | ||||||
|             'Content-Type': 'application/json', |  | ||||||
|           }, |  | ||||||
|           body: JSON.stringify({ devices: selectedDevices }), |  | ||||||
|         }) |  | ||||||
|           .then(response => response.json()) |  | ||||||
|           .then(data => { |  | ||||||
|             console.log(data.devicesData); |  | ||||||
|             updateMapMarkers(data.devicesData); |  | ||||||
|           }) |  | ||||||
|           .catch(error => { |  | ||||||
|             console.error('Ошибка при отправке запроса:', error); |  | ||||||
|           }); |  | ||||||
| }, 12000); |  | ||||||
| {{/if}} |  | ||||||
|     </script> --> |  | ||||||
|  |  | ||||||
|     <!-- <script> |  | ||||||
|       const panel = document.getElementById('signals-list'); |  | ||||||
|       const slider = document.getElementById('left-slider'); |  | ||||||
|  |  | ||||||
|       slider.addEventListener('click', () => { |  | ||||||
|         panel.classList.toggle('hide'); |  | ||||||
|       }); |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   </script> --> |  | ||||||
|      |      | ||||||
|     <script> |     <script> | ||||||
|         // Скрытие/Показ дополнительных меню аккаунта |         // Скрытие/Показ дополнительных меню аккаунта | ||||||
|   | |||||||
| @@ -4,10 +4,11 @@ | |||||||
|     <meta charset="UTF-8"> |     <meta charset="UTF-8"> | ||||||
|     <meta http-equiv="X-UA-Compatible" content="IE=edge"> |     <meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0"> |     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||||
|     <title>Отчёты</title> |     <title>Отчёт {{Id}}</title> | ||||||
|     <link rel="stylesheet" href="../styles/main.css" /> |     <link rel="stylesheet" href="../styles/main.css" /> | ||||||
|     <link href="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.css" rel="stylesheet" /> |     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ol3/4.6.5/ol.css" type="text/css"> | ||||||
|     <script src="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.js"></script> |   <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> | </head> | ||||||
| <body> | <body> | ||||||
|  |  | ||||||
| @@ -83,7 +84,7 @@ | |||||||
|  |  | ||||||
|                 <section class="for-table"> |                 <section class="for-table"> | ||||||
|  |  | ||||||
|                     <section class="report"> |                     <section class="report" style="position: relative;"> | ||||||
|                       <div class="report-top"> |                       <div class="report-top"> | ||||||
|                         <h1>Список предупреждений</h1> |                         <h1>Список предупреждений</h1> | ||||||
|                         <div class="export"> |                         <div class="export"> | ||||||
| @@ -120,7 +121,7 @@ | |||||||
|                       </div> |                       </div> | ||||||
|  |  | ||||||
|  |  | ||||||
|                       <div class="driver-info"> |                       <!-- <div class="driver-info"> | ||||||
|                         <ul> |                         <ul> | ||||||
|                           <li><svg xmlns="http://www.w3.org/2000/svg" width="23" height="23" fill="none" viewBox="0 0 22 23"> |                           <li><svg xmlns="http://www.w3.org/2000/svg" width="23" height="23" fill="none" viewBox="0 0 22 23"> | ||||||
|                             <path fill="#000" fill-opacity=".75" d="M2.99 23h15.337c2.025 0 2.99-.61 2.99-1.952 0-3.197-4.04-7.821-10.653-7.821C4.04 13.226 0 17.85 0 21.047 0 22.39.964 23 2.99 23Zm-.574-1.842c-.317 0-.452-.086-.452-.342 0-2.001 3.1-5.747 8.7-5.747 5.589 0 8.688 3.746 8.688 5.747 0 .256-.122.342-.44.342H2.416Zm8.248-9.444c2.904 0 5.271-2.587 5.271-5.735 0-3.124-2.355-5.576-5.27-5.576-2.893 0-5.272 2.501-5.272 5.6.012 3.136 2.367 5.71 5.271 5.71Zm0-1.843c-1.781 0-3.306-1.708-3.306-3.868 0-2.123 1.5-3.758 3.306-3.758 1.818 0 3.307 1.61 3.307 3.734 0 2.16-1.513 3.892-3.307 3.892Z"/> |                             <path fill="#000" fill-opacity=".75" d="M2.99 23h15.337c2.025 0 2.99-.61 2.99-1.952 0-3.197-4.04-7.821-10.653-7.821C4.04 13.226 0 17.85 0 21.047 0 22.39.964 23 2.99 23Zm-.574-1.842c-.317 0-.452-.086-.452-.342 0-2.001 3.1-5.747 8.7-5.747 5.589 0 8.688 3.746 8.688 5.747 0 .256-.122.342-.44.342H2.416Zm8.248-9.444c2.904 0 5.271-2.587 5.271-5.735 0-3.124-2.355-5.576-5.27-5.576-2.893 0-5.272 2.501-5.272 5.6.012 3.136 2.367 5.71 5.271 5.71Zm0-1.843c-1.781 0-3.306-1.708-3.306-3.868 0-2.123 1.5-3.758 3.306-3.758 1.818 0 3.307 1.61 3.307 3.734 0 2.16-1.513 3.892-3.307 3.892Z"/> | ||||||
| @@ -135,7 +136,7 @@ | |||||||
|                             <path fill="#000" fill-opacity=".75" d="M4.633 5.91h6.292c.38 0 .682-.311.682-.692a.67.67 0 0 0-.682-.673H4.633a.656.656 0 0 0-.673.673c0 .38.283.693.673.693Zm0 2.605h4.604c.38 0 .683-.302.683-.683a.679.679 0 0 0-.683-.682H4.633a.664.664 0 0 0-.673.682c0 .38.283.683.673.683Zm12.076.264a2.333 2.333 0 0 0 2.33-2.341 2.333 2.333 0 0 0-2.33-2.341 2.342 2.342 0 0 0 0 4.682ZM3.063 17.957h16.874c2.049 0 3.063-1.004 3.063-3.014V3.023C23 1.015 21.986 0 19.937 0H3.063C1.024 0 0 1.014 0 3.024v11.92c0 2.009 1.024 3.013 3.063 3.013Zm.02-1.57c-.976 0-1.513-.517-1.513-1.532V3.112c0-1.015.537-1.542 1.512-1.542h16.836c.965 0 1.512.527 1.512 1.542v11.743c0 1.015-.547 1.532-1.512 1.532H3.082Z"/> |                             <path fill="#000" fill-opacity=".75" d="M4.633 5.91h6.292c.38 0 .682-.311.682-.692a.67.67 0 0 0-.682-.673H4.633a.656.656 0 0 0-.673.673c0 .38.283.693.673.693Zm0 2.605h4.604c.38 0 .683-.302.683-.683a.679.679 0 0 0-.683-.682H4.633a.664.664 0 0 0-.673.682c0 .38.283.683.673.683Zm12.076.264a2.333 2.333 0 0 0 2.33-2.341 2.333 2.333 0 0 0-2.33-2.341 2.342 2.342 0 0 0 0 4.682ZM3.063 17.957h16.874c2.049 0 3.063-1.004 3.063-3.014V3.023C23 1.015 21.986 0 19.937 0H3.063C1.024 0 0 1.014 0 3.024v11.92c0 2.009 1.024 3.013 3.063 3.013Zm.02-1.57c-.976 0-1.513-.517-1.513-1.532V3.112c0-1.015.537-1.542 1.512-1.542h16.836c.965 0 1.512.527 1.512 1.542v11.743c0 1.015-.547 1.532-1.512 1.532H3.082Z"/> | ||||||
|                           </svg>{{DriverLicense}}</li> |                           </svg>{{DriverLicense}}</li> | ||||||
|                         </ul> |                         </ul> | ||||||
|                       </div> |                       </div> --> | ||||||
|  |  | ||||||
|                       <div class="speedometr"> |                       <div class="speedometr"> | ||||||
|                         <h1>Скорость</h1> |                         <h1>Скорость</h1> | ||||||
| @@ -174,40 +175,119 @@ | |||||||
|  |  | ||||||
|   <style> |   <style> | ||||||
|     .map { |     .map { | ||||||
|       height: 100%; |  | ||||||
|       width: calc(100% - 450px - 514px); |       width: calc(100% - 450px - 514px); | ||||||
|       display: inline-block; |  | ||||||
|       float: right; |       float: right; | ||||||
|       border-radius: 0 10px 10px 0 !important; |  | ||||||
|     } |     } | ||||||
|   </style> |   </style> | ||||||
|  |  | ||||||
|  |  | ||||||
|   <script> |   <script> | ||||||
|     mapboxgl.accessToken = 'pk.eyJ1IjoicHBlY2hlbmtvbyIsImEiOiJjbGs3Y3dkc3AwNmN1M2dudzRtd3gwNjl4In0.oEFhSBTsaiyBx1uOqHdrZQ'; |  | ||||||
|     const map = new mapboxgl.Map({ | var prevLongitude = {{PrevLongitude}}; | ||||||
|       container: 'map', | var prevLatitude = {{PrevLatitude}}; | ||||||
|       style: 'mapbox://styles/ppechenkoo/clkwfa6wu00ck01qgcrm93msr', | var nextLongitude = {{NextLongitude}}; | ||||||
|       center: [30.282995, 59.855198], // Задайте начальные координаты карты | var nextLatitude = {{NextLatitude}}; | ||||||
|       zoom: 10, // Задайте начальный уровень масштабирования карты |  | ||||||
|  | var startPoint = ol.proj.fromLonLat([prevLongitude, prevLatitude]);    | ||||||
|  | var endPoint = ol.proj.fromLonLat([nextLongitude, nextLatitude]);      | ||||||
|  |  | ||||||
|  | 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([prevLongitude, prevLatitude]),  | ||||||
|  |         zoom: 17  | ||||||
|  |     }) | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | // Скрыть кнопки приближения/отдаления | ||||||
|  | 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> | ||||||
|  |  | ||||||
| <script> | <script> | ||||||
|   window.addEventListener('DOMContentLoaded', function() { |  | ||||||
|  |   function sizeMap() { | ||||||
|     var mapContainer = document.querySelector('.map'); |     var mapContainer = document.querySelector('.map'); | ||||||
|     var mapArea = document.getElementById('map'); |     var mapArea = document.getElementById('map'); | ||||||
|  |  | ||||||
|     mapArea.style.height = (mapContainer.clientHeight) + 'px'; |     mapArea.style.height = (mapContainer.clientHeight) + 'px'; | ||||||
|     mapArea.style.width = (mapContainer.clientWidth) + 'px'; |     mapArea.style.width = (mapContainer.clientWidth) + 'px'; | ||||||
|   }); |   } | ||||||
|  |  | ||||||
|  |   // window.addEventListener('DOMContentLoaded', function() { | ||||||
|  |   //   sizeMap(); | ||||||
|  |   // }); | ||||||
|  |  | ||||||
|   window.addEventListener("resize", function (event) { |   window.addEventListener("resize", function (event) { | ||||||
|         var mapContainer = document.querySelector('.map'); |     sizeMap(); | ||||||
|         var mapArea = document.getElementById('map'); |  | ||||||
|  |  | ||||||
|         mapArea.style.height = (mapContainer.clientHeight) + 'px'; |  | ||||||
|         mapArea.style.width = (mapContainer.clientWidth) + 'px'; |  | ||||||
|   }); |   }); | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| @@ -332,12 +412,12 @@ Chart.defaults.font.weight = 400; | |||||||
|       borderColor: "#8086F9", |       borderColor: "#8086F9", | ||||||
|       fill: false, |       fill: false, | ||||||
|       data: [ |       data: [ | ||||||
|         17, 21, 40, 30, 43, 38, 40, 21, 24, 28, 26, |         {{Speeds}} | ||||||
|       ], |       ], | ||||||
|       pointStyle: false, |       pointStyle: false, | ||||||
|       pointRadius: 25, |       pointRadius: 25, | ||||||
|       pointHoverRadius: 25, |       pointHoverRadius: 25, | ||||||
|       tension: 0.4, |       tension: 0.1, | ||||||
|     }, |     }, | ||||||
|   ], |   ], | ||||||
| }; | }; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user