Skip to content

Commit

Permalink
FlightPlanner: KML Overlay improvements (text and colors)
Browse files Browse the repository at this point in the history
  • Loading branch information
meee1 committed Mar 27, 2024
1 parent aa3e2e2 commit c8f8c54
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 53 deletions.
55 changes: 55 additions & 0 deletions ExtLibs/Maps/GMapMarkerKMLLabel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using GMap.NET;
using GMap.NET.WindowsForms;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;

namespace MissionPlanner.GCSViews
{
public class GMapMarkerKMLLabel : GMapMarker
{
private PointLatLng pointLatLng;
private string text;
private Font font;
static Dictionary<string, Bitmap> fontBitmaps = new Dictionary<string, Bitmap>();
private SizeF txtsize;

public GMapMarkerKMLLabel(PointLatLng pointLatLng, string text): base(pointLatLng)
{
this.pointLatLng = pointLatLng;
this.text = text;

if (font == null)
font = SystemFonts.DefaultFont;

if (!fontBitmaps.ContainsKey(text))
{
Bitmap temp = new Bitmap(100, 40, PixelFormat.Format32bppArgb);
using (Graphics g = Graphics.FromImage(temp))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
txtsize = g.MeasureString(text, font);

g.DrawString(text, font, Brushes.White, new PointF(0, 0));
}
fontBitmaps[text] = temp;
}
IsHitTestVisible = false;
}

public override void OnRender(IGraphics g)
{
base.OnRender(g);

var midw = LocalPosition.X + 10;
var midh = LocalPosition.Y + 3;

if (txtsize.Width > 15)
midw -= 4;

g.DrawImageUnscaled(fontBitmaps[text], midw, midh);
}
}
}
140 changes: 87 additions & 53 deletions GCSViews/FlightPlanner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
using Resources = MissionPlanner.Properties.Resources;
using Newtonsoft.Json;
using MissionPlanner.ArduPilot.Mavlink;
using SharpKml.Engine;

