gpt4 book ai didi

vb.net - 将 Google map 添加到 VB 2010 应用程序

转载 作者:行者123 更新时间:2023-12-02 06:40:12 26 4
gpt4 key购买 nike

我想在 VB 2010 中编写一个 Windows 窗体应用程序,允许用户在 Google map 上搜索和查看地址或坐标点。我已经使用 WebBrowser 项完成了此操作。但是我想使用一个包装器,这样我就可以只向用户显示 map ,但仍然能够移动和缩放 map 或给出方向等。我知道在开发 ASP.NET 站点时有一些方法可以做到这一点,但我想为 WindowsForms 应用程序执行此操作。有人可以帮忙吗?

最佳答案

可能为时已晚,但我最近不得不在 vb 中处理谷歌地图并想分享我的解决方案:

这个例子的第一部分解释了如何实现它。在第二部分,我将解释它是如何工作的。这试图成为一个普遍的例子。 map 模板(参见步骤 3)和示例函数是完全可定制的。

################################# 实现 ########## ##################

第 1 步 首先,创建一个新项目并选择 Windows 窗体应用程序。让我们将其名称保留为“Form1”。

enter image description here

第 2 步。 将 WebBrowser 控件(将保存您的 map )添加到您的 Form1。我们称它为“wbmap”

第 3 步。使用您喜欢的文本编辑器创建一个名为“googlemap_template.html”的 .html 文件并粘贴以下代码:

