forked from libremesh/lime-app
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgetLinksCoordinates.ts
109 lines (97 loc) · 3.91 KB
/
getLinksCoordinates.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import {
MacToMacLink,
PontToPointLink,
} from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink";
import {
IBaseLink,
ILinks,
INodes,
LinkType,
LocatedLinkData,
} from "plugins/lime-plugin-mesh-wide/src/meshWideTypes";
import { isEmpty } from "utils/utils";
export const mergeLinksAndCoordinates = <T extends LinkType>(
links: ILinks<T>,
type: T,
nodes?: INodes
): LocatedLinkData => {
if (!links || isEmpty(links)) return {};
const result: LocatedLinkData = {};
// for every node check all links
for (const actualNodeName in links) {
if (
isEmpty(links[actualNodeName]) ||
typeof links[actualNodeName].links !== "object" // todo(kon): this is an error from the backend
)
continue;
const srcLoc = links[actualNodeName].src_loc;
for (const [linkKey, linkData] of Object.entries(
links[actualNodeName].links
)) {
// Find destination link info from shared state
let dest: IBaseLink<T>;
for (const destNodeKey in links) {
// Prevent empty objects crashing from shared state
if (links[destNodeKey] && !isEmpty(links[destNodeKey]?.links)) {
const link = Object.entries(links[destNodeKey].links).find(
([key]) =>
key === linkKey && destNodeKey !== actualNodeName
);
if (link) {
dest = { [destNodeKey]: link[1] };
}
}
}
let destLoc = linkData?.dst_loc;
// If destination coords are undefined, try to find it on other ways.
if (!destLoc) {
if (dest && links[Object.keys(dest)[0]].src_loc) {
// If we have destination link info, try to find the src_loc
destLoc = links[Object.keys(dest)[0]].src_loc;
} else {
// Find the destination MAC between existing located nodes to get the position
const dstNode = Object.values(nodes).find((node) => {
return node.macs.find((mac) => {
return (
mac.toLowerCase() ===
linkData.dst_mac.toLowerCase()
);
});
});
if (dstNode) {
destLoc = dstNode.coordinates;
}
}
}
// What happen if the destination link or location is undefined?
// Maybe drawing somehow to the map and show the user that the link is not complete
// For the moment lets ignore the link
if (!destLoc) {
continue;
}
// Get Geolink key to check if is already added
const geoLinkKey = PontToPointLink.generateId(srcLoc, destLoc);
// If the link PontToPointLink already exists and the link is already added, ignore it
if (result[geoLinkKey] && result[geoLinkKey].linkExists(linkKey)) {
continue;
}
// Instantiate new point to point link on the results array
if (!result[geoLinkKey]) {
result[geoLinkKey] = new PontToPointLink(srcLoc, destLoc);
}
// Add node names to the link data
result[geoLinkKey].addNodes([
actualNodeName,
...Object.keys(dest ?? ""), // If destination node is down, ignore node name
]);
const entry = {
[actualNodeName]: {
...linkData,
},
...dest,
} as IBaseLink<T>;
result[geoLinkKey].addLink(new MacToMacLink(linkKey, entry, type));
}
}
return result;
};