镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Increased Route Support #68

Open
Open

Description

Basically the title, but in our use case, we want to allow users to also send Route objects (b-m-r), in the current implementation these are automatically converted to LineString elements.

Is there a specific reason for this?

Activity

  1. changed the title [-]QUESTION: Why are CoT types other then Point are overriden?[/-] [+]QUESTION: Why are CoT types other then Point get overriden?[/+] on Apr 21, 2025
  2. ingalls commented on Apr 21, 2025

    @ingalls
    Member

    Yuval Bubnovsky (@YuvalBubnovsky) When parsing the raw CoT message, the original message is retained in CoT.raw as a 1:1 JSON representation of the COT message.

    I'm assuming you are referring to the output of the to_geojson() functionality?

    If so, then yes, the b-m-r messages are converted to LineStrings as although it is a lossy conversion from a metadata perspective, it is a necessary one for renderers that need a GeoJSON input file for UI interactions.

    There is no necessity to use the to_geojson function and you could handle these manually by checking the type of the COT message and not calling to_geojson and instead handling the route object manually.

    If however you are seeing the route converted to GeoJSON outside of the to_geojson function please give me a little more detail about what exactly you are calling and what the expected behavior is.

  3. YuvalBubnovsky commented on Apr 21, 2025

    @YuvalBubnovsky
    ContributorAuthor

    Nick (@ingalls) I'm calling the from_geojson() function, our application presents the users with the ability to create GeoJSON LineString.
    When exporting our GeoJSON data to a TAK system, I want to present that LineString as a TAK Route object (b-m-r) while adding the appropriate properties (for example: whether it's walking/driving)

    In short, I'd just like to be able to pass a GeoJSON LineString with additional properties and have it turned into the apropriate Route TAK object

  4. ingalls commented on Apr 21, 2025

    @ingalls
    Member

    Yuval Bubnovsky (@YuvalBubnovsky) Gotcha! So the GeoJSON definition that node-cot uses internally is an opinionated one in that it's something that State of Colorado - DFPC - Center of Excellence (@dfpc-coe) created for bi-directional support of features from our rendering engine to the underlying COT that gets passed to clients/TAK Server.

    For many of the fields we have 1:1 conversion between GeoJSON and TAK COT (IE Video Tags), but the route info isn't something we have focused on so we added MVP support for getting Routes INTO geojson for rendering on a map.

    I'd love to make support more complete here and if you could provide a couple of XML COT examples of routes and the properties you are most interested in supporting bidirectionally between COT <=> GeoJSON we can probably get a PR that expands our current Route support with a more complete set of COT Route properties.

  5. YuvalBubnovsky commented on Apr 22, 2025

    @YuvalBubnovsky
    ContributorAuthor

    Nick (@ingalls)
    Let's use this Route XML as an example, it's a Route (b-m-r) object containing two Route Waypoints (b-m-p-w)

    <?xml version='1.0' encoding='UTF-8' standalone='yes'?>
    <event version='2.0' uid='014323a0-5173-4271-af3f-e44c2a524a07' type='b-m-r' time='2025-04-22T10:48:54.250Z' start='2025-04-22T10:48:54.250Z' stale='2025-04-23T10:48:54.250Z' how='h-e'>
    	<point lat='0.0' lon='0.0' hae='9999999.0' ce='9999999.0' le='9999999.0' />
    	<detail>
    		<link uid='30a4c1a9-51e6-4740-b080-f3139537af59' callsign='Route 1 SP' type='b-m-p-w' point='32.2507585,34.8589471,30.791' remarks='' relation='c'/>
    		<link uid='855c4cfd-8965-44b0-bd77-623c5662501f' callsign='TGT' type='b-m-p-w' point='32.2472085,34.8595906,24.969' remarks='' relation='c'/>
    		<link_attr planningmethod='Infil' color='-1' method='Walking' prefix='CP' type='On Foot' stroke='3' direction='Infil' routetype='Primary' order='Ascending Check Points'/>
    		<contact callsign='Route 1'/>
    		<color value='-1'/>
    		<strokeColor value='-1'/>
    		<strokeWeight value='3.0'/>
    		<strokeStyle value='solid'/>
    		<labels_on value='false'/>
    		<archive/>
    		<__routeinfo>
    			<__navcues/>
    		</__routeinfo>
    		<remarks></remarks>
    	</detail>
    </event>

    For the Route object itself, the properties can probably still be a 1:1 mapping from the existing GeoJSON properties (uid, type, time, stale, stroke, color etc.), I also note that the entire Route's callsign is controled within <contact callsign>

    For each Route Waypoint I I'd like to be able to control it's callsign and coordinates
    I would also like to be able to define the following properties:

    • planningmethod
    • method
    • type = In this example, it says On Foot, there are also variations for driving/flying
    • direction = Infil/Exfil
    • routeType = Primary/Secondary

    My second example includes a Route which also has control points (b-m-p-c):

    <?xml version='1.0' encoding='UTF-8' standalone='yes'?>
    <event version='2.0' uid='06722b55-6426-4317-82a2-b627a563a4bc' type='b-m-r' time='2025-04-22T11:01:40.906Z' start='2025-04-22T11:01:40.906Z' stale='2025-04-23T11:01:40.906Z' how='h-e'>
    	<point lat='0.0' lon='0.0' hae='9999999.0' ce='9999999.0' le='9999999.0' />
    	<detail>
    		<link uid='ed519290-bd0f-40d4-a7ab-86e22fb4b93d' callsign='Route 1 SP' type='b-m-p-w' point='32.2529563,34.8573833,36.214' remarks='' relation='c'/>
    		<link uid='8ba4a5d4-9d2b-4503-8320-db67cc146b39' callsign='' type='b-m-p-c' point='32.2514376,34.856607,28.394' remarks='' relation='c'/>
    		<link uid='aa23fab8-0234-4ed9-99f6-bd43a201dc98' callsign='' type='b-m-p-c' point='32.2503341,34.8562692,26.469' remarks='' relation='c'/>
    		<link uid='a345e8cc-5fd8-440a-8837-7f6f23045521' callsign='' type='b-m-p-c' point='32.2494023,34.8583449,23.677' remarks='' relation='c'/>
    		<link uid='4f421cff-7daf-489d-83e2-33b04a57e5a2' callsign='CP1' type='b-m-p-w' point='32.2489017,34.8599831,27.454' remarks='' relation='c'/>
    		<link uid='f9e64dd4-a4d4-4fb9-b11c-f26f8ae56b79' callsign='' type='b-m-p-c' point='32.2483474,34.8626963,24.842' remarks='' relation='c'/>
    		<link uid='cf6c9c85-ec64-4c75-896f-6912fcde6b00' callsign='VDO' type='b-m-p-w' point='32.2476337,34.8646865,26.136' remarks='' relation='c'/>
    		<link_attr planningmethod='Infil' color='-16777089' method='Driving' prefix='CP' type='Vehicle' stroke='3' direction='Infil' routetype='Primary' order='Ascending Check Points'/>
    		<contact callsign='Route 1'/>
    		<color value='-16777089'/>
    		<strokeColor value='-16777089'/>
    		<strokeWeight value='3.0'/>
    		<strokeStyle value='solid'/>
    		<labels_on value='false'/>
    		<archive/>
    		<__routeinfo>
    			<__navcues/>
    		</__routeinfo>
    		<remarks></remarks>
    	</detail>
    </event>

    For these waypoints, the ability to set the already existing properties would be greatly appreciated (callsign, type, coordinates)

    Let me know if you need any further data here.

  6. ingalls commented on Apr 23, 2025

    @ingalls
    Member

    Yuval Bubnovsky (@YuvalBubnovsky) This is perfect and is jogging my memory as to why I didn't fully implement the route format.

    The issue I currently have is that I don't have a straightforward way to encode properties alongside internal points and remain valid GeoJSON.

    The only way I can think of is to either use a GeoJSON FeatureCollection within a FeatureCollection to store these points:
    IE:

    {
        "type": "FeatureCollection",
        "features": [
            <Feature: With LineString of entire route>
            <Feature of Waypoint with waypoint specific features>
        ]
    }
    

    OR run parallel arrays of some kind in the properties?

    {
        "type': "Feature",
        "properties": {
            "route": {
                "route-specific-keys": "Value",
                "more-route-specific-keys": "Value",
                "links": [ each link object is 1:1 with the number of coordinates in the geometry ]
            }
        },
        "geometry": {
            "type": "LineString",
            "coordinates": [[ coords ], [ more coords], etc ] 
        }
    }
    

    If the above seems reasonable I can update the schema with this parsing. I'd probably lean towards using parallel arrays but the user must then keep the order & number of the coordinates identical and in the same element positions as the links array

    I did the same thing at mapbox for encoding street numbers on a MultiPoint, it works but just doesn't quite feel right.

  7. YuvalBubnovsky commented on Jun 12, 2025

    @YuvalBubnovsky
    ContributorAuthor

    Nick (@ingalls) Hello, apologies for late reply again,
    I deleted my previous comment suggesting to use some sort of a Collection within a Collection - but after spending some time trying to make it work on my fork, I conclude that although not ideal, the solution of having parallel array between links and coordinates is probably the way to go..

    I have started by expanding the definition on features.ts:

    route: Type.Optional(Type.Object({
            planningmethod: Type.Optional(LinkAttrRouteFil),
            direction: Type.Optional(LinkAttrRouteFil),
            routetype: Type.Optional(LinkAttrRouteType),
            method: Type.Optional(LinkAttrRouteMethod),
            prefix: Type.Optional(Type.String()),
            type: Type.Optional(Type.String()),
            order: Type.Optional(LinkAttrRouteOrder),
            links: Type.Array(Type.Object({
                callsign: Type.String({ default: 'UNKNOWN' }),
                type: Type.String({ default: 'b-m-p-c' })
            }))
        }))

    I noticed in the from_geojson() function the case for LineString is:

    if (feature.geometry.type === 'LineString') {
                    cot.event._attributes.type = 'u-d-f';
    
                    if (!cot.event.detail.link) cot.event.detail.link = [];
                    else if (!Array.isArray(cot.event.detail.link)) cot.event.detail.link = [cot.event.detail.link]
    
                    for (const coord of feature.geometry.coordinates) {
                        cot.event.detail.link.push({
                            _attributes: { point: `${coord[1]},${coord[0]}` }
                        });
                    }

    So you have already implemented some handling for the links..
    I would love some extra guidance on how to proceed from this point, forcing the type to be b-m-r here will mean that every GeoJson LineString is going to be converted into a TAK Route, which I'm not sure is the correct way to go about this

    Would love to get some feedback and take it away from here as this is something I'd definitely like to be implemented.

  8. ingalls commented on Jun 12, 2025

    @ingalls
    Member

    Hey Yuval Bubnovsky (@YuvalBubnovsky) Let me sketch this out in a PR and get a feel for. I agree that the parallel construction at this point is probably a necessary evil. I'll have something hopefully today but if not by next monday to play with.

  9. YuvalBubnovsky commented on Jun 24, 2025

    @YuvalBubnovsky
    ContributorAuthor

    Hey Nick (@ingalls), just checking in kindly 🙏
    Wanted to see if you had a chance to sketch out the PR you mentioned - I know you're probably juggling a lot, but I’d love to help move this forward if there's anything I can do. Appreciate all the work you're doing 🙂

  10. ingalls commented on Jun 25, 2025

    @ingalls
    Member

    Hey working on this today, sorry got into the weeds dealing with Media Streaming

  11. ingalls commented on Jun 26, 2025

    @ingalls
    Member

    Starting to sketch this out here: #82

  12. changed the title [-]QUESTION: Why are CoT types other then Point get overriden?[/-] [+]Route Support[/+] on Jun 26, 2025
  13. changed the title [-]Route Support[/-] [+]Increased Route Support[/+] on Jun 26, 2025
  14. ingalls commented on Jun 26, 2025

    @ingalls
    Member

    OK v13.1.0 starts to sketch out better Route support. Initially it allows you to specify the feature.properties.type = "b-m-r" and then will treat the conversion of a GeoJSON LineString into a Route type.

    I'm leaving this ticket open as the other properties will still need mapping on the incoming GeoJSON

  15. YuvalBubnovsky commented on Jun 26, 2025

    @YuvalBubnovsky
    ContributorAuthor

    Nick (@ingalls) Sketch looks great, I'll upgrade the version and start to see how it looks on my end

  16. YuvalBubnovsky commented on Jun 30, 2025

    @YuvalBubnovsky
    ContributorAuthor

    Hey Nick (@ingalls) , had the chance to play around a bit with the new Route support (converting LineString GeoJSON to Route).

    I noticed that the following segment sets all coordinates passed as b-m-p-c (this code is from parser.ts)

                    for (const coord of feature.geometry.coordinates) {
                        cot.event.detail.link.push({
                            _attributes: {
                                type: 'b-m-p-c',
                                uid: randomUUID(),
                                callsign: "",
                                point: `${coord[1]},${coord[0]}`
                            }
                        });
                    }

    During my testing, all coordinates were succusefuly recognized by my Android ATAK app, but only the edge ones had attribute data assosicated with them (default values), the other coordinates in-between could be "upgraded" to hold said data by interacting with them.
    I'm assuming this is some default behaviour not related to your implementation.

    Looking forward to be able to set Link Attributes based on GeoJSON data!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions