Compare commits
10 Commits
08c92a7900
...
4466dc4331
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4466dc4331 | ||
|
|
b17c62ae09 | ||
|
|
5a59f87f13 | ||
|
|
f9e5916081 | ||
|
|
8a4795296e | ||
|
|
8f703dd1c7 | ||
|
|
46f041d58e | ||
|
|
3e95bc2633 | ||
|
|
f926604c7f | ||
|
|
c7140e0653 |
14
webapp/jsconfig.json
Normal file
14
webapp/jsconfig.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "Node",
|
||||||
|
"target": "ES2020",
|
||||||
|
"jsx": "react",
|
||||||
|
"strictNullChecks": true,
|
||||||
|
"strictFunctionTypes": true
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"**/node_modules/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
1146
webapp/package-lock.json
generated
1146
webapp/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -7,17 +7,20 @@
|
|||||||
"@testing-library/react": "^13.4.0",
|
"@testing-library/react": "^13.4.0",
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
"bootstrap": "^5.3.2",
|
"bootstrap": "^5.3.2",
|
||||||
|
"leaflet": "^1.9.4",
|
||||||
"leaflet-contextmenu": "^1.4.0",
|
"leaflet-contextmenu": "^1.4.0",
|
||||||
"milsymbol": "^2.2.0",
|
"milsymbol": "^2.2.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-bootstrap": "^2.9.0",
|
"react-bootstrap": "^2.9.0",
|
||||||
"react-container-dimensions": "^1.4.1",
|
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-hook-form": "^7.46.2",
|
"react-hook-form": "^7.46.2",
|
||||||
"react-leaflet": "^4.2.1",
|
"react-leaflet": "^4.2.1",
|
||||||
|
"react-router-dom": "^6.18.0",
|
||||||
"react-scripts": "^5.0.1",
|
"react-scripts": "^5.0.1",
|
||||||
"react-use-websocket": "^4.3.1",
|
"react-use-websocket": "^4.3.1",
|
||||||
"sass": "^1.66.1",
|
"sass": "^1.66.1",
|
||||||
|
"typescript": "^5.2.2",
|
||||||
|
"usehooks-ts": "^2.9.1",
|
||||||
"web-vitals": "^2.1.4",
|
"web-vitals": "^2.1.4",
|
||||||
"websocket": "^1.0.34"
|
"websocket": "^1.0.34"
|
||||||
},
|
},
|
||||||
|
|||||||
72
webapp/public/Own_Ship.svg
Normal file
72
webapp/public/Own_Ship.svg
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
id="svg2"
|
||||||
|
height="592.92773"
|
||||||
|
width="592.92773"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.91 r13725"
|
||||||
|
sodipodi:docname="NATO Map Symbol - Friendly Sea - Own Ship.svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1536"
|
||||||
|
inkscape:window-height="801"
|
||||||
|
id="namedview65"
|
||||||
|
showgrid="false"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
inkscape:zoom="1"
|
||||||
|
inkscape:cx="68.45469"
|
||||||
|
inkscape:cy="233.21213"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg2"
|
||||||
|
inkscape:object-nodes="true" />
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<path
|
||||||
|
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#00c8ff;stroke-width:8;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||||
|
id="path2988"
|
||||||
|
d="m 514.47312,296.57436 a 218.00928,218.00928 0 0 1 -436.018504,0 218.00928,218.00928 0 1 1 436.018504,0 z"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-rule:evenodd;stroke:#00c8ff;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 296.46387,78.454681 0,436.018369"
|
||||||
|
id="path4136"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-rule:evenodd;stroke:#00c8ff;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 514.47305,296.46387 -436.018363,0"
|
||||||
|
id="path4136-5"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -1,205 +1,39 @@
|
|||||||
// App.js
|
// App.js
|
||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import "./App.css";
|
import "./App.css";
|
||||||
// import { connect, sendMsg } from "./components/api/index";
|
import Header from "./components/Header/index"
|
||||||
import Header from './components/Header';
|
import SimControl from './components/SimControl'
|
||||||
import Controls from "./components/control/controls";
|
|
||||||
// import ChatHistory from "./components/ChatHistory/ChatHistory.jsx";
|
|
||||||
|
|
||||||
import OpenSeaMap from "./components/OpenSeaMap/OpenSeaMap";
|
|
||||||
import {w3cwebsocket as W3CWebSocket} from "websocket"
|
import {w3cwebsocket as W3CWebSocket} from "websocket"
|
||||||
|
|
||||||
|
import { BrowserRouter, Routes, Route } from "react-router-dom";
|
||||||
|
import Gateway from "./components/Gateway";
|
||||||
|
import Database from "./components/Database";
|
||||||
|
import Scenarios from "./components/Scenarios";
|
||||||
|
import Settings from "./components/Settings";
|
||||||
|
import Debug from "./components/Debug";
|
||||||
|
|
||||||
|
|
||||||
export const defaultLocale = "en-US";
|
export const defaultLocale = "en-US";
|
||||||
|
|
||||||
const config = {
|
|
||||||
// apiUrl: process.env.REACT_APP_WEBAPP_WS_URL,
|
const App = () => {
|
||||||
apiUrl: "192.168.3.13",
|
return (
|
||||||
apiProt: 30747
|
<><Header />
|
||||||
|
<BrowserRouter>
|
||||||
|
<Routes>
|
||||||
|
<Route path="/" element={<SimControl />} />
|
||||||
|
<Route path="/debug" element={<Debug />} />
|
||||||
|
|
||||||
|
<Route path="/scenarios" element={<Scenarios />} />
|
||||||
|
<Route path="/database" element={<Database />} />
|
||||||
|
<Route path="/gateway" element={<Gateway />} />
|
||||||
|
<Route path="/settings" element={<Settings />} />
|
||||||
|
|
||||||
|
</Routes>
|
||||||
|
</BrowserRouter></>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// const config = {
|
|
||||||
// // apiUrl: process.env.REACT_APP_WEBAPP_WS_URL,
|
|
||||||
// apiUrl: "localhost",
|
|
||||||
// apiProt: 9999
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
const client = new W3CWebSocket("ws://"+config.apiUrl+":"+config.apiProt+"/");
|
|
||||||
|
|
||||||
|
|
||||||
class App extends Component {
|
|
||||||
state = {
|
|
||||||
Entities: [],
|
|
||||||
EntityOnFocus: undefined,
|
|
||||||
PositionClicked: undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
console.log(config.apiUrl);
|
|
||||||
|
|
||||||
client.onopen = () => {
|
|
||||||
console.log("Websocket Client for Map Connected");
|
|
||||||
};
|
|
||||||
|
|
||||||
client.onmessage = (message) => {
|
|
||||||
const dataFromServer = JSON.parse(message.data);
|
|
||||||
// console.log('reply: ', dataFromServer);
|
|
||||||
|
|
||||||
if(dataFromServer.Data === "COP")
|
|
||||||
{
|
|
||||||
|
|
||||||
// console.log(this.state.EntityOnFocus);
|
|
||||||
var tmp = []
|
|
||||||
if(this.state.Entities.length !== 0){
|
|
||||||
|
|
||||||
|
|
||||||
dataFromServer.Entities.forEach((elementFromWS, indexWS) => {
|
|
||||||
|
|
||||||
this.state.Entities.forEach((elementStored, indexStore) => {
|
|
||||||
if(elementFromWS.id === elementStored.id)
|
|
||||||
{
|
|
||||||
|
|
||||||
if(elementStored.onFocus !==true | elementStored.onFocus === undefined)
|
|
||||||
{
|
|
||||||
tmp.push(elementFromWS);
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
tmp.push(elementStored);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
tmp = dataFromServer.Entities;
|
|
||||||
}
|
|
||||||
// console.log(tmp);
|
|
||||||
this.setState((state) => ({
|
|
||||||
// Entities: structuredClone(dataFromServer.Entities)
|
|
||||||
Entities: structuredClone(tmp)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// interval for updates
|
|
||||||
setInterval(() => {
|
|
||||||
this.updateEntities();
|
|
||||||
}, 2000);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
updateEntities()
|
|
||||||
{
|
|
||||||
var msg =
|
|
||||||
{
|
|
||||||
Type: "Request",
|
|
||||||
Data: "COP"
|
|
||||||
|
|
||||||
}
|
|
||||||
client.send(JSON.stringify(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
getEntityFromID(Entities, SelectedEntity)
|
|
||||||
{
|
|
||||||
// console.log(Entities);
|
|
||||||
}
|
|
||||||
|
|
||||||
setEntityOnFocus(Entity)
|
|
||||||
{
|
|
||||||
if(Entity == undefined)
|
|
||||||
{
|
|
||||||
this.resetEntityOnFocus();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getEntityFromID(this.state.Entities,Entity)
|
|
||||||
console.log(Entity);
|
|
||||||
this.setState({
|
|
||||||
EntityOnFocus: Entity
|
|
||||||
});
|
|
||||||
this.state.Entities.forEach((element, index) => {
|
|
||||||
// console.log(element);
|
|
||||||
|
|
||||||
if(element.id === Entity.EntityID)
|
|
||||||
{
|
|
||||||
var tmpList = structuredClone(this.state.Entities);
|
|
||||||
tmpList[index].onFocus = true;
|
|
||||||
if(Entity.NewPos !== undefined)
|
|
||||||
{
|
|
||||||
tmpList[index].Position = Entity.NewPos
|
|
||||||
}
|
|
||||||
this.setState({
|
|
||||||
Entities: structuredClone(tmpList)
|
|
||||||
});
|
|
||||||
if(Entity.dragged !== undefined)
|
|
||||||
{
|
|
||||||
if(Entity.dragged === true)
|
|
||||||
{
|
|
||||||
tmpList[index].dragged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(tmpList[index]);
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
resetEntityOnFocus()
|
|
||||||
{
|
|
||||||
if(this.state.EntityOnFocus !== undefined)
|
|
||||||
{
|
|
||||||
this.state.Entities.map((element ,index) => {
|
|
||||||
if(element.id === this.state.EntityOnFocus.EntityID)
|
|
||||||
{
|
|
||||||
this.state.Entities[index].onFocus = false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
console.log(this.state.Entities)
|
|
||||||
this.setState({
|
|
||||||
EntityOnFocus: undefined
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
setFocusPosition(props)
|
|
||||||
{
|
|
||||||
|
|
||||||
// console.log(Entity);
|
|
||||||
this.setState({
|
|
||||||
PositionClicked: props
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Functions = {
|
|
||||||
updateEntities: this.updateEntities.bind(this),
|
|
||||||
resetEntityOnFocus: this.resetEntityOnFocus.bind(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
|
|
||||||
const {name} = this.state;
|
|
||||||
return (
|
|
||||||
<div className="App">
|
|
||||||
<Header />
|
|
||||||
<div className="Content">
|
|
||||||
|
|
||||||
<Controls Functions= {this.Functions} Client= {client} Entities= {this.state.Entities} updateEntities = {this.updateEntities} EntityOnFocus = {this.state.EntityOnFocus} PositionClicked = {this.state.PositionClicked} />
|
|
||||||
|
|
||||||
<OpenSeaMap Entities= {this.state.Entities} updateEntities = {this.updateEntities} setEntityOnFocus = {this.setEntityOnFocus.bind(this)} setFocusPosition = {this.setFocusPosition.bind(this)}/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|||||||
12
webapp/src/components/Database/Database.jsx
Normal file
12
webapp/src/components/Database/Database.jsx
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
|
||||||
|
function Database()
|
||||||
|
{
|
||||||
|
return(
|
||||||
|
<p>Database</p>
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Database;
|
||||||
3
webapp/src/components/Database/index.js
Normal file
3
webapp/src/components/Database/index.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import Database from "./Database.jsx";
|
||||||
|
|
||||||
|
export default Database;
|
||||||
135
webapp/src/components/Debug/Debug.jsx
Normal file
135
webapp/src/components/Debug/Debug.jsx
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
import React from "react";
|
||||||
|
import {w3cwebsocket as W3CWebSocket} from "websocket"
|
||||||
|
import PerceivedTruth from "./components/perceivedTruth/perceivedTruth.jsx";
|
||||||
|
import "./Debug.scss"
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { getCOP,loadAutoraster } from "../api/APICalls";
|
||||||
|
|
||||||
|
import TrackListClass from "../SimControl/Tracklist.tsx";
|
||||||
|
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
// apiUrl: process.env.REACT_APP_WEBAPP_WS_URL,
|
||||||
|
apiUrl: "192.168.3.13",
|
||||||
|
apiProt: 30747
|
||||||
|
}
|
||||||
|
let client = null;
|
||||||
|
// let client = new W3CWebSocket("ws://"+config.apiUrl+":"+config.apiProt+"/");
|
||||||
|
|
||||||
|
function Scenarios()
|
||||||
|
{
|
||||||
|
const [trackList, settrackList] = useState([]);
|
||||||
|
const [entityTracklist, setEntityTracklist] = useState([]);
|
||||||
|
|
||||||
|
const [clientConnected, setclientConnected] = useState(false);
|
||||||
|
// const [client, setclient] = useState(W3CWebSocket);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
client = new W3CWebSocket("ws://"+config.apiUrl+":"+config.apiProt+"/");
|
||||||
|
|
||||||
|
client.onopen = () => {
|
||||||
|
console.log("Websocket Client for Debug Component");
|
||||||
|
setclientConnected(true)
|
||||||
|
};
|
||||||
|
console.log(`initializing interval`);
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
updateEntities();
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
console.log(`clearing interval`);
|
||||||
|
clearInterval(interval);
|
||||||
|
client.close();
|
||||||
|
client = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}, []); // has no dependency - this will be called on-component-mount
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
client.onmessage = (message) => {
|
||||||
|
if(message.data !== "null")
|
||||||
|
{
|
||||||
|
|
||||||
|
// console.log(message.data);
|
||||||
|
const dataFromServer = JSON.parse(message.data);
|
||||||
|
|
||||||
|
if(dataFromServer.Data === "COP")
|
||||||
|
{
|
||||||
|
settrackList(dataFromServer.Entities);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
// console.log(dataFromServer);
|
||||||
|
setEntityTracklist(dataFromServer)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
console.log(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function updateEntities()
|
||||||
|
{
|
||||||
|
// var msg =
|
||||||
|
// {
|
||||||
|
// Type: "Request",
|
||||||
|
// Data: "COP"
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
client.send(getCOP());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const sendSampleMessage = () =>
|
||||||
|
{
|
||||||
|
var msg =
|
||||||
|
{
|
||||||
|
Data: "TEST",
|
||||||
|
Type: "Save",
|
||||||
|
}
|
||||||
|
console.log(msg);
|
||||||
|
client.send(JSON.stringify(msg));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const startSampleScenario = () =>
|
||||||
|
{
|
||||||
|
|
||||||
|
client.send(loadAutoraster());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return(
|
||||||
|
<>
|
||||||
|
{/* <div><button onClick={sendSampleMessage}> Save Scenario</button></div>
|
||||||
|
<div><button onClick={startSampleScenario}> Sample Scenario</button></div> */}
|
||||||
|
<div className="Container">
|
||||||
|
|
||||||
|
<div className="InfoPane" >
|
||||||
|
<p>Debug</p>
|
||||||
|
<PerceivedTruth Client={client} EntityTracklist={entityTracklist} Tracklist= {trackList} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</>
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Scenarios;
|
||||||
9
webapp/src/components/Debug/Debug.scss
Normal file
9
webapp/src/components/Debug/Debug.scss
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
.Container
|
||||||
|
{
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.InfoPane{
|
||||||
|
width: 100%;
|
||||||
|
padding-left: 1rem
|
||||||
|
}
|
||||||
@@ -0,0 +1,185 @@
|
|||||||
|
import { useLeafletContext } from '@react-leaflet/core'
|
||||||
|
import { MapContainer, TileLayer, Marker,Tooltip} from 'react-leaflet'
|
||||||
|
|
||||||
|
import L, { Icon, icon } from 'leaflet'
|
||||||
|
import { useEffect, useState,useRef, useCallback,useMemo } from 'react'
|
||||||
|
|
||||||
|
import "./map.scss"
|
||||||
|
|
||||||
|
import { OwnShipIcon, createIcon } from '../../../../SimControl/components/OpenSeaMap/icon'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const zoom = 9
|
||||||
|
|
||||||
|
function DisplayPosition({ map,center }) {
|
||||||
|
const [position, setPosition] = useState(() => map.getCenter())
|
||||||
|
|
||||||
|
// const onClick = useCallback(() => {
|
||||||
|
// map.setView(center, zoom)
|
||||||
|
// }, [map])
|
||||||
|
|
||||||
|
const onMove = useCallback(() => {
|
||||||
|
|
||||||
|
setPosition(map.getCenter())
|
||||||
|
}, [map])
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
map.setView(center, zoom)
|
||||||
|
|
||||||
|
|
||||||
|
}, [center, map])
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
map.on('move', onMove)
|
||||||
|
return () => {
|
||||||
|
map.off('move', onMove)
|
||||||
|
}
|
||||||
|
}, [map, onMove])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<p>
|
||||||
|
latitude: {position.lat.toFixed(4)}, longitude: {position.lng.toFixed(4)}{' '}
|
||||||
|
{/* <button onClick={onClick}>reset</button> */}
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function MyMap({center,Tracklist}) {
|
||||||
|
const [map, setMap] = useState(null)
|
||||||
|
const [mapcenter, setMapcenter] = useState([51.505, -0.09])
|
||||||
|
const [isFocused, setIsFocused] = useState(false)
|
||||||
|
const [trackList,setTracklist] = useState([])
|
||||||
|
|
||||||
|
// const OwnShipIcon = L.icon({
|
||||||
|
// iconUrl: 'Own_Ship.svg',
|
||||||
|
|
||||||
|
// iconSize: [50, 50], // size of the icon
|
||||||
|
|
||||||
|
// });
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// console.log(center);
|
||||||
|
if(center.length !== 0)
|
||||||
|
{
|
||||||
|
setMapcenter(center);
|
||||||
|
setIsFocused(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}, [center]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// console.log(Tracklist);
|
||||||
|
// makeList(Tracklist.Tracks)
|
||||||
|
var tracks = Tracklist.Tracks
|
||||||
|
|
||||||
|
var list = [];
|
||||||
|
// var Symbol = {
|
||||||
|
// ID: "1234",
|
||||||
|
// Name:"Own Ship",
|
||||||
|
// Position: mapcenter ,
|
||||||
|
// IconData: OwnShipIcon,
|
||||||
|
// }
|
||||||
|
// list.push(Symbol);
|
||||||
|
// setTracklist(list);
|
||||||
|
|
||||||
|
if(tracks === undefined)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tracks.forEach(element => {
|
||||||
|
console.log(element)
|
||||||
|
|
||||||
|
var Symbol = {
|
||||||
|
ID: element.ID,
|
||||||
|
Name:element.Name,
|
||||||
|
Position: [element.Position[0], element.Position[1]] ,
|
||||||
|
IconData: createIcon(element.Type, element.Side),
|
||||||
|
}
|
||||||
|
|
||||||
|
list.push(Symbol);
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
// console.log(list);
|
||||||
|
setTracklist(list);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}, [Tracklist, mapcenter]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// function makeList(tracks)
|
||||||
|
// {
|
||||||
|
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
function makeIcons()
|
||||||
|
{
|
||||||
|
if(trackList === undefined)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var list =[];
|
||||||
|
trackList.forEach(element => {
|
||||||
|
list.push(
|
||||||
|
<Marker name={element.Name} key={element.ID} icon={element.IconData} position={element.Position} >
|
||||||
|
<Tooltip direction='bottom' offset={[0,10]} opacity={1} permanent>
|
||||||
|
<span>{element.Name}</span>
|
||||||
|
</Tooltip>
|
||||||
|
</Marker>)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
return(
|
||||||
|
list
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const displayMap = useMemo(
|
||||||
|
() => (
|
||||||
|
<MapContainer
|
||||||
|
center={mapcenter}
|
||||||
|
zoom={zoom}
|
||||||
|
attributionControl={false}
|
||||||
|
// scrollWheelZoom={false}
|
||||||
|
ref={setMap}>
|
||||||
|
<TileLayer
|
||||||
|
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||||
|
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||||
|
/>
|
||||||
|
|
||||||
|
{isFocused ? <Marker icon={OwnShipIcon} position={mapcenter} >
|
||||||
|
<Tooltip direction='bottom' offset={[0,13]} opacity={1} permanent>
|
||||||
|
<span>{"Own Ship"}</span>
|
||||||
|
</Tooltip>
|
||||||
|
</Marker> :null }
|
||||||
|
{ makeIcons()}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</MapContainer>
|
||||||
|
),
|
||||||
|
[isFocused, mapcenter, trackList],
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='Smallapmap'>
|
||||||
|
{map ? <DisplayPosition map={map} center={mapcenter} /> : null}
|
||||||
|
{displayMap }
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MyMap;
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
.Smallapmap {
|
||||||
|
// display: flex;
|
||||||
|
// padding-top: 10px;
|
||||||
|
height: 500px;
|
||||||
|
width: 100%;
|
||||||
|
// padding-left: 20%;
|
||||||
|
display: inline-flex;
|
||||||
|
// height: 80%;
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
.App {
|
||||||
|
display: flex;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.App-logo {
|
||||||
|
height: 40vmin;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
.App-logo {
|
||||||
|
animation: App-logo-spin infinite 20s linear;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.App-header {
|
||||||
|
background-color: #282c34;
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: calc(10px + 2vmin);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.App-link {
|
||||||
|
color: #61dafb;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes App-logo-spin {
|
||||||
|
from {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaflet-container {
|
||||||
|
width: 70vw;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 2em;
|
||||||
|
width: 30vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar h2,
|
||||||
|
.sidebar p,
|
||||||
|
.sidebar ul {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar h2 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar button {
|
||||||
|
width: 100%;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: .8em 1em;
|
||||||
|
}
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { getWSTestMessage ,getTracklist } from '../../../api/APICalls';
|
||||||
|
import MyMap from "./map/map.jsx"
|
||||||
|
|
||||||
|
import "./perceivedTruth.scss"
|
||||||
|
import TrackList from './tracklist/tracklist.jsx';
|
||||||
|
|
||||||
|
|
||||||
|
function PerceivedTruth(props)
|
||||||
|
{
|
||||||
|
|
||||||
|
const [selectedOption, setSelectedOption] = useState('option1')
|
||||||
|
const [selectedOptionFull, setSelectedOptionFull] = useState({
|
||||||
|
ID : null,
|
||||||
|
Label:"",
|
||||||
|
Position: []
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const [selectOptions, setSelectOptions] = useState([])
|
||||||
|
|
||||||
|
const [trackList, settrackList] = useState([]);
|
||||||
|
const [client, setclient] = useState()
|
||||||
|
|
||||||
|
const handleSubmit = (event) => {
|
||||||
|
if(selectedOption !== "option1" && selectedOption !== "" )
|
||||||
|
{
|
||||||
|
|
||||||
|
let updatedValue = getAttributesForID(selectedOption);
|
||||||
|
|
||||||
|
setSelectedOptionFull(selectedOptionFull => ({
|
||||||
|
...selectedOptionFull,
|
||||||
|
...updatedValue
|
||||||
|
}));
|
||||||
|
|
||||||
|
client.send(getTracklist(selectedOption));
|
||||||
|
event.preventDefault()
|
||||||
|
console.log(`Submitted selected option: ${selectedOption}`)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAttributesForID(ID)
|
||||||
|
{
|
||||||
|
let attributes = {
|
||||||
|
ID: undefined,
|
||||||
|
Name: "",
|
||||||
|
Position : []
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
selectOptions.forEach(element => {
|
||||||
|
// console.log(element);
|
||||||
|
|
||||||
|
if(element.value === ID)
|
||||||
|
{
|
||||||
|
attributes.ID = ID;
|
||||||
|
attributes.Name = element.label;
|
||||||
|
attributes.Position = element.position;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepareTracklistForSelect(Tracklist)
|
||||||
|
{
|
||||||
|
if(Tracklist!== undefined)
|
||||||
|
{
|
||||||
|
var options = [];
|
||||||
|
Tracklist.forEach(element => {
|
||||||
|
|
||||||
|
var item =
|
||||||
|
{
|
||||||
|
value : element.id,
|
||||||
|
label : element.Name,
|
||||||
|
position: element.Position
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
options.push(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
setSelectOptions(options);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
//Runs on the first render
|
||||||
|
//And any time any dependency value changes
|
||||||
|
console.log(props.EntityTracklist);
|
||||||
|
setclient(props.Client);
|
||||||
|
settrackList(props.Tracklist);
|
||||||
|
prepareTracklistForSelect(trackList);
|
||||||
|
|
||||||
|
|
||||||
|
}, [props, trackList]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div className='box'>
|
||||||
|
<div className='EntityTracklist'>
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<label htmlFor="my-select">Select Track:</label>
|
||||||
|
<select
|
||||||
|
id="my-select"
|
||||||
|
value={selectedOption}
|
||||||
|
onChange={(event) => setSelectedOption(event.target.value)}
|
||||||
|
>
|
||||||
|
<option> </option>
|
||||||
|
{selectOptions.map((option, index) => (
|
||||||
|
<option key={index} value={option.value} label={option.label} />
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
<button type="submit">Submit</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<p>{ selectedOptionFull.Label}</p>
|
||||||
|
|
||||||
|
<TrackList Tracklist ={props.EntityTracklist} />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div className='SideMap'>
|
||||||
|
<MyMap center={selectedOptionFull.Position} Tracklist ={props.EntityTracklist} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
export default PerceivedTruth;
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
.box{
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.EntityTracklist
|
||||||
|
{
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SideMap{
|
||||||
|
width: 40%;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import "./tracklist.scss"
|
||||||
|
|
||||||
|
import round from "../../../../Utils.jsx"
|
||||||
|
|
||||||
|
function TrackList(props)
|
||||||
|
{
|
||||||
|
const [tracklist, setTracklist] = useState(Array)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
setTracklist(Array);
|
||||||
|
// console.log(props)
|
||||||
|
|
||||||
|
}, []);
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
if(props.Tracklist.Tracks !== undefined)
|
||||||
|
{
|
||||||
|
setTracklist(props.Tracklist.Tracks);
|
||||||
|
|
||||||
|
}
|
||||||
|
// console.log(props)
|
||||||
|
|
||||||
|
}, [props]);
|
||||||
|
|
||||||
|
function MakeSensorList(props)
|
||||||
|
{
|
||||||
|
if(props === undefined)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var list = [];
|
||||||
|
props.Sensors.forEach(element => {
|
||||||
|
list.push(<span> {element.Name} Range: {element.Range} NM </span>)
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return(list);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div class="divTable">
|
||||||
|
<div class="divTableBody">
|
||||||
|
<div class="divTableRow">
|
||||||
|
<div class="divTableCell">NR</div>
|
||||||
|
<div class="divTableCell">ID</div>
|
||||||
|
<div class="divTableCell">Name</div>
|
||||||
|
<div class="divTableCell">Position</div>
|
||||||
|
<div class="divTableCell">Bearing</div>
|
||||||
|
<div class="divTableCell">Range</div>
|
||||||
|
<div class="divTableCell">Threat</div>
|
||||||
|
<div class="divTableCell">Sensors</div>
|
||||||
|
<div class="divTableCell">Status</div>
|
||||||
|
</div>
|
||||||
|
{/* {<MakeRow />} */}
|
||||||
|
|
||||||
|
{
|
||||||
|
tracklist.map( (elem,index) => {
|
||||||
|
if(elem.Position !== undefined)
|
||||||
|
{
|
||||||
|
// console.log(elem)
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div class="divTableRow">
|
||||||
|
|
||||||
|
<div class="divTableCell">{index}</div>
|
||||||
|
<div class="divTableCell">{elem.ID}</div>
|
||||||
|
<div class="divTableCell">{elem.Name}</div>
|
||||||
|
<div class="divTableCell">{round(elem.Position[0],4)}, {round(elem.Position[1],4)}</div>
|
||||||
|
<div class="divTableCell">{round(elem.Bearing,2)}</div>
|
||||||
|
<div class="divTableCell">{round(elem.Distance,2)}</div>
|
||||||
|
<div class="divTableCell">{elem.Threat}</div>
|
||||||
|
<div class="divTableCell">{}</div>
|
||||||
|
<div class="divTableCell">{elem.Status}</div>
|
||||||
|
|
||||||
|
{/* <div class="divTableCell">{MakeSensorList(elem) }</div> */}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
export default TrackList;
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/* DivTable.com */
|
||||||
|
.divTable{
|
||||||
|
display: table;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.divTableRow {
|
||||||
|
display: table-row;
|
||||||
|
}
|
||||||
|
.divTableHeading {
|
||||||
|
background-color: #EEE;
|
||||||
|
display: table-header-group;
|
||||||
|
}
|
||||||
|
.divTableCell, .divTableHead {
|
||||||
|
border: 1px solid #999999;
|
||||||
|
display: table-cell;
|
||||||
|
padding: 3px 10px;
|
||||||
|
}
|
||||||
|
.divTableHeading {
|
||||||
|
background-color: #EEE;
|
||||||
|
display: table-header-group;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.divTableFoot {
|
||||||
|
background-color: #EEE;
|
||||||
|
display: table-footer-group;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.divTableBody {
|
||||||
|
display: table-row-group;
|
||||||
|
}
|
||||||
3
webapp/src/components/Debug/index.js
Normal file
3
webapp/src/components/Debug/index.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import Debug from "./Debug.jsx";
|
||||||
|
|
||||||
|
export default Debug;
|
||||||
12
webapp/src/components/Gateway/Gateway.jsx
Normal file
12
webapp/src/components/Gateway/Gateway.jsx
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
|
||||||
|
function Gateway()
|
||||||
|
{
|
||||||
|
return(
|
||||||
|
<p>Gateway</p>
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Gateway;
|
||||||
3
webapp/src/components/Gateway/index.js
Normal file
3
webapp/src/components/Gateway/index.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import Gateway from "./Gateway.jsx";
|
||||||
|
|
||||||
|
export default Gateway;
|
||||||
@@ -1,10 +1,40 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import Container from 'react-bootstrap/Container';
|
||||||
|
import Nav from 'react-bootstrap/Nav';
|
||||||
|
import Navbar from 'react-bootstrap/Navbar';
|
||||||
import "./header.scss";
|
import "./header.scss";
|
||||||
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
|
|
||||||
|
function Header() {
|
||||||
|
return(
|
||||||
|
<Navbar expand="lg" bg="secondary">
|
||||||
|
|
||||||
|
<Container fluid >
|
||||||
|
<Navbar.Brand href="/"><h2>Cloud Simulator</h2></Navbar.Brand>
|
||||||
|
<Navbar.Toggle aria-controls="navbarScroll" />
|
||||||
|
<Navbar.Collapse id="navbarScroll">
|
||||||
|
<Nav
|
||||||
|
className="me-auto my-2 my-lg-0"
|
||||||
|
style={{ maxHeight: '100px' }}
|
||||||
|
navbarScroll
|
||||||
|
>
|
||||||
|
<Nav.Link href="debug">Debug</Nav.Link>
|
||||||
|
|
||||||
|
<Nav.Link href="scenarios">Scenarios</Nav.Link>
|
||||||
|
<Nav.Link href="database">Database</Nav.Link>
|
||||||
|
<Nav.Link href="gateway">Gateway</Nav.Link>
|
||||||
|
<Nav.Link href="settings">Settings</Nav.Link>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</Nav>
|
||||||
|
</Navbar.Collapse>
|
||||||
|
</Container>
|
||||||
|
</Navbar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const Header = () => (
|
|
||||||
<div className="header">
|
|
||||||
<font className="caption">Cloud Simulator</font>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default Header;
|
export default Header;
|
||||||
|
|||||||
@@ -1,211 +0,0 @@
|
|||||||
|
|
||||||
// import { useMapEvents } from 'react-leaflet/hooks'
|
|
||||||
import React, { Component } from "react";
|
|
||||||
import { MapContainer, TileLayer,Marker, Popup, Tooltip,useMapEvents,contextmenu } from 'react-leaflet'
|
|
||||||
import { friend,Hostile, iconShip,createIcon } from "./icon";
|
|
||||||
import "./OpenSeaMap.scss";
|
|
||||||
import {w3cwebsocket as W3CWebSocket} from "websocket";
|
|
||||||
import ContainerDimensions from 'react-container-dimensions';
|
|
||||||
import {} from "leaflet-contextmenu";
|
|
||||||
|
|
||||||
|
|
||||||
class OpenSeaMap extends Component {
|
|
||||||
|
|
||||||
state = {
|
|
||||||
EntityOnFocus: undefined,
|
|
||||||
}
|
|
||||||
updateDimensions() {
|
|
||||||
const height = window.innerWidth >= 950 ? window.innerHeight : 400
|
|
||||||
this.setState({ height: height })
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillMount() {
|
|
||||||
this.updateDimensions()
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
window.addEventListener("resize", this.updateDimensions.bind(this))
|
|
||||||
console.log(this.state.EntityOnFocus);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
window.removeEventListener("resize", this.updateDimensions.bind(this))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
handleClick(e)
|
|
||||||
{
|
|
||||||
// console.log(e.target)
|
|
||||||
// this.setState({ currentPos: e.latlng });
|
|
||||||
// console.log(e.latlng);
|
|
||||||
|
|
||||||
// console.log("hello world");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
makeIcon(index, entity,props,state)
|
|
||||||
{
|
|
||||||
var isOnFocus = false;
|
|
||||||
if(this.state.EntityOnFocus !== undefined){
|
|
||||||
// console.log(entity.id+ " " , this.state.EntityOnFocus);
|
|
||||||
|
|
||||||
if(entity.id === this.state.EntityOnFocus.EntityID)
|
|
||||||
{
|
|
||||||
isOnFocus = true
|
|
||||||
// if(this.state.EntityOnFocus.NewPos !== undefined)
|
|
||||||
// {
|
|
||||||
// entity.pos = this.state.EntityOnFocus.NewPos;
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
var icon;
|
|
||||||
icon = createIcon(entity.Type,entity.Side)
|
|
||||||
return (
|
|
||||||
<Marker name={entity.Name} key={index} icon={icon} position={entity.Position} data={entity.id}
|
|
||||||
draggable={isOnFocus? true : false}
|
|
||||||
contextmenu={true}
|
|
||||||
contextmenuWidth={140}
|
|
||||||
|
|
||||||
contextmenuItems={[{
|
|
||||||
text:"Edit",
|
|
||||||
index:0,
|
|
||||||
callback: function() {
|
|
||||||
// this.setState({
|
|
||||||
// EntityOnFocus:entity.id
|
|
||||||
// })
|
|
||||||
var Ent = {
|
|
||||||
EntityID : entity.id,
|
|
||||||
NewPos : undefined
|
|
||||||
}
|
|
||||||
state.EntityOnFocus = Ent;
|
|
||||||
props.setEntityOnFocus(Ent)
|
|
||||||
// console.log(state.EntityOnFocus);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
text:"Delete",
|
|
||||||
// separator: true,
|
|
||||||
index: 1
|
|
||||||
}, {
|
|
||||||
text:"Exit",
|
|
||||||
callback: function()
|
|
||||||
{
|
|
||||||
state.EntityOnFocus = undefined;
|
|
||||||
props.setEntityOnFocus(undefined);
|
|
||||||
},
|
|
||||||
// separator: true,
|
|
||||||
index: 2
|
|
||||||
}]}
|
|
||||||
// contextmenuItems: [{
|
|
||||||
// text: 'Circle 1',
|
|
||||||
// callback: function() {
|
|
||||||
// circleContextClick(circle1);
|
|
||||||
// }
|
|
||||||
// }]
|
|
||||||
eventHandlers={{
|
|
||||||
click: (e) => {
|
|
||||||
// console.log(e.target);
|
|
||||||
// var Ent = {
|
|
||||||
// EntityID : e.target.options.data,
|
|
||||||
// NewPos : undefined
|
|
||||||
|
|
||||||
// }
|
|
||||||
// this.setState((state) =>({
|
|
||||||
// EntityOnFocus: Ent
|
|
||||||
// }))
|
|
||||||
// this.props.setEntityOnFocus(Ent);
|
|
||||||
|
|
||||||
// this.props.setEntityOnFocus(e.target.options.data);
|
|
||||||
},
|
|
||||||
dragend: (e) =>
|
|
||||||
{
|
|
||||||
var Ent = {
|
|
||||||
EntityID : e.target.options.data,
|
|
||||||
NewPos : [e.target._latlng.lat,e.target._latlng.lng],
|
|
||||||
dragged: true
|
|
||||||
|
|
||||||
}
|
|
||||||
this.setState((state) =>({
|
|
||||||
EntityOnFocus: Ent
|
|
||||||
}))
|
|
||||||
|
|
||||||
this.props.setEntityOnFocus(Ent);
|
|
||||||
// console.log(e.target);
|
|
||||||
|
|
||||||
// console.log(e.target._latlng);
|
|
||||||
|
|
||||||
},
|
|
||||||
// contextmenu: (e) =>
|
|
||||||
// {
|
|
||||||
// console.log("right click");
|
|
||||||
// }
|
|
||||||
}}
|
|
||||||
// eventHandlers={this.MarkerEventHandler}
|
|
||||||
>
|
|
||||||
|
|
||||||
{/* <Popup>
|
|
||||||
Omu-Aran the Head Post of Igbomina land,
|
|
||||||
is a town in the Nigerian state of Kwara.
|
|
||||||
It originated from Ife and currently the local
|
|
||||||
government headquarters of Irepodun local government.
|
|
||||||
</Popup> */}
|
|
||||||
<Tooltip direction='bottom' offset={[0,13]} opacity={1} permanent>
|
|
||||||
<span>{entity.Name}</span>
|
|
||||||
</Tooltip>
|
|
||||||
</Marker>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
setPos(props)
|
|
||||||
{
|
|
||||||
console.log(props);
|
|
||||||
|
|
||||||
this.props.setFocusPosition([1,2])
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const LocationFinderDummy = (props) => {
|
|
||||||
const map = useMapEvents({
|
|
||||||
click(e) {
|
|
||||||
|
|
||||||
props.props.setFocusPosition(e.latlng)
|
|
||||||
// console.log(e.latlng);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
// const positions = this.props.Positions.map((pos, index) => (
|
|
||||||
// <Marker name={"test"} key={index} position={pos.position} icon= {ship} />
|
|
||||||
// ));
|
|
||||||
|
|
||||||
return (
|
|
||||||
|
|
||||||
<div className='map' style={{ height: this.state.height }} >
|
|
||||||
<MapContainer center={[54, 11]} zoom={6} scrollWheelZoom={true} contextmenu={false}
|
|
||||||
|
|
||||||
>
|
|
||||||
<LocationFinderDummy props ={this.props} />
|
|
||||||
|
|
||||||
<TileLayer
|
|
||||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
|
|
||||||
<TileLayer
|
|
||||||
url="https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png" />
|
|
||||||
{/* {positions} */}
|
|
||||||
{this.props.Entities.map((pos, index) => (
|
|
||||||
this.makeIcon(index,pos,this.props,this.state)
|
|
||||||
))}
|
|
||||||
</MapContainer>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default OpenSeaMap;
|
|
||||||
57
webapp/src/components/Scenarios/Scenarios.jsx
Normal file
57
webapp/src/components/Scenarios/Scenarios.jsx
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import React from "react";
|
||||||
|
import {w3cwebsocket as W3CWebSocket} from "websocket"
|
||||||
|
|
||||||
|
|
||||||
|
function Scenarios()
|
||||||
|
{
|
||||||
|
const config = {
|
||||||
|
// apiUrl: process.env.REACT_APP_WEBAPP_WS_URL,
|
||||||
|
apiUrl: "192.168.3.13",
|
||||||
|
apiProt: 30747
|
||||||
|
}
|
||||||
|
const client = new W3CWebSocket("ws://"+config.apiUrl+":"+config.apiProt+"/");
|
||||||
|
|
||||||
|
client.onmessage = (message) => {
|
||||||
|
console.log(message);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const sendSampleMessage = () =>
|
||||||
|
{
|
||||||
|
var msg =
|
||||||
|
{
|
||||||
|
Data: "TEST",
|
||||||
|
Type: "Save",
|
||||||
|
}
|
||||||
|
console.log(msg);
|
||||||
|
client.send(JSON.stringify(msg));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const startSampleScenario = () =>
|
||||||
|
{
|
||||||
|
var msg =
|
||||||
|
{
|
||||||
|
Data: "Scenario",
|
||||||
|
Type: "AutoRaster",
|
||||||
|
}
|
||||||
|
console.log(msg);
|
||||||
|
client.send(JSON.stringify(msg));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return(
|
||||||
|
<>
|
||||||
|
<p>Scenarios</p>
|
||||||
|
<div><button onClick={sendSampleMessage}> Save Scenario</button></div>
|
||||||
|
<div><button onClick={startSampleScenario}> Sample Scenario</button></div>
|
||||||
|
|
||||||
|
</>
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Scenarios;
|
||||||
3
webapp/src/components/Scenarios/index.js
Normal file
3
webapp/src/components/Scenarios/index.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import Scenarios from "./Scenarios.jsx";
|
||||||
|
|
||||||
|
export default Scenarios;
|
||||||
12
webapp/src/components/Settings/Settings.jsx
Normal file
12
webapp/src/components/Settings/Settings.jsx
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
|
||||||
|
function Settings()
|
||||||
|
{
|
||||||
|
return(
|
||||||
|
<p>Settings</p>
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Settings;
|
||||||
3
webapp/src/components/Settings/index.js
Normal file
3
webapp/src/components/Settings/index.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import Settings from "./Settings.jsx";
|
||||||
|
|
||||||
|
export default Settings;
|
||||||
224
webapp/src/components/SimControl/SimControl.jsx
Normal file
224
webapp/src/components/SimControl/SimControl.jsx
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
import React, { Component } from "react";
|
||||||
|
import {w3cwebsocket as W3CWebSocket} from "websocket"
|
||||||
|
// import Header from './components/Header';
|
||||||
|
import OpenSeaMap from "./components/OpenSeaMap/OpenSeaMap";
|
||||||
|
import EntityControl from './components/EntityControl/EntityControl';
|
||||||
|
import Tracklist from './components/Tracklist'
|
||||||
|
import Equipment from './components/EntityControl/components/Equipment'
|
||||||
|
|
||||||
|
import Tab from 'react-bootstrap/Tab';
|
||||||
|
import Tabs from 'react-bootstrap/Tabs';
|
||||||
|
|
||||||
|
import TrackListClass from "./Tracklist.tsx";
|
||||||
|
import Track from "./Track.tsx";
|
||||||
|
|
||||||
|
import './SimControl.scss'
|
||||||
|
import EntityTrackList from "./components/EntityTrackList";
|
||||||
|
import { getCOP, getWSTestMessage } from "../api/APICalls";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
// apiUrl: process.env.REACT_APP_WEBAPP_WS_URL,
|
||||||
|
apiUrl: "192.168.3.13",
|
||||||
|
apiProt: 30747
|
||||||
|
}
|
||||||
|
const client = new W3CWebSocket("ws://"+config.apiUrl+":"+config.apiProt+"/");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class SimControl extends Component {
|
||||||
|
state = {
|
||||||
|
Entities: [],
|
||||||
|
EntityOnFocus: undefined,
|
||||||
|
PositionClicked: undefined,
|
||||||
|
TrackList_: new TrackListClass()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
componentWillUnmount()
|
||||||
|
{
|
||||||
|
// client.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
console.log(config.apiUrl);
|
||||||
|
|
||||||
|
client.onopen = () => {
|
||||||
|
console.log("Websocket Client for Map Connected");
|
||||||
|
};
|
||||||
|
|
||||||
|
client.onmessage = (message) => {
|
||||||
|
const dataFromServer = JSON.parse(message.data);
|
||||||
|
// console.log('reply: ', dataFromServer);
|
||||||
|
|
||||||
|
|
||||||
|
if(dataFromServer.Data === "COP" && dataFromServer.Entities !== undefined )
|
||||||
|
{
|
||||||
|
var idsFromWs = [];
|
||||||
|
dataFromServer.Entities.forEach((elementFromWS, indexWS) => {
|
||||||
|
idsFromWs.push(elementFromWS.id);
|
||||||
|
});
|
||||||
|
this.state.TrackList_.checkifTrackIsStillSended(idsFromWs);
|
||||||
|
// this.state.TrackList_.deleteAll();
|
||||||
|
|
||||||
|
var allTracks = this.state.TrackList_.getArrayOfKeys();
|
||||||
|
dataFromServer.Entities.forEach((elementFromWS, indexWS) => {
|
||||||
|
|
||||||
|
// console.log(elementFromWS);
|
||||||
|
if(this.state.TrackList_.isInList(elementFromWS.id))
|
||||||
|
{
|
||||||
|
this.state.TrackList_.updateTrack(elementFromWS);
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
this.state.TrackList_.addTrack(structuredClone(new Track(elementFromWS)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// console.log(this.state.TrackList_.getSize());
|
||||||
|
this.setState((state) => ({
|
||||||
|
// // Entities: structuredClone(dataFromServer.Entities)
|
||||||
|
// Entities: structuredClone(tmp)
|
||||||
|
|
||||||
|
}))
|
||||||
|
}else if(dataFromServer.Entities === undefined)
|
||||||
|
{
|
||||||
|
this.state.TrackList_.deleteAll();
|
||||||
|
console.log("delting all");
|
||||||
|
console.log(this.state.TrackList_.getSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// interval for updates
|
||||||
|
setInterval(() => {
|
||||||
|
this.updateEntities();
|
||||||
|
}, 2000);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
isStored(id) {
|
||||||
|
var found = false;
|
||||||
|
this.state.Entities.forEach((elementStored, indexStore) => {
|
||||||
|
if (id === elementStored.id)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return found;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
updateEntities()
|
||||||
|
{
|
||||||
|
// var msg =
|
||||||
|
// {
|
||||||
|
// Type: "Request",
|
||||||
|
// Data: "COP"
|
||||||
|
|
||||||
|
// }
|
||||||
|
client.send(getCOP());
|
||||||
|
}
|
||||||
|
|
||||||
|
getEntityFromID(Entities, SelectedEntity)
|
||||||
|
{
|
||||||
|
// console.log(Entities);
|
||||||
|
}
|
||||||
|
|
||||||
|
setEntityOnFocus(Entity)
|
||||||
|
{
|
||||||
|
console.log(Entity);
|
||||||
|
this.setState({
|
||||||
|
EntityOnFocus: structuredClone(this.state.TrackList_.getTrack(Entity))
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
resetEntityOnFocus()
|
||||||
|
{
|
||||||
|
if(this.state.EntityOnFocus !== undefined)
|
||||||
|
{
|
||||||
|
this.state.Entities.map((element ,index) => {
|
||||||
|
if(element.id === this.state.EntityOnFocus.EntityID)
|
||||||
|
{
|
||||||
|
this.state.Entities[index].onFocus = false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
console.log(this.state.Entities)
|
||||||
|
this.setState({
|
||||||
|
EntityOnFocus: undefined
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
setFocusPosition(props)
|
||||||
|
{
|
||||||
|
|
||||||
|
// console.log(props);
|
||||||
|
this.setState({
|
||||||
|
PositionClicked: props
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Functions = {
|
||||||
|
updateEntities: this.updateEntities.bind(this),
|
||||||
|
resetEntityOnFocus: this.resetEntityOnFocus.bind(this),
|
||||||
|
PositionClicked: this.setFocusPosition.bind(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="App">
|
||||||
|
|
||||||
|
<div className="Content">
|
||||||
|
|
||||||
|
{/* <Controls TrackList = {this.state.TrackList_} Functions= {this.Functions} Client= {client} Entities= {this.state.Entities} updateEntities = {this.updateEntities} EntityOnFocus = {this.state.EntityOnFocus} PositionClicked = {this.state.PositionClicked} /> */}
|
||||||
|
<div className="controls">
|
||||||
|
<Tracklist entities= {this.state.TrackList_} />
|
||||||
|
<Tabs
|
||||||
|
defaultActiveKey="home"
|
||||||
|
transition={false}
|
||||||
|
id="noanim-tab-example"
|
||||||
|
className="mb-3"
|
||||||
|
>
|
||||||
|
<Tab eventKey="home" title="Home">
|
||||||
|
<EntityControl
|
||||||
|
Functions = {this.props.Functions}
|
||||||
|
Client = { client }
|
||||||
|
Entity = { this.state.EntityOnFocus}
|
||||||
|
PositionClicked = {this.state.PositionClicked}
|
||||||
|
/>
|
||||||
|
</Tab>
|
||||||
|
<Tab eventKey="Equipment" title="Equipment">
|
||||||
|
<Equipment Entity ={this.state.EntityOnFocus} />
|
||||||
|
</Tab>
|
||||||
|
<Tab eventKey="internalTrack" title="internal Tracks">
|
||||||
|
Internaltracklist
|
||||||
|
</Tab>
|
||||||
|
<Tab eventKey="orders" title="Orders">
|
||||||
|
Orders
|
||||||
|
</Tab>
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<OpenSeaMap Client = {client} TrackListMap = {this.state.TrackList_.getTracks()} TrackList = {this.state.TrackList_} setFocusPosition = {this.setFocusPosition.bind(this)} setEntityOnFocus = {this.setEntityOnFocus.bind(this)} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SimControl;
|
||||||
6
webapp/src/components/SimControl/SimControl.scss
Normal file
6
webapp/src/components/SimControl/SimControl.scss
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
.controls{
|
||||||
|
/* display: flex; */
|
||||||
|
width: 24%;
|
||||||
|
float: left;
|
||||||
|
min-width: 400px;
|
||||||
|
}
|
||||||
38
webapp/src/components/SimControl/Track.tsx
Normal file
38
webapp/src/components/SimControl/Track.tsx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
class Track{
|
||||||
|
Id : string;
|
||||||
|
Name = String();
|
||||||
|
Type = String();
|
||||||
|
Side = String();
|
||||||
|
Course = Number();
|
||||||
|
Speed = Number();
|
||||||
|
External = Boolean();
|
||||||
|
Height = Number();
|
||||||
|
Position = [Number(), Number()]
|
||||||
|
isOnFucus = Boolean();
|
||||||
|
isOnEdit = Boolean();
|
||||||
|
|
||||||
|
constructor(input)
|
||||||
|
{
|
||||||
|
if(input.id !== undefined)
|
||||||
|
{
|
||||||
|
this.Id = input.id;
|
||||||
|
}else{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Name = input.Name;
|
||||||
|
this.Course = input.Course;
|
||||||
|
this.Speed = input.Speed;
|
||||||
|
this.External = input.External;
|
||||||
|
this.Height = input.Height;
|
||||||
|
this.Position = input.Position;
|
||||||
|
this.Type = input.Type;
|
||||||
|
this.Side = input.Side;
|
||||||
|
this.isOnFucus = false;
|
||||||
|
this.isOnEdit = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
export default Track
|
||||||
118
webapp/src/components/SimControl/Tracklist.tsx
Normal file
118
webapp/src/components/SimControl/Tracklist.tsx
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
|
||||||
|
import { ObjectType } from 'typescript';
|
||||||
|
import Track from './Track'
|
||||||
|
|
||||||
|
|
||||||
|
class TrackListCLass
|
||||||
|
{
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
|
this.trackMap = new Map<string, Track>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
trackMap: Map<string, Track> ;
|
||||||
|
|
||||||
|
|
||||||
|
getTrack(id :string)
|
||||||
|
{
|
||||||
|
return this.trackMap.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
isInList(id :string)
|
||||||
|
{
|
||||||
|
return this.trackMap.has(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
addTrack(track :Track)
|
||||||
|
{
|
||||||
|
this.trackMap.set(track.Id,track);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTrack(input: { id: string; Name: string; Course: number; Speed: number; External: boolean; Height: number; Position: number[]; Type: string; Side: string; })
|
||||||
|
{
|
||||||
|
|
||||||
|
var Track = this.trackMap.get(input.id);
|
||||||
|
if(Track === undefined)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Track.isOnEdit === false)
|
||||||
|
{
|
||||||
|
Track.Name = input.Name;
|
||||||
|
Track.Course = input.Course;
|
||||||
|
Track.Speed = input.Speed;
|
||||||
|
Track.External = input.External;
|
||||||
|
Track.Height = input.Height;
|
||||||
|
Track.Position = input.Position;
|
||||||
|
Track.Type = input.Type;
|
||||||
|
Track.Side = input.Side;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getKeys()
|
||||||
|
{
|
||||||
|
return this.trackMap.keys;
|
||||||
|
}
|
||||||
|
getSize()
|
||||||
|
{
|
||||||
|
return this.trackMap.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
getArrayOfKeys()
|
||||||
|
{
|
||||||
|
var Tracks = new Array<string>();
|
||||||
|
this.trackMap.forEach((val,index) =>
|
||||||
|
Tracks.push(val.Id)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
return Tracks;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTracks()
|
||||||
|
{
|
||||||
|
var Tracks = new Array<Track>();
|
||||||
|
this.trackMap.forEach((val,index) =>
|
||||||
|
Tracks.push(val)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
return Tracks;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getTrackMap()
|
||||||
|
{
|
||||||
|
return this.trackMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
deteleTrack(id :string)
|
||||||
|
{
|
||||||
|
this.trackMap.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteAll()
|
||||||
|
{
|
||||||
|
this.trackMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
checkifTrackIsStillSended(tracksFromWS: Array<string>)
|
||||||
|
{
|
||||||
|
this.trackMap.forEach((val,index) => {
|
||||||
|
if(!tracksFromWS.includes(val.Id))
|
||||||
|
{
|
||||||
|
this.deteleTrack(val.Id);
|
||||||
|
console.log("deleted: " + val.Id);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default TrackListCLass
|
||||||
@@ -4,6 +4,7 @@ import { useForm, SubmitHandler } from "react-hook-form"
|
|||||||
import Form from 'react-bootstrap/Form';
|
import Form from 'react-bootstrap/Form';
|
||||||
import FloatingLabel from 'react-bootstrap/FloatingLabel';
|
import FloatingLabel from 'react-bootstrap/FloatingLabel';
|
||||||
import InputGroup from 'react-bootstrap/InputGroup';
|
import InputGroup from 'react-bootstrap/InputGroup';
|
||||||
|
import round from "../../../Utils";
|
||||||
|
|
||||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
|
|
||||||
@@ -14,7 +15,8 @@ import './controls.css'
|
|||||||
|
|
||||||
function EntityControl(props)
|
function EntityControl(props)
|
||||||
{
|
{
|
||||||
|
const RoundPrecision = 2;
|
||||||
|
const RoundPrecisionPosition = 5;
|
||||||
|
|
||||||
|
|
||||||
const [Entity, setEntity] = useState(undefined);
|
const [Entity, setEntity] = useState(undefined);
|
||||||
@@ -23,55 +25,98 @@ function EntityControl(props)
|
|||||||
const [PositionDragged, setPositionDragged] = useState(false);
|
const [PositionDragged, setPositionDragged] = useState(false);
|
||||||
// const [Speed, setSpeed] = useState();
|
// const [Speed, setSpeed] = useState();
|
||||||
|
|
||||||
const [formData, setFormData] = useState({name: "",course: "" ,speed: 0,position: [0,0],height:0});
|
const [formData, setFormData] = useState({name: "",course: 0 ,speed: 0,position: [0,0],height:0});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => { // Update the document title using the browser API document.title = `You clicked ${count} times`;
|
// useEffect(() => { // Update the document title using the browser API document.title = `You clicked ${count} times`;
|
||||||
|
|
||||||
// console.log(props.Entity);
|
// console.log(props.Entity);
|
||||||
|
|
||||||
if(props.Entity !== undefined)
|
// if(props.Entity !== undefined)
|
||||||
{
|
// {
|
||||||
console.log(props.Entity)
|
// setEntity(Entity);
|
||||||
if(Entity === undefined)
|
// setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position,height:round(props.Entity.Height,RoundPrecision)})
|
||||||
{
|
|
||||||
setEntity(props.Entity);
|
|
||||||
setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position,height:props.Entity.Height })
|
|
||||||
|
|
||||||
}else if(Entity.id !== props.Entity.id)
|
|
||||||
{
|
|
||||||
setEntity(props.Entity);
|
|
||||||
setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position,height:props.Entity.Height})
|
|
||||||
|
|
||||||
} else if(Entity.id === props.Entity.id && Entity.Position !== props.Entity.Position)
|
|
||||||
{
|
|
||||||
setFormData({...formData,position:props.Entity.Position,height:props.Entity.Height})
|
|
||||||
setPositionDragged(true);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
// setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position})
|
|
||||||
|
|
||||||
}
|
// // // console.log(props.Entity)
|
||||||
|
// // if(Entity === undefined)
|
||||||
|
// // {
|
||||||
|
// // setEntity(props.Entity);
|
||||||
|
// // setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position,height:round(props.Entity.Height,RoundPrecision) })
|
||||||
|
|
||||||
|
// // }else if(Entity.id !== props.Entity.id)
|
||||||
|
// // {
|
||||||
|
// // setEntity(props.Entity);
|
||||||
|
// // setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position,height:round(props.Entity.Height,RoundPrecision)})
|
||||||
|
// // console.log("new entity")
|
||||||
|
// // } else if(Entity.id === props.Entity.id && Entity.Position !== props.Entity.Position)
|
||||||
|
// // {
|
||||||
|
// // setFormData({...formData,position:props.Entity.Position,height:round(props.Entity.Height,RoundPrecision)})
|
||||||
|
// // setPositionDragged(true);
|
||||||
|
// // console.log("dragged");
|
||||||
|
|
||||||
|
// // }
|
||||||
|
// // setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position})
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
},[props.Entity,props]);
|
// },[Entity, props.Entity]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if(props.PositionCliecked !== undefined)
|
// console.log(props.Entity);
|
||||||
|
|
||||||
|
// console.log(Entity);
|
||||||
|
if(props.Entity !== undefined)
|
||||||
{
|
{
|
||||||
console.log(props.PositionCliecked)
|
setEntity(structuredClone(props.Entity));
|
||||||
var pos = [0,0];
|
if(Entity === undefined)
|
||||||
pos[0] = props.PositionCliecked.lat;
|
{
|
||||||
pos[1] = props.PositionCliecked.lng
|
setEntity(props.Entity);
|
||||||
setFormData({...formData,position:pos});
|
setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position,height:round(props.Entity.Height,RoundPrecision) })
|
||||||
|
|
||||||
|
}else if(Entity.Id !== props.Entity.Id)
|
||||||
|
{
|
||||||
|
setEntity(props.Entity);
|
||||||
|
setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position,height:round(props.Entity.Height,RoundPrecision)})
|
||||||
|
console.log("new entity")
|
||||||
|
} else if(Entity.Id === props.Entity.Id && Entity.Position !== props.Entity.Position)
|
||||||
|
{
|
||||||
|
// setFormData({...formData,position:props.Entity.Position,height:round(props.Entity.Height,RoundPrecision)})
|
||||||
|
setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position,height:round(props.Entity.Height,RoundPrecision)})
|
||||||
|
|
||||||
|
setPositionDragged(true);
|
||||||
|
console.log("dragged");
|
||||||
|
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
console.log("reset");
|
||||||
|
setFormData({name:"",course:"",speed:"",position:["",""],height:"" })
|
||||||
|
setEntity(undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
},[props.PositionCliecked])
|
|
||||||
|
},[props.Entity])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(props.PositionClicked !== undefined)
|
||||||
|
{
|
||||||
|
// setEntity(undefined);
|
||||||
|
// console.log(props.PositionClicked)
|
||||||
|
var pos = [0,0];
|
||||||
|
pos[0] = props.PositionClicked.lat;
|
||||||
|
pos[1] = props.PositionClicked.lng
|
||||||
|
setFormData({...formData,name:"",course:0,speed:0,position:pos});
|
||||||
|
}
|
||||||
|
|
||||||
|
},[props.PositionClicked])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -195,9 +240,9 @@ const handleClick = (e) => {
|
|||||||
{
|
{
|
||||||
props.Entity.onFocus = undefined;
|
props.Entity.onFocus = undefined;
|
||||||
}
|
}
|
||||||
setFormData({name:'',course:'',speed:'',position:['','']})
|
setFormData({name:'',course:0,speed:0,position:[0,0],height:0})
|
||||||
setEntity(undefined)
|
setEntity(undefined)
|
||||||
props.Functions.resetEntityOnFocus();
|
// props.Functions.resetEntityOnFocus();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,16 +261,15 @@ const handleClick = (e) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// const handleChange = (event) => {
|
|
||||||
// const { name, value } = event.target;
|
|
||||||
// setFormData((prevFormData) => ({ ...prevFormData, [name]: value }));
|
|
||||||
// };
|
|
||||||
|
|
||||||
const handleSubmit = (e) => {
|
const handleSubmit = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// console.log(e.target.data);
|
// console.log(e.target.data);
|
||||||
// console.log(formData)
|
// console.log(formData)
|
||||||
console.log(Entity)
|
// console.log(Entity)
|
||||||
if(Entity === undefined)
|
if(Entity === undefined)
|
||||||
{
|
{
|
||||||
var msg =
|
var msg =
|
||||||
@@ -235,8 +279,8 @@ const handleClick = (e) => {
|
|||||||
Name: formData.name,
|
Name: formData.name,
|
||||||
Speed: formData.speed.toString(),
|
Speed: formData.speed.toString(),
|
||||||
Course: formData.course.toString(),
|
Course: formData.course.toString(),
|
||||||
Position: formData.position,
|
Position: [formData.position[0].toString(),formData.position[1].toString()],
|
||||||
Height: formData.height,
|
Height: formData.height.toString(),
|
||||||
SetPosition: true
|
SetPosition: true
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -254,11 +298,11 @@ const handleClick = (e) => {
|
|||||||
{
|
{
|
||||||
Data: "Entity",
|
Data: "Entity",
|
||||||
Type: "Update",
|
Type: "Update",
|
||||||
ID: Entity.id,
|
ID: Entity.Id,
|
||||||
Speed: formData.speed.toString(),
|
Speed: formData.speed.toString(),
|
||||||
Course: formData.course.toString(),
|
Course: formData.course.toString(),
|
||||||
Position: formData.position,
|
Position: [formData.position[0].toString(),formData.position[1].toString()],
|
||||||
Height: formData.height,
|
Height: formData.height.toString(),
|
||||||
SetPosition: setPos
|
SetPosition: setPos
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -274,7 +318,7 @@ const handleClick = (e) => {
|
|||||||
return (
|
return (
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div><button onClick={ emptyForm}> New</button> </div>
|
|
||||||
|
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<div className="ControlsComponent">
|
<div className="ControlsComponent">
|
||||||
@@ -320,6 +364,7 @@ const handleClick = (e) => {
|
|||||||
<InputGroup className="mb-3">
|
<InputGroup className="mb-3">
|
||||||
<InputGroup.Text id="basic-addon1">Name</InputGroup.Text>
|
<InputGroup.Text id="basic-addon1">Name</InputGroup.Text>
|
||||||
<Form.Control
|
<Form.Control
|
||||||
|
required
|
||||||
name="Name"
|
name="Name"
|
||||||
placeholder="Name"
|
placeholder="Name"
|
||||||
aria-label="Name"
|
aria-label="Name"
|
||||||
@@ -353,14 +398,14 @@ const handleClick = (e) => {
|
|||||||
<div class="div7">
|
<div class="div7">
|
||||||
<div class="input-group mb-3 NumberInputsGroup">
|
<div class="input-group mb-3 NumberInputsGroup">
|
||||||
<span class="input-group-text">Lat</span>
|
<span class="input-group-text">Lat</span>
|
||||||
<input className="ControlInput NumberInputs" name="Lat" type="text" onChange={handleInput} value={formData.position[0]} />
|
<input className="ControlInput NumberInputs" name="Lat" type="text" onChange={handleInput} value={round(formData.position[0],RoundPrecisionPosition)} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="div8">
|
<div class="div8">
|
||||||
<div class="input-group mb-3 NumberInputsGroup" >
|
<div class="input-group mb-3 NumberInputsGroup" >
|
||||||
<span class="input-group-text">Lon</span>
|
<span class="input-group-text">Lon</span>
|
||||||
{/* <input className="ControlInput" name="Lat" readOnly={true} type="text" onClick={handleClick} value={formData.position[0]} /> */}
|
{/* <input className="ControlInput" name="Lat" readOnly={true} type="text" onClick={handleClick} value={formData.position[0]} /> */}
|
||||||
<input className="ControlInput NumberInputs" name="Lon" readOnly={true} type="text" onClick={handleClick} onChange={handleInput} value={formData.position[1]}/>
|
<input className="ControlInput NumberInputs" name="Lon" readOnly={true} type="text" onClick={handleClick} onChange={handleInput} value={round(formData.position[1],RoundPrecisionPosition)}/>
|
||||||
</div>
|
</div>
|
||||||
{/* <div className="flex">
|
{/* <div className="flex">
|
||||||
<div className="ControlHeader">Lon:</div>
|
<div className="ControlHeader">Lon:</div>
|
||||||
@@ -378,11 +423,17 @@ const handleClick = (e) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div> <button type='submit'>Save</button> </div>
|
<div className="TopButtons">
|
||||||
|
<div><button onClick={ emptyForm}> New</button></div>
|
||||||
|
<div><button type="button" onClick={resetForm}> Reset</button></div>
|
||||||
|
<div><button type='submit'>Save</button> </div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<button onClick={resetForm}> RESET</button>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import React from "react"
|
||||||
|
import {useState,useEffect, useRef} from 'react';
|
||||||
|
|
||||||
|
|
||||||
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
|
|
||||||
|
|
||||||
|
import './Equipment.css'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function Equipment(props)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const [Entity, setEntity] = useState(undefined);
|
||||||
|
const [EntitySelected, setEntitySelected] = useState(false)
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(props.Entity !== undefined)
|
||||||
|
{
|
||||||
|
setEntity(props.Entity);
|
||||||
|
setEntitySelected(true);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
setEntitySelected(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(props)
|
||||||
|
|
||||||
|
|
||||||
|
},[props.Entity])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<b>{EntitySelected ? '' : 'no Entity Selected'}</b>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Equipment;
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import Equipment from "./Equipment";
|
||||||
|
|
||||||
|
export default Equipment;
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
.controls{
|
|
||||||
/* display: flex; */
|
|
||||||
width: 24%;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ControlsComponent{
|
.ControlsComponent{
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -56,20 +51,12 @@ float: left;
|
|||||||
display: contents;
|
display: contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .parent {
|
.TopButtons
|
||||||
display: grid;
|
{
|
||||||
grid-template-columns: repeat(2, 1fr);
|
width: 100%;
|
||||||
grid-template-rows: repeat(3 2em);
|
justify-content: space-evenly;
|
||||||
grid-column-gap: 0px;
|
display: flex;
|
||||||
grid-row-gap: 0px;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.div1 { grid-area: 1 / 1 / 2 / 3; }
|
|
||||||
.div2 { grid-area: 2 / 1 / 3 / 2; }
|
|
||||||
.div3 { grid-area: 2 / 2 / 3 / 3; }
|
|
||||||
.div4 { grid-area: 3 / 2 / 4 / 3; }
|
|
||||||
.div5 { grid-area: 3 / 1 / 4 / 2; } */
|
|
||||||
|
|
||||||
|
|
||||||
.parent {
|
.parent {
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import './controls.css'
|
||||||
|
// import { sendMsg } from '../api';
|
||||||
|
import Tracklist from './Tracklist'
|
||||||
|
import EntityControl from './EntityControl';
|
||||||
|
import round from '../../../Utils';
|
||||||
|
// import {w3cwebsocket as W3CWebSocket} from "websocket"
|
||||||
|
import Tab from 'react-bootstrap/Tab';
|
||||||
|
import Tabs from 'react-bootstrap/Tabs';
|
||||||
|
import Track from '../../Track';
|
||||||
|
|
||||||
|
|
||||||
|
class Controls extends React.Component
|
||||||
|
{
|
||||||
|
|
||||||
|
state = {
|
||||||
|
EntityOnFocus: undefined,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getEntityOnEdit(Entities)
|
||||||
|
{
|
||||||
|
// console.log(Entities.getTracks());
|
||||||
|
// Entities.getTracks().map()
|
||||||
|
var val = undefined;
|
||||||
|
var array = Entities.getTracks();
|
||||||
|
for (let index = 0; index < array.length; index++)
|
||||||
|
{
|
||||||
|
if(array[index].isOnEdit === true)
|
||||||
|
{
|
||||||
|
val = array[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
saveScenario(e)
|
||||||
|
{
|
||||||
|
var msg =
|
||||||
|
{
|
||||||
|
Data: "Scenario",
|
||||||
|
Type: "Save",
|
||||||
|
}
|
||||||
|
|
||||||
|
this.props.Client.send(JSON.stringify(msg))
|
||||||
|
console.log("save scenario")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
render() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// console.log(getEntityFromID(this.props.Entities,this.props.EntityOnFocus));
|
||||||
|
return (
|
||||||
|
<div className="controls">
|
||||||
|
<Tracklist entities= {this.props.TrackList} />
|
||||||
|
<br />
|
||||||
|
<div><button onClick={ this.saveScenario}> Save Scenario</button></div>
|
||||||
|
|
||||||
|
{/* <Tabs
|
||||||
|
defaultActiveKey="home"
|
||||||
|
transition={false}
|
||||||
|
id="noanim-tab-example"
|
||||||
|
className="mb-3"
|
||||||
|
>
|
||||||
|
<Tab eventKey="home" title="Home">
|
||||||
|
<EntityControl
|
||||||
|
Functions = {this.props.Functions}
|
||||||
|
Client = { this.props.Client }
|
||||||
|
TrackList = { this.props.TrackList}
|
||||||
|
PositionCliecked = {this.props.PositionClicked}
|
||||||
|
/>
|
||||||
|
</Tab>
|
||||||
|
<Tab eventKey="internalTrack" title="Internaltrack">
|
||||||
|
Internaltracklist
|
||||||
|
</Tab>
|
||||||
|
<Tab eventKey="orders" title="Orders">
|
||||||
|
Orders
|
||||||
|
</Tab>
|
||||||
|
</Tabs> */}
|
||||||
|
<div className="controls">
|
||||||
|
{/* <button onClick={this.props.updateEntities}>update</button> */}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Controls;
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import EntityControl from "../EntityControl/EntityControl";
|
||||||
|
|
||||||
|
export default EntityControl;
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
import { useEffect } from "react";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
import { useInterval } from 'usehooks-ts'
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
// apiUrl: process.env.REACT_APP_WEBAPP_WS_URL,
|
||||||
|
apiUrl: "192.168.3.13",
|
||||||
|
apiProt: 30747
|
||||||
|
}
|
||||||
|
const client = new WebSocket("ws://"+config.apiUrl+":"+config.apiProt+"/");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function EntityTrackList( props)
|
||||||
|
{
|
||||||
|
|
||||||
|
const [Entity, setEntity] = useState(undefined);
|
||||||
|
// const [client, setclient] = useState(new WebSocket("ws://"+config.apiUrl+":"+config.apiProt+"/"));
|
||||||
|
|
||||||
|
// const client = new WebSocket("ws://"+config.apiUrl+":"+config.apiProt+"/");
|
||||||
|
const [TrackList, setTrackList] = useState([]);
|
||||||
|
client.onopen =() =>{
|
||||||
|
console.log("ws client for tracklist is connected");
|
||||||
|
// var msg =
|
||||||
|
// {
|
||||||
|
// Data: "COP",
|
||||||
|
// Type: "EntityTrackList"
|
||||||
|
|
||||||
|
// }
|
||||||
|
// client.send(JSON.stringify(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
client.onmessage = (message) => {
|
||||||
|
console.log(message);
|
||||||
|
if(Array.isArray(message)=== true)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useInterval(
|
||||||
|
() => {
|
||||||
|
// Your custom logic here
|
||||||
|
// setCount(count + 1)
|
||||||
|
console.log("updating")
|
||||||
|
updateTracklist();
|
||||||
|
},
|
||||||
|
// Delay in milliseconds or null to stop it
|
||||||
|
5000
|
||||||
|
// isPlaying ? delay : null,
|
||||||
|
)
|
||||||
|
|
||||||
|
const updateTracklist = () =>
|
||||||
|
{
|
||||||
|
if(Entity !== undefined)
|
||||||
|
{
|
||||||
|
var msg =
|
||||||
|
{
|
||||||
|
Data: "COP",
|
||||||
|
Type: "EntityTrackList",
|
||||||
|
ID: props.Entity.Id
|
||||||
|
|
||||||
|
}
|
||||||
|
client.send(JSON.stringify(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
console.log("wird neu gerendert")
|
||||||
|
},[])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(props.Entity !== undefined)
|
||||||
|
{
|
||||||
|
if(Entity === undefined)
|
||||||
|
{
|
||||||
|
setEntity(props.Entity);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
if(props.Entity.Id !== Entity.Id)
|
||||||
|
{
|
||||||
|
setEntity(props.Entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateTracklist();
|
||||||
|
|
||||||
|
}
|
||||||
|
console.log(props.Entity);
|
||||||
|
|
||||||
|
},[props.Entity])
|
||||||
|
|
||||||
|
// useEffect(() =>
|
||||||
|
// {
|
||||||
|
|
||||||
|
// },[Entity])
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div className="tracklist">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr className='TracklistHeader'>
|
||||||
|
<th className='TracklistHeaderCell'>Name</th>
|
||||||
|
<th className='TracklistHeaderCell'>Course</th>
|
||||||
|
<th className='TracklistHeaderCell'>Speed</th>
|
||||||
|
<th className='TracklistHeaderCell'>Distance</th>
|
||||||
|
<th className='TracklistHeaderCell'>Bearing</th>
|
||||||
|
<th className='TracklistHeaderCell'>Kind</th>
|
||||||
|
<th className='TracklistHeaderCell'>Side</th>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{ TrackList.map((val,index) => {
|
||||||
|
return (
|
||||||
|
<tr key={index}>
|
||||||
|
<td >{val.Name}</td>
|
||||||
|
<td className='TracklistCell'>{val.Course}</td>
|
||||||
|
<td className='TracklistCell'>{val.Speed}</td>
|
||||||
|
<td className='TracklistCell'>{}</td>
|
||||||
|
<td className='TracklistCell'>{}</td>
|
||||||
|
<td className='TracklistCell'>{val.Type}</td>
|
||||||
|
<td className='TracklistCell'>{val.Side}</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
)}
|
||||||
|
|
||||||
|
export default EntityTrackList;
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import EntityTrackList from "./EntityTrackList";
|
||||||
|
|
||||||
|
export default EntityTrackList;
|
||||||
@@ -0,0 +1,249 @@
|
|||||||
|
|
||||||
|
// import { useMapEvents } from 'react-leaflet/hooks'
|
||||||
|
import React, { Component } from "react";
|
||||||
|
import { MapContainer, TileLayer,Marker, Popup, Tooltip,useMapEvents } from 'react-leaflet'
|
||||||
|
import { createIcon } from "./icon";
|
||||||
|
import "./OpenSeaMap.scss";
|
||||||
|
// import {w3cwebsocket as W3CWebSocket} from "websocket";
|
||||||
|
// import ContainerDimensions from 'react-container-dimensions';
|
||||||
|
import {} from "leaflet-contextmenu";
|
||||||
|
import Track from "../../Track.tsx";
|
||||||
|
|
||||||
|
|
||||||
|
class OpenSeaMap extends Component {
|
||||||
|
|
||||||
|
|
||||||
|
state = {
|
||||||
|
EntityOnFocus: Track,
|
||||||
|
}
|
||||||
|
updateDimensions() {
|
||||||
|
const height = window.innerWidth >= 950 ? window.innerHeight : 400
|
||||||
|
this.setState({ height: height })
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
this.updateDimensions()
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
window.addEventListener("resize", this.updateDimensions.bind(this))
|
||||||
|
// console.log(this.state.EntityOnFocus);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
window.removeEventListener("resize", this.updateDimensions.bind(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
handleClick(e)
|
||||||
|
{
|
||||||
|
// console.log(e.target)
|
||||||
|
// this.setState({ currentPos: e.latlng });
|
||||||
|
// console.log(e.latlng);
|
||||||
|
|
||||||
|
// console.log("hello world");
|
||||||
|
}
|
||||||
|
|
||||||
|
markerOnClick(e) {
|
||||||
|
// console.log(e);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
setOnEdit(e)
|
||||||
|
{
|
||||||
|
var Track = this.props.TrackList.getTrack(e.relatedTarget.options.data);
|
||||||
|
Track.isOnEdit = true;
|
||||||
|
// console.log(Track);
|
||||||
|
|
||||||
|
|
||||||
|
this.setState((state) =>({
|
||||||
|
EntityOnFocus: Track
|
||||||
|
}))
|
||||||
|
this.props.setEntityOnFocus(Track.Id);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteEntity(id)
|
||||||
|
{
|
||||||
|
// console.log(id);
|
||||||
|
try {
|
||||||
|
var msg =
|
||||||
|
{
|
||||||
|
Data: "Entity",
|
||||||
|
Type: "Delete",
|
||||||
|
ID: id,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.props.TrackList.deteleTrack(id);
|
||||||
|
this.props.Client.send(JSON.stringify(msg))
|
||||||
|
this.forceUpdate();
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
resetFocus(e)
|
||||||
|
{
|
||||||
|
if(e !== undefined)
|
||||||
|
{
|
||||||
|
var Track = this.props.TrackList.getTrack(e.relatedTarget.options.data);
|
||||||
|
if(Track !== undefined)
|
||||||
|
{
|
||||||
|
Track.isOnEdit = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(Track);
|
||||||
|
}
|
||||||
|
this.props.setEntityOnFocus(undefined);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
setNewEntityPosition(e)
|
||||||
|
{
|
||||||
|
// console.log(e.target.options);
|
||||||
|
var Track = this.props.TrackList.getTrack(e.target.options.data);
|
||||||
|
Track.isOnEdit = true;
|
||||||
|
Track.Position = [e.target._latlng.lat,e.target._latlng.lng];
|
||||||
|
// console.log(Track);
|
||||||
|
this.props.setEntityOnFocus(e.target.options.data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
makeIcon(index, entity,props,state)
|
||||||
|
{
|
||||||
|
|
||||||
|
// console.log(entity);
|
||||||
|
var isOnFocus = false;
|
||||||
|
|
||||||
|
if(entity.isOnEdit === true)
|
||||||
|
{
|
||||||
|
isOnFocus = true
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var icon = createIcon(entity.Type,entity.Side)
|
||||||
|
return (
|
||||||
|
<Marker name={entity.Name} key={entity.Id} icon={icon} position={entity.Position} data={entity.Id}
|
||||||
|
draggable={isOnFocus? true : false}
|
||||||
|
contextmenu={true}
|
||||||
|
contextmenuWidth={140}
|
||||||
|
|
||||||
|
contextmenuItems={[{
|
||||||
|
text:"Edit",
|
||||||
|
index:0,
|
||||||
|
callback: this.setOnEdit.bind(this),
|
||||||
|
},{
|
||||||
|
text:"Delete",
|
||||||
|
index: 1,
|
||||||
|
callback: this.deleteEntity.bind(this,entity.Id),
|
||||||
|
}, {
|
||||||
|
text:"Test",
|
||||||
|
callback: this.markerOnClick.bind(this),
|
||||||
|
// separator: true,
|
||||||
|
index: 2
|
||||||
|
}, {
|
||||||
|
text:"Exit",
|
||||||
|
callback: this.resetFocus.bind(this),
|
||||||
|
|
||||||
|
index: 3
|
||||||
|
}]}
|
||||||
|
|
||||||
|
eventHandlers={{
|
||||||
|
click: (e) => {
|
||||||
|
console.log(entity.Name);
|
||||||
|
console.log(entity.id);
|
||||||
|
|
||||||
|
this.props.setEntityOnFocus(e.target.options.data)
|
||||||
|
|
||||||
|
},
|
||||||
|
dragend: this.setNewEntityPosition.bind(this),
|
||||||
|
|
||||||
|
}}
|
||||||
|
// eventHandlers={this.MarkerEventHandler}
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
<Tooltip direction='bottom' offset={[0,13]} opacity={1} permanent>
|
||||||
|
<span>{entity.Name}</span>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
|
</Marker>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
setPos(props)
|
||||||
|
{
|
||||||
|
console.log(props);
|
||||||
|
|
||||||
|
this.props.setFocusPosition([1,2])
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const LocationFinderDummy = (props) => {
|
||||||
|
const map = useMapEvents({
|
||||||
|
|
||||||
|
click(e) {
|
||||||
|
|
||||||
|
// console.log(props)
|
||||||
|
props.props.resetFocus();
|
||||||
|
// props.props.state.EntityOnFocus =undefined
|
||||||
|
|
||||||
|
// props.props.props.setEntityOnFocus(undefined);
|
||||||
|
|
||||||
|
|
||||||
|
props.props.props.setFocusPosition(e.latlng)
|
||||||
|
|
||||||
|
|
||||||
|
// console.log(e.latlng);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// this.state.EntityOnFocus = undefined;
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
|
||||||
|
<div className='map' style={{ height: this.state.height }} >
|
||||||
|
<MapContainer center={[54, 11]} zoom={6} scrollWheelZoom={true} contextmenu={false} attributionControl={false}
|
||||||
|
|
||||||
|
>
|
||||||
|
<LocationFinderDummy props ={{props:this.props, resetFocus:this.resetFocus.bind(this)}} />
|
||||||
|
|
||||||
|
<TileLayer
|
||||||
|
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
|
||||||
|
<TileLayer
|
||||||
|
url="https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png" />
|
||||||
|
|
||||||
|
{
|
||||||
|
this.props.TrackListMap.map((element,index) => (
|
||||||
|
this.makeIcon(index,element)
|
||||||
|
))}
|
||||||
|
|
||||||
|
</MapContainer>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default OpenSeaMap;
|
||||||
@@ -93,4 +93,11 @@ const Hostile = new Icon({
|
|||||||
iconAnchor: [hostile.getAnchor().x, hostile.getAnchor().y],
|
iconAnchor: [hostile.getAnchor().x, hostile.getAnchor().y],
|
||||||
});
|
});
|
||||||
|
|
||||||
export { iconShip, friend,Hostile,createIcon };
|
|
||||||
|
|
||||||
|
var OwnShipIcon = new Icon({
|
||||||
|
iconUrl: 'Own_Ship.svg',
|
||||||
|
iconSize: [50, 50], // size of the icon
|
||||||
|
});
|
||||||
|
|
||||||
|
export {OwnShipIcon, iconShip, friend,Hostile,createIcon };
|
||||||
@@ -1,15 +1,25 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './tracklist.scss'
|
import './tracklist.scss'
|
||||||
import round from '../../Utils';
|
import round from '../../../Utils';
|
||||||
|
import {useState,useEffect, useRef} from 'react';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Tracklist extends React.Component
|
// class Tracklist extends React.Component
|
||||||
{
|
|
||||||
render()
|
|
||||||
{
|
|
||||||
|
|
||||||
return(
|
|
||||||
|
function Tracklist(props) {
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
console.log("tracklist")
|
||||||
|
|
||||||
|
|
||||||
|
},[])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return(
|
||||||
<div className="tracklist">
|
<div className="tracklist">
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
@@ -25,14 +35,14 @@ class Tracklist extends React.Component
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{ this.props.entities.map((val,index) => {
|
{ props.entities.getTracks().map((val,index) => {
|
||||||
return (
|
return (
|
||||||
<tr key={index}>
|
<tr key={index}>
|
||||||
<td >{val.Name}</td>
|
<td >{val.Name}</td>
|
||||||
<td className='TracklistCell'>{val.Course}</td>
|
<td className='TracklistCell'>{val.Course}</td>
|
||||||
<td className='TracklistCell'>{val.Speed}</td>
|
<td className='TracklistCell'>{val.Speed}</td>
|
||||||
<td className='TracklistCell'>{round(val.Position[0],3)}</td>
|
<td className='TracklistCell'>{round(val.Position[0],4)}</td>
|
||||||
<td className='TracklistCell'>{round(val.Position[1],3)}</td>
|
<td className='TracklistCell'>{round(val.Position[1],4)}</td>
|
||||||
<td className='TracklistCell'>{val.Type}</td>
|
<td className='TracklistCell'>{val.Type}</td>
|
||||||
<td className='TracklistCell'>{val.Side}</td>
|
<td className='TracklistCell'>{val.Side}</td>
|
||||||
|
|
||||||
@@ -43,7 +53,7 @@ class Tracklist extends React.Component
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2,8 +2,9 @@
|
|||||||
{
|
{
|
||||||
display: flex;
|
display: flex;
|
||||||
max-height: 40%;
|
max-height: 40%;
|
||||||
height: 300px;
|
height: 400px;
|
||||||
display: block;
|
display: block;
|
||||||
|
overflow: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
td
|
td
|
||||||
3
webapp/src/components/SimControl/index.js
Normal file
3
webapp/src/components/SimControl/index.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import SimControl from "./SimControl.jsx";
|
||||||
|
|
||||||
|
export default SimControl;
|
||||||
133
webapp/src/components/api/APICalls.jsx
Normal file
133
webapp/src/components/api/APICalls.jsx
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
export function getCOP()
|
||||||
|
{
|
||||||
|
var msg =
|
||||||
|
{
|
||||||
|
Type: "Request",
|
||||||
|
Data: "COP"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.stringify(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function deleteEntity(id)
|
||||||
|
{
|
||||||
|
var msg =
|
||||||
|
{
|
||||||
|
Data: "Entity",
|
||||||
|
Type: "Delete",
|
||||||
|
ID: id,
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.stringify(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createEntity(Name,Speed,Course, Position, Height)
|
||||||
|
{
|
||||||
|
var msg =
|
||||||
|
{
|
||||||
|
Data: "Entity",
|
||||||
|
Type: "New",
|
||||||
|
Name: Name,
|
||||||
|
Speed: Speed.toString(),
|
||||||
|
Course: Course.toString(),
|
||||||
|
Position: [Position[0].toString(),Position[1].toString()],
|
||||||
|
Height: Height.toString(),
|
||||||
|
SetPosition: true
|
||||||
|
|
||||||
|
}
|
||||||
|
return JSON.stringify(msg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateEntity(id,Speed,Course, Position, Height, setPos)
|
||||||
|
{
|
||||||
|
var msg =
|
||||||
|
{
|
||||||
|
Data: "Entity",
|
||||||
|
Type: "Update",
|
||||||
|
ID: id,
|
||||||
|
Speed: Speed.toString(),
|
||||||
|
Course: Course.toString(),
|
||||||
|
Position: [Position[0].toString(),Position[1].toString()],
|
||||||
|
Height: Height.toString(),
|
||||||
|
SetPosition: setPos
|
||||||
|
|
||||||
|
}
|
||||||
|
return JSON.stringify(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function getTracklist(id)
|
||||||
|
{
|
||||||
|
var msg =
|
||||||
|
{
|
||||||
|
Data: "COP",
|
||||||
|
Type: "EntityTrackList",
|
||||||
|
ID: id,
|
||||||
|
}
|
||||||
|
return JSON.stringify(msg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function saveScenario()
|
||||||
|
{
|
||||||
|
var msg =
|
||||||
|
{
|
||||||
|
Data: "Scenario",
|
||||||
|
Type: "Save",
|
||||||
|
}
|
||||||
|
return JSON.stringify(msg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deleteScenario()
|
||||||
|
{
|
||||||
|
var msg =
|
||||||
|
{
|
||||||
|
Data: "Scenario",
|
||||||
|
Type: "Delete",
|
||||||
|
}
|
||||||
|
return JSON.stringify(msg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export function loadScenario(id)
|
||||||
|
{
|
||||||
|
var msg =
|
||||||
|
{
|
||||||
|
Data: "Scenario",
|
||||||
|
Type: "Load",
|
||||||
|
ID: id,
|
||||||
|
}
|
||||||
|
return JSON.stringify(msg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export function loadAutoraster()
|
||||||
|
{
|
||||||
|
var msg =
|
||||||
|
{
|
||||||
|
Data: "Scenario",
|
||||||
|
Type: "AutoRaster",
|
||||||
|
}
|
||||||
|
return JSON.stringify(msg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function getWSTestMessage()
|
||||||
|
{
|
||||||
|
var msg =
|
||||||
|
{
|
||||||
|
Data: "TEST",
|
||||||
|
}
|
||||||
|
return JSON.stringify(msg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
// // api/index.js
|
|
||||||
// var socket = new WebSocket("ws://localhost:8008/");
|
|
||||||
|
|
||||||
// let connect = cb => {
|
|
||||||
// console.log("connecting");
|
|
||||||
|
|
||||||
// socket.onopen = () => {
|
|
||||||
// console.log("Successfully Connected");
|
|
||||||
// };
|
|
||||||
|
|
||||||
// socket.onmessage = msg => {
|
|
||||||
// cb(msg);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// socket.onclose = event => {
|
|
||||||
// console.log("Socket Closed Connection: ", event);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// socket.onerror = error => {
|
|
||||||
// console.log("Socket Error: ", error);
|
|
||||||
// };
|
|
||||||
// };
|
|
||||||
|
|
||||||
|
|
||||||
// let sendMsg = msg => {
|
|
||||||
// console.log("sending msg: ", msg);
|
|
||||||
// socket.send(msg);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// export { connect, sendMsg };
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import './controls.css'
|
|
||||||
// import { sendMsg } from '../api';
|
|
||||||
import Tracklist from './Tracklist'
|
|
||||||
import EntityControl from './EntityControl';
|
|
||||||
import round from '../Utils';
|
|
||||||
// import {w3cwebsocket as W3CWebSocket} from "websocket"
|
|
||||||
|
|
||||||
|
|
||||||
// const config = {
|
|
||||||
// // apiUrl: process.env.REACT_APP_WEBAPP_WS_URL,
|
|
||||||
// apiUrl: "192.168.3.13",
|
|
||||||
// apiProt: 30747
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// const client = new W3CWebSocket("ws://"+config.apiUrl+":"+config.apiProt+"/");
|
|
||||||
|
|
||||||
// const round = (n, dp) => {
|
|
||||||
// const h = +('1'.padEnd(dp + 1, '0')) // 10 or 100 or 1000 or etc
|
|
||||||
// return Math.round(n * h) / h
|
|
||||||
// }
|
|
||||||
|
|
||||||
class Controls extends React.Component
|
|
||||||
{
|
|
||||||
|
|
||||||
state = {
|
|
||||||
EntityOnFocus: undefined,
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount()
|
|
||||||
{
|
|
||||||
// client.onopen = () => {
|
|
||||||
// console.log(" Control Websocket Client Connected");
|
|
||||||
// };
|
|
||||||
|
|
||||||
// client.onmessage = (message) => {
|
|
||||||
// const dataFromServer = JSON.parse(message.data);
|
|
||||||
// console.log('reply', dataFromServer);
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
|
||||||
function getEntityFromID(Entities, SelectedEntity)
|
|
||||||
{
|
|
||||||
if(SelectedEntity !== undefined)
|
|
||||||
{
|
|
||||||
var tmp = {};
|
|
||||||
// tmp.NewPos= new Array(0,0);
|
|
||||||
// console.log(tmp);
|
|
||||||
|
|
||||||
Entities.map((val) => {
|
|
||||||
if(val.id === SelectedEntity.EntityID)
|
|
||||||
{
|
|
||||||
tmp = val
|
|
||||||
// tmp = JSON.parse(JSON.stringify(val));
|
|
||||||
// console.log(tmp);
|
|
||||||
val.dragged = SelectedEntity.dragged;
|
|
||||||
if(SelectedEntity.dragged === undefined)
|
|
||||||
{
|
|
||||||
val.dragged = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log(SelectedEntity);
|
|
||||||
|
|
||||||
// if(SelectedEntity.NewPos !== undefined)
|
|
||||||
// {
|
|
||||||
// // Object.assign(tmp, {NewPos: [{},{}]});
|
|
||||||
// Object.assign(val, {NewPos: [{},{}]});
|
|
||||||
|
|
||||||
// // tmp.OldPos = val.Position;
|
|
||||||
// // Object.assign(tmp, {NewPos: [round(SelectedEntity.NewPos[0],3),0]});
|
|
||||||
// // val.NewPos = SelectedEntity.NewPos;
|
|
||||||
// val.NewPos[0] = round(SelectedEntity.NewPos[0],3);
|
|
||||||
// val.NewPos[1] = round(SelectedEntity.NewPos[1],3);
|
|
||||||
|
|
||||||
// // tmp.NewPos[0] = round(SelectedEntity.NewPos[0],3);
|
|
||||||
// // tmp.NewPos[1] = round(SelectedEntity.NewPos[1],3);
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// tmp.NewPos = SelectedEntity.NewPos;
|
|
||||||
}
|
|
||||||
return tmp;
|
|
||||||
})
|
|
||||||
// console.log(tmp);
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// console.log(getEntityFromID(this.props.Entities,this.props.EntityOnFocus));
|
|
||||||
return (
|
|
||||||
<div className="controls">
|
|
||||||
<Tracklist entities= {this.props.Entities} />
|
|
||||||
<br />
|
|
||||||
<div>
|
|
||||||
{/* <button onClick={this.props.updateEntities}>update</button> */}
|
|
||||||
<EntityControl Functions = {this.props.Functions} Client = { this.props.Client } Entity = { getEntityFromID(this.props.Entities,this.props.EntityOnFocus)} EntityOnFocus= {this.props.EntityOnFocus} PositionCliecked = {this.props.PositionClicked}/>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Controls;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
import Controls from "./controls.jsx";
|
|
||||||
|
|
||||||
export default Controls;
|
|
||||||
Reference in New Issue
Block a user