Visual Basic .NET Language
Windows Form의 Google지도
수색…
Windows Form에서 Google Map을 사용하는 방법
이 예제의 첫 번째 부분에서는 구현 방법을 설명합니다. 둘째, 어떻게 작동하는지 설명하겠습니다. 이것은 일반적인 예입니다. 지도 템플릿 (3 단계 참조)과 예제 기능은 완전히 사용자 정의 할 수 있습니다.
################ 구현 ########## ##################
1 단계. 먼저 새 프로젝트를 만들고 Windows Form Application을 선택합니다. 그 이름을 "Form1"로 남겨 둡시다.
2 단계. Form1에 WebBrowser 컨트롤 (맵을 보유 할)을 추가합니다. "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>
이것은지도 템플릿으로 사용됩니다. 나중에 어떻게 작동하는지 설명하겠습니다.
4 단계. googlemap_template.hmtl 파일을 프로젝트에 추가합니다 (프로젝트 -> 추가 -> 기존 항목을 마우스 오른쪽 버튼으로 클릭).
5 단계. 솔루션 탐색기에 나타나면 해당 속성을 다음과 같이 설정하십시오.
- 빌드 액션 -> 임베디드 리소스
- 사용자 정의 도구 네임 스페이스 -> 프로젝트 이름 작성
6 단계. 새 클래스를 추가하십시오 (프로젝트 -> 추가 -> 클래스를 마우스 오른쪽 단추로 클릭하십시오). 예제에서는 GoogleMapHelper라고 부릅니다.
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 클래스를 사용하여 loadMap () 메소드를 호출하고 인스턴스를 작성하고 호출함으로써 웹 브라우저에지도를로드 할 수 있습니다. markerData를 작성하는 방법은 귀하에게 달려 있습니다. 이 예제에서는 설명을 위해 직접 작성합니다. 마커 데이터를 정의하는 세 가지 옵션이 있습니다 (GoogleMapHelper 클래스 주석 참조). 세 번째 옵션 (제목 및 아이콘 포함)을 사용하는 경우 Debug / Release 폴더에서 "marker_icons"(또는 GoogleMapHelper 상수 ICON_FOLDER에서 정의한 항목)라는 폴더를 만들어서 .png 파일을 배치해야합니다. 나의 경우에는:
Map1과 WF가 상호 작용하는 방식을 설명하기 위해 Form1에 두 개의 버튼을 만들었습니다. 어떻게 보이는지 다음과 같습니다.
그리고 여기 코드가 있습니다 :
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에 fulltrust를 원하고 COM에서 클래스를 볼 수 있도록하여 Form1을 JavaScript에서 볼 수있게하는 것입니다.
또한 Form1로드 함수에서 이것을 잊지 마십시오.
Me.wbmap.ObjectForScripting = Me
Form1 클래스를 googlemap_template.hmtl 페이지의 JavaScript로 노출합니다.
이제 실행할 수 있고 작동해야합니다.
################# 어떻게 작동합니까 ############# ##################
기본적으로 GoogleMapHelper 클래스가 수행하는 작업은 googlemap_template.html을 읽고 임시 복사본을 만들고 마커 ([[MARKER_DATA]])와 관련된 코드를 대체 한 다음 양식의 웹 브라우저 컨트롤에서 페이지를 실행하는 것입니다. 이 html은 모든 마커를 반복하고 각각에 '클릭'리스너를 지정합니다. 이 클릭 기능은 완전히 사용자 정의 할 수 있습니다. 이 예제에서는 마커에 제목이 있으면 정보 창을 열고, 마커에 맵을 중앙에 배치하고 Form1 클래스에 정의 된 두 개의 외부 함수를 호출합니다.
반면에 우리는이 html에 wbmap.Document.InvokeScript를 사용하여 Windows Form에서 호출 할 수있는 다른 javascript 함수 (인수가 있거나 없음)를 정의 할 수 있습니다.