Skip to content

Commit e36257a

Browse files
committed
label background
1 parent 77296a9 commit e36257a

9 files changed

Lines changed: 68 additions & 22 deletions

RateAppSource/RateController/RateMap/ElevationOverlayCreator.cs

Lines changed: 68 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Diagnostics;
88
using System.Drawing;
99
using System.Linq;
10+
using System.Windows.Forms;
1011

1112
namespace RateController.RateMap
1213
{
@@ -72,7 +73,7 @@ public void Build()
7273
var bounds = ComputeBounds();
7374
var grid = BuildGrid(bounds);
7475

75-
grid = SmoothGrid(grid, passes: 2);
76+
grid = SmoothGrid(grid, passes: 1);
7677

7778
var contours = GenerateContours(grid, bounds);
7879

@@ -142,6 +143,7 @@ private void ApplySimulatedElevations()
142143
Readings = simulatedReadings;
143144
ShowReadings();
144145
}
146+
145147
private double[,] BuildGrid((double minLat, double maxLat, double minLon, double maxLon) b)
146148
{
147149
gridRows = (int)(MetersBetweenLat(b.minLat, b.maxLat) / GridResolutionMeters) + 1;
@@ -212,7 +214,6 @@ private void DrawContours(List<ContourLine> contours)
212214
.Select(ratio => contour.Points[(int)(contour.Points.Count * ratio)])
213215
.ToList();
214216

215-
bool labelPlaced = false;
216217
foreach (var labelPos in candidates)
217218
{
218219
bool tooClose = allPlacedLabels.Any(p =>
@@ -221,10 +222,9 @@ private void DrawContours(List<ContourLine> contours)
221222
if (!tooClose)
222223
{
223224
_labelOverlay.Markers.Add(
224-
new TextMarker(labelPos, $"{group.Key:0} m"));
225+
new TextMarker(labelPos, group.Key));
225226
allPlacedLabels.Add(labelPos);
226227
labelCountThisLevel++;
227-
labelPlaced = true;
228228
break; // Successfully placed, move to next contour
229229
}
230230
}
@@ -233,6 +233,7 @@ private void DrawContours(List<ContourLine> contours)
233233
}
234234
}
235235
}
236+
236237
private List<ContourLine> GenerateContours(
237238
double[,] grid,
238239
(double minLat, double maxLat, double minLon, double maxLon) b)
@@ -242,7 +243,10 @@ private List<ContourLine> GenerateContours(
242243
double minElev = Readings.Min(r => r.Elevation);
243244
double maxElev = Readings.Max(r => r.Elevation);
244245

245-
for (double level = minElev; level <= maxElev; level += ContourInterval)
246+
double start = Math.Floor(minElev / ContourInterval) * ContourInterval;
247+
double end = Math.Ceiling(maxElev / ContourInterval) * ContourInterval;
248+
249+
for (double level = start; level <= end + 1e-9; level += ContourInterval)
246250
{
247251
var lines = MarchingSquares(grid, b, level);
248252

@@ -309,7 +313,8 @@ private double Haversine(double lat1, double lon1, double lat2, double lon2)
309313
private double InterpolateElevation(double lat, double lon)
310314
{
311315
var nearest = Readings
312-
.Select(r => new {
316+
.Select(r => new
317+
{
313318
Reading = r,
314319
Dist = Haversine(lat, lon, r.Latitude, r.Longitude)
315320
})
@@ -330,7 +335,6 @@ private double InterpolateElevation(double lat, double lon)
330335
return valueSum / weightSum;
331336
}
332337

333-
334338
private List<List<PointLatLng>> MarchingSquares(
335339
double[,] grid,
336340
(double minLat, double maxLat, double minLon, double maxLon) b,
@@ -391,7 +395,6 @@ private double MetersBetweenLat(double lat1, double lat2)
391395
private double MetersBetweenLon(double lon1, double lon2, double lat)
392396
=> Haversine(lat, lon1, lat, lon2);
393397

394-
395398
private double PolylineLengthMeters(List<PointLatLng> line)
396399
{
397400
double length = 0;
@@ -413,7 +416,7 @@ private void ShowReadings()
413416
{
414417
if (reading.Elevation > 280) count++;
415418
}
416-
Debug.Print("total: "+Readings.Count.ToString()+ ", above 280: " + count.ToString());
419+
Debug.Print("total: " + Readings.Count.ToString() + ", above 280: " + count.ToString());
417420
}
418421

419422
private double[,] SmoothGrid(double[,] grid, int passes = 2)
@@ -538,30 +541,73 @@ private struct Segment
538541

539542
public class TextMarker : GMapMarker
540543
{
541-
private readonly Brush _brush = Brushes.Black;
542-
private readonly Font _font = new Font("Segoe UI", 12, FontStyle.Bold);
543-
private readonly Pen _outline = new Pen(Color.White, 3);
544+
private static readonly Font TextFont =
545+
new Font("Segoe UI", 11, FontStyle.Bold);
546+
547+
// Fully opaque tooltip-style yellow
548+
private static readonly Brush BgBrush =
549+
new SolidBrush(Color.FromArgb(255, 255, 255, 200));
550+
551+
private static readonly Brush TextBrush =
552+
new SolidBrush(Color.Black);
553+
554+
private static readonly Pen BorderPen =
555+
new Pen(Color.FromArgb(255, 160, 160, 120), 1);
556+
557+
// Minimal padding
558+
private const int PadX = 3;
559+
private const int PadY = 1;
560+
561+
public double ElevationMeters { get; }
544562

545-
public TextMarker(PointLatLng pos, string text) : base(pos)
563+
public TextMarker(PointLatLng position, double elevationMeters)
564+
: base(position)
546565
{
547-
Text = text;
566+
ElevationMeters = elevationMeters;
548567
}
549568

550-
public string Text { get; set; }
569+
private string GetDisplayText()
570+
{
571+
if (Props.UseMetric)
572+
{
573+
return $"{ElevationMeters:F1} m";
574+
}
575+
else
576+
{
577+
double feet = ElevationMeters * 3.28084;
578+
return $"{Math.Round(feet):0} ft";
579+
}
580+
}
551581

552582
public override void OnRender(Graphics g)
553583
{
554-
if (string.IsNullOrEmpty(Text))
584+
string text = GetDisplayText();
585+
if (string.IsNullOrEmpty(text))
555586
return;
556587

557-
SizeF size = g.MeasureString(Text, _font);
588+
// Prevent yellow washout in GMap.NET
589+
var oldMode = g.CompositingMode;
590+
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
591+
592+
SizeF textSize = g.MeasureString(text, TextFont);
593+
594+
float w = textSize.Width + PadX * 2;
595+
float h = textSize.Height + PadY * 2;
596+
597+
float x = LocalPosition.X - w / 2;
598+
float y = LocalPosition.Y - h / 2;
599+
600+
RectangleF rect = new RectangleF(x, y, w, h);
601+
602+
// Background
603+
g.FillRectangle(BgBrush, rect);
558604

559-
// Center text
560-
float x = LocalPosition.X - size.Width / 2;
561-
float y = LocalPosition.Y - size.Height / 2;
605+
// Restore normal blending
606+
g.CompositingMode = oldMode;
562607

563-
// Outline for readability
564-
g.DrawString(Text, _font, _brush, x, y);
608+
// Border + text
609+
g.DrawRectangle(BorderPen, rect.X, rect.Y, rect.Width, rect.Height);
610+
g.DrawString(text, TextFont, TextBrush, rect.X + PadX, rect.Y + PadY);
565611
}
566612
}
567613
}
512 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)