【WP 8.1开发】电子罗盘

罗盘,估计也不用我过多介绍,学过初中物理的都知道,不管是指南针,还是指北针,其本质就是用来辨别方向的。

操作电子罗盘伟感器也不复杂,主要就是两个角度:

1、当前方向与磁北的夹角;

2、当前方向与地北的夹角。

同时,我们也了解到,地理北极与地磁北极并不是重合的,存在地偏角。在读取电子罗盘数据时,可以优先考虑读取与地北极的夹角,如果读不到地北极的夹角,再读取磁北极的夹角数据。

CompassReading类(位于Windows.Devices.Sensors命名空间)封装了从电子罗盘所读到的数据。

1、HeadingMagneticNorth属性:获取当前方向与磁北的夹角度数。

2、HeadingTrueNorth属性:该属性获取的是真北夹角,即地理夹角。我们注意到它的类型为double?,即Nullable<double>,表明这个数值有可能为null,也就是说有可能获取不到地北夹角的值。在使用时,我们可以先判断地北角是否为null,如不为null就用这个值;如果为null就用磁北角的值。

3、HeadingAccuracy属性:表示罗盘读数的准确性,如果读数精度较高,其返回High。我们的应用程序可以在合适的时候检查这个属性是否为High,如果不是,可以考虑提示用户校准罗盘。

提到校准,不得不说一下的是,校准罗盘是不需要系统提示,应用也可以不提示。只是考虑到用户体验的问题,可以提示用户校准。校准方法很简单,不管你是使用WP自带的地图应用,还是其他第三方应用,或者你自己开发的应用。只要在使用到罗盘的地方,你拿着手机,在空中做几次“8”字形来回移动就可以了,不需要等待提示,只要在用到罗盘的地方就可以随时校准。

电子罗盘的API封装在Windows.Devices.Sensors.Compass类中,WP API中的所有传感器调用都很简单,首先获取到某个传感器类的实例,一般通过GetDefault方法(静态方法)就能返回,然后设置读取的时间间隔,以毫秒为单位,如果你希望每秒读一次数据,就把ReportInterval设置为1000,但是,这个时间间隔不能小于MinimumReportInterval属性指定的值,这个要注意,设置为20毫秒以上的间隔,效果都不错了,当然这要看你使用的实际情况了。

最后处理ReadingChanged事件,当有新的数据读到时,会引发该事件,并把新读到的数据传递给该事件,我们就可以从事件参数中获取最新的读数。

好了,理论永远都是抽象的,下面给大家看一下我做的一个简陋指南针,确实很简,希望大家莫笑,因为本人较菜,所以连主页上的罗盘也是用XAML直接画的。

先上一个效果图。

看吧,简陋吧,没办法,人穷就是这样,要简食素衣。指南针背景我是用几个圈圈画的,指示方向的指针是用Path元素画的。

原理是这样的:

根据电子罗盘读到的角度,对红色的指针对象进行旋转变换——就是用RotateTransform类来旋转。但要注意旋转的角度。比如,我当前方向是20度,即东北偏北方向,那么,要怎么设置角度才能保证红色的指针始终指向南方呢。

我们知道,夹角是以正北为参考的,如果要使指针指向南方,一种方法是将罗盘读到的角度加上180,因为南北的夹角正好是180度(平角);另一种方法是,让指针的初始位置向下,即指向正南方,我就是用这个方法的。如图。

不管是指向北方还是南方(上北下南),都可以按相同的角度来旋转,因为它们的夹角正好是180。

于是,第二个问题产生了——要旋转多少度才合适?我们上面举例说当前方向为20度,参照标准是北极,也就是说此时我们的手机已经偏向20度方向,如果把指针旋转20度,那么指针相对于屏幕,偏转的角度就是40度了,本来就偏了20度,你再转20度,就番倍了,显然这样不妥,我们必须把这个角度差抵消掉。

