560 lines
20 KiB
JavaScript
Executable File
560 lines
20 KiB
JavaScript
Executable File
class Footprint {
|
|
|
|
constructor(name, id, path, refPoint, z, mseId) {
|
|
this.name = name;
|
|
this.id = id;
|
|
this.path = path;
|
|
this.refPoint = refPoint;
|
|
this.type = "footprint";
|
|
this.graphic = null;
|
|
this.status = "not ready";
|
|
this.z = z;
|
|
this.mseId = mseId;
|
|
}
|
|
}
|
|
|
|
class MountingPoint {
|
|
|
|
constructor(name, id, levelId, objId, position, roomId, supportedAsset) {
|
|
this.name = name;
|
|
this.id = id;
|
|
this.levelId = levelId;
|
|
this.objId = objId;
|
|
this.position = position; //wird als positionsObjekt übergeben. Bezieht sich auf Referenzpunkt des zugehörigen Gebäudes
|
|
this.roomId = roomId;
|
|
this.supportedAsset = supportedAsset;
|
|
this.type = "mountingPoint";
|
|
this.graphic = null;
|
|
this.status = "not ready";
|
|
}
|
|
}
|
|
|
|
class layer {
|
|
|
|
constructor(name) {
|
|
this.name = name;
|
|
this.ids = [];
|
|
this.layer = null;
|
|
}
|
|
}
|
|
|
|
let ipadresse = "localhost:";
|
|
let ipadresseSendPos = "localhost:";
|
|
let port = "2080";
|
|
let portSendPos = "12346";
|
|
let layerArr = [];
|
|
let objArr = [];
|
|
let AssetTypeArr = [];
|
|
let socket;
|
|
let equipmentNumber = "3801";
|
|
let outSpatialReference = {
|
|
wkid: 4326
|
|
};
|
|
let buildHigh = 0;
|
|
let mseId = 0;
|
|
|
|
function reconnect() {
|
|
|
|
ipadresse = document.getElementById("ipadresse").value;
|
|
document.getElementById("Serverconnect").innerHTML = "Server: not connected";
|
|
document.getElementById("Serverconnect").style.color = "red";
|
|
|
|
getEssentials();
|
|
}
|
|
|
|
function connectSendPos() {
|
|
|
|
ipadresseSendPos = document.getElementById("ipadresseSendPos").value;
|
|
portSendPos = document.getElementById("portSendPos").value;
|
|
|
|
socket = new WebSocket("ws://" + ipadresseSendPos + portSendPos); // connected on the port 12346
|
|
|
|
socket.onopen = function () { // if the connection is established, a port query will be sent to port 12346
|
|
document.getElementById("SendPosServerconnect").innerHTML = "Server: connected";
|
|
document.getElementById("SendPosServerconnect").style.color = "green"
|
|
};
|
|
}
|
|
|
|
window.onload = function () {
|
|
|
|
let selects = document.getElementsByName("layerSelect");
|
|
|
|
selects.forEach(selectable => {
|
|
selectable.checked = false;
|
|
});
|
|
|
|
document.getElementById("ipadresseSendPos").value = "";
|
|
document.getElementById("ipadresseSendPos").value = ipadresseSendPos;
|
|
document.getElementById("portSendPos").value = "";
|
|
document.getElementById("portSendPos").value = portSendPos;
|
|
document.getElementById("equipmentNumber").value = "";
|
|
document.getElementById("equipmentNumber").value = equipmentNumber;
|
|
|
|
getEssentials();
|
|
}
|
|
|
|
// Step 1 - Essentials are loaded
|
|
function getEssentials() {
|
|
|
|
if ("WebSocket" in window) {
|
|
let exampleSocket = new WebSocket("ws://" + ipadresse + port); //connected standartmäßig auf den port 2080
|
|
layerArr = [];
|
|
|
|
document.getElementById("layers").innerHTML = "";
|
|
document.getElementById("ipadresse").value = "";
|
|
document.getElementById("ipadresse").value = ipadresse;
|
|
document.getElementById("port").value = "";
|
|
document.getElementById("port").value = port;
|
|
|
|
exampleSocket.onopen = function () { //ist die Verbindung hergestellt so wird eine Portabfrage an den port 2080 geschickt
|
|
document.getElementById("Serverconnect").innerHTML = "Server: connected";
|
|
document.getElementById("Serverconnect").style.color = "green"
|
|
|
|
exampleSocket.send(JSON.stringify({
|
|
type: "getEssentials",
|
|
uuid: "UUID"
|
|
}));
|
|
};
|
|
|
|
exampleSocket.onmessage = function (event) {
|
|
let msg = JSON.parse(event.data);
|
|
let essentialArrays = msg.data;
|
|
AssetTypeArr = essentialArrays.assetTypes;
|
|
|
|
createObjects(essentialArrays);
|
|
};
|
|
} else {
|
|
alert("WebSocket is NOT supported by your Browser!");
|
|
}
|
|
}
|
|
|
|
//Step 2 - Creating objects of the essentials
|
|
function createObjects(essentialArrays) {
|
|
|
|
let levelCompareArr = [];
|
|
|
|
require([
|
|
"esri/layers/GraphicsLayer",
|
|
],
|
|
function (
|
|
GraphicsLayer
|
|
) {
|
|
//Buildings(footPrints)
|
|
essentialArrays.objects.forEach(building => {
|
|
if (building.path.length <= 0) {
|
|
building.path = null;
|
|
}
|
|
|
|
let footprintObj = new Footprint(building.designation, building.id, building.path, building.refPoint, building.z, building.mseId);
|
|
|
|
objArr.push(footprintObj);
|
|
});
|
|
|
|
//Layer für Levels
|
|
essentialArrays.levels.forEach(level => {
|
|
if (!levelCompareArr.includes(level.designation)) {
|
|
let layerObj = new layer(level.designation);
|
|
|
|
layerObj.ids.push(level.id);
|
|
layerObj.layer = new GraphicsLayer({});
|
|
layerArr.push(layerObj);
|
|
levelCompareArr.push(layerObj.name);
|
|
} else {
|
|
layerArr.forEach(layer => {
|
|
if (layer.name === level.designation) {
|
|
layer.ids.push(level.id);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
let outdoorLayer = new layer("outdoorLayer");
|
|
outdoorLayer.layer = new GraphicsLayer({});
|
|
outdoorLayer.ids.push(-1);
|
|
layerArr.push(outdoorLayer);
|
|
|
|
let footprintLayer = new layer("footprintLayer");
|
|
footprintLayer.layer = new GraphicsLayer({});
|
|
layerArr.push(footprintLayer);
|
|
|
|
//Mountingpoints
|
|
essentialArrays.mountingPoints.forEach(mountingP => {
|
|
let mountingPointObj = new MountingPoint(mountingP.designation, mountingP.id, mountingP.levelId, mountingP.objectId, mountingP.position3d, mountingP.roomId, mountingP.supportedAssetTypeIds[0]);
|
|
objArr.push(mountingPointObj);
|
|
});
|
|
|
|
createLayerSelection();
|
|
createMap();
|
|
}
|
|
)
|
|
|
|
};
|
|
|
|
function formatObjs() {
|
|
|
|
require([
|
|
"esri/geometry/Point",
|
|
"esri/geometry/projection",
|
|
"esri/Graphic",
|
|
], function (
|
|
Point,
|
|
projection,
|
|
Graphic) {
|
|
projection.load().then(function () {
|
|
objArr.forEach(obj => {
|
|
switch (obj.type) {
|
|
|
|
case "footprint":
|
|
|
|
if (obj.status == "not ready") {
|
|
let footprintEsriP = new Point({
|
|
y: (obj.refPoint.lat * 180) / Math.PI,
|
|
x: (obj.refPoint.lon * 180) / Math.PI
|
|
});
|
|
|
|
if (obj.id === 25) {
|
|
buildHigh = obj.z;
|
|
mseId = obj.mseId;
|
|
};
|
|
|
|
footprintEsriP = projection.project(footprintEsriP, getSpatialRefOut());
|
|
obj.refPoint = footprintEsriP;
|
|
|
|
if (obj.path !== null) {
|
|
let x = 0;
|
|
|
|
obj.path.forEach(pathPoint => {
|
|
esriPathPoint = new Point({
|
|
y: (pathPoint.lat * 180) / Math.PI,
|
|
x: (pathPoint.lon * 180) / Math.PI,
|
|
});
|
|
|
|
esriPathPoint = projection.project(esriPathPoint, getSpatialRefOut());
|
|
obj.path[x] = [esriPathPoint.__accessor__.store._values.x, esriPathPoint.__accessor__.store._values.y];
|
|
x++;
|
|
});
|
|
}
|
|
|
|
let polygon = {
|
|
type: "polygon",
|
|
rings: obj.path,
|
|
spatialReference: { wkid: getWkid() }
|
|
};
|
|
|
|
let fillSymbol = {
|
|
type: "simple-fill",
|
|
color: [227, 139, 79, 0.8],
|
|
outline: {
|
|
color: [255, 255, 255],
|
|
width: 1
|
|
}
|
|
};
|
|
|
|
let buildingAtr = {
|
|
BuildingName: obj.name,
|
|
type: obj.type
|
|
}
|
|
|
|
obj.graphic = new Graphic({ // Grafik des Footlayer
|
|
geometry: polygon,
|
|
symbol: fillSymbol,
|
|
attributes: buildingAtr
|
|
});
|
|
|
|
obj.status = "ready";
|
|
}
|
|
break;
|
|
|
|
case "mountingPoint":
|
|
|
|
if (obj.status == "not ready") {
|
|
objArr.forEach(subObj => {
|
|
if (subObj.type === "footprint") {
|
|
if (obj.objId === subObj.id && subObj.path != null) {
|
|
// Drehung der Mountingpoints um 318.82°
|
|
rad = 318.82 * Math.PI / 180;
|
|
x = obj.position.x;
|
|
y = obj.position.y;
|
|
|
|
obj.position.x = x * Math.cos(rad) - y * Math.sin(rad);
|
|
obj.position.y = x * Math.sin(rad) + y * Math.cos(rad);
|
|
|
|
obj.position.x += subObj.refPoint.__accessor__.store._values.x;
|
|
obj.position.y += subObj.refPoint.__accessor__.store._values.y;
|
|
}
|
|
}
|
|
});
|
|
|
|
let mountingPointEsriP = new Point({
|
|
y: obj.position.y,
|
|
x: obj.position.x,
|
|
spatialReference: getSpatialRefOut()
|
|
});
|
|
|
|
let mountingPointS = {
|
|
type: "simple-marker",
|
|
color: "black",
|
|
}
|
|
|
|
let mountingPointEventAttribs = {
|
|
name: obj.name,
|
|
objectId: obj.objId,
|
|
id: obj.id,
|
|
levelId: obj.levelId,
|
|
roomId: obj.roomId,
|
|
supportedAssets: obj.supportedAsset,
|
|
type: obj.type,
|
|
z: obj.position.z,
|
|
}
|
|
|
|
obj.graphic = new Graphic({ // Grafik von einem Mountingpoint
|
|
geometry: mountingPointEsriP,
|
|
symbol: mountingPointS,
|
|
attributes: mountingPointEventAttribs,
|
|
popupTemplate: {
|
|
actions: [{
|
|
title: "SendParticipantPos",
|
|
id: "sendPartPos",
|
|
className: "esri-icon-contact"
|
|
}],
|
|
title: "MountingPoint",
|
|
content: [{
|
|
type: "fields",
|
|
fieldInfos: [{
|
|
fieldName: "name"
|
|
}, {
|
|
fieldName: "objectId"
|
|
}, {
|
|
fieldName: "id"
|
|
}, {
|
|
fieldName: "levelId"
|
|
}, {
|
|
fieldName: "roomId"
|
|
}, {
|
|
fieldName: "supportedAssets"
|
|
}],
|
|
}]
|
|
}
|
|
});
|
|
|
|
obj.status = "ready";
|
|
}
|
|
break;
|
|
}
|
|
});
|
|
|
|
createDropDownAssets();
|
|
|
|
// Fires the sendPartPos() function after holding a mouse button on the view for a short amount of time
|
|
view.on("hold", function (event) {
|
|
|
|
mapPointClone = event.mapPoint;
|
|
mapPointClone = projection.project(mapPointClone, outSpatialReference);
|
|
|
|
positionY = mapPointClone.__accessor__.store._values.y;
|
|
positionX = mapPointClone.__accessor__.store._values.x;
|
|
positionZ = 0;
|
|
lvlId = -1;
|
|
rmId = -1;
|
|
objectId = -1;
|
|
|
|
sendPartPos(positionY, positionX, positionZ, lvlId, rmId, objectId);
|
|
});
|
|
|
|
/* Quick and Dirty-Methode! Event vom Action-Trigger sehr verschachtelt, die nötigen Attribute einzeln rausgesucht.
|
|
Noch auf der Suche nach einem Weg die Zugriffe zu vereinfachen */
|
|
|
|
// Action-Trigger PopupTemplate
|
|
view.popup.on("trigger-action", function (event) {
|
|
// If the sendPartPos action is clicked, fire the sendPartPos() function
|
|
if (event.action.id === "sendPartPos") {
|
|
geometryClone = event.target.__accessor__.store._values.selectedFeature.__accessor__.store._values.geometry;
|
|
geometryClone = projection.project(geometryClone, outSpatialReference);
|
|
|
|
positionY = geometryClone.__accessor__.store._values.y;
|
|
positionX = geometryClone.__accessor__.store._values.x;
|
|
positionZ = event.target.__accessor__.store._values.selectedFeature.__accessor__.store._values.attributes.z + buildHigh;
|
|
lvlId = event.target.__accessor__.store._values.selectedFeature.__accessor__.store._values.attributes.levelId;
|
|
rmId = event.target.__accessor__.store._values.selectedFeature.__accessor__.store._values.attributes.roomId;
|
|
objectId = mseId;
|
|
|
|
sendPartPos(positionY, positionX, positionZ, lvlId, rmId, objectId);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
);
|
|
};
|
|
|
|
//Step 3 - Connection to new websocket to retrieve the existing exercises
|
|
function createMap() {
|
|
|
|
require([
|
|
"esri/Map",
|
|
"esri/views/MapView",
|
|
"esri/layers/TileLayer",
|
|
"esri/geometry/Point",
|
|
"dojo/domReady!",
|
|
],
|
|
function (
|
|
Map,
|
|
MapView,
|
|
TileLayer,
|
|
Point
|
|
) {
|
|
map = new Map({
|
|
});
|
|
|
|
view = new MapView({
|
|
container: "mapDiv",
|
|
map: map,
|
|
scale: 500
|
|
});
|
|
|
|
view.center = new Point({ // Center vom View auf Gebäude 56 setzen
|
|
x: 493066.09059222677,
|
|
y: 5878330.0818853425,
|
|
spatialReference: 32632
|
|
});
|
|
|
|
tile = new TileLayer({
|
|
url: "http://excgeo21.sl.defence-elec.de/arcgis/rest/services/Bremen/BremenHemelingenAerialGeoAmt_32632/MapServer",
|
|
});
|
|
|
|
tile.load().then(function () {
|
|
map.layers.add(tile);
|
|
formatObjs();
|
|
})
|
|
}
|
|
);
|
|
};
|
|
|
|
function getSpatialRefOut() {
|
|
|
|
let spatialOut = view.spatialReference;
|
|
return spatialOut;
|
|
}
|
|
|
|
function getWkid() {
|
|
|
|
let wkid = view.spatialReference.__accessor__.store._values.wkid;
|
|
return (wkid);
|
|
}
|
|
|
|
// Die jeweiligen Points/Footprints des ausgewählten Layer auf der Map anzeigen
|
|
function place() {
|
|
|
|
let filter = document.getElementById("AssetTypes").value;
|
|
|
|
layerArr.forEach(layer => {
|
|
layer.layer.removeAll();
|
|
});
|
|
|
|
objArr.forEach(obj => {
|
|
switch (obj.type) {
|
|
|
|
case "mountingPoint":
|
|
|
|
layerArr.forEach(layer => {
|
|
if (layer.ids.includes(obj.levelId) && obj.supportedAsset == filter) {
|
|
layer.layer.add(obj.graphic);
|
|
}
|
|
});
|
|
break;
|
|
|
|
case "footprint":
|
|
|
|
layerArr.forEach(layer => {
|
|
if (layer.name === "footprintLayer") {
|
|
layer.layer.add(obj.graphic);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
// Ausgewähltes Layer dem "layer"-Attribut der Map zuweisen
|
|
function toggleLayer() {
|
|
|
|
place();
|
|
|
|
layerArr.forEach(layer => {
|
|
map.remove(layer.layer);
|
|
});
|
|
|
|
let selectedLayers = document.getElementsByName('layerSelect');
|
|
|
|
for (let x = selectedLayers.length - 1; x >= 0; x--) {
|
|
if (selectedLayers[x].checked) {
|
|
layerArr.forEach(layer => {
|
|
if (layer.name === selectedLayers[x].value) {
|
|
map.add(layer.layer)
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// Das Drop-Down Menü für die Assets generieren
|
|
function createDropDownAssets() {
|
|
|
|
let dropDdiv = document.getElementById("AssetTypesDiv");
|
|
let dropD = "<select id=\"AssetTypes\" onchange=\"place()\">";
|
|
|
|
AssetTypeArr.forEach(AssetType => {
|
|
dropD += "<option value=" + AssetType.id + ">" + AssetType.designation + "</option>"
|
|
});
|
|
|
|
dropD += "</select>"
|
|
dropDdiv.innerHTML = dropD;
|
|
}
|
|
|
|
// Die Auswahl der Layer füllen (Container rechts eben der Map)
|
|
function createLayerSelection() {
|
|
|
|
let layerDiv = document.getElementById("layers");
|
|
let append = "";
|
|
|
|
layerArr.forEach(layer => {
|
|
if (layer.name != undefined) {
|
|
append += `<div class="checkbox"><input class="layer" type="checkbox" value=${layer.name} name="layerSelect" onchange="toggleLayer()">${layer.name}</input></div>`;
|
|
}
|
|
});
|
|
|
|
layerDiv.innerHTML += append;
|
|
}
|
|
|
|
// Die ausgewählte Position an Port 12346 senden um den Teilnehmer zu positionieren
|
|
function sendPartPos(positionY, positionX, positionZ, lvlId, rmId, objectId) {
|
|
|
|
// zu lat/long umrechnen
|
|
positionY = (positionY * Math.PI) / 180;
|
|
positionX = (positionX * Math.PI) / 180;
|
|
equipmentNumber = Number(document.getElementById("equipmentNumber").value);
|
|
|
|
var type = "PositionReport";
|
|
var timestamp = Date.now();
|
|
var jsonMsg = JSON.stringify({ //make JSON-string from the data
|
|
data: {
|
|
equipmentNumber: equipmentNumber,
|
|
lat: positionY,
|
|
lon: positionX,
|
|
moutAreaId: lvlId,
|
|
moutObjectId: objectId,
|
|
moutRoomId: rmId,
|
|
timestamp: timestamp,
|
|
z: positionZ
|
|
},
|
|
type: type
|
|
});
|
|
|
|
var jsonOb = JSON.parse(jsonMsg);
|
|
|
|
if (socket != undefined) {
|
|
readout = "Equipment Number: " + jsonOb.data.equipmentNumber + "\n" + "Latitude: " + jsonOb.data.lat + "\n" + "Longitude: " + jsonOb.data.lon + "\n" + "Z: " + jsonOb.data.z + "\n" + "Area ID: " + jsonOb.data.moutAreaId + "\n" + "Object ID: " + jsonOb.data.moutObjectId + "\n" + "Room ID: " + jsonOb.data.moutRoomId + "\n" + "Time: " + jsonOb.data.timestamp;
|
|
socket.send(jsonMsg); // if the server is connected send the JSON telegram
|
|
alert("Current position sent!" + "\n" + readout);
|
|
} else {
|
|
alert("Server not connected!");
|
|
}
|
|
} |