none
GMap.NET and VB : How to set a Custom Marker's hit region? RRS feed

  • Question

  • Greetings,
    this is about GMap.NET library use in VB 2015.

    I'm using GMap.NET GmapControl in a VB 2015 Windows Forms Application.

    Here's what I do to simply add a custom flag ( designed by me as a bitmap and then imported in my VB 2015 project as a Resource ) on Map :

        Dim BMPMarker As New Bitmap(My.Resources.TestFlag01)
        BMPMarker.MakeTransparent(Color.White)
        Dim GMapMarkers As New GMap.NET.WindowsForms.GMapOverlay
        GMC.Overlays.Add(GMapMarkers)
        Dim M As New GMap.NET.WindowsForms.Markers.GMarkerGoogle(New 
        PointLatLng(40.669599, -73.94625), BMPMarker)
        GMapMarkers.Markers.Add(M)

    The Marker's bitmap I use is like the one in this picture :

    So, setting the Transparent Color to White on bitmap, makes my marker visible correctly as a flag without the white part.

    The problem is that the marker's hit region is still a rectangle. And If I pass the mouse over the areas that were White, it allows me to click the invisible part of the marker.

    Maybe this is not the right way to get a real flag marker from my Bitmap.

    How could I obtain it ?

    Thanks to anyone able to help.

    Monday, June 25, 2018 9:06 AM

