wiedehopf / tar1090

Provides an improved webinterface for use with ADS-B decoders readsb / dump1090-fa
Other
1.21k stars 222 forks source link

allow multi range outlines to be used #303

Closed dirkhh closed 2 months ago

dirkhh commented 2 months ago

This is a special case for a tar1090 instance that shows the combined output of multiple readsb instances (like in a stage2 instance of the adsb.im feeder image).

This tries once to download a multiOutline.json file and remembers if it exists or if it should use the outline.json file instead. In the update loop it simply checks for a third format where points is an array of arrays. And then loops over that outer array - which in the case of the regular output.json is simply an array with just one entry.

The additional overhead is negligible, the additional feature is really cool (once you have the code to create merged outlines).

something like this can be used to create such a file:

from shapely.geometry import LinearRing, Polygon
from shapely.ops import unary_union

import json
import pathlib
import sys

if __name__ == "__main__":
    json_files = []
    for i in range(1, len(sys.argv)):
        if pathlib.Path(sys.argv[i]).exists():
            json_files.append(sys.argv[i])
    data = []
    for f in json_files:
        with open(f, "r") as jf:
            try:
                j = json.load(jf)
            except:
                pass
            else:
                data.append(j)

    result = { "multiRange": [] }
    polygons = []
    for i in range(len(data)):
        polygons.append(
            Polygon(
                shell=LinearRing(
                    data[i]["actualRange"]["last24h"]["points"]
                )
            )
        )
    to_consider = [0]
    for i in range(1, len(data)):
        combined = False
        for j in to_consider:
            if polygons[j].disjoint(polygons[i]):
                print(f"polygon {i} disjoint {j}")
            else:
                print(f"combine polygons {i} and {j}")
                p = unary_union([polygons[j], polygons[i]])
                polygons[j] = p
                combined = True
        if not combined:
            to_consider.append(i)
    for i in to_consider:
        points = [[x, y] for x, y, a in polygons[i].exterior.coords]
        result["multiRange"].append(points)

    with open("multiOutline.json", "w") as out:
        print(json.dumps(result), file=out)

manually download the /data/outline.json from multiple readsb instances (and rename them...) and start the above python script with the various json files as command line args. It will write out a multiOutline.json file that removes all "interior" parts of the ranges (this is designed for feeders that have (partially) overlapping ranges -- the script creates the envelope of all those ranges) Now copy this multiOutline.json file into /run/readsb of the instance that has the shared tar1090. Refresh your map and you will see the very cool combined outline (this is from five feeders, four of which combined create the lower area, the fifth one creates an outline that is disjoint from the other four...): Screenshot 2024-04-24 at 20 40 43