/// <summary> /// Merges cell2 into cell1. Cell2 is removed. /// Only cells which are neighbours can be merged. /// </summary> public bool CellMerge(Cell cell1, Cell cell2) { if (cell1 == null || cell2 == null) { return(false); } if (!cell1.region.neighbours.Contains(cell2.region)) { return(false); } cell1.center = (cell2.center + cell1.center) / 2.0f; // Polygon UNION operation between both regions PolygonClipper pc = new PolygonClipper(cell1.polygon, cell2.polygon); pc.Compute(PolygonOp.UNION); // Remove cell2 from lists int territoryIndex = cell2.territoryIndex; if (territories[territoryIndex].cells.Contains(cell2)) { territories[territoryIndex].cells.Remove(cell2); } if (cells.Contains(cell2)) { cells.Remove(cell2); } // Updates geometry data on cell1 UpdateCellGeometry(cell1, pc.subject); return(true); }
void CountryMergeAdjacentRegions(Country targetCountry) { // Merges adjacent regions of target country int numRegions = targetCountry.regions.Count; WPM.Geom.Polygon[] countryPolys = new WPM.Geom.Polygon[numRegions]; for (int k = 0; k < numRegions; k++) { countryPolys[k] = GetGeomPolygon(targetCountry.regions[k].latlon); } for (int k = 0; k < targetCountry.regions.Count; k++) { if (countryPolys[k] != null) { Region region1 = targetCountry.regions[k]; for (int j = k + 1; j < targetCountry.regions.Count; j++) { if (countryPolys[j] != null) { PolygonClipper pc = new PolygonClipper(countryPolys[k], countryPolys[j]); if (pc.OverlapsSubjectAndClipping()) { pc.Compute(PolygonOp.UNION); ReplacePointsFromPolygon(region1, pc.subject); countryPolys[k] = GetGeomPolygon(targetCountry.regions[k].latlon); targetCountry.regions.RemoveAt(j); if (countryIndex >= 0 && targetCountry == _map.countries[countryIndex] && countryRegionIndex >= j) { countryRegionIndex--; } countryPolys[j] = null; } } } } } }
void ProvinceMergeAdjacentRegions(Province targetProvince) { // Searches for adjacency - merges in first region int regionCount = targetProvince.regions.Count; for (int k = 0; k < regionCount; k++) { Region region1 = targetProvince.regions[k]; for (int j = k + 1; j < regionCount; j++) { Region region2 = targetProvince.regions[j]; if (!region1.Intersects(region2)) { continue; } RegionMagnet(region1, region2); PolygonClipper pc = new PolygonClipper(region1, region2); if (pc.Compute(PolygonOp.UNION, null)) { // Add new neighbours for (int n = 0; n < region2.neighbours.Count; n++) { Region neighbour = region2.neighbours[n]; if (neighbour != null && neighbour != region1 && !region1.neighbours.Contains(neighbour)) { region1.neighbours.Add(neighbour); } } // Remove merged region targetProvince.regions.RemoveAt(j); region1.sanitized = false; j--; regionCount--; } } } }
public PolygonManagementViewModel(PolygonGeneratorProvider generatorProvider = null, IDialogHandler dialogHandler = null, PolygonClipper clipper = null, AreaCalculator areaCalculator = null) { Polygons = new ObservableCollection <Polygon>(); DialogHandler = dialogHandler; Clipper = clipper; AreaCalculator = areaCalculator; GenerateAndAddPolygonCommand = new DelegateCommand( GenerateAndAddPolygon, () => SelectedPolygonGenerator != null); ClipPolygonsCommand = new DelegateCommand( ClipPolygons, () => Polygons.Count == 2 && Clipper != null); Polygons.CollectionChanged += (_, __) => ClipPolygonsCommand.RaiseCanExecuteChanged(); CalculateAreaForSelectedPolygonCommand = new DelegateCommand( CalculateAreaForSelectedPolygon, () => SelectedPolygon != null && !IsCalculatingArea && AreaCalculator != null); CancelAreaCalculationCommand = new DelegateCommand( () => CancelSource.Cancel(), () => IsCalculatingArea); if (generatorProvider != null) { Generators = GetGeneratorsFromContainer(generatorProvider); SelectedPolygonGenerator = Generators.LastOrDefault()?.Generator; } MouseCommand = new DelegateCommand <Polygon>((x) => SelectedPolygon = x); }
/// <summary> /// Makes one country region to annex another country /// </summary> public void CountryRegionTransferTo() { if (countryIndex < 0 || GUICountryTransferToCountryIndex < 0 || GUICountryTransferToCountryIndex >= countryNames.Length || countryRegionIndex < 0) { return; } // Get target country // recover GUI country index selection int targetCountryIndex = -1; string[] s = countryNames [GUICountryTransferToCountryIndex].Split(new char[] { '(', ')' }, System.StringSplitOptions.RemoveEmptyEntries); if (s.Length >= 2) { if (!int.TryParse(s [1], out targetCountryIndex)) { return; } } Country sourceCountry = map.countries [countryIndex]; Country targetCountry = map.countries [targetCountryIndex]; Region sourceRegion = sourceCountry.regions [countryRegionIndex]; Region targetRegion = targetCountry.regions [targetCountry.mainRegionIndex]; // Transfer all provinces records to target country if (targetCountry.provinces == null && !map.showProvinces) { map.showProvinces = true; // Forces loading of provinces map.showProvinces = false; } if (sourceCountry.provinces != null) { List <Province> destProvinces; if (targetCountry.provinces != null) { destProvinces = new List <Province> (targetCountry.provinces); } else { destProvinces = new List <Province> (); } List <Province> sourceProvinces = new List <Province> (sourceCountry.provinces); for (int k = 0; k < sourceCountry.provinces.Length; k++) { Province province = sourceCountry.provinces [k]; if (sourceRegion.Contains(province.center)) { province.countryIndex = targetCountryIndex; destProvinces.Add(province); sourceProvinces.Remove(province); provinceChanges = true; } } sourceCountry.provinces = sourceProvinces.ToArray(); targetCountry.provinces = destProvinces.ToArray(); } // Add region to target country's polygon - only if the province is touching or crossing target country frontier PolygonClipper pc = new PolygonClipper(targetRegion, sourceRegion); if (pc.OverlapsSubjectAndClipping()) { pc.Compute(PolygonOp.UNION); } else { // Add new region to country Region newCountryRegion = new Region(targetCountry, targetCountry.regions.Count); newCountryRegion.points = new List <Vector3> (sourceRegion.points).ToArray(); targetCountry.regions.Add(newCountryRegion); } // Transfer cities & mount points TransferRegionCities(countryIndex, sourceRegion, targetCountryIndex); TransferRegionMountPoints(countryIndex, sourceRegion, targetCountryIndex); // Remove region from source country sourceCountry.regions.Remove(sourceRegion); // Finish operation map.HideCountryRegionHighlights(true); map.HideProvinceRegionHighlights(true); map.RefreshCountryDefinition(countryIndex, null); map.RefreshCountryDefinition(targetCountryIndex, null); countryChanges = true; countryIndex = targetCountryIndex; countryRegionIndex = targetCountry.mainRegionIndex; CountryRegionSelect(); map.RedrawMapLabels(); }
/// <summary> /// Changes province's owner to specified country /// </summary> public void ProvinceTransferTo() { if (provinceIndex < 0 || GUIProvinceTransferToCountryIndex < 0 || GUIProvinceTransferToCountryIndex >= countryNames.Length) { return; } // Get target country // recover GUI country index selection int targetCountryIndex = -1; string[] s = countryNames [GUIProvinceTransferToCountryIndex].Split(new char[] { '(', ')' }, System.StringSplitOptions.RemoveEmptyEntries); if (s.Length >= 2) { if (!int.TryParse(s [1], out targetCountryIndex)) { return; } } // Remove province form source country Province province = map.provinces[provinceIndex]; Country sourceCountry = map.countries[countryIndex]; if (map.countries[countryIndex].provinces != null) { List <Province> sourceProvinces = new List <Province>(sourceCountry.provinces); int provIndex = -1; for (int k = 0; k < sourceCountry.provinces.Length; k++) { if (sourceCountry.provinces[k].name.Equals(province.name)) { provIndex = k; } } if (provIndex >= 0) { sourceProvinces.RemoveAt(provIndex); sourceCountry.provinces = sourceProvinces.ToArray(); } } // Adds province to target country province.countryIndex = targetCountryIndex; Country targetCountry = map.countries[targetCountryIndex]; List <Province> destProvinces = new List <Province>(targetCountry.provinces); destProvinces.Add(province); targetCountry.provinces = destProvinces.ToArray(); // Apply boolean operations on country polygons Region provinceRegion = province.regions[provinceRegionIndex]; Region sourceRegion = sourceCountry.regions[sourceCountry.mainRegionIndex]; Region targetRegion = targetCountry.regions[targetCountry.mainRegionIndex]; // Extract from source country - only if province is in the frontier or is crossing the country RegionSanitize(sourceRegion); RegionSanitize(provinceRegion); WPM.Geom.Polygon provincePolygon = GetGeomPolygon(provinceRegion.latlon); PolygonClipper pc = new PolygonClipper(GetGeomPolygon(sourceRegion.latlon), provincePolygon); if (pc.OverlapsSubjectAndClipping()) { pc.Compute(PolygonOp.DIFFERENCE); ReplacePointsFromPolygon(sourceRegion, pc.subject); } // Add region to target country's polygon - only if the province is touching or crossing target country frontier RegionSanitize(targetRegion); pc = new PolygonClipper(GetGeomPolygon(targetRegion.latlon), provincePolygon); if (pc.OverlapsSubjectAndClipping()) { pc.Compute(PolygonOp.UNION); ReplacePointsFromPolygon(targetRegion, pc.subject); } else { // Add new region to country Region newCountryRegion = new Region(targetCountry, targetCountry.regions.Count); newCountryRegion.points = new List <Vector3>(provinceRegion.points).ToArray(); UpdateLatLonFromPoints(newCountryRegion); targetCountry.regions.Add(newCountryRegion); } // Finish operation map.HideCountryRegionHighlights(true); map.HideProvinceRegionHighlights(true); // Refresh definition of old country map.RefreshCountryDefinition(countryIndex, null); // Link province to target country and refresh definition of target country map.RefreshCountryDefinition(targetCountryIndex, null); map.RefreshProvinceDefinition(provinceIndex); countryChanges = true; provinceChanges = true; countryIndex = targetCountryIndex; countryRegionIndex = targetCountry.mainRegionIndex; ProvinceRegionSelect(); }
/// <summary> /// Makes one country to annex another /// </summary> public void CountryTransferTo() { if (countryIndex < 0 || GUICountryTransferToCountryIndex < 0 || GUICountryTransferToCountryIndex >= countryNames.Length) { return; } // Get target country // recover GUI country index selection int targetCountryIndex = -1; string[] s = countryNames [GUICountryTransferToCountryIndex].Split(new char[] { '(', ')' }, System.StringSplitOptions.RemoveEmptyEntries); if (s.Length >= 2) { if (!int.TryParse(s [1], out targetCountryIndex)) { return; } } // Transfer all provinces records to target country Country sourceCountry = map.countries [countryIndex]; Country targetCountry = map.countries [targetCountryIndex]; //MAX! mergeCountryData(sourceCountry, targetCountry); dataChanges = true; ndChanges = true; if (targetCountry.provinces == null && !map.showProvinces) { map.showProvinces = true; // Forces loading of provinces map.showProvinces = false; } if (sourceCountry.provinces != null) { List <Province> destProvinces; if (targetCountry.provinces != null) { destProvinces = new List <Province> (targetCountry.provinces); } else { destProvinces = new List <Province> (); } for (int k = 0; k < sourceCountry.provinces.Length; k++) { Province province = sourceCountry.provinces [k]; province.countryIndex = targetCountryIndex; destProvinces.Add(province); } targetCountry.provinces = destProvinces.ToArray(); } // Add main region of the source country to target if they are joint Region sourceRegion = sourceCountry.regions [sourceCountry.mainRegionIndex]; Region targetRegion = targetCountry.regions [targetCountry.mainRegionIndex]; //MAX! if (sourceRegion.neighbours.Contains(targetRegion)) { // Add region to target country's polygon - only if the province is touching or crossing target country frontier PolygonClipper pc = new PolygonClipper(targetRegion, sourceRegion); if (pc.OverlapsSubjectAndClipping()) { pc.Compute(PolygonOp.UNION); } //MAX! } else { // Add new region to country Region newCountryRegion = new Region(targetCountry, targetCountry.regions.Count); newCountryRegion.points = new List <Vector3> (sourceRegion.points).ToArray(); targetCountry.regions.Add(newCountryRegion); } // Transfer additional regions if (sourceCountry.regions.Count > 1) { List <Region> targetRegions = new List <Region> (targetCountry.regions); for (int k = 0; k < sourceCountry.regions.Count; k++) { if (k != sourceCountry.mainRegionIndex) { targetRegions.Add(sourceCountry.regions [k]); } } targetCountry.regions = targetRegions; } //MAX! if (!map.showCities && map.cities == null) { map.ReadCitiesPackedString(); } // Transfer cities & mount points TransferCities(countryIndex, targetCountryIndex); TransferMountPoints(countryIndex, targetCountryIndex); // Finish operation map.HideCountryRegionHighlights(true); map.HideProvinceRegionHighlights(true); map.CountryDelete(countryIndex, false); map.RefreshCountryDefinition(targetCountryIndex, null); countryChanges = true; provinceChanges = true; countryIndex = targetCountryIndex; countryRegionIndex = targetCountry.mainRegionIndex; CountryRegionSelect(); map.RedrawMapLabels(); }
void ProvinceSubstractProvinceEnclaves(int provinceIndex, Region region, Poly2Tri.Polygon poly) { List <Region> negativeRegions = new List <Region>(); for (int oc = 0; oc < _countries.Length; oc++) { Country ocCountry = _countries[oc]; if (ocCountry.hidden || ocCountry.provinces == null) { continue; } if (!ocCountry.regionsRect2D.Overlaps(region.latlonRect2D)) { continue; } for (int op = 0; op < ocCountry.provinces.Length; op++) { Province opProvince = ocCountry.provinces[op]; if (opProvince == provinces[provinceIndex]) { continue; } if (opProvince.regions == null) { continue; } if (opProvince.regionsRect2D.Overlaps(region.latlonRect2D, true)) { Region oProvRegion = opProvince.regions[opProvince.mainRegionIndex]; if (region.Contains(oProvRegion)) // just check main region of province for speed purposes { negativeRegions.Add(oProvRegion); } } } } // Collapse negative regions in big holes for (int nr = 0; nr < negativeRegions.Count - 1; nr++) { for (int nr2 = nr + 1; nr2 < negativeRegions.Count; nr2++) { if (negativeRegions[nr].Intersects(negativeRegions[nr2])) { PolygonClipper pc = new PolygonClipper(negativeRegions[nr], negativeRegions[nr2]); if (pc.Compute(PolygonOp.UNION, null)) { negativeRegions.RemoveAt(nr2); nr = -1; break; } } } } // Substract holes for (int r = 0; r < negativeRegions.Count; r++) { Poly2Tri.Polygon polyHole = new Poly2Tri.Polygon(negativeRegions[r].latlon); poly.AddHole(polyHole); } }
/// <summary> /// Makes one country to annex another /// </summary> public void CountryTransferTo() { if (countryIndex < 0 || GUICountryTransferToCountryIndex < 0 || GUICountryTransferToCountryIndex >= countryNames.Length) { return; } // Get target country // recover GUI country index selection int targetCountryIndex = -1; string[] s = countryNames [GUICountryTransferToCountryIndex].Split(new char[] { '(', ')' }, System.StringSplitOptions.RemoveEmptyEntries); if (s.Length >= 2) { if (!int.TryParse(s [1], out targetCountryIndex)) { return; } } // Transfer all provinces records to target country Country sourceCountry = map.countries[countryIndex]; Country targetCountry = map.countries[targetCountryIndex]; if (targetCountry.provinces == null && !map.showProvinces) { map.showProvinces = true; // Forces loading of provinces map.showProvinces = false; } List <Province> destProvinces = new List <Province>(targetCountry.provinces); for (int k = 0; k < sourceCountry.provinces.Length; k++) { Province province = sourceCountry.provinces[k]; province.countryIndex = targetCountryIndex; destProvinces.Add(province); } targetCountry.provinces = destProvinces.ToArray(); // Add main region of the source country to target if they are joint Region sourceRegion = sourceCountry.regions[countryRegionIndex]; // sourceCountry.mainRegionIndex]; Region targetRegion = targetCountry.regions[targetCountry.mainRegionIndex]; // Add region to target country's polygon - only if the province is touching or crossing target country frontier // RegionSanitize(targetRegion); // RegionSanitize(sourceRegion); PolygonClipper pc = new PolygonClipper(GetGeomPolygon(targetRegion.latlon), GetGeomPolygon(sourceRegion.latlon)); if (pc.OverlapsSubjectAndClipping()) { pc.Compute(PolygonOp.UNION); ReplacePointsFromPolygon(targetRegion, pc.subject); } else { // Add new region to country sourceRegion.entity = targetCountry; sourceRegion.regionIndex = targetCountry.regions.Count; targetCountry.regions.Add(sourceRegion); } // Transfer additional regions if (sourceCountry.regions.Count > 1) { List <Region> targetRegions = new List <Region>(targetCountry.regions); for (int k = 0; k < sourceCountry.regions.Count; k++) { if (k != countryRegionIndex) //sourceCountry.mainRegionIndex) { { targetRegions.Add(sourceCountry.regions[k]); } } targetCountry.regions = targetRegions; } CountryMergeAdjacentRegions(targetCountry); // Finish operation map.HideCountryRegionHighlights(true); map.HideProvinceRegionHighlights(true); map.CountryDelete(countryIndex, false); if (countryIndex < targetCountryIndex) { targetCountryIndex--; // source country has been deleted moving up remaining countries in the list } map.RefreshCountryDefinition(targetCountryIndex, null); countryChanges = true; provinceChanges = true; countryIndex = targetCountryIndex; countryRegionIndex = targetCountry.mainRegionIndex; CountryRegionSelect(); map.RedrawMapLabels(); }
/// <summary> /// Separates a province from its current country producing a new country /// </summary> public void ProvinceSeparate(string newCountryName) { if (provinceIndex < 0 || provinceIndex >= map.provinces.Length) { return; } // Remove province form source country Province province = map.provinces [provinceIndex]; Country sourceCountry = map.countries [countryIndex]; if (map.countries [countryIndex].provinces != null) { List <Province> sourceProvinces = new List <Province> (sourceCountry.provinces); int provIndex = -1; for (int k = 0; k < sourceCountry.provinces.Length; k++) { if (sourceCountry.provinces [k].name.Equals(province.name)) { provIndex = k; } } if (provIndex >= 0) { sourceProvinces.RemoveAt(provIndex); sourceCountry.provinces = sourceProvinces.ToArray(); } } // Adds province region to a new country Region regionProvince = province.regions [provinceRegionIndex]; Country targetCountry = new Country(newCountryName, sourceCountry.continent); Region region = new Region(targetCountry, 0); region.points = new List <Vector3> (regionProvince.points).ToArray(); targetCountry.regions.Add(region); map.CountryAdd(targetCountry); int targetCountryIndex = map.countries.Length - 1; map.RefreshCountryDefinition(targetCountryIndex, null); lastCountryCount = -1; // Add province to the new country if (targetCountry.provinces == null) { targetCountry.provinces = new Province[0]; } List <Province> destProvinces = new List <Province> (targetCountry.provinces); destProvinces.Add(province); targetCountry.provinces = destProvinces.ToArray(); // Apply boolean operations on country polygons Region provinceRegion = province.regions [provinceRegionIndex]; Region sourceRegion = sourceCountry.regions [sourceCountry.mainRegionIndex]; // Extract from source country - only if province is in the frontier or is crossing the country for (int k = 0; k < sourceCountry.regions.Count; k++) { Region otherSourceRegion = sourceCountry.regions [k]; otherSourceRegion.sanitized = true; } PolygonClipper pc = new PolygonClipper(sourceRegion, provinceRegion); if (pc.OverlapsSubjectAndClipping()) { sourceRegion.sanitized = false; pc.Compute(PolygonOp.DIFFERENCE); } else { // Look for other regions to substract for (int k = 0; k < sourceCountry.regions.Count; k++) { Region otherSourceRegion = sourceCountry.regions [k]; pc = new PolygonClipper(otherSourceRegion, provinceRegion); if (pc.OverlapsSubjectAndClipping()) { otherSourceRegion.sanitized = false; pc.Compute(PolygonOp.DIFFERENCE); } } } // Remove invalid regions from source country for (int k = 0; k < sourceCountry.regions.Count; k++) { Region otherSourceRegion = sourceCountry.regions [k]; if (!otherSourceRegion.sanitized && otherSourceRegion.points.Length < 5) { sourceCountry.regions.RemoveAt(k); k--; } } // Transfer cities int cityCount = map.cities.Count; for (int k = 0; k < cityCount; k++) { City city = map.cities [k]; if (city.countryIndex == countryIndex && city.province.Equals(province.name)) { city.countryIndex = targetCountryIndex; } } // Transfer mount points int mountPointCount = map.mountPoints.Count; for (int k = 0; k < mountPointCount; k++) { MountPoint mp = map.mountPoints [k]; if (mp.countryIndex == countryIndex && mp.provinceIndex == provinceIndex) { mp.countryIndex = targetCountryIndex; } } // Finish operation map.HideCountryRegionHighlights(true); map.HideProvinceRegionHighlights(true); map.RefreshCountryDefinition(province.countryIndex, null); province.countryIndex = targetCountryIndex; map.RefreshProvinceDefinition(provinceIndex); map.RefreshCountryDefinition(targetCountryIndex, null); countryChanges = true; provinceChanges = true; cityChanges = true; mountPointChanges = true; ProvinceRegionSelect(); }
/// <summary> /// Deletes current region or province if this was the last region /// </summary> public void ProvinceDelete() { if (provinceIndex < 0 || provinceIndex >= map.provinces.Length) { return; } // Apply boolean operations on country polygons Province province = map.provinces [provinceIndex]; Region provinceRegion = province.regions [provinceRegionIndex]; Country sourceCountry = map.countries [countryIndex]; // Extract from source country - only if province is in the frontier or is crossing the country for (int k = 0; k < sourceCountry.regions.Count; k++) { Region otherSourceRegion = sourceCountry.regions [k]; otherSourceRegion.sanitized = true; } for (int k = 0; k < sourceCountry.regions.Count; k++) { Region otherSourceRegion = sourceCountry.regions [k]; PolygonClipper pc = new PolygonClipper(otherSourceRegion, provinceRegion); if (pc.OverlapsSubjectAndClipping()) { otherSourceRegion.sanitized = false; pc.Compute(PolygonOp.DIFFERENCE); } } // Remove invalid regions from source country for (int k = 0; k < sourceCountry.regions.Count; k++) { Region otherSourceRegion = sourceCountry.regions [k]; if (!otherSourceRegion.sanitized && otherSourceRegion.points.Length < 5) { sourceCountry.regions.RemoveAt(k); k--; } } // Remove it from the country array List <Province> newProvinces = new List <Province> (map.countries [countryIndex].provinces.Length - 1); for (int k = 0; k < map.countries [countryIndex].provinces.Length; k++) { if (!map.countries [countryIndex].provinces [k].name.Equals(GUIProvinceName)) { newProvinces.Add(map.countries [countryIndex].provinces [k]); } } map.countries [countryIndex].provinces = newProvinces.ToArray(); // Remove from the global array newProvinces = new List <Province> (map.provinces.Length - 1); for (int k = 0; k < map.provinces.Length; k++) { if (k != provinceIndex) { newProvinces.Add(map.provinces [k]); } } map.provinces = newProvinces.ToArray(); // Finish operation map.HideCountryRegionHighlights(true); map.HideProvinceRegionHighlights(true); map.RefreshCountryDefinition(countryIndex, null); ClearProvinceSelection(); map.OptimizeFrontiers(); map.Redraw(); countryChanges = true; provinceChanges = true; CountryRegionSelect(); }
public void ProvinceTransferTo(int targetCountryIndex, int provinceIndex) { // Remove province form source country Province province = map.provinces [provinceIndex]; Country sourceCountry = map.countries [countryIndex]; if (map.countries [countryIndex].provinces != null) { List <Province> sourceProvinces = new List <Province> (sourceCountry.provinces); int provIndex = -1; for (int k = 0; k < sourceCountry.provinces.Length; k++) { if (sourceCountry.provinces [k].name.Equals(province.name)) { provIndex = k; } } if (provIndex >= 0) { sourceProvinces.RemoveAt(provIndex); sourceCountry.provinces = sourceProvinces.ToArray(); } } // Adds province to target country Country targetCountry = map.countries [targetCountryIndex]; if (targetCountry.provinces == null) { targetCountry.provinces = new Province[0]; } List <Province> destProvinces = new List <Province> (targetCountry.provinces); destProvinces.Add(province); targetCountry.provinces = destProvinces.ToArray(); // Apply boolean operations on country polygons Region provinceRegion = province.regions [provinceRegionIndex]; Region sourceRegion = sourceCountry.regions [sourceCountry.mainRegionIndex]; Region targetRegion = targetCountry.regions [targetCountry.mainRegionIndex]; // Extract from source country - only if province is in the frontier or is crossing the country for (int k = 0; k < sourceCountry.regions.Count; k++) { Region otherSourceRegion = sourceCountry.regions [k]; otherSourceRegion.sanitized = true; } PolygonClipper pc = new PolygonClipper(sourceRegion, provinceRegion); if (pc.OverlapsSubjectAndClipping()) { sourceRegion.sanitized = false; pc.Compute(PolygonOp.DIFFERENCE); } else { // Look for other regions to substract for (int k = 0; k < sourceCountry.regions.Count; k++) { Region otherSourceRegion = sourceCountry.regions [k]; pc = new PolygonClipper(otherSourceRegion, provinceRegion); if (pc.OverlapsSubjectAndClipping()) { otherSourceRegion.sanitized = false; pc.Compute(PolygonOp.DIFFERENCE); } } } // Remove invalid regions from source country for (int k = 0; k < sourceCountry.regions.Count; k++) { Region otherSourceRegion = sourceCountry.regions [k]; if (!otherSourceRegion.sanitized && otherSourceRegion.points.Length < 5) { sourceCountry.regions.RemoveAt(k); k--; } } // Add region to target country's polygon - only if the province is touching or crossing target country frontier pc = new PolygonClipper(targetRegion, provinceRegion); if (pc.OverlapsSubjectAndClipping()) { pc.Compute(PolygonOp.UNION); } else { // Add new region to country Region newCountryRegion = new Region(targetCountry, targetCountry.regions.Count); newCountryRegion.points = new List <Vector3> (provinceRegion.points).ToArray(); targetCountry.regions.Add(newCountryRegion); } //Max! if (!map.showCities && map.cities == null) { map.ReadCitiesPackedString(); } // Transfer cities int cityCount = map.cities.Count; for (int k = 0; k < cityCount; k++) { City city = map.cities [k]; if (city.countryIndex == countryIndex && city.province.Equals(province.name)) { city.countryIndex = targetCountryIndex; } } // Transfer mount points int mountPointCount = map.mountPoints.Count; for (int k = 0; k < mountPointCount; k++) { MountPoint mp = map.mountPoints [k]; if (mp.countryIndex == countryIndex && mp.provinceIndex == provinceIndex) { mp.countryIndex = targetCountryIndex; } } // Finish operation map.HideCountryRegionHighlights(true); map.HideProvinceRegionHighlights(true); map.RefreshCountryDefinition(province.countryIndex, null); province.countryIndex = targetCountryIndex; map.RefreshProvinceDefinition(provinceIndex); map.RefreshCountryDefinition(targetCountryIndex, null); countryChanges = true; provinceChanges = true; cityChanges = true; mountPointChanges = true; }