private static ChannelCells GetChannelZones(ChannelsTree channelsTree, int mapW, int mapH)
            {
                var result = new Dictionary <Channel, IEnumerable <(int, int)> >();

                channelsTree.VisitChannelsFromTop(channel =>
                {
                    var visited     = new HashSet <(int, int)>();
                    var channelZone = new List <(int, int)>();
                    foreach (var point in channel.Points)
                    {
                        var x0 = Math.Max(0, point.X - ZoneR);
                        var y0 = Math.Max(0, point.Y - ZoneR);
                        var x1 = Math.Min(mapW - 1, point.X + ZoneR);
                        var y1 = Math.Min(mapH - 1, point.Y + ZoneR);

                        for (var x = x0; x <= x1; x++)
                        {
                            for (var y = y0; y < y1; y++)
                            {
                                if (!visited.Contains((x, y)))
                                {
                                    visited.Add((x, y));
                                    channelZone.Add((x, y));
                                }
                            }
                        }
                    }

                    result[channel] = channelZone;
                });
                return(result);
            }
            public static Targets Create(ChannelsTree channelsTree, GridMap targetMap, double targetValue, GridMap floodMap)
            {
                var zones          = GetChannelZones(channelsTree, targetMap.Width, targetMap.Height);
                var needFlood      = new ChannelCells();
                var alreadyFlooded = new ChannelCells();

                foreach (var channelZone in zones)
                {
                    var zoneFloodedCells = new List <(int, int)>();
                    var zoneDryCells     = new List <(int, int)>();
                    foreach (var(x, y) in channelZone.Value)
                    {
                        if (targetMap[x, y] == targetValue)
                        {
                            if (floodMap[x, y] == 0)
                            {
                                zoneDryCells.Add((x, y));
                            }
                            else
                            {
                                zoneFloodedCells.Add((x, y));
                            }
                        }
                    }

                    needFlood[channelZone.Key]      = zoneDryCells;
                    alreadyFlooded[channelZone.Key] = zoneFloodedCells;
                }

                return(new Targets(zones, needFlood, alreadyFlooded));
            }
Example #3
0
        private static void BinarizeChannels(ChannelsTree channelsTree)
        {
            var newId = 0L;

            // start numeration of new channels without intersections with old channels
            channelsTree.VisitChannelsFromTop(channel => { newId = Math.Max(channel.Id, newId) + 1; });

            channelsTree.VisitChannelsFromTop(channel =>
            {
                var childrenDict = new Dictionary <ChannelPoint, List <Channel> >();
                foreach (var child in channel.Connecions)
                {
                    var closestPoint = FindClosestPoint(channel, child);
                    if (closestPoint != null)
                    {
                        if (!childrenDict.ContainsKey(closestPoint))
                        {
                            childrenDict[closestPoint] = new List <Channel>();
                        }
                        childrenDict[closestPoint].Add(child);
                    }
                }

                var curChannel = channel;
                var curPoints  = new List <ChannelPoint>();
                var points     = new List <ChannelPoint>(channel.Points);

                for (var i = 0; i < points.Count; i++)
                {
                    var point = points[i];
                    curPoints.Add(point);
                    if (childrenDict.ContainsKey(point))
                    {
                        var channelChildren   = childrenDict[point];
                        curChannel.Points     = curPoints;
                        curChannel.Connecions = channelChildren;
                        var newChannel        = new Channel(newId++)
                        {
                            Points = new List <ChannelPoint>(curPoints),
                        };
                        if (i != points.Count - 1)
                        {
                            curChannel.Connecions.Add(newChannel);
                        }
                        curChannel = newChannel;
                        curPoints  = new List <ChannelPoint>();
                    }
                }

                if (curPoints.Count > 0)
                {
                    curChannel.Points = curPoints;
                }
            });
        }
Example #4
0
        private static void CheckChannels(ChannelsTree tree)
        {
            tree.VisitChannelsFromTop(channel =>
            {
                for (var i = 1; i < channel.Points.Count; i++)
                {
                    var p0   = channel.Points[i - 1];
                    var p1   = channel.Points[i];
                    var dist = Dist(p0, p1);
                    if (Dist(p0, p1) > 2)
                    {
                        Console.WriteLine($"Points {p0} and {p1} are too far in {channel.Id} with dist {dist}");
                    }
                }

                if (channel.Points.Count == 0)
                {
                    Console.WriteLine($"{channel.Id} is empty");
                }

                foreach (var child in channel.Connecions)
                {
                    if (child != null)
                    {
                        var p = FindClosestPoint(channel, child);
                        if (p != null)
                        {
                            var dist = Dist(p, child.Points[0]);
                            if (dist > 1)
                            {
                                Console.WriteLine($"Child {child.Id} is too far from it's parent {channel.Id} with dist {dist}");
                            }

                            if (dist == 0)
                            {
                                Console.WriteLine($"Child {child.Id} has shared point {p} with it's parent {channel.Id}");
                            }
                        }
                    }
                }
            });
        }
