欢迎访问移动开发之家(rcyd.net),关注移动开发教程。移动开发之家  移动开发问答|  每日更新
页面位置 : > > > 内容正文

Windows Phone 地图定位 及导出GPX文件

来源: 开发者 投稿于  被查看 35850 次 评论:173

Windows Phone 地图定位 及导出GPX文件


1  概述
通过ArcGIS Runtime for WindowsPhone SDK开发手机地图应用,能够定位所在位置,并将多个定位位置信息导出为GPX文件,供其他软件,如ArcMap、Google Earth等调用。本文将介绍如何实现地图定位,以及导出GPX文件的功能。
2  GeoCoordinateWatcher
Windows Phone SDK提供了GeoCoordinateWatcher类实现定位相关功能,需要引入System.Device.dll库,添加System.Device.Location命名空间。
2.1 参数设置
使用GeoCoordinateWatcher,需要创建一个实例,并设置定位精度、移动间距等基本属性,另外监听状态变化、结果变化等事件。如下代码所示:
[csharp]  
if (_watcher == null)  
{  
    _watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High); // 使用高定位精度                  
    _watcher.MovementThreshold = 50; // 最小移动间距,单位米,大于该间距的点才会触发PositionChanged事件  
    _watcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged);  
    _watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);  
}  
2.2 启动定位
启动定位功能,即调用GeoCoordinateWatcher的Start方法,如下:
[csharp]  
_watcher.Start();  
2.3 定位状态
监听定位状态变化事件,如果出错可提示用户,如下:
[csharp] 
void watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)  
{  
    switch (e.Status)  
    {  
        case GeoPositionStatus.Disabled:                      
            if (_watcher.Permission == GeoPositionPermission.Denied)  
            {              
                txtStatus.Text = "应用程序无权访问定位服务";  
            }  
            else  
            {  
                txtStatus.Text = "设备不支持定位服务";  
            }  
            break;  
        case GeoPositionStatus.Initializing:                      
            break;  
        case GeoPositionStatus.NoData:                      
            txtStatus.Text = "获取定位数据失败";   
            break;  
        case GeoPositionStatus.Ready:  
            txtStatus.Text = "GPS已经就绪";  
            break;  
    }  
}  
2.4 定位结果
对定位结果的处理,需要在定位位置变化事件中进行,如下所示:
[csharp] 
void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)  
{  
            try  
            {  
                txtStatus.Text = "";  
  
                MapPoint point = new MapPoint(e.Position.Location.Longitude, e.Position.Location.Latitude);  
                ESRI.ArcGIS.Client.Projection.WebMercator mercator = new ESRI.ArcGIS.Client.Projection.WebMercator();  
                MapPoint ptCurrent = mercator.FromGeographic(point) as MapPoint;  
  
                //更新GPS定位点位置  
                _gLocation.Geometry = ptCurrent;  
  
                //更新轨迹线  
                if (_gpsPoints == null)  
                {  
                    _gpsPoints = new PointCollection();  
                    _gpsPoints.Add(ptCurrent);  
                }  
                else  
                {  
                    _gpsPoints.Add(ptCurrent);  
                    Polyline line = new Polyline();  
                    line.Paths.Add(_gpsPoints);  
                    _gTrackLine.Geometry = line;  
                }  
 
                #region 记录GPS定位信息  
  
                GpsInfo gpsInfo = new GpsInfo();  
                gpsInfo.Altitude = e.Position.Location.Altitude;  
                gpsInfo.Course = e.Position.Location.Course;  
                gpsInfo.HorizontalAccuracy = e.Position.Location.HorizontalAccuracy;  
                gpsInfo.Latitude = e.Position.Location.Latitude;  
                gpsInfo.Longitude = e.Position.Location.Longitude;  
                gpsInfo.Speed = e.Position.Location.Speed;  
                gpsInfo.VerticalAccuracy = e.Position.Location.VerticalAccuracy;  
                gpsInfo.Time = e.Position.Timestamp.DateTime;  
  
                _gpxWriter.AddGpsInfo(gpsInfo);  
 
                #endregion  
  
                _gpsLayer.Refresh();  
                map.ZoomToResolution(2.38865713397468, ptCurrent);//定位到16级比例尺            
            }  
            catch (Exception ex)  
            {  
                MessageBox.Show("显示定位信息错误");  
            }  
}  
其中ESRI.ArcGIS.Client.Projection.WebMercator是用于将GPS获得的WGS 84经纬度坐标转换为Web Mercator投影坐标,这需要根据坐标系的具体情况来选择,如果地图坐标系本身就是WGS84,则无需转换,如果地图是Web Mercator,则需要进行转换,如果地图是其他坐标系,如Xian1980,或CGCS2000等,则需要调用ArcGIS Server的Geometry Service进行在线转换。
2.5 停止定位
当需要停止定位的时候,直接调用Stop方法即可,如下:
[csharp]  
if (_watcher != null)  
{  
    _watcher.Stop();  
  
   txtStatus.Text = "";  
   _gpsLayer.Graphics.Clear();  
}  
3 导出GPX文件
在上文定位结果处理中,已经将每次位置记录存储为GpsInfo对象,便于进行统一的导出处理。
3.1 GpsInfo
GpsInfo对象只是简单的属性字段集合,用于记录GPS设备获取的数据信息。其属性如下:
[csharp] 
public class GpsInfo  
    {  
        private double _longitude = 0;  
        public double Longitude  
        {  
            get { return _longitude; }  
            set { _longitude = value; }  
        }  
  
        private double _latitude = 0;  
        public double Latitude  
        {  
            get { return _latitude; }  
            set { _latitude = value; }  
        }  
  
        private double _altitude = 0;  
        public double Altitude  
        {  
            get { return _altitude; }  
            set { _altitude = value; }  
        }  
  
        private double _speed = 0;  
        public double Speed  
        {  
            get { return _speed; }  
            set { _speed = value; }  
        }  
  
        private double _course = 0;  
        public double Course  
        {  
            get { return _course; }  
            set { _course = value; }  
        }  
  
        private double _horizontalAccuracy = 0;  
        public double HorizontalAccuracy  
        {  
            get { return _horizontalAccuracy; }  
            set { _horizontalAccuracy = value; }  
        }  
  
        private double _verticalAccuracy = 0;  
        public double VerticalAccuracy  
        {  
            get { return _verticalAccuracy; }  
            set { _verticalAccuracy = value; }  
        }  
  
        private DateTime _time = new DateTime();  
        public DateTime Time  
        {  
            get { return _time; }  
            set { _time = value; }  
        }  
    }  
