public void RegionSanitize(Region region) { // UpdateLatLonFromPoints(region); // reduces precision List <PolygonPoint> newLatLons = new List <PolygonPoint>(region.latlon); // removes points which are too near from others for (int k = 0; k < newLatLons.Count; k++) { PolygonPoint p0 = newLatLons[k]; for (int j = k + 1; j < newLatLons.Count; j++) { PolygonPoint p1 = newLatLons[j]; double distance = (p1 - p0).MagnitudeSquared(); if (distance < 0.000001) { newLatLons.RemoveAt(j); j--; } } } // remove crossing segments region.latlon = PolygonSanitizer.RemoveCrossingSegments(newLatLons).ToArray(); // updates points UpdatePointsFromLatLon(region); }
/// <summary> /// Exports the geographic data in packed string format with reduced quality. /// </summary> public string GetCountryGeoDataLowQuality() { // step 1: duplicate data IAdminEntity[] entities; if (editingMode == EDITING_MODE.COUNTRIES) { entities = map.countries; } else { entities = map.provinces; } List <IAdminEntity> entities1 = new List <IAdminEntity>(entities); // step 1: prepare data structures for (int k = 0; k < entities1.Count; k++) { entities1[k].regions = new List <Region>(entities1[k].regions); } // step 2: catalog points int totalPoints = 0; List <PolygonPoint> allPoints = new List <PolygonPoint>(150000); for (int k = 0; k < entities1.Count; k++) { for (int r = 0; r < entities1[k].regions.Count; r++) { Region region1 = entities1[k].regions[r]; totalPoints += region1.latlon.Length; allPoints.AddRange(region1.latlon); } } allPoints = DouglasPeucker.SimplifyCurve(allPoints, 0.1); Dictionary <PolygonPoint, bool> allPointsLookup = new Dictionary <PolygonPoint, bool>(allPoints.Count); for (int k = 0; k < allPoints.Count; k++) { if (!allPointsLookup.ContainsKey(allPoints[k])) { allPointsLookup.Add(allPoints[k], true); } } // step 3: reduce region points according to exclusion catalog int savings = 0; List <PolygonPoint> goodLatLons = new List <PolygonPoint>(15000); for (int k = 0; k < entities1.Count; k++) { for (int r = 0; r < entities1[k].regions.Count; r++) { goodLatLons.Clear(); Region region = entities1[k].regions[r]; for (int p = 0; p < region.latlon.Length; p++) { PolygonPoint latlon = region.latlon[p]; if (allPointsLookup.ContainsKey(latlon)) { goodLatLons.Add(latlon); } } goodLatLons = PolygonSanitizer.RemoveCrossingSegments(goodLatLons); if (goodLatLons.Count < 5) { entities1[k].regions.Remove(region); r--; } else { totalPoints += region.latlon.Length; savings += (region.latlon.Length - goodLatLons.Count); region.latlon = goodLatLons.ToArray(); } } } Debug.Log(savings + " points removed of " + totalPoints + " (" + (((float)savings / totalPoints) * 100.0f).ToString("F1") + "%)"); StringBuilder sb = new StringBuilder(); for (int k = 0; k < entities1.Count; k++) { IAdminEntity entity = entities1[k]; if (entity.regions.Count == 0) { continue; } if (k > 0) { sb.Append("|"); } sb.Append(entity.name + "$"); if (entity is Country) { sb.Append(((Country)entity).continent + "$"); } else { sb.Append(map.countries[((Province)entity).countryIndex].name + "$"); } for (int r = 0; r < entity.regions.Count; r++) { if (r > 0) { sb.Append("*"); } Region region = entity.regions [r]; for (int p = 0; p < region.latlon.Length; p++) { if (p > 0) { sb.Append(";"); } Point2D point = region.latlon [p] * WorldMapGlobe.MAP_PRECISION; sb.Append(Mathf.RoundToInt(point.Xf).ToString() + ","); sb.Append(Mathf.RoundToInt(point.Yf).ToString()); } } } return(sb.ToString()); }