示例#1
0
        private static void CalculateAveragePolylabelCellSize(AIXMBasicMessage msg, out double averageCellSize)
        {
            // Calculate the average polylabel cell size to "guestimate" what the font scaling value should be

            double aggregatedCellSize = 0;
            int    totalTests         = 0;

            foreach (var member in msg.hasMember)
            {
                var polygonTest = new List <MyPoint>();

                var coords = member.Airspace.timeSlice.AirspaceTimeSlice1.geometryComponent.AirspaceGeometryComponent
                             .theAirspaceVolume.AirspaceVolume.horizontalProjection.Surface.patches.PolygonPatch.exterior
                             .LinearRing.posList.Split(' ');

                ReverseArray(coords);

                var interiorCoords = new List <string>();
                if (member.Airspace.timeSlice.AirspaceTimeSlice1.geometryComponent
                    .AirspaceGeometryComponent.theAirspaceVolume.AirspaceVolume.horizontalProjection.Surface.patches
                    .PolygonPatch.interior != null)
                {
                    foreach (var tmp in member.Airspace.timeSlice.AirspaceTimeSlice1.geometryComponent
                             .AirspaceGeometryComponent.theAirspaceVolume.AirspaceVolume.horizontalProjection.Surface.patches
                             .PolygonPatch.interior.Select(interior => interior.LinearRing.posList.Split(' ')))
                    {
                        ReverseArray(tmp);
                        interiorCoords.AddRange(tmp);
                    }
                }

                var combined = new List <LatLng>();
                if (interiorCoords.Count > 0)
                {
                    // If the polygons are overlapping, then we need to do some extra
                    // magic to ensure the mva label is placed in the correct polygon.
                    // To do this, we combine the exterior and interior coordinate groups
                    // which will be used to calculate the polylabel bounding box.
                    var combinedCoords = coords.Concat(interiorCoords).ToArray();

                    for (var i = 0; i < combinedCoords.Length; i += 2)
                    {
                        combined.Add(new LatLng(double.Parse(combinedCoords[i]), double.Parse(combinedCoords[i + 1])));
                    }

                    for (var i = 0; i < combined.Count; i++)
                    {
                        var x1 = i == 0 ? (combined[i].Lat) : (combined[i - 1].Lat);
                        var y1 = i == 0 ? (combined[i].Lon) : (combined[i - 1].Lon);

                        var geo = GeoUtils.GeoToPixels(x1, y1, mCenterLat, mCenterLon);
                        polygonTest.Add(new MyPoint(geo.X, geo.Y));
                    }
                }

                var temp = new List <LatLng>();

                for (var i = 0; i < coords.Length; i += 2)
                {
                    temp.Add(new LatLng(double.Parse(coords[i]), double.Parse(coords[i + 1])));
                }

                for (var i = 0; i < temp.Count; i++)
                {
                    var x1 = i == 0 ? (temp[i].Lat) : (temp[i - 1].Lat);
                    var y1 = i == 0 ? (temp[i].Lon) : (temp[i - 1].Lon);

                    if (interiorCoords.Count == 0)
                    {
                        var geo = GeoUtils.GeoToPixels(x1, y1, mCenterLat, mCenterLon);
                        polygonTest.Add(new MyPoint(geo.X, geo.Y));
                    }
                }

                var poly = PolyLabel.GetPolyLabel(polygonTest);
                aggregatedCellSize += poly.Radius / 100;
                totalTests++;
            }

            averageCellSize = aggregatedCellSize / totalTests;
        }
        public static PolyLabel GetPolyLabel(List <MyPoint> polygon, float precision = 1.0f, bool debug = false)
        {
            float minX = float.MaxValue;
            float minY = float.MaxValue;
            float maxX = float.MinValue;
            float maxY = float.MinValue;

            for (int i = 0; i < polygon.Count; i++)
            {
                MyPoint p = polygon[i];
                if (i == 0 || p.X < minX)
                {
                    minX = p.X;
                }
                if (i == 0 || p.Y < minY)
                {
                    minY = p.Y;
                }
                if (i == 0 || p.X > maxX)
                {
                    maxX = p.X;
                }
                if (i == 0 || p.Y > maxY)
                {
                    maxY = p.Y;
                }
            }

            float width    = maxX - minX;
            float height   = maxY - minY;
            float cellSize = Math.Min(width, height);
            float h        = cellSize / 2;

            SimplePriorityQueue <Cell> cellQueue = new SimplePriorityQueue <Cell>();

            if (cellSize == 0)
            {
                PolyLabel degeneratePoleOfInaccessibility = new PolyLabel()
                {
                    Centroid = new MyPoint(minX, minY),
                    Radius   = 0
                };
                return(degeneratePoleOfInaccessibility);
            }

            for (var x = minX; x < maxX; x += cellSize)
            {
                for (var y = minY; y < maxY; y += cellSize)
                {
                    Cell cell = new Cell(x + h, y + h, h, polygon);
                    cellQueue.Enqueue(cell, cell.Max);
                }
            }

            Cell bestCell = GetCentroidCell(polygon);

            Cell bBoxCell = new Cell(minX + width / 2, minY + height / 2, 0, polygon);

            if (bBoxCell.D > bestCell.D)
            {
                bestCell = bBoxCell;
            }

            int numProbes = cellQueue.Count;

            while (cellQueue.Count != 0)
            {
                // pick the most promising cell from the queue
                var cell = cellQueue.Dequeue();

                // update the best cell if we found a better one
                if (cell.D > bestCell.D)
                {
                    bestCell = cell;
                    if (debug)
                    {
                        Console.WriteLine("found best {0} after {1} probes", Math.Round(1e4 * cell.D) / 1e4, numProbes);
                    }
                }

                // do not drill down further if there's no chance of a better solution
                if (cell.Max - bestCell.D <= precision)
                {
                    continue;
                }

                // split the cell into four cells
                h = cell.H / 2;

                Cell temp;
                temp = new Cell(cell.X - h, cell.Y - h, h, polygon);
                cellQueue.Enqueue(temp, temp.Max);
                temp = new Cell(cell.X + h, cell.Y - h, h, polygon);
                cellQueue.Enqueue(temp, temp.Max);
                temp = new Cell(cell.X - h, cell.Y + h, h, polygon);
                cellQueue.Enqueue(temp, temp.Max);
                temp = new Cell(cell.X + h, cell.Y + h, h, polygon);
                cellQueue.Enqueue(temp, temp.Max);
                numProbes += 4;
            }

            if (debug)
            {
                Console.WriteLine("num probes: " + numProbes);
                Console.WriteLine("best distance: " + bestCell.D);
            }

            PolyLabel poleOfInaccessibility = new PolyLabel()
            {
                Centroid = new MyPoint(bestCell.X, bestCell.Y),
                Radius   = bestCell.D
            };

            return(poleOfInaccessibility);
        }