namespace MissionPlanner.GCSViews
{
Expand Down Expand Up @@ -4100,9 +4101,12 @@ public void kMLOverlayToolStripMenuItem_Click(object sender, EventArgs e)
{
kmlpolygonsoverlay.Polygons.Clear();
kmlpolygonsoverlay.Routes.Clear();
kmlpolygonsoverlay.Markers.Clear();

FlightData.kmlpolygons.Routes.Clear();
FlightData.kmlpolygons.Polygons.Clear();
FlightData.kmlpolygons.Markers.Clear();

if (file.ToLower().EndsWith("gpkg"))
{
#if !LIB
Expand Down Expand Up @@ -4198,9 +4202,12 @@ public void kMLOverlayToolStripMenuItem_Click(object sender, EventArgs e)

var parser = new Parser();

parser.ElementAdded += parser_ElementAdded;
parser.ParseString(kml, false);

Kml rootnode = parser.Root as Kml;

processKML(rootnode.Feature);

if ((int) DialogResult.Yes ==
CustomMessageBox.Show(Strings.Do_you_want_to_load_this_into_the_flight_data_screen,
Strings.Load_data,
Expand Down Expand Up @@ -4925,16 +4932,6 @@ public void panelMap_Resize(object sender, EventArgs e)
label11.Location = new Point(panelMap.Size.Width - 50, label11.Location.Y);
}

private void panelWaypoints_ExpandClick(object sender, EventArgs e)
{
Commands.AutoResizeColumns();
}

private void parser_ElementAdded(object sender, ElementEventArgs e)
{
processKML(e.Element);
}

public void Planner_Resize(object sender, EventArgs e)
{
MainMap.Zoom = trackBar1.Value;
Expand Down Expand Up @@ -5047,68 +5044,105 @@ public void prefetchWPPathToolStripMenuItem_Click(object sender, EventArgs e)
FetchPath();
}

private void processKML(Element Element)
private void processKML(Element Element, Document root = null)
{
Document doc = Element as Document;
Placemark pm = Element as Placemark;
Folder folder = Element as Folder;
Polygon polygon = Element as Polygon;
LineString ls = Element as LineString;
MultipleGeometry geom = Element as MultipleGeometry;

if (doc != null)
if (Element is Document)
{
foreach (var feat in doc.Features)
foreach (var feat in ((Document)Element).Features)
{
//Console.WriteLine("feat " + feat.GetType());
//processKML((Element)feat);
processKML(feat, (Document)Element);
}
}
else if (folder != null)

return;
}
else if (Element is Folder)
{
foreach (Feature feat in folder.Features)
foreach (var feat in ((Folder)Element).Features)
{
//Console.WriteLine("feat "+feat.GetType());
//processKML(feat);
processKML(feat, root);
}
}
else if (pm != null)
else if (Element is Placemark)
{
}
else if (polygon != null)
{
GMapPolygon kmlpolygon = new GMapPolygon(new List<PointLatLng>(), "kmlpolygon");
var styleurl = ((Placemark)Element).StyleUrl;

kmlpolygon.Stroke.Color = Color.Purple;
kmlpolygon.Fill = Brushes.Transparent;

foreach (var loc in polygon.OuterBoundary.LinearRing.Coordinates)
if (((Placemark)Element).Geometry != null)
{
kmlpolygon.Points.Add(new PointLatLng(loc.Latitude, loc.Longitude));
}
var Element2 = ((Placemark)Element).Geometry;
if (Element2 is Polygon)
{
GMapPolygon kmlpolygon = new GMapPolygon(new List<PointLatLng>(), "kmlpolygon");

kmlpolygonsoverlay.Polygons.Add(kmlpolygon);
}
else if (ls != null)
{
GMapRoute kmlroute = new GMapRoute(new List<PointLatLng>(), "kmlroute");
var colorwidth = GetKMLLineColor(styleurl.OriginalString.TrimStart('#'), root);
kmlpolygon.Stroke = new Pen(colorwidth.Item1, colorwidth.Item2);
kmlpolygon.Fill = Brushes.Transparent;

kmlroute.Stroke.Color = Color.Purple;
foreach (var loc in ((Polygon)Element2).OuterBoundary.LinearRing.Coordinates)
{
kmlpolygon.Points.Add(new PointLatLng(loc.Latitude, loc.Longitude));
}

foreach (var loc in ls.Coordinates)
{
kmlroute.Points.Add(new PointLatLng(loc.Latitude, loc.Longitude));
}
kmlpolygonsoverlay.Polygons.Add(kmlpolygon);
}
else if (Element2 is LineString)
{
GMapRoute kmlroute = new GMapRoute(new List<PointLatLng>(), "kmlroute");

kmlpolygonsoverlay.Routes.Add(kmlroute);
var colorwidth = GetKMLLineColor(styleurl.OriginalString.TrimStart('#'), root);
kmlroute.Stroke = new Pen(colorwidth.Item1, colorwidth.Item2);

foreach (var loc in ((LineString)Element2).Coordinates)
{
kmlroute.Points.Add(new PointLatLng(loc.Latitude, loc.Longitude));
}

kmlpolygonsoverlay.Routes.Add(kmlroute);
}
else if (Element2 is MultipleGeometry)
{
foreach (var geometry in ((MultipleGeometry)Element2).Geometry)
{
processKML(new Placemark() { Geometry = geometry, StyleUrl = ((Placemark)Element).StyleUrl }, root);
}
}
else if (Element2 is SharpKml.Dom.Point)
{

// its a label
var placemark = (Placemark)Element;
var text = placemark.Name;
var lookat = placemark.CalculateLookAt();

kmlpolygonsoverlay.Markers.Add(new GMapMarkerKMLLabel(new PointLatLng(lookat.Latitude.Value, lookat.Longitude.Value), text));

}
}
}
else if (geom != null)
}

private (Color,int) GetKMLLineColor(string styleurl, Document root)
{
var style2 = root.Styles.Where(a => a.Id == styleurl.TrimStart('#')).First();

if (style2 is StyleMapCollection)
{
foreach (var geometry in geom.Geometry)
var styleurl2 = ((StyleMapCollection)(style2)).First().StyleUrl;

var style = root.Styles.Where(a => a.Id == styleurl2.OriginalString.TrimStart('#')).First();
if (style != null)
{
processKML(geometry);
if (((Style)style).Line != null)
{
int color = ((Style)style).Line.Color.Value.Abgr;
// convert color from ABGR to ARGB
color = (int)((color & 0xFF00FF00) | ((color & 0x00FF0000) >> 16) | ((color & 0x000000FF) << 16));

// ABGR
return (Color.FromArgb(color), (int)((Style)style).Line.Width.Value);
}
}
}
return (Color.White, 2);
}

private void processKMLMission(object sender, ElementEventArgs e)
Expand Down

0 comments on commit c8f8c54

Please sign in to comment.