All replies

  • Marco,

    I am not sure but I am guessing that statement does not produce a true transparent bitmap? Plus windows forms in vb is not truly transparent in all cases.

    See what happens if you use the image at this link which is supposedly a true transparency I found in a search. I just found this on search. Careful when saving sometimes it looses the transparency?

    http://www.clipartbest.com/cliparts/nTE/7gk/nTE7gkgnc.png

    Search:

    https://www.bing.com/images/search?view=detailV2&ccid=9RURobWi&id=D9B6B8DC1E0BC40C3E882D567C51407C6AD5BDE8&thid=OIP.9RURobWipidV1EtyR9rsiwAAAA&mediaurl=http%3a%2f%2fwww.clipartbest.com%2fcliparts%2fnTE%2f7gk%2fnTE7gkgnc.png&exph=256&expw=338&q=arrow+transparent+images&simid=608044282018005538&selectedIndex=4&ajaxhist=0

    Hmm off topic google chrome browser does not show links?


    If that transparent image does not help then you might ask at Google api forum if there is one. 

    How do you detect a click ? Is that vb code or is it done with a google api? Show the code. If vb perhaps you can use a region.

    Or maybe someone else knows more??

    Monday, June 25, 2018 2:05 PM
  • Hi, tommytwotrain, and thanks for attention.

    I put here my example's entire code, so you can see easily what I'm doing.

    All very simple. 

    First of all, the image I'm using now it's a really transparent .png
    Here it is :


    Let's say I must set on Map a Person, so first of all my Person Class :

    Option Explicit On
    Option Strict On
    
    Public Class clsPerson
    
    #Region "Members"
    
        Private mID As Integer
        Private mName As String
    
    #End Region
    
    #Region "Properties"
    
        Public Property ID As Integer
            Get
                Return mID
            End Get
            Set(value As Integer)
                mID = value
            End Set
        End Property
    
        Public Property Name As String
            Get
                Return mName
            End Get
            Set(value As String)
                mName = value
            End Set
        End Property
    
    #End Region
    
    
    End Class


    Now I must create my own GMap Marker, in order to pass a Person Object to the Constructor Method, and so I inherit from GMap.NET.WindowsForms.Markers.GMarkerGoogle :

    Option Explicit On
    Option Strict On
    
    Public Class clsGMarkerGoogleTest
        Inherits GMap.NET.WindowsForms.Markers.GMarkerGoogle
    
    #Region "Members"
    
        Private mPerson As clsPerson
        Private mPointLatLng As GMap.NET.PointLatLng
        Private mMarkerBmp As Bitmap
    
    #End Region
    
    #Region "Properties"
    
        Public ReadOnly Property Person As clsPerson
            Get
                Return mPerson
            End Get
        End Property
    
    #End Region
    
    #Region "Constructor"
    
        Public Sub New(ByVal pPerson As clsPerson,
                       ByVal pPointLatLng As GMap.NET.PointLatLng,
                       ByVal pMarkerBmp As Bitmap)
    
            MyBase.New(pPointLatLng,
                       pMarkerBmp)
            mPerson = pPerson
            mMarkerBmp = pMarkerBmp
            Using G As Graphics = Graphics.FromImage(mMarkerBmp)
                G.DrawString(mPerson.ID.ToString & " . " & mPerson.Name,
                             New Font(FontFamily.GenericSerif, 14, FontStyle.Bold), Brushes.Black, 2, 2)
            End Using
            Me.Bitmap = mMarkerBmp
    
        End Sub
    
    #End Region
    
    
    End Class
    


    Finally, the test Form code :

    Option Explicit On
    Option Strict On
    
    Public Class FormMainTEST
    
    #Region "Members"
    
        Private mMapProvider As GMap.NET.MapProviders.GMapProvider
        Private mMarkersOverlay As New GMap.NET.WindowsForms.GMapOverlay
    
    #End Region
    
    #Region "Events"
    
        Private Sub FormMainTEST_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
    
            For Each GMP As GMap.NET.MapProviders.GMapProvider In GMap.NET.MapProviders.GMapProviders.List
                If GMP.Name = "GoogleHybridMap" Then 'Or any other map provider available ...
                    mMapProvider = GMP
                    Exit For
                End If
            Next
            With GMC
                .MapProvider = mMapProvider
                .Position = New PointLatLng(40.685165, -73.944357)
                .MinZoom = 5
                .MaxZoom = 20
                .Zoom = 15
                .Cursor = Cursors.Cross
                .DragButton = MouseButtons.Left
                .Overlays.Add(mMarkersOverlay)
            End With
    
        End Sub
    
        Private Sub btn_test_Click(sender As Object, e As EventArgs) Handles btn_test.Click
    
            Dim P1 As New clsPerson
            With P1
                .ID = 1
                .Name = "Jack"
            End With
            Dim MP As New clsGMarkerGoogleTest(P1,
                                               New GMap.NET.PointLatLng(40.685165, -73.944357),
                                               My.Resources.TestFlag02)
            mMarkersOverlay.Markers.Add(MP)
    
        End Sub
    
        Private Sub GMC_OnMarkerClick(item As GMapMarker, e As MouseEventArgs) Handles GMC.OnMarkerClick
    
            If TypeOf item Is clsGMarkerGoogleTest Then
                With DirectCast(item, clsGMarkerGoogleTest)
                    MessageBox.Show("Click on : " & .Person.Name)
                End With
            End If
    
        End Sub
    
    #End Region
    
    
    End Class

    As you can see, I use GMapControl's Event "Private Sub GMC_OnMarkerClick" to detect Clicks.

    Monday, June 25, 2018 3:40 PM
  • I see. So you use a control from google? Like a picturebox?

    I dont really know. So if no one else responds you prob need to ask in the google forum.

    However I think you could create a region of the actual clicvkable area you want in coordinates and then test the hit yourself in the GMC_OnMarkerClick of the vb part but there must be a bettter way??

    Do you see other examples using what you use that does this?

    Are there bitmaps you can spec from google? Are they transparent so it works how you want? Why not use those and why do they work but yours dont? Are they png? etc.

    Maybe someone else knows something???

    PS Maybe that is how it works unless you have an example where it is transparent as you want?

    On these docs is Adding polygons maybe you can use to define and test the clicakble area polygon. Have you seen that?

    http://www.independent-software.com/gmap-net-tutorial-maps-markers-and-polygons.html


    Monday, June 25, 2018 5:12 PM
  • I don't know what kind of "Control" could it be.
    GMarkerGoogle is the Class name but I see it works the same on every map, every provider available ( Bing, Google, OpenStreetMap, ecc... ).

    I've found an Overrides Method "OnRender", with a Graphics object as argument, and maybe this could be the right way, but I don't know how to use it to define the marker's region.

        Public Overrides Sub OnRender(g As Graphics)
    
            MyBase.OnRender(g)
    
        End Sub

    Tuesday, June 26, 2018 6:57 AM
  • I don't know what kind of "Control" could it be.
    GMarkerGoogle is the Class name but I see it works the same on every map, every provider available ( Bing, Google, OpenStreetMap, ecc... ).

    I've found an Overrides Method "OnRender", with a Graphics object as argument, and maybe this could be the right way, but I don't know how to use it to define the marker's region.

        Public Overrides Sub OnRender(g As Graphics)
    
            MyBase.OnRender(g)
    
        End Sub

    I dont understand what you mean sorry.

    But at the bottom of the link I gave you find this method of making a clickable polygon. Did you look at that? Is that what you are doing?

    You can make a polygon region and click it.

    Is that the GMap.Net control you are using??? If not give a link to what you use.

    It also talks about layers and adding to them etc. I think that is what you do? 

    If you want more help perhaps ask at the bottom of that page in the comments.

    Here is a quote:

    Adding polygons

    Markers may not always cut it. Sometimes you need to delimit an area of your map. For instance, you may need to indicate where new construction will take place, or who owns which land. Polygons allow you to show just that.

    The following code shows how to create another overlay, and add a four-point polygon to it.

    <figure class="highlight" style="margin:0px;padding:0px;background:rgb(240, 240, 240);color:#333333;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';font-size:16px;">
    GMapOverlay polyOverlay = new GMapOverlay("polygons");
    IList points = new List();
    points.Add(new PointLatLng(-25.969562,32.585789));
    points.Add(new PointLatLng(-25.966205,32.588171));
    points.Add(new PointLatLng(-25.968134,32.591647));
    points.Add(new PointLatLng(-25.971684,32.589759));
    GMapPolygon polygon = new GMapPolygon(points, "mypolygon");
    polygon.Fill = new SolidBrush(Color.FromArgb(50, Color.Red));
    polygon.Stroke = new Pen(Color.Red, 1);
    polyOverlay.Polygons.Add(polygon);
    gmap.Overlays.Add(polyOverlay);
    </figure>

    Tuesday, June 26, 2018 11:59 AM
  • Hi, tommytwotrain, and thanks again.

    Yes, the control I'm using is Gmap.NET "GMapControl" for Windows Forms.

    In the Project's references I've got :

    GMap.NET.Core v1.8.5.0
    GMap.NET.WindowsForms v1.8.5.0

    I already know that guide you have linked here, but I don't need polygons.
    To set a polygon you need N points, N coordinates.
    I need a single Marker on a single coordinate ( Lat, Lon ).

    The only problem I'm facing here is that I don't want a standard marker, but I need a custom Marker designed by me, with a custom shape, and I want to be able to write text and draw my own icons on it.
    And by now every marker I've tried has always a rectangular hit region.
    I want the clickable marker's region to be the same as the marker's visible shape.

    I think this could be obtained with some code in the Override Sub OnRender() Method of the Class I have made, which inherits from 
    GMap.NET.WindowsForms.Markers.GMarkerGoogle.
    But I don't know the code to use.
    That was the meaning of my last post.
     

    Wednesday, June 27, 2018 7:03 AM
  • Hi, tommytwotrain, and thanks again.

    Yes, the control I'm using is Gmap.NET "GMapControl" for Windows Forms.

    In the Project's references I've got :

    GMap.NET.Core v1.8.5.0
    GMap.NET.WindowsForms v1.8.5.0

    I already know that guide you have linked here, but I don't need polygons.
    To set a polygon you need N points, N coordinates.
    I need a single Marker on a single coordinate ( Lat, Lon ).

    The only problem I'm facing here is that I don't want a standard marker, but I need a custom Marker designed by me, with a custom shape, and I want to be able to write text and draw my own icons on it.
    And by now every marker I've tried has always a rectangular hit region.
    I want the clickable marker's region to be the same as the marker's visible shape.

    I think this could be obtained with some code in the Override Sub OnRender() Method of the Class I have made, which inherits from 
    GMap.NET.WindowsForms.Markers.GMarkerGoogle.
    But I don't know the code to use.
    That was the meaning of my last post.
     

    Yes I think I am understanding what you want to do now.

    One problem I suspect will be how to convert the click point in the mouse events in the form/control mouse click coordinates (pixels) with the map coordinates lat/long? that are showing in the control? Can you do that? Tell me how.

    What I am suggesting is you use your image as the marker and make a polygon using the control the shape of the clickable area of the marker image and overlay that on the marker image in the gmap control. Then when the user clicks the marker image, the polygon hot spot overlay will capture the click event. There is a similar hot spot thing for html I think.

    Do you know what I mean?

    Assuming the polygon will work that way.

    If you want to try your method I can show you how to make a clickable region in vb. But you will have to figure the coordinates to use. And it is possible it wont work anyway due to various other problems that may come up???

    Have you asked at the place that makes the control??? That is where you need to ask. Its possible there is a simple way just using the control as is without inventing your own wheels for it.

    Wednesday, June 27, 2018 12:08 PM
  • PS Here is an example using a clickable region in the vb mouse events (path in this example). You can optionally put an image in the path. I just drew a semi opaque color in a triangle.

    The example is basically the polygon in the gnet control as far as I can tell. But the one we do in vb is in form coordinates (pixels). I assume the polygon in gnet is in map coordinates?? See what I mean? So to use this you must translate from the pixels in the form to whatever the map is in the control?

    That is why I suspect there is an easier way but you will have to ask at gnet control.

    Public Class Form6
        Private star1 As New Drawing2D.GraphicsPath
    
        Private Sub Form6_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            BackgroundImage = Image.FromFile("c:\bitmaps\rusty.jpg")
    
            Dim thePolygon() As PointF = {New PointF(100, 100), New PointF(150, 200), New PointF(200, 100)}
    
            star1.AddLines(thePolygon)
    
        End Sub
    
        Private Sub Form6_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
            If star1.IsVisible(e.Location) Then MsgBox("Here I am")
        End Sub
    
        Private Sub Form6_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
            If star1.IsVisible(e.Location) Then Cursor = Cursors.Hand Else Cursor = Cursors.Default
        End Sub
    
        Private Sub Form6_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
    
            e.Graphics.FillPath(New SolidBrush(Color.FromArgb(100, Color.LightGoldenrodYellow)), star1)
            e.Graphics.DrawPath(Pens.Lime, star1)
        End Sub
    End Class

    • Proposed as answer by Alex Li-MSFT Thursday, July 5, 2018 9:47 AM
    • Unproposed as answer by MarcoGG Monday, July 16, 2018 10:00 AM
    Wednesday, June 27, 2018 1:52 PM
  • Ok, tommytwotrain, I've read your last posts.
    I will return on this topic as soon as possible.

    Tahnk you again very much for your attention.

    Thursday, June 28, 2018 1:26 PM