C#调用Google Earth API绘制路径

一、准备

        在开发之前,必须先安装Google Earth客户端,版本不限。在安装客户端后,需要进行注册,只有注册后才能调用相关的API。

        GE的注册方法为:使用管理员运行CMD,切换到安装盘符,执行命令googleearth.exe /regserver,没有出现错误即为注册成功。

        GoogleEarth COM API参考文档可以在这里找到:http://earth.google.com/comapi/index.html

二、嵌入GE

    新建一个WinForm工程,添加Google Earth 1.0 Type Library的COM引用后就可以使用GE的API,目前API为1.0版本,提供了很少的接口方法。


        下面示例代码为将GE嵌入到WinForm窗体:

        static readonly Int32 WM_QUIT = 0x0012;
        private IntPtr _gehMainWnd = (IntPtr)0;
        private IntPtr _gehRenderWnd = (IntPtr)0;

        private ApplicationGE GEApp;

        public Form1()
        {
            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            //启动GoogleEarth实例
            GEApp = new ApplicationGE();

            _gehMainWnd = (IntPtr)GEApp.GetMainHwnd();
            //隐藏GoogleEarth主窗口
            NativeMethods.SetWindowPos(_gehMainWnd, NativeMethods.HWND_BOTTOM, 0, 0, 0, 0, NativeMethods.SWP_NOSIZE | NativeMethods.SWP_HIDEWINDOW);

            _gehRenderWnd = (IntPtr)GEApp.GetRenderHwnd();
            //将渲染窗口嵌入到主窗体
            NativeMethods.MoveWindow(_gehRenderWnd, 0, 50, this.Width, this.Height - 50, true);
            NativeMethods.SetParent(_gehRenderWnd, this.Handle);
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);
            //关闭窗口
            NativeMethods.PostMessage((int)_gehMainWnd, WM_QUIT, 0, 0);
        }

三、绘制路径

    COM API提供了方法OpenKmlFile(string fileName, int suppressMessages)和LoadKmlData(ref string kmlData)方法来加载轨迹数据,这两个方法都可以加载数据,但不同的是OpenKmlFile方法会清空原有路径,而LoadKmlData则不会。

    KML数据是有GE规定的一种数据格式,其中可以包含点、线等多种数据。KML的生成方式将在第四点介绍。

    下面示例代码用来绘制轨迹:

                if (GEApp != null)
                {
                    var kmlpath = AppDomain.CurrentDomain.BaseDirectory + "test.kml";
                    GEApp.OpenKmlFile(kmlpath, 1);
                }

四、KML文件生成

    生成KML文件需要添加相关的元素类,首先是根元素

using System.IO;
using System.Xml.Serialization;

namespace GeDemo.Kml
{
    [XmlRoot("kml", Namespace = "http://www.opengis.net/kml/2.2")]
    public class KmlRoot
    {
        [XmlElement("Document")]
        public KmlDocument Document { get; set; }

        public KmlRoot()
        {
            
        }

        public KmlRoot(KmlDocument doc)
        {
            this.Document = doc;
        }

        public void GenerateKmlFile(string kmlFileName)
        {
            using (var fs = new FileStream(kmlFileName, FileMode.Create, FileAccess.ReadWrite))
            {
                using (var sw = new StreamWriter(fs, System.Text.Encoding.UTF8))
                {
                    XmlSerializer serializer = new XmlSerializer(GetType());
                    serializer.Serialize(sw, this);
                }
            }
        }
    }
}
    
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;

namespace GeDemo.Kml
{
    public class KmlDocument
    {
        [XmlElement("name")]
        public string Name { get; set; }

        [XmlElement("Style")]
        public List<KmlStyle> Styles { get; set; }

        [XmlElement("StyleMap")]
        public KmlStyleMap StyleMap { get; set; }

        [XmlElement("Placemark")]
        public List<KmlPlacemark> PlaceMarkers { get; set; } 

        public KmlDocument()
        {
        }

        public KmlDocument(string name, List<KmlPlacemark> folderList, string mapId)
        {
            Name = name;
            PlaceMarkers = folderList;
            Styles = KmlStyle.GetStyleList();
            StyleMap = new KmlStyleMap(mapId);
        }

    }
}
using System.Collections.Generic;
using System.Xml.Serialization;

namespace GeDemo.Kml
{
    public class KmlStyle
    {
        private static readonly string[,] styleTable =
        {
            {"green", "FF006400", "4"},
            {"red", "FF006400", "4"}
        };

        [XmlAttribute("id")]
        public string ID { get; set; }

        [XmlElement("LineStyle")]
        public KmlLineStyle lineStyle { get; set; }

        public KmlStyle()
        {
        }

        public KmlStyle(string id, string color, string width)
        {
            ID = id;
            lineStyle = new KmlLineStyle(color, width);
        }

