Insert point on lat/lng VBA MS Access

Hello. I’m just starting with MapWindow and need some guidance. I simply want to put a marker on a lat/lng location. I have the map of the US already loaded. I’ve tried many things but can’t seem to get it to work. Here is my code:

Private Sub Form_Load()

Me.Map0.Projection = tkMapProjection.PROJECTION_GOOGLE_MERCATOR
Me.Map0.TileProvider = tkTileProvider.OpenStreetMap
Me.Map0.KnownExtents = tkKnownExtents.keUSA
Me.Map0.CursorMode = cmPan

Dim lat, lng, refx, refy As Double
lat = 40.084947008
lng = -104.98548798

Dim shp As New MapWinGIS.shape
shp.Create (ShpfileType.SHP_POINT)
shp.AddPoint(lng,lat)

End Sub

The last line brings the following error “Expected =”. I would appreciate any help!

Hello @mikeradtke and welcome.

There are two things going on.
First is that you have to create a layer to hold the point. This additional code creates the layer, then your point, and finally adds the point to the layer.

        ' create Shapefile
        Dim sf As New Shapefile
        sf.CreateNew("", ShpfileType.SHP_POINT)
        .AddLayer(sf, True)

        Dim lat, lng, refx, refy As Double
        lat = 40.084947008
        lng = -104.98548798

        ' create Shape
        Dim shp As New MapWinGIS.Shape
        shp.Create(ShpfileType.SHP_POINT)
        shp.AddPoint(lng, lat)

        ' add Shape to Shapefile
        sf.EditAddShape(shp)

The second issue is that your map projection is Google Mercator (which is correct for the Open Street Maps, but is in meters with 0, 0 at the equator and prime meridian. So your point is being added 40 meters north of the equator and 104 meters west of prime meridian, as seen below.

So what you have to do next is transform your point from DMS to Google Mercator, as follows:

        ' create Shapefile
        Dim sf As New Shapefile
        sf.CreateNew("", ShpfileType.SHP_POINT)
        .AddLayer(sf, True)

        Dim lat, lng, refx, refy As Double
        lat = 40.084947008
        lng = -104.98548798

        ' transform point into Google Mercator coordinate system
        Dim tf As New GeoProjection
        tf.SetWellKnownGeogCS(tkCoordinateSystem.csWGS_84) ' DMS
        tf.StartTransform(.GeoProjection)   ' target is the maps geoprojection
        tf.Transform(lng, lat)              ' lng, lat are now in google mercator
        tf.StopTransform()

        ' create Shape
        Dim shp As New MapWinGIS.Shape
        shp.Create(ShpfileType.SHP_POINT)
        shp.AddPoint(lng, lat)

        sf.EditAddShape(shp)

And now there’s you point just north of Denver.

Regards,
Jerry.

1 Like

Hi Jerry,
Thank you very much for your reply! This all makes perfect sense; however, I’m getting hung up on the syntax. Is there something I need to reference in VBA that I’m missing? I have the MapWinGIS objects loaded, so that can’t be the problem. Here is where I’m getting errors:
syntax error - “expected: =”: sf.CreateNew("", ShpfileType.SHP_POINT)
syntax error- “expected: =”: sf.AddLayer(sf, True)
invalid reference: (.GeoProjection)

I have the library as mentioned:
Screenshot 2021-10-15 094151
Here are my references:
Screenshot 2021-10-15 094520

Thoughts?

Hello again.

Those functions return values (e.g. AddLayer returns an integer layer handle, AddPoint returns an integer point index and EditAddShape returns and integer Shape index). I’m guessing that VBA is enforcing you to catch that returned value, something like

Dim index As Integer
index = shp.AddPoint(lng, lat)

This is good practice anyway, since there will be many cases in which you need to reference the proper layer handle or Shape index.

I’m not sure about the GeoProjection reference. In my code, I had all of this within a With statement…

With AxMap1
    . . .
End With

You could try specifically referencing AxMap1.GeoProjection and see if that helps. Or VBA may require a two-step process, first extracting the GeoProjection reference, then using the reference (I’m just guessing here, but I’ve seen similar things)…

Dim gp as GeoProjection
Set gp = AxMap1.GeoProjection
. . .
tf.StartTransform(gp)

Regards,
Jerry.

I almost have it. The code is getting hung up on the transformation. I am getting a “beref argument type mismatch” error here:

tx = tf.Transform(lng, lat)

it highlights lng when the errors shows. lng and lat are Dim as Double earlier in the code, so i’m not sure why there would be a type mismatch?

Also… when I type in the coordinates manually I get no errors, but the point is not transformed. Here is full code so far:

Me.Map0.Projection = tkMapProjection.PROJECTION_GOOGLE_MERCATOR
Me.Map0.TileProvider = tkTileProvider.OpenStreetMap
Me.Map0.KnownExtents = tkKnownExtents.keUSA
Me.Map0.CursorMode = cmPan

Dim gp As GeoProjection
Set gp = Me.Map0.GeoProjection
Dim index, lyr, shp1, tx As Integer
Dim lat, lng, refx, refy As Double
lat = 40.084947008
lng = -104.98548798


With Me.Map0

       Dim sf As New Shapefile
       shape = sf.CreateNew("", ShpfileType.SHP_POINT)
       lyr = Me.Map0.AddLayer(sf, True)


        ' transform point into Google Mercator coordinate system
        Dim tf As New GeoProjection
        tf.SetWellKnownGeogCS (tkCoordinateSystem.csWGS_84) ' DMS
        tf.StartTransform (Me.Map0.GeoProjection)  ' target is the maps geoprojection
       tx = tf.Transform(-104.98548798, 40.084947008)
       tf.StopTransform

        ' create Shape
        Dim shp As New MapWinGIS.shape
        shp.Create (ShpfileType.SHP_POINT)
       index = shp.AddPoint(lng, lat)

       index = sf.EditAddShape(shp)
End With

Regarding the lng, lat; check to see if they’re actually Doubles. I have a recollection (may be mistaken) that if you declare as follows:

Dim lat, lng, refx, refy As Double

then only the last one is actually a Double; the others would be Variants.

Try specifically declaring

Dim lat As Double
Dim lng As Double
2 Likes

That did the trick! Thank you so much, Jerry!

:+1: glad to hear it.

It’s an old VB6 and VBA characteristic. In VB.NET they would all be interpreted as Doubles.

1 Like