示例#3
0
        private static void CreateMvaTextLabels(StringBuilder sb, double averageCellSize, string mvaLabel,
                                                List <MyPoint> polygonPoints)
        {
            if (string.IsNullOrEmpty(mvaLabel))
            {
                return;
            }

            var scale = Math.Min(Math.Max(0.03f, averageCellSize), 0.5f);

            var polyLabel = PolyLabel.GetPolyLabel(polygonPoints);

            var x = polyLabel.Centroid.X - (mvaLabel.Length - 1) * 20 * scale;
            var y = polyLabel.Centroid.Y;

            foreach (var digit in mvaLabel.ToCharArray())
            {
                switch (digit)
                {
                case '0':
                    GetCharacterLines(HersheyFont.Zero, x, y, scale, sb);
                    break;

                case '1':
                    GetCharacterLines(HersheyFont.One, x, y, scale, sb);
                    break;

                case '2':
                    GetCharacterLines(HersheyFont.Two, x, y, scale, sb);
                    break;

                case '3':
                    GetCharacterLines(HersheyFont.Three, x, y, scale, sb);
                    break;

                case '4':
                    GetCharacterLines(HersheyFont.Four, x, y, scale, sb);
                    break;

                case '5':
                    GetCharacterLines(HersheyFont.Five, x, y, scale, sb);
                    break;

                case '6':
                    GetCharacterLines(HersheyFont.Six, x, y, scale, sb);
                    break;

                case '7':
                    GetCharacterLines(HersheyFont.Seven, x, y, scale, sb);
                    break;

                case '8':
                    GetCharacterLines(HersheyFont.Eight, x, y, scale, sb);
                    break;

                case '9':
                    GetCharacterLines(HersheyFont.Nine, x, y, scale, sb);
                    break;
                }

                x += (20 * scale);
            }
        }