        public static List<KmlStyle> GetStyleList()
        {
            List<KmlStyle> rtn = new List<KmlStyle>();
            for (int i = 0; i < styleTable.GetLength(0); i++)
            {
                KmlStyle style = new KmlStyle(styleTable[i, 0], styleTable[i, 1], styleTable[i, 2]);
                rtn.Add(style);
            }
            return rtn;
        }

        public class KmlLineStyle
        {
            [XmlElement("color")]
            public string Color { get; set; }

            [XmlElement("width")]
            public string Width { get; set; }

            public KmlLineStyle()
            {
            }

            public KmlLineStyle(string color, string width)
            {
                Color = color;
                Width = width;
            }
        }
    }
}
using System.Collections.Generic;
using System.Xml.Serialization;

namespace GeDemo.Kml
{
    public class KmlStyleMap
    {
        private static readonly string[,] styleTable =
        {
            {"normal", "#green"},
            {"highlight", "#red"}
        };

        [XmlAttribute("id")]
        public string ID { get; set; }
        [XmlElement("Pair")]
        public List<Pair> pairs { get; set; }

        public KmlStyleMap()
        {
        }

        public KmlStyleMap(string id)
        {
            ID = id;
            pairs = GetPairList();
        }

        public static List<Pair> GetPairList()
        {
            List<Pair> rtn = new List<Pair>();
            for (int i = 0; i < styleTable.GetLength(0); i++)
            {
                Pair pair = new Pair(styleTable[i, 0], styleTable[i, 1]);
                rtn.Add(pair);
            }
            return rtn;
        }

        public class Pair
        {
            [XmlElement("key")]
            public string Key { get; set; }

            [XmlElement("styleUrl")]
            public string StyleUrl { get; set; }

            public Pair()
            {
            }

            public Pair(string key, string url)
            {
                Key = key;
                StyleUrl = url;
            }
        }
    }
}
using System.Xml;
using System.Xml.Serialization;

namespace GeDemo.Kml
{
    public class KmlPlacemark
    {
        [XmlElement("name")]
        public string Name { get; set; }

        [XmlElement("description")]
        public string Description { get; set; }

        [XmlElement("styleUrl")]
        public string StyleUrl { get; set; }

        [XmlElement("LineString")]
        public KmlLineString LineString { get; set; }

        public KmlPlacemark()
        {
            
        }
        public KmlPlacemark(string name, string des, string style, KmlLineString lineString)
        {
            this.Name = name;
            this.Description = des;
            this.StyleUrl = style;
            this.LineString = lineString;
        }
    }
}
using System.Xml.Serialization;

namespace GeDemo.Kml
{
    public class KmlLineString
    {
        [XmlElement("altitudeMode")]
        public string AltitudeMode { get; set; }

        [XmlElement("coordinates")]
        public string Coordinates { get; set; }

        public KmlLineString()
        {
        }

        public KmlLineString(KmlLine line)
        {
            AltitudeMode = "clampToGround";
            Coordinates = line.ToString();
        }

        public KmlLineString(string tessel, KmlLine line)
        {
            AltitudeMode = "clampToGround";

            Coordinates = line.ToString();
        }
    }
}
using System.Collections.Generic;
using System.Linq;

namespace GeDemo.Kml
{
    public class KmlLine
    {
        private List<KmlPoint> _pointList;
        public KmlLine()
        {
            _pointList = new List<KmlPoint>();
        }
        public void Add(KmlPoint point)
        {
            _pointList.Add(point);
        }
        public override string ToString()
        {
            return _pointList.Aggregate(string.Empty, (current, point) => current + (point + " "));
        }
    }
}
namespace GeDemo.Kml
{
    public class KmlPoint
    {
        private double B;
        private double L;
        private double H;

        public KmlPoint()
        {
        }

        public KmlPoint(double b, double l, double h)
        {
            B = b;
            L = l;
            H = h;
        }

        public override string ToString()
        {
            return L.ToString("F6") + "," + B.ToString("F6") + "," + H.ToString("F2");
        }
    }
}

    最终生成的KML文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
    <Style id="line_color1"> 
        <LineStyle>
            <color>FFFFFF00</color>
            <width>1.0</width>
        </LineStyle>
    </Style>
    <Style id="line_color2"> 
        <LineStyle>
            <color>FFFFFF00</color>
            <width>3.0</width>
        </LineStyle>
    </Style>

    <name>ship_路径</name>
    <Placemark>
        <name>Line1</name>
        <description>0</description>
        <styleUrl>#line_num1</styleUrl>
        <LineString>
            <altitudeMode>clampToGround</altitudeMode>
            <coordinates>
                122.246005555556,34.8119416666667,0 122.246875,34.8112555555556,0
            </coordinates>
        </LineString>
    </Placemark>
    <Placemark>
        <name>Line2</name>
        <description>1</description>
        <styleUrl>#line_num1</styleUrl>
        <LineString>
            <altitudeMode>clampToGround</altitudeMode>
            <coordinates>
                122.246005555556,34.8119416666667,0 122.246875,34.8112555555556,0
            </coordinates>
        </LineString>
    </Placemark>
</Document>
</kml>

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值