Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        /// <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());
        }