WPF 中的 Google Maps 结合 WebBrowser 和 Google Maps API v3
您可以使用 Google Maps API v3 在 WPF 应用程序中显示地图。
引言
Google 提供了一个 JavaScript API,用于在 HTML 页面中包含具有与 maps.google.com 相同功能的地图。
在 v2 版本中,您需要注册才能获取 API 密钥来使用该库,而在 v3 版本中,这是可选的,但仍建议这样做,因为 API 有一个限制,您每天只能生成 25,000 张地图。如果您需要更多,则需要付费,因此您需要注册,如果您注册,您可以
- 获取每日生成地图的统计信息
- 为额外的地图付费(每天超过 25,000 张)
- 限制您密钥的使用,以防止在未经授权的网站上使用
要创建您的 API 密钥,请访问 APIs Console 并使用您的 Google 帐户登录。
背景
最基本的示例是下一个
<!-- saved from url=(0014)about:internet -->
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript"
src="http://maps.google.com.mx/maps/api/js?sensor=true&language=es"></script>
<script src='http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/src/markerclusterer.js'>
</script><script type="text/javascript">
function initialize() {
var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width:100%; height:100%"></div>
</body>
</html>
通过第一行,您启用了 HTML 本地文件来完全测试其与用户安全设置的兼容性。
您需要 5 个元素
<meta>
标签指定地图应全屏显示,并且用户无法修改其大小。<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
- Google 的 API
<script src='http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/src/markerclusterer.js'></script> <script type="text/javascript" src="http://maps.google.com.mx/maps/api/js?sensor=true&language=es&key=your_key"></script>
在此示例中,我使用标记集群,您可以使用此标记显示大量位置或标记,例如 300 个标记,并且这些标记按区域分组。
第二个脚本是 Google 地图的脚本,
sensor = true
参数表示应用程序使用传感器来识别用户的位置。语言参数指定指令的语言。在密钥参数中,您应该包含您的 API。 - 您需要包含一个位置来包含地图。通常是一个
div
。在此示例中,地图的大小与页面大小相同。<div id="map_canvas" style="width:100%; height:100%"></div>
- 初始化并显示地图的函数
- 要定位地图,您需要您想显示的地点的位置的纬度和经度
- 地图的选项,例如缩放、地图类型
ROADMAP
显示 Google Maps 的默认地图SATELLITE
显示照片地图HYBRID
显示照片地图和默认地图的混合TERRAIN
显示用于显示高程和水体(山脉、河流等)的地形图块
- 为确保地图在页面创建后显示并且显示正确,您需要在页面加载事件中加载地图。
<body onload="initialize()">
如果地图未显示,可能是纬度和经度,它位于海上,或者您可能遇到了 JavaScript 错误。
您可以自定义地图的许多方面,例如地图样式、放置标记和信息窗口、自行车、汽车、步行路线以及交通状况。
要添加标记,您可以包含以下代码
function addMarker( Lat, Long)
{
var latLng = new google.maps.LatLng(Lat, Long);
marker = new google.maps.Marker({
position: latLng,
icon: 'down2.png',
draggable: true,
animation: google.maps.Animation.DROP,
title:"Click for show the data of the client"
});
markers.push(marker);
marker.setMap(map);
}
//add the Drag end event to send the dragEvent to cs
google.maps.event.addListener(marker, 'dragend', function()
{
eventEndDragMarker(marker)
});
function eventEndDragMarker(shape)
{
var pos = new google.maps.LatLng;
pos = shape.getPosition();
endDragMarkerCS(pos.lat(), pos.lng());
}
您可以为标记指定图像、动画以及鼠标悬停在图像上时显示文本。draggable : true
选项意味着用户可以将其标记移动到另一个位置。
接下来,我为标记添加了一个监听器,以在用户结束拖动标记时发出通知。通过此事件,我将新位置发送到 WPF 应用程序。
要为标记添加一个显示文本和图像的信息窗口,您可以包含以下代码
var contentString = '<div id="content">'+
'<h1>[Client]</h1>'+
'<img src="/images/image.jpg width="200"
height="200" style="margin: 0 auto; display:block"/>'+
'<br/><br/>[Direction]'+
'</div>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
您可以在 此处 查看实时示例。
您可以显示两点之间的路线,为此您需要地图的 <div>
,还可以选择包含一个用于路线的 <div>
。JavaScript 函数是
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var origin = new google.maps.LatLng(37.7699298, -122.4469157);
var destination = new google.maps.LatLng(37.7683909618184, -122.51089453697205);
function initialize() {
directionsDisplay = new google.maps.DirectionsRenderer();
var myOptions = {
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: origin
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
directionsDisplay.setMap(map);
calcRoute();
directionsDisplay.setPanel(document.getElementById("directionsPanel"));
}
function calcRoute() {
var selectedMode = document.getElementById("mode").value;
var request = {
origin: origen,
destination: destino,
travelMode: google.maps.TravelMode[selectedMode]
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
您可以在 此处 查看实时示例。
为了在 WPF 中包含地图,我使用了一个 WebBrowser
控件,并加载了一个我之前创建的 HTML 文件,然后读取该文件并替换纬度和经度以及信息窗口的文本。
演示应用程序显示客户数据、客户在地图上的位置,以及从公司位置前往客户位置的路线的另一个选项。
在演示中,我使用了一个 DockPanel
来在窗口大小更改时自动调整地图大小。我读取 HTML 页面并查找并替换示例中的 latLng
、origin
和 destination
等文本。我设置了一个短 URI,因为路径过长 WPF 会显示错误。
if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + "html\\map.html"))
{
StreamReader objReader = new StreamReader(AppDomain.CurrentDomain.BaseDirectory + "html\\map.html");
string line = "";
line = objReader.ReadToEnd();
objReader.Close();
line = line.Replace("[Location]", tbLocation.Text);
line = line.Replace("[Client]", "25.520581,-105.40607");
line = line.Replace("[Image]", "client" + tbID.Text + ".png");
line = line.Replace("[Direction]", tbDirection.Text +
"<br />" + tbCity.Text + "," + tbState.Text);
StreamWriter page = File.CreateText(AppDomain.CurrentDomain.BaseDirectory + "html\\map2.html");
page.Write(line);
page.Close();
Uri uri = new Uri(AppDomain.CurrentDomain.BaseDirectory + "html\\map2.html");
webBrowser1.Navigate(uri);
}
从 WPF 应用程序调用 JavaScript 函数
使用 WPF Browser,您可以调用 HTML 中的 JavaScript 函数。这是一个示例。您可以将参数作为对象数组传递给函数。
private void Button_Click_1(object sender, RoutedEventArgs e)<br /> {
webBrowser1.InvokeScript("addMarker", new Object[] { 25.520581, -103.40607);
}
从 JavaScript 调用 WPF 函数
使用 windows.external
指令,您可以从 JavaScript 调用 WPF 函数,您需要创建一个类并将其 COMVisibleAttribute
设置为 true
,并将 Object
添加到 WPFBrowser
。
这是 HTML JavaScript 中的一个示例
function endDragMarkerCS(lat, long) {
window.external.endDragMarkerCS( lat, long);
}
在 WPF 应用程序中
<WebBrowser DockPanel.Dock="Right"
Loaded="setupObjectForScripting" Name="webBrowser1" />
private void setupObjectForScripting(object sender, RoutedEventArgs e)
{
((WebBrowser)sender).ObjectForScripting = new HtmlInteropInternalTestClass();
}
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public class HtmlInteropInternalTestClass
{
public void endDragMarkerCS(Decimal Lat, Decimal Lng)
{ ((MainWindow)Application.Current.MainWindow).tbLocation.Text = Math.Round(Lat,5) + "," +Math.Round(Lng,5);
}
}
关注点
使用新的 Google Maps API V3 和 .NET 中的 WebBrowser,您可以在应用程序中添加地图。API 提供了大量的配置,并且通过 CSS,您可以为地图添加更多设计,以便集成到您的 WPF 或 Winforms 应用程序中。我更喜欢 WPF,因为我正在学习 WPF,但它在 Winforms 中也很相似。
您可以将客户的纬度和经度数据保存在数据库中,这将有助于添加地图来定位、用于建筑项目或发送文章给您的客户。
另外,如果您愿意,您可以使用 Bing Maps WPF 控件,有了这个组件,您就可以使用 .NET 代码添加标记,而无需 JavaScript 和 HTML 页面。