3.2 GpxWriter
GpxWriter则提供了将GpsInfo写入GPX文件的功能,代码如下:
[csharp]  
public class GpxWriter  
    {  
        private string _gpxFile = "";  
        private IList<GpsInfo> _lstGpsInfo = null;  
  
        private XmlWriterSettings _settings = null;  
  
        public GpxWriter(string gpxFile)  
        {  
            _settings = new XmlWriterSettings();  
            _settings.Indent = true;  
            _settings.Encoding = new UTF8Encoding(false);  
            _settings.NewLineChars = Environment.NewLine;  
  
            _lstGpsInfo = new List<GpsInfo>();  
  
            _gpxFile = gpxFile;  
        }  
  
        public void AddGpsInfo(GpsInfo gpsInfo)  
        {  
            _lstGpsInfo.Add(gpsInfo);  
        }  
  
        public void WriteToGpx()  
        {  
            try  
            {  
                if (_lstGpsInfo == null || _lstGpsInfo.Count == 0) return;  
  
                IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication();  
                if (myIsolatedStorage.FileExists(_gpxFile) == true)  
                {  
                    myIsolatedStorage.DeleteFile(_gpxFile);  
                }  
  
                using (IsolatedStorageFileStream stream = myIsolatedStorage.OpenFile(_gpxFile, FileMode.CreateNew))  
                {  
                    using (XmlWriter xmlWriter = XmlWriter.Create(stream, _settings))  
                    {  
                        //写xml文件开始<?xml version="1.0" encoding="utf-8" ?>  
                        xmlWriter.WriteStartDocument();  
  
                        //写根节点  
                        xmlWriter.WriteStartElement("gpx", "http://www.topografix.com/GPX/1/0");  
                        //给节点添加属性  
                        xmlWriter.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");  
                        xmlWriter.WriteAttributeString("xmlns", "mbx", null, "http://www.motionbased.net/mbx");  
                        xmlWriter.WriteAttributeString("xsi", "schemaLocation", null, "http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd http://www.motionbased.net/mbx http://www.motionbased.net/site/schemas/mbx/0.0.1/mbx.xsd");  
                        xmlWriter.WriteAttributeString("creator", "YELLOW EAST http://weibo.com/yelloweast");  
                        xmlWriter.WriteAttributeString("version", "1.0");  
  
                        //写内容根节点  
                        xmlWriter.WriteStartElement("trk");  
                        //写内容根节点  
                        xmlWriter.WriteStartElement("trkseg");  
  
                        //写GPS信息节点  
                        foreach (GpsInfo gpsInfo in _lstGpsInfo)  
                        {  
                            xmlWriter.WriteStartElement("trkpt");  
  
                            //给节点添加属性  
                            xmlWriter.WriteAttributeString("lat", gpsInfo.Latitude.ToString());  
                            xmlWriter.WriteAttributeString("lon", gpsInfo.Longitude.ToString());  
  
                            //添加子节点  
                            xmlWriter.WriteElementString("ele", gpsInfo.Altitude.ToString());  
                            xmlWriter.WriteElementString("time", gpsInfo.Time.ToShortDateString() + " " + gpsInfo.Time.ToLongTimeString());  
                            xmlWriter.WriteElementString("course", gpsInfo.Course.ToString());  
                            xmlWriter.WriteElementString("speed", gpsInfo.Speed.ToString());  
  
                            xmlWriter.WriteEndElement();//trkpt  
                        }  
  
                        xmlWriter.WriteEndElement();//trkseg  
                        xmlWriter.WriteEndElement();//trk  
                        xmlWriter.WriteEndElement();//gpx  
  
                        xmlWriter.WriteEndDocument();  
                    }  
                }  
  
                _lstGpsInfo.Clear();//清空历史记录  
            }  
            catch (Exception ex)  
            {  
                System.Windows.MessageBox.Show("写GPX文件错误:" + ex.Message);  
            }  
        }  
    }  
在调用的时候,只需要指定gpx文件名,然后调用相关的方法,例如变量定义:
[csharp]  
private GpxWriter _gpxWriter = null;  
初始化:
[csharp]  
DateTime now = DateTime.Now;  
            string gpxName = String.Format("{0}-{1}-{2}_{3}-{4}-{5}.gpx", now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second);  
            _gpxWriter = new GpxWriter(gpxName);  
导出GPX文件:
[csharp]  
_gpxWriter.WriteToGpx();  

相关文章

    暂无相关文章

用户评论