googlemap_template.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<style type="text/css">
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#gmap {
height: 100%;
}
</style>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
function initialize() {
//Use window.X instead of var X to make a variable globally available
window.markers = new Array();
window.marker_data = [[MARKER_DATA]];
window.gmap = new google.maps.Map(document.getElementById('gmap'), {
zoom: 15,
center: new google.maps.LatLng(marker_data[0][0], marker_data[0][1]),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var newmarker, i;
for (i = 0; i < marker_data.length; i++) {
if (marker_data[0].length == 2) {
newmarker = new google.maps.Marker({
position: new google.maps.LatLng(marker_data[i][0], marker_data[i][1]),
map: gmap
});
} else if (marker_data[0].length == 3) {
newmarker = new google.maps.Marker({
position: new google.maps.LatLng(marker_data[i][0], marker_data[i][1]),
map: gmap,
title: (marker_data[i][2])
});
} else {
newmarker = new google.maps.Marker({
position: new google.maps.LatLng(marker_data[i][0], marker_data[i][1]),
map: gmap,
title: (marker_data[i][2]),
icon: (marker_data[i][3])
});
}
google.maps.event.addListener(newmarker, 'click', (function (newmarker, i) {
return function () {
if (newmarker.title) {
infowindow.setContent(newmarker.title);
infowindow.open(gmap, newmarker);
}
gmap.setCenter(newmarker.getPosition());
// Calling functions written in the WF
window.external.showVbHelloWorld();
window.external.getMarkerDataFromJavascript(newmarker.title,i);
}
})(newmarker, i));
markers[i] = newmarker;
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<script type="text/javascript">
// Function triggered from the WF with no arguments
function showJavascriptHelloWorld() {
alert("Hello world in HTML from WF");
}
</script>
<script type="text/javascript">
// Function triggered from the WF with a String argument
function focusMarkerFromIdx(idx) {
google.maps.event.trigger(markers[idx], 'click');
}
</script>
</head>
<body>
<div id="gmap"></div>
</body>
</html>

这将用作我们的 map 模板。我稍后会解释它是如何工作的。

第 4 步。将 googlemap_template.hmtl 文件添加到您的项目(右键单击您的项目->添加->现有项目)

第 5 步。一旦它出现在您的解决方案资源管理器中,将其属性设置为: - 构建操作 -> 嵌入式资源 - 自定义工具命名空间 -> 编写 项目名称

enter image description here

第 6 步 添加一个新类(右键单击您的项目->添加->类)。在我的示例中,我将其称为 GoogleMapHelper。

enter image description here

第 7 步将以下代码粘贴到您的类中:

GoogleMapHelper.vb

    Imports System.IO
Imports System.Reflection
Imports System.Text

Public Class GoogleMapHelper

' 1- googlemap_template.html must be copied in the main project folder
' 2- add the file into the Visual Studio Solution Explorer (add existing file)
' 3- set the properties of the file to:
' Build Action -> Embedded Resource
' Custom Tool Namespace -> write the name of the project

Private Const ICON_FOLDER As String = "marker_icons/" 'images must be stored in a folder inside Debug/Release folder
Private Const MAP_TEMPLATE As String = "WindowsApplication1.googlemap_template.html"
Private Const TEXT_TO_REPLACE_MARKER_DATA As String = "[[MARKER_DATA]]"
Private Const TMP_NAME As String = "tmp_map.html"


Private mWebBrowser As WebBrowser

'MARKER POSITIONS
Private mPositions As Double(,) 'lat, lon
' marker data allows different formats to include lat,long and optionally title and icon:
' op1: mMarkerData = New String(N-1, 1) {{lat1, lon1}, {lat2, lon2}, {latN, lonN}}
' op2: mMarkerData = New String(N-1, 2) {{lat1, lon1,'title1'}, {lat2, lon2,'title2'}, {latN, lonN, 'titleN'}}
' op3: mMarkerData = New String(N-1, 3) {{lat1, lon1,'title1','image1.png'}, {lat2, lon2,'title2','image2.png'}, {latN, lonN, 'titleN','imageN.png'}}
Private mMarkerData As String(,) = Nothing


Public Sub New(ByRef wb As WebBrowser, pos As Double(,))
mWebBrowser = wb
mPositions = pos
mMarkerData = getMarkerDataFromPositions(pos)
End Sub

Public Sub New(ByRef wb As WebBrowser, md As String(,))
mWebBrowser = wb
mMarkerData = md
End Sub

Public Sub loadMap()
mWebBrowser.Navigate(getMapTemplate())
End Sub

Private Function getMapTemplate() As String

If mMarkerData Is Nothing Or mMarkerData.GetLength(1) > 4 Then
MessageBox.Show("Marker data has not the proper size. It must have 2, 3 o 4 columns")
Return Nothing
End If

Dim htmlTemplate As New StringBuilder()
Dim tmpFolder As String = Environment.GetEnvironmentVariable("TEMP")
Dim dataSize As Integer = mMarkerData.GetLength(1) 'number of columns
Dim mMarkerDataAsText As String = String.Empty
Dim myresourcePath As String = My.Resources.ResourceManager.BaseName
Dim myresourcefullPath As String = Path.GetFullPath(My.Resources.ResourceManager.BaseName)
Dim localPath = myresourcefullPath.Replace(myresourcePath, "").Replace("\", "/") & ICON_FOLDER

htmlTemplate.AppendLine(getStringFromResources(MAP_TEMPLATE))
mMarkerDataAsText = "["

For i As Integer = 0 To mMarkerData.GetLength(0) - 1
If i <> 0 Then
mMarkerDataAsText += ","
End If
If dataSize = 2 Then 'lat,lon
mMarkerDataAsText += "[" & mMarkerData(i, 0) & "," + mMarkerData(i, 1) & "]"
ElseIf dataSize = 3 Then 'lat,lon and title
mMarkerDataAsText += "[" & mMarkerData(i, 0) & "," + mMarkerData(i, 1) & ",'" & mMarkerData(i, 2) & "']"
ElseIf dataSize = 4 Then 'lat,lon,title and image
mMarkerDataAsText += "[" & mMarkerData(i, 0) & "," + mMarkerData(i, 1) & ",'" & mMarkerData(i, 2) & "','" & localPath & mMarkerData(i, 3) & "']" 'Ojo a las comillas simples en las columnas 3 y 4
End If
Next

mMarkerDataAsText += "]"
htmlTemplate.Replace(TEXT_TO_REPLACE_MARKER_DATA, mMarkerDataAsText)

Dim tmpHtmlMapFile As String = (tmpFolder & Convert.ToString("\")) + TMP_NAME
Dim existsMapFile As Boolean = False
Try
existsMapFile = createTxtFile(tmpHtmlMapFile, htmlTemplate)
Catch ex As Exception
MessageBox.Show("Error writing temporal file", "Writing Error", MessageBoxButtons.OK, MessageBoxIcon.[Error])
End Try

If existsMapFile Then
Return tmpHtmlMapFile
Else
Return Nothing
End If
End Function

Private Function getMarkerDataFromPositions(pos As Double(,)) As String(,)
Dim md As String(,) = New String(pos.GetLength(0) - 1, 1) {}
For i As Integer = 0 To pos.GetLength(0) - 1
md(i, 0) = pos(i, 0).ToString("g", New System.Globalization.CultureInfo("en-US"))
md(i, 1) = pos(i, 1).ToString("g", New System.Globalization.CultureInfo("en-US"))
Next
Return md
End Function

Private Function getStringFromResources(resourceName As String) As String
Dim assem As Assembly = Me.[GetType]().Assembly

Using stream As Stream = assem.GetManifestResourceStream(resourceName)
Try
Using reader As New StreamReader(stream)
Return reader.ReadToEnd()
End Using
Catch e As Exception
Throw New Exception((Convert.ToString("Error de acceso al Recurso '") & resourceName) + "'" & vbCr & vbLf + e.ToString())
End Try
End Using
End Function

Private Function createTxtFile(mFile As String, content As StringBuilder) As Boolean
Dim mPath As String = Path.GetDirectoryName(mFile)
If Not Directory.Exists(mPath) Then
Directory.CreateDirectory(mPath)
End If
If File.Exists(mFile) Then
File.Delete(mFile)
End If
Dim sw As StreamWriter = File.CreateText(mFile)
sw.Write(content.ToString())
sw.Close()
Return True
End Function
End Class

注意:MAP_TEMPLATE 常量必须包含您的项目名称

第 8 步。 现在我们可以使用我们的 GoogleMapHelper 类将 map 加载到我们的网络浏览器中,方法是简单地创建和实例化并调用它的 loadMap() 方法。如何构建 markerData 取决于您。在这个例子中,为了清楚起见,我手写了它们。有 3 个选项来定义标记数据(请参阅 GoogleMapHelper 类注释)。请注意,如果您使用第三个选项(包括标题和图标),您必须在调试/发布文件夹中创建一个名为“marker_icons”(或您在 GoogleMapHelper 常量 ICON_FOLDER 中定义的任何内容)的文件夹,并将您的 .png 文件放在那里。就我而言:

enter image description here

我在我的 Form1 中创建了两个按钮来说明 map 和 WF 是如何交互的。这是它的样子:

enter image description here

代码如下:

Form1.vb

Imports System.IO
Imports System.Reflection
Imports System.Security.Permissions
Imports System.Text
<PermissionSet(SecurityAction.Demand, Name:="FullTrust")>
<System.Runtime.InteropServices.ComVisible(True)>
Public Class Form1

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

Me.wbmap.ObjectForScripting = Me

Dim onlyPositions As Double(,) = New Double(2, 1) {{42.13557, -0.40806}, {42.13684, -0.40884}, {42.13716, -0.40729}}
Dim positonAndTitles As String(,) = New String(2, 2) {{"42.13557", "-0.40806", "marker0"}, {"42.13684", "-0.40884", "marker1"}, {"42.13716", "-0.40729", "marker2"}}
Dim positonTitlesAndIcons As String(,) = New String(2, 3) {{"42.13557", "-0.40806", "marker0", "truck_red.png"}, {"42.13684", "-0.40884", "marker1", "truck_red.png"}, {"42.13716", "-0.40729", "marker2", "truck_red.png"}}

'Dim gmh As GoogleMapHelper = New GoogleMapHelper(wbmap, onlyPositions)
'Dim gmh As GoogleMapHelper = New GoogleMapHelper(wbmap, positonAndTitles)
Dim gmh As GoogleMapHelper = New GoogleMapHelper(wbmap, positonTitlesAndIcons)
gmh.loadMap()
End Sub

'############################### CALLING JAVASCRIPT METHODS ##############################
'This methods call methods written in googlemap_template.html
Private Sub callMapJavascript(sender As Object, e As EventArgs) Handles Button1.Click
wbmap.Document.InvokeScript("showJavascriptHelloWorld")
End Sub

Private Sub callMapJavascriptWithArguments(sender As Object, e As EventArgs) Handles Button2.Click
wbmap.Document.InvokeScript("focusMarkerFromIdx", New String() {2})
End Sub
'#########################################################################################

'############################### METHODS CALLED FROM JAVASCRIPT ##########################
'This methods are called by the javascript defined in googlemap_template.html when some events are triggered
Public Sub getMarkerDataFromJavascript(title As String, idx As String)
MsgBox("Title: " & title & " idx: " & idx)
End Sub

Public Sub showVbHelloWorld()
MsgBox("Hello world in WF from HTML")
End Sub
End Class

重要:不要忘记在类 Form1 定义之前添加这些行:

<PermissionSet(SecurityAction.Demand, Name:="FullTrust")>
<System.Runtime.InteropServices.ComVisible(True)>

他们所做的是告诉 .NET Framework 我们需要完全信任并使该类对 COM 可见,以便 Form1 对 JavaScript 可见。

另外不要在 Form1 加载函数中忘记这一点:

Me.wbmap.ObjectForScripting = Me

它将您的 Form1 类公开给 googlemap_template.hmtl 页面上的 JavaScript。

现在你可以执行了,它应该可以工作了

#################################它是如何工作的######## #########################

基本上,我们的 GoogleMapHelper 类所做的是读取我们的 googlemap_template.html,制作临时副本,替换与标记相关的代码 ([[MARKER_DATA]]) 并在我们表单的网络浏览器控件中执行页面。此 html 循环遍历所有标记并为每个标记分配一个“点击”监听器。这个点击功能显然是完全可定制的。在示例中,如果标记有标题,它会打开一个信息窗口,将 map 置于此类标记的中心,并调用在我们的 Form1 类中定义的两个外部函数。

另一方面,我们可以在此 html 中定义其他 javascript 函数(带或不带参数)以从我们的 Windows 窗体调用(通过使用 wbmap.Document.InvokeScript)。

关于vb.net - 将 Google map 添加到 VB 2010 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9451954/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com