Automating the Aviation Maps Assembly Process
By Dominic Frank · September 9, 2026
[!INFO] Don’t want to read? Scroll through the pretty pictures :)
The very first aviation map I made for my buddy Nate’s birthday took me 10+ hours. From the software side- writing custom code to grab weather data from aviationweather.gov, to the assembly process- painstakingly wiring 3 wires per LED for a total of 33 little segments.
Since I would eventually turn this into our business, I employed some measures to make both the process faster and the end product cleaner.
Step 1: Solving a Traveling Salesman Problem
There is a famous unsolved problem in mathematics called the “traveling salesman problem”, which involves finding the shortest distance a traveling salesman must travel to reach every city exactly once. The wiring for my LEDs is exactly this problem. I’ve employed an algorithm which first computes the distances between each airport, then finds the shortest distance between them and connects a path.
However, there are a few issues with this approach. For one, LEDs have pads on either end and the wire is not able to bend at an extreme angle like you can see at KNKX (4) above. We needed something which looks smoother, more like this:
Step 2: Curve-Fitting
Wires do not bend at 30 degree angles. Therefore, we needed a method to take the straight lines we had earlier and turn them into bendy shapes. This is where curve fitting comes in, and such an algorithm exists in the form of Catmull-Rom splines. In the image below, you can see the green dots which represent the first pass. This first pass generated the tangents or angles at which the LEDs should sit at. This is only a heuristic algorithm, but it gets us close enough. Next, the physical length of the LED is accounted for in the fitting of a second curve (purple). This is especially apparent if you look closely where the wire bends sharply.
Automated Solving… kind of
I played around with automated solvers for a long time to “tighten the wires”, but couldn’t find anything I was happy with. The problem comes with so many moving parts. What rotation should each LED be at? How much “slack” should be given to each individual wire? How much bend is too much bend? Or is there actually a better way to order all of the LEDs? (moving BACK a step in the algorithm…) Something which comes so intuitively to humans is actually incredibly difficult to replicate in a computer, because it relies so heavily on heuristic knowledge. There is no “right answer”, but probably hundreds of really close answers to the best path.
Here is a screen recording of the iterative solver I came up with after tens of hours.
And here are some fails…
Step 3: Manual fitting
So the computer is not good at finding the best path. The computer is fast though, and as you could see from the video earlier, I was able to rotate the LEDs instantly, which means the curve-fitting algorithm was fast enough for comfortable real-time movement, sort of like how video games work. This means we can put humans in the loop, and gamify the wiring a little.
Step 4: Calculating Wire Lengths
fast forward a little, we added the other 2 wires as an offset from the middle wire.
The Catmull-Rom curves from three.js, the software our website uses anyway for rendering 3D maps, expose a method for obtaining their lengths in pixel space. From there it was a simple calculation of going from pixel space to physical space, and the wire lengths could be determined, in mm, which could later be used to print a “guide” for how long to cut each wire.
In the top right of this image, you can see a black line. This line was chopped up (in Microsoft Paint), then overlayed. As you can see, the lengths are nearly identical. This passed the sniff test!
Here are some methods we exposed on the computer-side. These will prove handy in just a second, when we want to send them to a real wire extruder to cut wires to size.
KRNM → KSEE {curveLengthMm: '72.94', directLengthMm: '72.94', extraMm: '0.00', ratio: '1.000'}
KSEE → KNKX {curveLengthMm: '57.83', directLengthMm: '51.13', extraMm: '6.70', ratio: '1.131'}
KNKX → KMYF {curveLengthMm: '28.93', directLengthMm: '19.04', extraMm: '9.89', ratio: '1.519'}
KMYF → KSAN {curveLengthMm: '38.96', directLengthMm: '31.77', extraMm: '7.19', ratio: '1.226'}
KSAN → KNZY {curveLengthMm: '18.56', directLengthMm: '13.62', extraMm: '4.94', ratio: '1.363'}
KNZY → KNRS {curveLengthMm: '63.33', directLengthMm: '53.94', extraMm: '9.39', ratio: '1.174'}
KNRS → KSDM {curveLengthMm: '49.97', directLengthMm: '39.38', extraMm: '10.60', ratio: '1.269'} Step 5: The Wire Extruder
Just to recap, this is where we are at now. The “game” of manually rotating wires looks like this, with some basic “collision detection” turning the wires mangenta when a wire configuration would cause overlap. You can see how the wire lengths automatically change in the top right. Magenta signifies an overlap, and the process becomes somewhat gamified with the goal of eliminating overlapping wires.
POSSIBLY GIVE PEOPLE AN INTERACTIVE THING HERE!!!
Next, I repurposed an old stepper motor from the filament extruder of a broken 3D printer, hooked it up to an ESP32, and had ChatGPT generate the software for extruding precise lengths of wire from it.
I created a 3D model in Fusion 360 to keep it all enclosed, and here are the results.
Conclusion
This project took hundreds of hours to go from idea to real life. It is still ongoing. I have plans to create a whole “factory” to FULLY automate the LED bundle.
It has been immensely rewarding to work on this so far. I recall Nate’s map taking 4 hours in just wiring alone. One day, I may fully automate this process and be completely hands-off. In the 40+ maps we have assembled, soldering the LEDs together has historically taken the majority of the time. Automating the process means lower labor costs per map, and lower prices for consumers. Additionally, it is so rewarding to see my knowledge of engineering be transformed into a real problem-solving tool! Thank you for reading. Soon I will provide an update.
Return to all posts