Добавление Google Maps в приложение VB 2010 - PullRequest
2 голосов
/ 26 февраля 2012

Я хочу написать приложение Windows Forms в VB 2010, которое позволит пользователю искать и просматривать адреса или координаты точек на Картах Google. Я уже сделал это с помощью элемента WebBrowser. Однако я хочу использовать оболочку, чтобы я мог просто отобразить карту пользователю, но при этом иметь возможность перемещать и масштабировать карту или указывать направления и т. Д. Я знаю, что есть способы сделать это при разработке сайта ASP.NET. , но я хочу сделать это для приложения WindowsForms. Может ли кто-нибудь помочь, пожалуйста?

Ответы [ 5 ]

6 голосов
/ 10 октября 2016

Возможно, слишком поздно, но недавно я имел дело с картами Google в vb и хотел поделиться своим решением:

Первая часть этого примера объясняет, как его реализовать.Во втором я объясню, как это работает.Это пытается быть общим примером.Шаблон для карты (см. Шаг 3) и пример функций полностью настраиваемы.

################################# РЕАЛИЗАЦИЯ ############################

Шаг 1. Сначала создайте новый проект и выберите Приложение Windows Form,Давайте оставим его имя как «Form1».

enter image description here

Шаг 2. Добавить элемент управления WebBrowser (который будет содержать вашу карту)на вашу форму1.Давайте назовем его «wbmap»

Шаг 3. Создайте HTML-файл с именем «googlemap_template.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 в свой проект (щелкните правой кнопкой мыши свой проект-> add-> существующий элемент)

Шаг 5. Как только он появится в обозревателе решений, задайте его свойства: - Действие построения -> Встроенный ресурс - Пространство имен настраиваемого инструмента -> введите имя проекта

enter image description here

Шаг 6. Добавьте новый класс (щелкните правой кнопкой мыши по вашему проекту-> add-> class).В моем примере я назову его 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 для загрузки карты в наш веб-браузер, просто создав и скопировав и вызвав его метод loadMap ().Как вы строите свой маркерДата зависит от вас.В этом примере для пояснения я пишу их от руки.Существует 3 варианта определения данных маркера (см. Комментарии класса GoogleMapHelper).Обратите внимание, что если вы используете третий вариант (включая заголовок и значки), вы должны создать папку с именем marker_icons (или то, что вы определили в константе GoogleMapHelper ICON_FOLDER) в папке Debug / Release и поместить туда свои файлы .png.В моем случае:

enter image description here

Я создал две кнопки в моей форме Form1, чтобы проиллюстрировать, как карта и 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 дляJavaScript на странице googlemap_template.hmtl.

Теперь вы можете выполнить, и он должен работать

######################################## КАК ЭТО УСТРОЕНО#################################

По сути, наш класс GoogleMapHelper выполняет чтение нашего googlemap_template.html, делает временную копию, заменяет код, связанный с маркерами ([[MARKER_DATA]]) и выполняет страницу ввеб-браузер контроля нашей формы.Этот html проходит по всем маркерам и назначает слушателю «щелчок» для каждого.Эта функция клика, очевидно, полностью настраиваемая.В этом примере он открывает информационное окно, если маркер имеет заголовок, центрирует карту в таком маркере и вызывает две внешние функции, определенные в нашем классе Form1.

С другой стороны, мы можем определить другие функции javascript(с аргументами или без аргументов) в этом html для вызова из нашей формы Windows (с помощью wbmap.Document.InvokeScript).

2 голосов
/ 26 февраля 2012

Я использовал этот элемент управления, и это действительно фантастика Это позволило вам использовать не только GoogleMaps, но и практически все основные картографические сервисы, однако, в последний раз, когда я проверял, у них возникли некоторые проблемы с лицензированием в Google.

Великие Карты в кодовом комплексе

0 голосов
/ 05 февраля 2017

Проект Google Maps Control 2017 оборачивает API Карт Google как пользовательский элемент управления ASP.NET, предоставляя простой и быстрый способ добавления карт Google в страницы ASP.NET C # или VB с кодом «Zero-Written-JavaScript».

ASP.NET Google Maps Control включает в себя множество функций (маркеры, полилинии, многоугольники, направления) и предоставляет вам практически все функциональные возможности API Карт Google в приятном способе кодирования ASP.NET.

PM>Установить-пакет GoogleMapControl

0 голосов
/ 06 ноября 2014

Попробуйте этот код, чтобы получить направление между двумя местоположениями

Dim queryaddress As New System.Text.StringBuilder
        Dim sStreet As String = String.Empty
        Dim sCity As String = String.Empty
        Dim sState As String = String.Empty
        Dim sPincode As String = String.Empty
        Dim sProvider_no As String = String.Empty
        queryaddress.Append("https://www.google.com/maps/dir/")

        If txtprovider_no.Text <> "" Then
            sProvider_no = txtprovider_no.Text.Replace(" ", "+")
            queryaddress.Append(sProvider_no + "," & "+")
        End If
        If txtState.Text <> "" Then
            sState = txtState.Text.Replace("  ", "+")
            queryaddress.Append(sState + "," & "+")
        End If
        If txtCity.Text <> "" Then
            sCity = txtCity.Text.Replace("  ", "+")
            queryaddress.Append(sCity + "," & "+")
        End If
        If txtPincode.Text <> "" Then
            sPincode = txtPincode.Text.Replace("  ", "+")
            queryaddress.Append(sPincode)
        End If

        queryaddress.Append("/")
        sStreet = String.Empty
        sCity = String.Empty
        sState = String.Empty
        sPincode = String.Empty
        If txtlindmark.Text <> "" Then
            sStreet = txtlindmark.Text.Replace("  ", "+")
            queryaddress.Append(sStreet + "," & "+")
        End If
        If txtclient_city.Text <> "" Then
            sCity = txtclient_city.Text.Replace("  ", "+")
            queryaddress.Append(sCity + "," & "+")
        End If
        If ttxtclient_city.Text <> "" Then
            sPincode = ttxtclient_city.Text.Replace("  ", "+")
            queryaddress.Append(sPincode)
        End If
        If txtclient_state.Text <> "" Then
            sState = txtclient_state.Text.Replace("  ", "+")
            queryaddress.Append(sState + "," & "+")
        End If

        WBR.Navigate(queryaddress.ToString())
0 голосов
/ 26 февраля 2012

API Карт Google для .NET, кажется, то, что вы ищете

http://gmaps.codeplex.com/

с сайта

Этот проект намеревается предоставить все функции, доступные в API Карт Google. Он разрабатывается в C # для .NET Framework 3.5.

Хотя проект находится на C #, вы, вероятно, можете просто добавить ссылку на проект и использовать ее так же, как любую другую ссылку, и записать свой код на любом языке CLR, совместимом с ним, включая VB.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...