Metro风格应用程序定位其实很简单,分2步

1.开启定位功能,

找到项目文件package.appxmanifest,双击打开,找到功能(features)选项卡>勾选 位置(location),保存。

2.使用JS异步定位函数

            var geolocator = Windows.Devices.Geolocation.Geolocator();
            geolocator.getGeopositionAsync().done(function (position) {
                var lat = position.coordinate.latitude;
                var lon = position.coordinate.longitude;
            });

这样就获得了经度纬度信息

但是使用谷歌地图就比较麻烦,因为WinRT安全模块不允许运行远程脚本,也就是

<script src="http://maps.google.com/maps/api/js?sensor=false"></script>直接添加到代码里面是没有用的,

如果把google_map.js下载下来放在本地呢?也行不通,google_map.js里面动态加载其他js文件也不允许的(不知道是不是设置问题?)

目前想到的方法是用iframe嵌套外部地图

如果是使用Bing地图,相对来说简单些,因为已经有SDK,也就是

BingMap SDK for Win8 Metro App

这里包含了C#,VB等语言的例子

 

查了不少资料终于实现了使用Iframe嵌套谷歌地图,先上图看效果

具体实现也很简单:

1.嵌入在要显示的page里面添加iframe,使用本地的html文件,

<div> Longitude:<span id="lon"></span> Latitude:<span id="lat"></span></div>
 <iframe id="mapIframe" name="targetFrame"  src="ms-appx-web:///googlemap.html">               
 </iframe>

  注意这里的src使用的是ms-appx-web,可以参考这里,后面///表示根目录,当然也可以是其他目录,只要在项目中有这个文件就可以了。

2.在googlemap.html中,这个就和普通的html没区别,不过要引用一个外部的js(gogole map api)和实现地图加载的js,

        <script src="http://maps.google.com/maps/api/js?sensor=false"></script>
        <script src="js/map.js" type="text/javascript"></script>

当然还包含一个承载地图的容器DIV以及样式。

3.编写js加载地图,map.js

(function () {
    'use strict';

    var map;

    function initialize() {
        //initialize the map
        var latlng = new google.maps.LatLng(38.96, -96.78);//初始位置(美国)
        var myOptions = {
            zoom: 4,
            center: latlng,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        map = new google.maps.Map(document.getElementById("map"),myOptions);
    }

    document.addEventListener("DOMContentLoaded", initialize, false);
})();

  其实到这一步已经可以加载地图了,不过还不能定位,运行试试就知道了。

4.最后一步也是最关键的一步就是把上面的讨论的位置信息传给map.js,因为googlemap.html是运行在Iframe里面,传数据也就没那么简单了。

首先在map.js里面定义个接收器,然后把接收的数据解析出我们想要的数据,具体代码如下:

    //Process messages from main script
    window.addEventListener("message", receiveMessage, false);
    function receiveMessage(event) {
        if (event.origin === "ms-appx://" + document.location.host) {

            //Return the message string to an object
            var messageObject = JSON.parse(event.data);

            //If message is to zoom, change the location and zoom level
            if (messageObject.command == "zoomTo") {
                var newCenter = new google.maps.LatLng(messageObject.latitude,messageObject.longitude);
                var newOptions = {
                    zoom: messageObject.zoom,
                    center: newCenter,
                    mapTypeId: google.maps.MapTypeId.ROADMAP
                };
                map.setOptions(newOptions);
            }
        }
    }

然后在上面的异步函数得到位置信息后,把位置信息封装成json格式(这不是必须的),通过document.frames.postMessage方法传递过来。

 var lat = position.coordinate.latitude;//纬度
        var lon = position.coordinate.longitude;//经度
        //var latlon = new google.maps.LatLng(lat, lon)

        $("#lon").text(lon);
        $("#lat").text(lat);
            
        var msg = {
            command: 'zoomTo',
            latitude: lat,
            longitude: lon,
            zoom: 10
            //Even more info here.
        };
        //Convert message object to string and send to the map control.
        var data = JSON.stringify(msg);
        sendJsonDataFrame(data);
    }

    function sendJsonDataFrame(data) {
        document.frames['mapIframe'].postMessage(data, "ms-appx-web://" + document.location.host);
    }

OK,现在基本上可以成上面的效果。

 

 参考资料:

http://code.msdn.microsoft.com/windowsapps/Geolocation-2483de66

http://social.msdn.microsoft.com/Forums/zh-CN/winappswithhtml5/thread/f5a852c1-c757-40f2-bc41-8d6a190a233e

http://code.msdn.microsoft.com/windowsapps/Mashup-Sample-10689f5b

 

 

posted on 2012-07-04 13:32  visi  阅读(973)  评论(1编辑  收藏  举报