Example #5
0
        private static void RestoreChildren(ChannelsTree channelsTree)
        {
            channelsTree.VisitChannelsFromTop(channel => {
                foreach (var child in channel.Connecions)
                {
                    var origin       = child.Points[0];
                    var closestPoint = FindClosestPoint(channel, child);
                    if (closestPoint != null)
                    {
                        var dist = Dist(origin, closestPoint);

                        if (dist >= 1)
                        {
                            // child.Points.InsertRange(0, Bresenham(closestPoint, origin));
                        }

                        var sharedPoints = GetSharedPoints(channel, child);

                        child.Points = child.Points.Except(sharedPoints).ToList();
                    }
                }
            });
        }
Example #6
0
        private static void RestoreHoles(ChannelsTree channelsTree)
        {
            channelsTree.VisitChannelsFromTop(channel =>
            {
                var set = new HashSet <ChannelPoint>();

                for (var i = 1; i < channel.Points.Count; i++)
                {
                    var p0     = channel.Points[i - 1];
                    var p1     = channel.Points[i];
                    var points = Bresenham(p0, p1);
                    set.UnionWith(points);
                }
                if (channel.Points.Count == 1)
                {
                    var p = channel.Points[0];
                    set.Add(new ChannelPoint(p.X, p.Y));
                }

                var result = new List <ChannelPoint>();

                while (result.Count != set.Count)
                {
                    var count = result.Count;
                    foreach (var point in set)
                    {
                        if (result.Contains(point))
                        {
                            continue;
                        }
                        if (result.Count == 0)
                        {
                            result.Add(point);
                            continue;
                        }

                        var x = point.X;
                        var y = point.Y;

                        var xs = result[0].X;
                        var ys = result[0].Y;

                        var xe = result[result.Count - 1].X;
                        var ye = result[result.Count - 1].Y;

                        if (Math.Abs(xs - x) + Math.Abs(ys - y) <= 5)
                        {
                            result.Insert(0, point);
                        }
                        else if (Math.Abs(xe - x) + Math.Abs(ye - y) <= 5)
                        {
                            result.Add(point);
                        }
                    }

                    if (result.Count == count)
                    {
                        break;
                    }
                }
                result.Reverse();
                channel.Points = result;
            });
        }
Example #7
0
        private static Bitmap DrawDirectionsBitmap(ChannelsTree channels, GridMap vxMap, GridMap vyMap)
        {
            var undecidedChannels = new List <Channel>();
            var channelCos        = new Dictionary <Channel, double>();

            channels.VisitChannelsFromTop(channel =>
            {
                if (channel.Points.Count == 0)
                {
                    return;
                }

                double vxSum = 0;
                double vySum = 0;

                foreach (var point in channel.Points)
                {
                    vxSum += vxMap[point.X, point.Y];
                    vySum += vyMap[point.X, point.Y];
                }

                double vLen = Length(vxSum, vySum);

                if (Math.Abs(vLen) < 1e-6)
                {
                    undecidedChannels.Add(channel);
                    return;
                }

                double vx = vxSum / vLen;
                double vy = vySum / vLen;

                var p1 = channel.Points[0];

                if (channel.Connecions.Count == 0)
                {
                    undecidedChannels.Add(channel);
                }
                else
                {
                    double p2x = 0;
                    double p2y = 0;
                    foreach (var child in channel.Connecions)
                    {
                        p2x += child.Points[0].X;
                        p2y += child.Points[0].Y;
                    }

                    p2x /= channel.Connecions.Count;
                    p2y /= channel.Connecions.Count;

                    double px   = p2x - p1.X;
                    double py   = p2y - p1.Y;
                    double pLen = Length(px, py);

                    if (Math.Abs(pLen) < 1e-6)
                    {
                        undecidedChannels.Add(channel);
                        return;
                    }

                    px /= pLen;
                    py /= pLen;

                    var cosVal          = px * vx + py * vy;
                    channelCos[channel] = cosVal;
                }
            });

            return(Drawing.DrawBitmap(944, 944, graphics =>
            {
                Drawing.DrawChannels(graphics, undecidedChannels, new SolidBrush(Color.DarkOrchid));
                foreach (var entry in channelCos)
                {
                    var cos = entry.Value;
                    var color = cos < 0 ? Drawing.GetColorBetween(Color.Black, Color.Red, cos * -1)
                        : Drawing.GetColorBetween(Color.Black, Color.LawnGreen, cos);
                    Drawing.DrawChannels(graphics, new [] { entry.Key }, new SolidBrush(color));
                }
            }));
        }
