private IList <TransportWay> BuildWaysForCell(
            TransportNetworkType transportNetworkType,
            TransportCellKey cellKey
            )
        {
            var cellKeyInterop = cellKey.ToInterop();
            int wayCount       = NativeTransportApi_GetWayCountForNetworkInCell(NativePluginRunner.API, transportNetworkType, cellKeyInterop);

            if (wayCount <= 0)
            {
                return(new List <TransportWay>());
            }

            // alloc and pin buffers
            var wayIdInteropBuffer         = new TransportWayIdInterop[wayCount];
            var wayIdInteropBufferGCHandle = GCHandle.Alloc(wayIdInteropBuffer, GCHandleType.Pinned);
            var wayIdInteropBufferPtr      = wayIdInteropBufferGCHandle.AddrOfPinnedObject();

            // populate buffers from C++ api
            var waySuccess = NativeTransportApi_TryGetWayIdsForNetworkInCell(NativePluginRunner.API, transportNetworkType, cellKeyInterop, wayCount, wayIdInteropBufferPtr);

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

            var ways = FetchWays(wayIdInteropBuffer);

            // free buffers
            wayIdInteropBufferGCHandle.Free();

            return(ways);
        }
        private bool TryFetchWay(TransportWayIdInterop wayIdInterop, out TransportWay way)
        {
            var wayInterop = new TransportWayInterop()
            {
                Id = wayIdInterop
            };


            bool success = NativeTransportApi_TryGetWayBufferSizes(NativePluginRunner.API, ref wayInterop);

            if (!success)
            {
                way = TransportWay.MakeEmpty();
                return(false);
            }

            var centerLinePointsBuffer         = new DoubleVector3[wayInterop.CenterLinePointsBufferSize];
            var centerLinePointsBufferGCHandle = GCHandle.Alloc(centerLinePointsBuffer, GCHandleType.Pinned);

            wayInterop.CenterLinePoints = centerLinePointsBufferGCHandle.AddrOfPinnedObject();

            var centerLineSplineParamsBuffer         = new double[wayInterop.CenterLineSplineParamsBufferSize];
            var centerLineSplineParamsBufferGCHandle = GCHandle.Alloc(centerLineSplineParamsBuffer, GCHandleType.Pinned);

            wayInterop.CenterLineSplineParams = centerLineSplineParamsBufferGCHandle.AddrOfPinnedObject();

            var classificationBuffer         = new byte[wayInterop.ClassificationBufferSize];
            var classificationBufferGCHandle = GCHandle.Alloc(classificationBuffer, GCHandleType.Pinned);

            wayInterop.Classification = classificationBufferGCHandle.AddrOfPinnedObject();

            success = NativeTransportApi_TryGetWay(NativePluginRunner.API, ref wayInterop);
            if (!success)
            {
                way = TransportWay.MakeEmpty();
                return(false);
            }

            var classification = Marshal.PtrToStringAnsi(wayInterop.Classification, wayInterop.ClassificationBufferSize - 1);

            way = new TransportWay(
                wayInterop.Id.FromInterop(),
                centerLinePointsBuffer,
                centerLineSplineParamsBuffer,
                wayInterop.LengthMeters,
                wayInterop.HalfWidthMeters,
                wayInterop.WayDirection,
                classification,
                wayInterop.AverageSpeedKph,
                wayInterop.ApproximateSpeedLimitKph
                );

            centerLinePointsBufferGCHandle.Free();
            centerLineSplineParamsBufferGCHandle.Free();
            classificationBufferGCHandle.Free();
            return(true);
        }
        private IList <TransportWayIdInterop> FetchWayIdsForNetworkInCell(TransportNetworkType transportNetwork, MortonKeyInterop cellKeyInterop)
        {
            int wayCount = NativeTransportApi_GetWayCountForNetworkInCell(NativePluginRunner.API, transportNetwork, cellKeyInterop);

            if (wayCount <= 0)
            {
                return(new List <TransportWayIdInterop>());
            }

            var wayIdInteropBuffer         = new TransportWayIdInterop[wayCount];
            var wayIdInteropBufferGCHandle = GCHandle.Alloc(wayIdInteropBuffer, GCHandleType.Pinned);
            var wayIdInteropBufferPtr      = wayIdInteropBufferGCHandle.AddrOfPinnedObject();
            var waySuccess = NativeTransportApi_TryGetWayIdsForNetworkInCell(NativePluginRunner.API, transportNetwork, cellKeyInterop, wayCount, wayIdInteropBufferPtr);

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

            wayIdInteropBufferGCHandle.Free();

            return(wayIdInteropBuffer);
        }