Пример #1
0
        /// <summary>
        /// Производит обновление соседей для всех учреждений, которые связаны
        /// с дорогой <paramref name="roadWithNeighbours"/>.
        /// Если у учерждений есть общая дорога, то значит они «соседствуют». Данная функция проверяет
        /// уже существующих соседей у всех учреждений дороги.
        /// Если у какого-либо учреждения еще нет соседей, то новая постройка сразу добавляется в качестве соседа.
        /// Если же соседи уже существуют, то сначала проверяется, находится ли сосед на той же дороге, что и
        /// новая постройка. Если нет, то постройка также добавляется в качестве соседа.
        /// Если существующие соседи находятся на той же дороге, что и новая постройка, то
        /// в таком случае проверяется местоположение новой постройки относительно постройки, у которой проверяем
        /// соседей, а также каждого из соседей. Если новая постройка находится «между» этими двумя объектами, то
        /// считаем, что уже существующий сосед перестал быть таковым, удаляем его из списка, и добавляем вместо него
        /// нашу новую постройку.
        /// </summary>
        /// <param name="roadWithNeighbours">Объект дороги, которая связана с <paramref name="newInstitution"/>, и
        /// у существующих учреждений на которой необходимо обновить соседей.</param>
        /// <param name="newInstitution">Новая постройка, одной из дорог
        /// которой является <paramref name="roadWithNeighbours"/></param>
        /// <param name="intersectPoint">Точка пересечения дороги <paramref name="roadWithNeighbours"/> с некой
        /// другой дорогой, вследствие чего был создан <paramref name="newInstitution"/></param>
        private void UpdateNeighbours(Road roadWithNeighbours, Institution newInstitution, Point2D intersectPoint)
        {
            // Если на данной дороге еще не было никаких учреждений, то необходимо инициализировать для неё их список.
            if (!_roadInstitutions.ContainsKey(roadWithNeighbours))
            {
                _roadInstitutions[roadWithNeighbours] = new List <Institution>();
            }

            foreach (Institution existedInstitution in _roadInstitutions[roadWithNeighbours])
            {
                // Если у какой-либо из построек на дороге еще нет соседей, то можно сразу добавлять туда нашу новую.
                if (existedInstitution.Neighbours.Count == 0)
                {
                    existedInstitution.AddNeighbour(newInstitution);
                    newInstitution.AddNeighbour(existedInstitution);
                    continue;
                }

                bool neighbourOnSameLineExists = false;

                // Так как функции ReplaceNeighbour и AddNeighbour меняют содержимое Neighbours, то
                // «ходим» по копии этого объекта.
                foreach (Institution neighbour in existedInstitution.Neighbours.ToList())
                {
                    // Игнорируем тех «соседей», которые находятся на другой дороге, и которые никак не мешают нам.
                    if (neighbour.FirstRoad != roadWithNeighbours && neighbour.SecondRoad != roadWithNeighbours)
                    {
                        continue;
                    }

                    neighbourOnSameLineExists = true;

                    // Если наша новая постройка находится между некой постройкой и её соседом (на одной дороге), то
                    // значит мы «разорвали» соседство, и теперь сами являемся соседом той постройки.
                    if (intersectPoint.IsBetweenTwoPointsOnSameLine(existedInstitution.Location,
                                                                    neighbour.Location))
                    {
                        existedInstitution.ReplaceNeighbour(neighbour, newInstitution);
                        newInstitution.AddNeighbour(existedInstitution);
                        break;
                    }
                }

                // Если нет никаких построек между нашей новой постройкой и той, которую обрабатываем в цикле foreach,
                // то считаем нас её соседом.
                if (!neighbourOnSameLineExists)
                {
                    existedInstitution.AddNeighbour(newInstitution);
                    newInstitution.AddNeighbour(existedInstitution);
                }
            }

            _roadInstitutions[roadWithNeighbours].Add(newInstitution);
        }