private IList <TransportNode> BuildNodesForCell(
            TransportNetworkType transportNetworkType,
            TransportCellKey cellKey
            )
        {
            var cellKeyInterop = cellKey.ToInterop();
            int nodeCount      = NativeTransportApi_GetNodeCountForNetworkInCell(NativePluginRunner.API, transportNetworkType, cellKeyInterop);

            if (nodeCount <= 0)
            {
                return(new List <TransportNode>());
            }

            // alloc and pin buffers
            var nodeIdInteropBuffer         = new TransportNodeIdInterop[nodeCount];
            var nodeIdInteropBufferGCHandle = GCHandle.Alloc(nodeIdInteropBuffer, GCHandleType.Pinned);
            var nodeIdInteropBufferPtr      = nodeIdInteropBufferGCHandle.AddrOfPinnedObject();

            // populate buffers from C++ api
            var nodeSuccess = NativeTransportApi_TryGetNodeIdsForNetworkInCell(NativePluginRunner.API, transportNetworkType, cellKeyInterop, nodeCount, nodeIdInteropBufferPtr);

            if (!nodeSuccess)
            {
                throw new System.ArgumentOutOfRangeException("incorrect buffer size passed for node ids");
            }

            var nodes = FetchNodes(nodeIdInteropBuffer);

            // free buffers
            nodeIdInteropBufferGCHandle.Free();

            return(nodes);
        }
        private bool TryFetchNode(TransportNodeIdInterop nodeIdInterop, out TransportNode node)
        {
            int incidentDirectedEdgeCount = NativeTransportApi_GetIncidentDirectedEdgeCountForNode(NativePluginRunner.API, nodeIdInterop);

            if (incidentDirectedEdgeCount < 0)
            {
                node = TransportNode.MakeEmpty();
                return(false);
            }

            var incidentDirectedEdgeIdInteropBuffer         = new TransportDirectedEdgeIdInterop[incidentDirectedEdgeCount];
            var incidentDirectedEdgeIdInteropBufferGCHandle = GCHandle.Alloc(incidentDirectedEdgeIdInteropBuffer, GCHandleType.Pinned);
            var incidentDirectedEdgeIdInteropPtr            = incidentDirectedEdgeIdInteropBufferGCHandle.AddrOfPinnedObject();

            var nodeInterop = new TransportNodeInterop()
            {
                Id = nodeIdInterop,
                IncidentDirectedEdgeIdsSize = incidentDirectedEdgeCount,
                IncidentDirectedEdgeIds     = incidentDirectedEdgeIdInteropPtr
            };

            bool success = NativeTransportApi_TryGetNode(NativePluginRunner.API, ref nodeInterop);

            if (!success)
            {
                node = TransportNode.MakeEmpty();
                return(false);
            }

            var incidedDirectedEdgeIds = incidentDirectedEdgeIdInteropBuffer.Select(_x => _x.FromInterop()).ToList();

            node = new TransportNode(
                nodeInterop.Id.FromInterop(),
                nodeInterop.Point,
                incidedDirectedEdgeIds
                );

            incidentDirectedEdgeIdInteropBufferGCHandle.Free();

            return(true);
        }
        private IList <TransportNodeIdInterop> FetchNodeIdsForNetworkInCell(TransportNetworkType transportNetwork, MortonKeyInterop cellKeyInterop)
        {
            int nodeCount = NativeTransportApi_GetNodeCountForNetworkInCell(NativePluginRunner.API, transportNetwork, cellKeyInterop);

            if (nodeCount <= 0)
            {
                return(new List <TransportNodeIdInterop>());
            }

            var nodeIdInteropBuffer         = new TransportNodeIdInterop[nodeCount];
            var nodeIdInteropBufferGCHandle = GCHandle.Alloc(nodeIdInteropBuffer, GCHandleType.Pinned);
            var nodeIdInteropBufferPtr      = nodeIdInteropBufferGCHandle.AddrOfPinnedObject();

            if (!NativeTransportApi_TryGetNodeIdsForNetworkInCell(NativePluginRunner.API, transportNetwork, cellKeyInterop, nodeCount, nodeIdInteropBufferPtr))
            {
                throw new System.ArgumentOutOfRangeException("incorrect buffer size passed for node ids");
            }

            nodeIdInteropBufferGCHandle.Free();

            return(nodeIdInteropBuffer);
        }
 private static extern int NativeTransportApi_GetIncidentDirectedEdgeCountForNode(IntPtr ptr, TransportNodeIdInterop nodeIdInterop);