Example #8
0
        public static ChannelSystemStats GetStats(
            ChannelsTree channelsTree, GridMap floodMap, GridMap typeUseMap,
            ISet <double> hozValues, ISet <double> socValues, double nonCadastrId, int r)
        {
            var selfStatsDict = new Dictionary <Channel, Stats>();
            var aggrStatsDict = new Dictionary <Channel, Stats>();

            channelsTree.VisitChannelsFromTop(channel =>
            {
                var nonCadastrFlooded    = 0;
                var nonCadastrNotFlooded = 0;
                var hozFlooded           = 0;
                var hozNotFlooded        = 0;
                var socNotFlooded        = 0;

                var visitedCells = new HashSet <(int, int)>();
                foreach (var point in channel.Points)
                {
                    for (var x = point.X - r; x <= point.X + r; x++)
                    {
                        for (var y = point.Y - r; y <= point.Y + r; y++)
                        {
                            if (x >= 0 && x < typeUseMap.Width && y >= 0 && y < typeUseMap.Height && !visitedCells.Contains((x, y)))
                            {
                                var targetVal = typeUseMap[x, y];
                                var floodVal  = floodMap[x, y];
                                if (targetVal == nonCadastrId)
                                {
                                    if (floodVal == 0)
                                    {
                                        nonCadastrNotFlooded++;
                                    }
                                    else
                                    {
                                        nonCadastrFlooded++;
                                    }
                                }
                                else if (hozValues.Contains(targetVal))
                                {
                                    if (floodVal == 0)
                                    {
                                        hozNotFlooded++;
                                    }
                                    else
                                    {
                                        hozFlooded++;
                                    }
                                }
                                else if (socValues.Contains(targetVal) && floodVal == 0)
                                {
                                    socNotFlooded++;
                                }
                            }
                            visitedCells.Add((x, y));
                        }
                    }
                }
                var selfStats = new Stats(
                    channel.Points.Count,
                    nonCadastrFlooded,
                    nonCadastrNotFlooded,
                    hozFlooded,
                    hozNotFlooded,
                    socNotFlooded);

                selfStatsDict[channel] = selfStats;
            });

            var channelsStats = new List <ChannelStats>();

            channelsTree.VisitChannelsFromBottom(channel =>
            {
                var channelStats = selfStatsDict[channel];

                var aggrLength               = channelStats.Length;
                var aggrNonCadastrFlooded    = channelStats.NonCadastrFlooded;
                var aggrNonCadastrNotFlooded = channelStats.NonCadastrNotFlooded;
                var aggrHozFlooded           = channelStats.HozFlooded;
                var aggrHozNotFlooded        = channelStats.HozNotFlooded;
                var aggrSocNotFlooded        = channelStats.SocNotFlooded;

                foreach (var child in channel.Connecions)
                {
                    var childAggrStats        = aggrStatsDict[child];
                    aggrLength               += childAggrStats.Length;
                    aggrNonCadastrFlooded    += childAggrStats.NonCadastrFlooded;
                    aggrNonCadastrNotFlooded += childAggrStats.NonCadastrNotFlooded;
                    aggrHozFlooded           += childAggrStats.HozFlooded;
                    aggrHozNotFlooded        += childAggrStats.HozNotFlooded;
                    aggrSocNotFlooded        += childAggrStats.SocNotFlooded;
                }

                var aggrStats = new Stats(
                    aggrLength,
                    aggrNonCadastrFlooded,
                    aggrNonCadastrNotFlooded,
                    aggrHozFlooded,
                    aggrHozNotFlooded,
                    aggrSocNotFlooded);

                aggrStatsDict[channel] = aggrStats;

                channelsStats.Add(new ChannelStats(channel, channelStats, aggrStats));
            });


            return(new ChannelSystemStats(channelsStats));
        }