也就是说,如果我当前方向是20度,那么指针的旋转变换应为-20度,这样才能把偏差的角度补平,不然的话,你试试就知道了,如果不抵消的话,指针会越走越偏。

还有一种方法就是用360度作为被减数,如360 - 20 = 340度,-20度和340度虽然计算方向不同,但它们的位置是相同的。因此两种方法都可以。比如读数是80度,可以把指针旋转-80度,也可以旋转360 - 80度。

        async void _compass_ReadingChanged ( Compass sender, CompassReadingChangedEventArgs args )
        {
            var res = args.Reading;
            // 如果地北极的偏角值不可用,则使用磁北极角度
            double val = res.HeadingTrueNorth ?? res.HeadingMagneticNorth;
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
                () =>
                {
                    // 如果精度较高,则停止校准
                    if (isChecking && res.HeadingAccuracy == MagnetometerAccuracy.High)
                    {
                        fly.Hide();
                        isChecking = false;
                    }

                    // 旋转的方向是罗盘角度的负值
                    rotatTransform.Angle = -val;
                    Display(val);
                });
        }

Display方法是我自定义的方法,用来判断读数所指的方向,并在页面上以文本的方式显示。比如,读数为0,就是“正北”,读数为180度,为“正南”等。

        /// <summary>
        /// 显示方位
        /// </summary>
        private void Display ( double v )
        {
            string d = "";
            int ind = Convert.ToInt32(v);
            if (ind == 0 || ind == 360)
            {
                d = "正北";
            }
            else if (ind == 90)
            {
                d = "正东";
            }
            else if (ind == 180)
            {
                d = "正南";
            }
            else if (ind == 270)
            {
                d = "正西";
            }
            else if (ind > 0 && ind < 90)
            {
                d = "东北";
            }
            else if (ind > 90 && ind < 180)
            {
                d = "东南";
            }
            else if (ind > 180 && ind < 270)
            {
                d = "西南";
            }
            else if (ind > 270 && ind < 360)
            {
                d = "西北";
            }
            tbW.Text = string.Format("{0}°({1})", ind, d);
        }

以上所列是重点的代码片段,其他代码大家可以参考我上传的示例源代码。

下载地址:http://files.cnblogs.com/tcjiaan/CompassApp.zip

时间: 2024-11-08 19:51:42

【WP 8.1开发】电子罗盘的相关文章

【WP 8.1开发】自定义(RAW)通知的使用

继续前面的话题,还是推送通知.上一篇文章中遗留了RAW通知的推送没有给各位演示,特特地留到现在,不为别的,只为这个RAW通知有点意思,玩起来会比较有意思.官方文档将RAW通知译为“原始通知”,这里还是沿用官方的翻译. 在开始吹牛之前,先说一说与推送通知相关的要点. 有人说,如果我有22222222个客户端,岂不是都要获取每个手机客户端的通道URL来推送吗?是的.于是有人想到了所谓的“极光推送”,忽悠人的,“极光”显然偷换了概念.我们得明确,在什么情况下才会考虑使用推送. 推送好比服务器与手机客户

【WP 8.1开发】手机客户端应用接收推送通知

上一篇文章中,已经完成了用于发送通知的服务器端,接下来我们就用这个服务端来测试一下. 在开始测试之前,我们要做一个接收通知的WP应用. 1.启动VS Express for Windows,新建项目,在项目模板中选择“空白应用程序(Windows Phone)”. 2.既然要接收通知,肯定少不了Toast.磁贴这几样常用的通知的,故我们得先准备一些图片. 在“解决方案资源管理器”中,双击打开清单文件,切换到“可见资产”选项卡,这个“资产”指的不你的银行卡存款有多少,而是你的应用中的一些如图片.音

【WP 8.1开发】How to 图像处理

