Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
Executable
+339
@@ -0,0 +1,339 @@
|
||||
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"
|
||||
}));
|
||||
}
|
||||
Reference in new issue
Block a user