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