在今天的吹牛节目开始之前,先交代一件事: 关于玩WP 8.1开发所使用的VS版本问题.对版本的要求是2013的Update2,这是最低要求,只要是这个版本或以上都可以,而update3,update4,update5是不是必须更新呢?不是的,VS的update是可选的,而且每个update都会累积,所以,update越多,安装包的体积越大.因此,WP开发我们只需update2就行了,我用的也是u2.如果你觉得MSDN原版不好下,可以从下面的地址下,我已经把相关的.iso上传到115.这里面是旗舰

【WP 8.1开发】推送通知测试服务端程序

所谓推送通知,用老爷爷都能听懂的话说,就是: 1.我的服务器将通知内容发送到微软的通知服务器,再由通知服务器帮我转发消息. 2.那么,微软的推送服务器是如何知道我的服务器要发消息给哪台手机呢?手机客户端应用程序在创建推送通道时,微软的通知服务器会为手机分配一个URL,我的服务器只要知道这个URL就可以向指定的手机发送消息.所以,手机客户端必须通过网络把获取到的手机URL发给我的服务器,方法很多,如使用Socket.HTTP提交.Web服务.WCF等都可以. 要测试推送通知,可以通过WP 8.1的

【WP 8.1开发】如何把自定义字体塞进应用里

或许,系统自带的字体不足以体现应用程序的魅力,对于表现极强的汉字来说,更是如此.这时候,我们就会想,要是能把网上下载的艺术字体塞到应用包中,那岂不美哉?那么,这可以实现吗?答案是Yes的. 接下来,阿拉就给大家分别演示WP 8.1两个开发框架中如何嵌入自定义字体. 为啥是两大框架?我们知道从7x到8.0的开发框架是Silverlight for Windows Phone,为了便于兼容和直接项目升级,在8.1中,微软的开发团队依然保留了这个框架:另外一个框架是从Win RT应用移植的API集,这

【WP 8.1开发】解决调用真实摄像头会死机的问题

无论你是用Silverlight还是用RT的API来开发,在使用MediaCapture拍照片或录视频时,要是在模拟器上运行会万事大吉:但是,一旦放到真实手机上运行,肯定有人发现了,细心的朋友肯定发现了——不知道为什么,会经常导致手机重启,或者死机. 啊,顺便给大家说说,死机不可怕,也不用重置,也不用刷机,不会丢失资料的,你只要同时按下“音量减”+“电源”两个键,要同时按住,不要放开,大约等10多秒后,会关机,然后你再放开这两个键,这样手机就软启了,不会丢失数据. 不过,如果你的运营商(如中国联

[WP]使用ApacheCordova开发HTML5-WindowsPhone应用程序

下载代码示例 这篇文章介绍 Apache 科尔多瓦,创建使用 HTML5 和 JavaScript,跨平台移动应用程序的框架,并显示了如何使用它为 Windows Phone 开发应用程序. Windows Phone 和其本机开发平台允许您轻松地创建美丽地铁样式的应用程序. 最近诺基亚的伙伴关系,与 Windows Phone 开始越来越多口袋找到出路. 最近的数据发表的研究公司 Gartner Inc. 预测微软操作系统的一个充满希望的未来 (bit.ly/h5Ic32),具有重大的市场零碎

【WP 8.1开发】文件选取器的使用方法

在以往的WP7x/8.0开发中,我们使用选择器可以浏览并打开图片.音频.视频等一些特殊文件,在8.0 SDK中的运行时API(从Win 8 app中移植)尽管提供了Windows.Storage.Pickers命名空间,但里面的Picker是不能用的,到了8.1,随着移植的深入和WP的完善,这些Picker们终于可以派上用场了,比如用于打开文件的FileOpenPicker类,用来保存文件的FileSavePicker类等. 使用Picker的好处在于,文件类型不必被限制为特定的几个,而是可以根

WP、Win10开发或者WPF开发时绘制自定义窗体~例如:一个手机

WP and Win10 效果:(数字是参考值,和UI无关) <Page x:Class="_05.AllControls._BorderUsePage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using