339 lines
14 KiB
JavaScript
Executable File
339 lines
14 KiB
JavaScript
Executable File
import { Equipment } from "./EquipmentClass.js";
|
|
import { paintIt } from "./Helpers.js";
|
|
import * as mapLayers from "./Map.js";
|
|
var exercises = {};
|
|
var participantBaseData = {};
|
|
var partyBaseData = {};
|
|
var parties = {}; //Ersatzobjekt statt 'equipments'-Map
|
|
|
|
popup();
|
|
|
|
document.getElementById('connectStaticBtn').addEventListener ('click', webSocketConnectStatic);
|
|
|
|
document.getElementById('connectDynamicBtn').addEventListener ('click', webSocketConnectDynamic);
|
|
|
|
// Map
|
|
var map = L.map('content-map', {
|
|
layers: [mapLayers.OpenStreetMap_Mapnik], // only add one!
|
|
zoomControl: false
|
|
})
|
|
.setView([53.055311, 8.896582], 16);
|
|
|
|
var baseLayers = {
|
|
"Gelände": mapLayers.OpenStreetMap_Mapnik,
|
|
"Sattelit": mapLayers.Esri_WorldImagery
|
|
};
|
|
|
|
var overlays = {
|
|
"Katar": mapLayers.KatarGeoJSON
|
|
}
|
|
|
|
L.control.layers(baseLayers, overlays).addTo(map);
|
|
|
|
L.control.zoom({position: 'bottomright'}).addTo(map);
|
|
|
|
// WebSocket Static Port
|
|
function webSocketConnectStatic() {
|
|
var ws = new WebSocket (document.getElementById('connectInput').value);
|
|
ws.onopen = function () {
|
|
document.getElementById('connectStaticBtn').classList.replace("btn-outline-danger", "btn-outline-success")
|
|
servicePortsInformationRequest(ws);
|
|
}
|
|
|
|
ws.onmessage = function(msg) {
|
|
var object = (JSON.parse(msg.data)).data;
|
|
object.forEach((item, index, array) => {
|
|
if (item.exerciseId != 0) {
|
|
exercises[item.exerciseId] = item;
|
|
document.getElementById('exerciseSelect').innerHTML += `<option value=${item.exerciseId}>Exercise ${item.exerciseId}</option>`
|
|
}
|
|
})
|
|
|
|
document.getElementById('exerciseSelect').disabled = false;
|
|
document.getElementById('connectDynamicBtn').disabled = false;
|
|
}
|
|
|
|
ws.onclose = function() {
|
|
document.getElementById('connectStaticBtn').classList.replace("btn-outline-success", "btn-outline-danger")
|
|
}
|
|
}
|
|
|
|
// WebSocket Dynamic Port
|
|
function webSocketConnectDynamic() {
|
|
var exerciseId = parseInt(document.getElementById("exerciseSelect").value);
|
|
var dynamicPort1 = exercises[exerciseId].services[0].ports[1].number; //Objekt-Pfad zum dynamischen Port, der Teilnehmerinfos enthaelt.
|
|
var dynamicPort2 = exercises[exerciseId].services[0].ports[0].number; //Objekt-Pfad zum dynamischen Port, der Positionsdaten empfaengt.
|
|
var wsPort2 = new WebSocket (`ws://localhost:${dynamicPort2}`);
|
|
// Positionsdaten empfangen (PortId 2)
|
|
wsPort2.onopen = function () {
|
|
document.getElementById('connectDynamicBtn').classList.replace("btn-outline-danger", "btn-outline-success")
|
|
window.setTimeout(popdown, 1000);
|
|
}
|
|
|
|
wsPort2.onmessage = function(msg) {
|
|
processEquipment(msg);
|
|
}
|
|
|
|
wsPort2.onclose = function() {
|
|
document.getElementById('connectDynamicBtn').classList.replace("btn-outline-success", "btn-outline-danger")
|
|
}
|
|
|
|
// einmalig Participant-Informationen abfragen (PortId 1)
|
|
var wsPort1 = new WebSocket (`ws://localhost:${dynamicPort1}`);
|
|
wsPort1.onopen = function () {
|
|
BaseDlRequest(wsPort1);
|
|
}
|
|
|
|
wsPort1.onmessage = function (msg) {
|
|
if (JSON.parse(msg.data).type == "partyBaseData") {
|
|
JSON.parse(msg.data).data.forEach (partyInfo => {
|
|
partyBaseData[partyInfo.id] = partyInfo; //Objekt
|
|
})
|
|
}
|
|
|
|
if (JSON.parse(msg.data).type == "participantBaseData") {
|
|
JSON.parse(msg.data).data.forEach (participantInfo => {
|
|
if (!participantInfo.equipmentNumber == 0) { //unsausgesattete Teilnehmer (= EquipNr 0) ignorieren
|
|
participantBaseData[participantInfo.equipmentNumber] = participantInfo;
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Equipment-Informationen verarbeiten aus Positionsmeldung durch WebSocket*/
|
|
|
|
function processEquipment(msg) {
|
|
var equipmentNumber = JSON.parse(msg.data).equipmentNumber;
|
|
var height = JSON.parse(msg.data).height;
|
|
var lat = JSON.parse(msg.data).lat;
|
|
var lon = JSON.parse(msg.data).lon;
|
|
var participantId = JSON.parse(msg.data).participantId;
|
|
var partyId = participantBaseData[equipmentNumber].partyId;
|
|
var eq = null;
|
|
|
|
//PartyId anzeigen: Accordion und LayerGroup
|
|
if (!parties.hasOwnProperty(partyId)) {
|
|
var partyName = partyBaseData[partyId].name;
|
|
var partyColor = paintIt(partyBaseData[partyId].color);
|
|
var partyContainer = document.getElementById('accordionParty');
|
|
var partyDiv = document.createElement('div');
|
|
partyDiv.id = `item-${partyId}`
|
|
partyDiv.classList.add('border-bottom')
|
|
partyDiv.innerHTML = `<h2 class="accordion-header" id="heading${equipmentNumber}">
|
|
<button id="button-${partyId}" class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapse${equipmentNumber}" aria-expanded="true" aria-controls="collapse${equipmentNumber}">
|
|
${partyName}
|
|
</button>
|
|
<a id="hide-party-${partyId}" class="hide-party" href="#" data-bs-toggle="collapse">
|
|
<img id = "party-icon-${partyId}" src="./res/eye.svg">
|
|
</a>
|
|
</h2>
|
|
<div id="collapse${equipmentNumber}" class="accordion-collapse collapse show" aria-labelledby="heading${equipmentNumber}">
|
|
<div id="accordion-body-${partyId}" class="accordion-body p-0">
|
|
<table class="table table-hover table-condensed">
|
|
<tbody id="table-${partyId}">
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>`
|
|
partyContainer.appendChild(partyDiv);
|
|
document.getElementById(`button-${partyId}`).style.color = partyColor
|
|
|
|
parties[partyId] = {
|
|
equipments: {},
|
|
layerGroup: L.layerGroup(),
|
|
partyName: partyName,
|
|
partyColor: partyColor,
|
|
tracked: true,
|
|
visible: true,
|
|
followedEquipment: null
|
|
}
|
|
|
|
// Show / Hide Party
|
|
document.getElementById(`hide-party-${partyId}`).addEventListener('click', () => {
|
|
|
|
if (!parties[partyId].visible) {
|
|
for (var key in parties[partyId].equipments) {
|
|
if (!parties[partyId].equipments[key].visible) {
|
|
parties[partyId].equipments[key].toggleMarkerVisibility(map)
|
|
}
|
|
}
|
|
parties[partyId].visible = true;
|
|
document.getElementById(`party-icon-${partyId}`).src = `./res/eye.svg`;
|
|
}
|
|
else {
|
|
for (var key in parties[partyId].equipments) {
|
|
if (parties[partyId].equipments[key].visible) {
|
|
parties[partyId].equipments[key].toggleMarkerVisibility(map);
|
|
}
|
|
}
|
|
parties[partyId].visible = false;
|
|
document.getElementById(`party-icon-${partyId}`).src = `./res/eye-slash.svg`;
|
|
}
|
|
});
|
|
}
|
|
|
|
//Equipment-Instanz im Party-Objekt anlegen
|
|
if (!parties[partyId].equipments.hasOwnProperty(equipmentNumber)) {
|
|
|
|
parties[partyId].equipments[equipmentNumber] = new Equipment(equipmentNumber, height, lat, lon, participantId);
|
|
parties[partyId].equipments[equipmentNumber].setPartyId(partyId);
|
|
parties[partyId].equipments[equipmentNumber].setDesignator(participantBaseData[equipmentNumber].designator);
|
|
parties[partyId].equipments[equipmentNumber].setTatcicalIdentifier(participantBaseData[equipmentNumber].tacticalIdentifier);
|
|
parties[partyId].equipments[equipmentNumber].setPartyColor(parties[partyId].partyColor);
|
|
}
|
|
//Equipment-Position aktualisieren
|
|
else {
|
|
parties[partyId].equipments[equipmentNumber].updatePosition(height, lat, lon);
|
|
if (parties.followedEquipment == equipmentNumber) {
|
|
parties[partyId].equipments[equipmentNumber].followMarker(map);
|
|
}
|
|
}
|
|
|
|
eq = parties[partyId].equipments[equipmentNumber];
|
|
|
|
|
|
//Equipment anzeigen: Accordion-Item und Marker (sortiert einfuegen)
|
|
if (!eq.tracked) {
|
|
var equipmentTable = document.getElementById(`table-${eq.getPartyId()}`)
|
|
var equipmentRow = document.createElement('tr');
|
|
equipmentRow.id = `${eq.equipmentNr}`; //ID ist EquipmentNr
|
|
var equipmentNrCell = document.createElement('td');
|
|
equipmentNrCell.style.paddingLeft = "1.25rem";
|
|
equipmentNrCell.innerHTML = `<a id ="focus-${eq.equipmentNr}" href = "#">${eq.equipmentNr}</a>`
|
|
var participantIdCell = document.createElement('td');
|
|
participantIdCell.innerHTML = `Participant ${eq.participantId}`;
|
|
var followCell = document.createElement('td');
|
|
followCell.style = "text-align:right";
|
|
followCell.style.width = "50px";
|
|
followCell.innerHTML = `<a id ="follow-${eq.equipmentNr}" href = "#"><img id="follow-icon-${eq.equipmentNr}" src="./res/crosshair_light.svg"></a>`;
|
|
var hideCell = document.createElement('td');
|
|
hideCell.style = "text-align:right";
|
|
hideCell.style.width = "50px";
|
|
hideCell.style.paddingRight = "1.25rem";
|
|
hideCell.innerHTML = `<a id ="visibility-${eq.equipmentNr}" href = "#"><img id="icon-${eq.equipmentNr}" src="./res/eye.svg"></a>`;
|
|
|
|
equipmentRow.append(equipmentNrCell);
|
|
equipmentRow.append(participantIdCell);
|
|
equipmentRow.append(followCell);
|
|
equipmentRow.append(hideCell);
|
|
|
|
breakme: if (equipmentTable.children.length > 0){ // Nach EquipmentID in Liste einsortieren
|
|
var children = equipmentTable.children;
|
|
for(var i=0; i<children.length; i++){
|
|
if (children[i].id > eq.equipmentNr) {
|
|
equipmentTable.insertBefore(equipmentRow,children[i]);
|
|
break breakme;
|
|
}
|
|
else {
|
|
equipmentTable.append(equipmentRow);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
equipmentTable.append(equipmentRow);
|
|
}
|
|
|
|
// Show / Hide
|
|
document.getElementById(`visibility-${eq.equipmentNr}`).addEventListener('click', () => {
|
|
eq.toggleMarkerVisibility(map);
|
|
var allHidden = true
|
|
for (var key in parties[partyId].equipments) {
|
|
if (parties[partyId].equipments[key].visible){
|
|
allHidden = false;
|
|
}
|
|
}
|
|
if (allHidden) {
|
|
parties[partyId].visible = false;
|
|
document.getElementById(`party-icon-${partyId}`).src = `./res/eye-slash.svg`;
|
|
}
|
|
else {
|
|
parties[partyId].visible = true;
|
|
document.getElementById(`party-icon-${partyId}`).src = `./res/eye.svg`;
|
|
}
|
|
});
|
|
|
|
// Pan to
|
|
document.getElementById(`focus-${eq.equipmentNr}`).addEventListener('click', () => {
|
|
eq.focusMarker(map);
|
|
parties[partyId].visible = true;
|
|
document.getElementById(`party-icon-${partyId}`).src = `./res/eye.svg`;
|
|
});
|
|
|
|
// Follow
|
|
document.getElementById(`follow-${eq.equipmentNr}`).addEventListener('click', () => {
|
|
if (parties.followedEquipment != eq.equipmentNr) {
|
|
if (!parties.followedEquipment == 0) {
|
|
document.getElementById(`follow-icon-${parties.followedEquipment}`).src = `./res/crosshair_light.svg`;
|
|
}
|
|
parties[partyId].visible = true;
|
|
document.getElementById(`party-icon-${partyId}`).src = `./res/eye.svg`;
|
|
parties.followedEquipment = equipmentNumber;
|
|
eq.focusMarker(map);
|
|
document.getElementById(`svgIcon-${eq.equipmentNr}`).style.strokeWidth = 3;
|
|
document.getElementById(`follow-icon-${eq.equipmentNr}`).src = `./res/crosshair_dark.svg`;
|
|
document.getElementById('infoOverlay').hidden = false;
|
|
document.getElementById('infoOverlay').innerHTML = "Equipment <b>" + eq.equipmentNr + "</b> Lat: " + eq.getLatDeg().toFixed(5) + " Lon: " + eq.getLonDeg().toFixed(5) + " Height: " + eq.height.toFixed(2)
|
|
} else {
|
|
parties.followedEquipment = null;
|
|
document.getElementById(`svgIcon-${eq.equipmentNr}`).style.strokeWidth = 1;
|
|
document.getElementById(`follow-icon-${eq.equipmentNr}`).src = `./res/crosshair_light.svg`;
|
|
document.getElementById('infoOverlay').hidden = true;
|
|
}
|
|
})
|
|
|
|
eq.setMarker(); //Marker anlegen
|
|
|
|
var party = parties[eq.getPartyId()].layerGroup;
|
|
party.addLayer(eq.getMarker()).addTo(map); //Marker werden zur jeweiligen Layer-Group hinzugefuegt und auf map dargestellt
|
|
|
|
eq.tracked = true;
|
|
eq.visible = true;
|
|
}
|
|
else {
|
|
eq.resetLatLng(parties.followedEquipment);
|
|
}
|
|
}
|
|
|
|
/* HTML-Funktionalitaet */
|
|
|
|
// Modal
|
|
var modal = new bootstrap.Modal(document.getElementById('staticBackdrop'));
|
|
|
|
function popup() {
|
|
document.onreadystatechange = function () {
|
|
modal.show();
|
|
};
|
|
}
|
|
|
|
function popdown() {
|
|
modal.hide();
|
|
}
|
|
|
|
// Sidebar on Btn
|
|
const sidebarToggle = document.body.querySelector('#sidebarToggle');
|
|
if (sidebarToggle) {
|
|
sidebarToggle.addEventListener('click', event => {
|
|
event.preventDefault();
|
|
document.body.classList.toggle('sb-sidenav-toggled');
|
|
localStorage.setItem('sb|sidebar-toggle', document.body.classList.contains('sb-sidenav-toggled'));
|
|
setTimeout(function(){ map.invalidateSize({animate: true})}, 280)
|
|
});
|
|
}
|
|
|
|
// Request
|
|
function servicePortsInformationRequest(ws) {
|
|
|
|
ws.send(JSON.stringify({
|
|
type: "servicePortsInformationRequest",
|
|
uuid: "UUID"
|
|
}));
|
|
}
|
|
|
|
function BaseDlRequest(ws) {
|
|
|
|
ws.send(JSON.stringify({
|
|
type: "baseDlRequest",
|
|
uuid: "UUID"
|
|
}));
|
|
} |