Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Node-RED TAK Map Flow
[
{
"id": "c574bf6a.276f2",
"type": "tcp in",
"z": "65e4b241.fe35fc",
"name": "FTS Server",
"server": "client",
"host": "fts.example.com",
"port": "8087",
"datamode": "stream",
"datatype": "utf8",
"newline": "",
"topic": "",
"base64": false,
"x": 180,
"y": 100,
"wires": [
[
"aebc8b7b.787ad8"
]
]
},
{
"id": "aebc8b7b.787ad8",
"type": "xml",
"z": "65e4b241.fe35fc",
"name": "",
"property": "payload",
"attr": "",
"chr": "",
"x": 310,
"y": 100,
"wires": [
[
"369f8d28.1a2892"
]
]
},
{
"id": "369f8d28.1a2892",
"type": "function",
"z": "65e4b241.fe35fc",
"name": "CoT to Map",
"func": "/*\nThe following block of code transforms a JSONified CoT Event into a Worldmap \nPoint Payload.\n*/\n\nlet icon = null;\nlet invalid = \"9999999.0\";\nlet event = msg.payload[\"event\"];\n\n/* \nIf the CoT Event contains Detail Elements, extract the first one.\nIf there are no Detail Elements, break.\n*/\nlet _detail = event[\"detail\"];\nif (_detail === undefined) {\n return null;\n}\nlet detail = _detail[0];\n\n/*\nIf the CoT Event contains a Point element, use it. If not, break.\n*/\nlet point = event[\"point\"];\nif (point === undefined) {\n return null;\n}\n\n/* We'll use UID a couple of times, so lets set it as a variable here. */\nlet uid = event[\"$\"][\"uid\"];\n\n/* Extract the Event Type and Affiliation. */\nlet eventType = event[\"$\"][\"type\"];\net = eventType.split(\"-\");\nlet affil = et[1];\n\n/* There is no '.' notation in SDR, so mark Neutral. */\nif (affil.includes(\".\")) {\n affil = \"n\";\n} \n\n/* Ram the CoT Event Type portions into a SIDR Type */\nlet SIDC = `s${affil}${et[2]}p${et[3] || \"-\" }${et[4] || \"-\" }${et[5] || \"-\" }--------`;\n\n/* \nPoints on the Worldmap can only have one uniquite identifier, which is also\nthat Points display name. If possible, use a Callsign, otherwise use UID.\n*/\nlet callsign;\nlet _contact = detail[\"contact\"];\nif (_contact === undefined) {\n callsign = uid;\n} else {\n callsign = _contact[0][\"$\"][\"callsign\"]; \n}\n\n/* Mouse-over Label */\nlet label = `Callsign: ${callsign} UID: ${uid}<br/>Type: ${eventType} SIDC: ${SIDC}`\n\nlet remarks = detail[\"remarks\"];\nif (remarks) {\n remark = remarks[0][\"$\"];\n label = `${label}<br/>${remarks}`;\n}\n\nlet track = detail[\"track\"]\n\nbearing = null;\nspeed = null;\n\nif (track) {\n course = track[0][\"$\"][\"course\"];\n if (course) {\n if (course.toString() !== invalid && course.toString() !== \"0\") {\n bearing = course;\n }\n }\n\n _speed = track[0][\"$\"][\"speed\"];\n if (_speed) {\n if (_speed.toString() !== invalid) {\n speed = _speed;\n }\n }\n}\n\n/* \nIf CoT Point CE is set and is not invalid, use that as Worldmap Point Accuracy. \n*/\naccuracy = null;\nce = event[\"point\"][0][\"$\"][\"ce\"];\nif (ce.toString() !== invalid) {\n accuracy = ce;\n}\n\n/* Add a helpful weblink to Worldmap Points. */\nweblink = null;\nif (uid.includes(\"ICAO\")) {\n weblink = `https://globe.adsbexchange.com/?icao=${uid.replace(\"ICAO-\", \"\")}`;\n} else if (uid.includes(\"APRS\")) {\n weblink = `https://qrz.com/db/${uid.replace(\"APRS.\", \"\").split(\"-\")[0]}`;\n}\n\n/* Serialize as a Worldmap compatible Payload. */\nmsg.payload = {\n name: callsign,\n tooltip: label,\n lat: event[\"point\"][0][\"$\"][\"lat\"],\n lon: event[\"point\"][0][\"$\"][\"lon\"],\n speed: speed,\n bearing: bearing,\n accuracy: accuracy,\n SIDC: SIDC,\n icon: icon,\n ttl: 3600,\n weblink: weblink,\n layer: eventType\n}\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 450,
"y": 100,
"wires": [
[
"f7b3616c.ff8d4"
]
]
},
{
"id": "f7b3616c.ff8d4",
"type": "worldmap",
"z": "65e4b241.fe35fc",
"name": "TAK Map",
"lat": "37.76",
"lon": "-122.4975",
"zoom": "",
"layer": "OSM",
"cluster": "",
"maxage": "",
"usermenu": "show",
"layers": "show",
"panit": "false",
"panlock": "false",
"zoomlock": "false",
"hiderightclick": "false",
"coords": "deg",
"showgrid": "true",
"path": "/tak",
"x": 600,
"y": 100,
"wires": []
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment