Problems with Markers

Topics: Windows Forms
Nov 19, 2012 at 5:13 PM
Edited Nov 19, 2012 at 5:40 PM

I am really hoping someone can help me here as I am tearing my hair out at the moment.  

Windows Forms App in was working perfectly, following a parsing run of upto 20,000 IP Addresses, GEOIP them then pull the latest run from the database with any new entries would add custom markers to map depending on the type.  Then, with no warning or code change it suddenly stopped working and I have tried everything I can think of to get it working again, even starting from scratch and going back to a previous version.

The strange thing is this, if I put the code in form load, it works perfectly and displays all the markers.  however, using the EXACT same code in a checkbox update event it either gives me an exception error of 'Parameter is not valid' on the overlay.markers.add line or it places all the markers on the same spot (the co-ordinates set for map center).

GMapProvider.WebProxy = New WebProxy("XXXXXXX)
        GMapProvider.WebProxy.Credentials = New NetworkCredential("xxxxxxxxx")
            Dim es As System.Net.IPHostEntry = System.Net.Dns.GetHostEntry("")
            GMapControl1.Manager.Mode = AccessMode.CacheOnly
            MessageBox.Show("No internet connection avaible, going to CacheOnly mode.", "GMap.NET - Demo.WindowsForms", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        End Try

        ' config map
        GMapControl1.MapProvider = GMapProviders.BingMap

        GMapControl1.MaxZoom = 11
        GMapControl1.MinZoom = 1
        GMapControl1.Zoom = 2
        GMapControl1.Position = New PointLatLng(49.7951, 0.12902) 'it's seems that currentposition can't be used anymore.
        GMapControl1.ShowCenter = False

        GMapControl1.Manager.Mode = AccessMode.ServerOnly

        Dim overlayOne As New GMapOverlay("Map")

        Dim adaptera As New SqlDataAdapter
        Dim dk As New DataSet
        Dim command As SqlCommand

        sql = "select top 10000 [lat],[lng],maltype from [MalDash].[dbo].[main] order by whenadded desc;"
        command = New SqlCommand(sql, myConn)
        adaptera.SelectCommand = command

        Dim picim As String

        For Each row As DataRow In dk.Tables(0).Rows
            picim = row.Item("maltype")
            Me.GMapControl1.HoldInvalidation = True
            overlayOne.Markers.Add(New GMarkerGoogle(New PointLatLng(row.Item("lat"), row.Item("lng")), New Bitmap("C:\\" & picim & ".png")))

        Next row

I've done some further digging with a try catch block to see the actual error and row.  Each time it is run, it is a different row that is causing the error.  So far, I've run it 25 times and its never given the error on the same row twice.
Nov 19, 2012 at 5:39 PM

because you set  Me.GMapControl1.HoldInvalidation = True and don't call map.Refresh(); at the end

  1. Me.GMapControl1.Overlays.Add(overlayOne) 
  2. set HoldInvalidation = true
  3. loop with markers
  4. call map.Refresh();
Nov 19, 2012 at 6:44 PM

thanks for the advice radio man, I'd love to say it solved my problem but unfortunately not.  I've stripped the code right down to the bare essentials and used a sqldatareader instead of an adapter.

I still get 'Parameter not valid' on random lines whenadding the marker to the overlay collection, only once has it stopped on the same line twice.  However, if I put the map gmapcontrol1.refresh() inside the loop, it adds the markers one by one, in their correct locations and continues without error to the end, the only problem is that the more it adds the slower it gets, the 6000 selected below took almost 15 mins to map.  Yet, on form load, it collects 10000 entries, adds them to the overlay and displays it correctly in less than 30 seconds ?  I'm just stumped how the exact same code works in one part of the form (ie. form.load) but not in another.

        nonqueryCommand.CommandText = "Select top 6000 lat,lng,maltype from maldash.dbo.main order by whenadded desc;"
        Dim reader As SqlDataReader = nonqueryCommand.ExecuteReader()
        Me.GMapControl1.HoldInvalidation = True
        While reader.Read()
            overlayOne.Markers.Add(New GMarkerGoogle(New PointLatLng(reader.GetString(0), reader.GetString(1)), New Bitmap("C:\\" & reader.GetString(2) & ".png")))
         End While

Nov 19, 2012 at 6:55 PM

reader.GetString(0), reader.GetString(1)), New Bitmap("C:\\" & reader.GetString(2) // in this line lives your bug

Nov 20, 2012 at 10:32 AM

I know, but what is causing it and why is it so intermittant ?  I've just tried it again with 2000 at a time displayed separately in each of my 16 categories and it worked a treat, all 32,000 markers showed correctly as they should.  Closed the form, re-opened it (shows 10000 markers at open), clear markers then begin to add individually again and get the error on the very first one.  No new data has been entered to the underlying database and no code had changed.  Close and re-open form again and the one that just gave me the error worked straight away but now another throws the exception.  

I could catch the exception quite easily but I've found that by doing so cause an out of memory exception to occur.  I'm pretty sure its something simple but I've run out of places to look.  For info, the error first began just after i started adding circles to the map and then changed my mind.  Even though I went back to the original code I just cannot remove this random error and would really appreciate any help or suggestions.

Nov 20, 2012 at 10:37 AM

it's not a map issue

Nov 20, 2012 at 3:35 PM

thanks for your help.  After trial and error and numerous amounts of digging, it seems that the issue was calling the PNG file from the local drive.  Basically, the app and map control were too quick for the system under heavy load and it couldnt grab the files quick enough, causing the error.  I moved the PNG files from the local drive into the resources of the app and called them through my.resources etc and so far, I'm back to mapping 2-3000 IPs without a problem.

Nov 20, 2012 at 3:43 PM

i see ;}

p.s. you can improve loading time by not calling directly, but saving bitmap instance into some variable, because accessing resources is quite slow too