Ejemplo n.º 1
0
        IEnumerator RemoveHexagons(IAdminEntity[] entities)
        {
            Clipper clipper = new Clipper();

            Cell[] cells = _map.cells;
            for (int j = 0; j < cells.Length; j++)
            {
                if (j % 100 == 0)
                {
                    if (hexifyContext.progress != null)
                    {
                        if (hexifyContext.progress((float)j / cells.Length, hexifyContext.title, "Pass 5/6: removing cells from neighbours..."))
                        {
                            cancelled = true;
                            hexifyContext.finish(true);
                            yield break;
                        }
                    }
                    yield return(null);
                }

                int entityIndex = procCells [j].entityIndex;
                if (entityIndex < 0)
                {
                    continue;
                }

                RegionCell   regionCell = procCells [j];
                IAdminEntity entity     = entities [entityIndex];

                // Substract cell region from any other entity
                List <Region> otherRegions;
                if (entity is Country)
                {
                    otherRegions = _map.GetCountryRegionsOverlap(regionCell.cellRegion);
                }
                else
                {
                    otherRegions = _map.GetProvinceRegionsOverlap(regionCell.cellRegion);
                }
                int orCount = otherRegions.Count;
                for (int o = 0; o < orCount; o++)
                {
                    Region       otherRegion = otherRegions [o];
                    IAdminEntity otherEntity = otherRegion.entity;
                    if (otherEntity == entity)
                    {
                        continue;
                    }
                    clipper.Clear();
                    clipper.AddPath(otherRegion, PolyType.ptSubject);
                    clipper.AddPath(regionCell.cellRegion, PolyType.ptClip);
                    clipper.Execute(ClipType.ctDifference, otherEntity);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Adjusts all countries frontiers to match the hexagonal grid
        /// </summary>
        public IEnumerator HexifyCountries(HexifyOpContext context)
        {
            Cell[] cells = _map.cells;
            if (cells == null)
            {
                yield break;
            }


            // Initialization
            cancelled     = false;
            hexifyContext = context;

            if (procCells == null || procCells.Length < cells.Length)
            {
                procCells = new RegionCell[cells.Length];
            }
            for (int k = 0; k < cells.Length; k++)
            {
                procCells [k].entityIndex = -1;
            }

            // Compute area of a single cell; for optimization purposes we'll ignore all regions whose surface is smaller than a 20% the size of a cell
            float  minArea            = 0;
            Region templateCellRegion = null;

            for (int k = 0; k < cells.Length; k++)
            {
                if (cells [k] != null)
                {
                    templateCellRegion = new Region(null, 0);
                    templateCellRegion.UpdatePointsAndRect(cells [k].points, true);
                    minArea = templateCellRegion.rect2DArea * 0.2f;
                    break;
                }
            }

            if (templateCellRegion == null)
            {
                yield break;
            }

            if (hexagonPoints == null || hexagonPoints.Length != 6)
            {
                hexagonPoints = new Vector2[6];
            }
            for (int k = 0; k < 6; k++)
            {
                hexagonPoints [k] = templateCellRegion.points [k] - templateCellRegion.center;
            }

            // Pass 1: remove minor regions
            yield return(RemoveSmallRegions(minArea, _map.countries));

            // Pass 2: assign all region centers to each country from biggest country to smallest country
            if (!cancelled)
            {
                yield return(AssignRegionCenters(_map.countries));
            }

            // Pass 3: add cells to target countries
            if (!cancelled)
            {
                yield return(AddHexagons(_map.countries));
            }

            // Pass 4: merge adjacent regions
            if (!cancelled)
            {
                yield return
                    (MergeAdjacentRegions(_map.countries));
            }

            // Pass 5: remove cells from other countries
            if (!cancelled)
            {
                yield return(RemoveHexagons(_map.countries));
            }

            // Pass 6: update geometry of resulting countries
            if (!cancelled)
            {
                yield return(UpdateCountries());
            }

            if (!cancelled)
            {
                _map.OptimizeFrontiers();
                _map.Redraw(true);
            }

            hexifyContext.progress(1f, hexifyContext.title, "");               // hide progress bar
            yield return(null);

            if (hexifyContext.finish != null)
            {
                hexifyContext.finish(cancelled);
            }
        }