Extracting mouse cursor Lat/Long in MWG v4.9.5

Hi
For some time I have used the MapWinGIS ActiveX plugin to implement a map client in a Labview program. This has been challenging for a few reasons, mainly because MWG is only partial supported in Labview with only 2 versions working (v4.7 and v4.9.5), and the fact that there is very little info on the net about using MWG in Labview. However, I managed to make a map client in v4.7 which I later on ported into v4.9.5 because of the added functionality it provided. My problem now is that I cannot find a method to read out Lat/Long of the cursor position in the map with v4.9.5, which was easy to do in v4.7, just reading the MapState string on each Mouse Move event, but this property is removed from v.4.9.5, and so far I have not been able to find a method to extract mouse Lat/Long, although it is clearly displayed in the upper right corner of the map!
Without knowing mouse Lat/Long I cannot perform certain important functions that worked in v4.7 (drawing lines/boxes etc)

I don’t expect an explanation how to do it in Labview, so any tips using C# examples that will point me in the right direction is highly appreciated.
NB! I’m using the WebMercator projection maps which dont use Lat/Long, in case that is an issue.

Hello @bbend

As of 4.9.1, there should be properties on the Map (AxMap), Latitude and Longitude, which return floating point values in decimal degrees. Do you see these?

Regards,
Jerry.

Hello Jerry

If you mean the Lat/Long values in the upper right corner of the Map, I can see them changing as I move the cursor in the map. The issue is to grab these values programatically. To be honest, using the MWG ActiveX plugin within Labview is a big challenge as the native language is C++ which prevents me from using example code to build my app, but if you can provide some code on how it is done in C++/C#, I may get an idea how to implement it in Labview. As it is now I cannot go back to v4.7, as v4.9.5 has too many desirable features that 4.7 doesn’t have, although the seamingly complicated method to extract Lat/Long is a major limitation to the needed functionality.

Regards
BĂĄrd

Hello @bbend

I’m sorry that I was not clear. There are callable Properties on the Map control, Latitude and Longitude, that will return the values as a single-precision floating point value.

From c#, it would be something like:

    double lon = AxMap1.Longitude();
    double lat = AxMap1.Latitude();

Hope that helps.

Addendum: I’ve done a bit of c++ coding around the Map component, so if there are specific things you are interested in, let me know, and perhaps I can find some sample code. Regards.

Hello again. I was mistaken…

The Longitude and Latitude properties return the coordinate at the center of the current map view, which doesn’t do you much good.

Plan B involves using the current mouse position, capturing either the MouseMove or the MouseDown event, depending upon your context. I have a customer that needs to display map coordinates in the Military Grid Reference System, so they’re always capturing and converting the mouse position on the MouseMove event. It is not an expensive operation.

The MouseMove event parameter includes the x and y position, in screen coordinates, and you can use the PixelToProj method to convert to the current Map projection, which in your case is Web Mercator. If you need the coordinate in another projection, you can transform it again as necessary. The code will be something like:

double mapX, mapY;
AxMap1.PixelToProj(e.x, e.y, ref mapX, ref mapY);

I hope this can work for you.

Regards,
Jerry.

Hi Jerry

That last post sent me in the right direction to solve problem. After some fiddling I managed to set up a Mouse Move event handler in Labview, which captured the X,Y pixel pos of the mouse. Now I’m able to use mouse to draw boxes/lines in map. Thanks for the help!

Regarding drawing on the map, I experience this to be an expensive operation, using DrawPoint/DrawLine, and drawing mulitple points (few hundreds) in a map track, or redrawing a box/line with the mouse pointer, is painfully slow/jerky. Writing points to a Shapefile first makes it a lot quicker to plot points, but with the Labview plugin I loose control of pointsize/color/type etc, so is not an optimal solution. I even think drawings are slower with v4.9.5 than v4.7!
A reason test of plotting a track with Drawpoint in a loop resulted in 20points/sec, which is slow. The question is: Is this a known limitation til MWG or is it only slow in Labview plugin? Wouldn’t it be fairly easy to make a multipoint/multiline method to draw all at once?

Regards
BĂĄrd

It is best to create a new post when you have a new question.
It makes it easier to track.

Regarding your second question about redrawing.
Several redraw functions exist. For example AxMap.Redraw2(). They are especially for performance.
Also locking the window might help as well: AxMap.LockWindow(). Don’t forget to unlock in the finally or else your view stays locked when an error occurs.

And can’t you upgrade to the latest version of MapWinGIS? Currently it is on v5.1.1

1 Like

Hello BĂĄrd [@bbend]

I would speculate that the drawing speed may be related to the LabView plugin. As a reference, I’ve attached a video clip of a circle drawing tool that I implemented in an old VB6 application. Every mouse move event clears the drawing layer and adds a new circle of the new size, and displays the current circle size in a tooltip, and you can see that it is able to keep up quite easily.

Perhaps this isn’t comparing apples to apples; would you like to provide a small sample of your test code? I could try it on this end.

Regards.

Private Sub Map_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Long, ByVal y As Long)
...
    If m_DrawingCircle Then
        ' get the current point
        Set pPoint = PixelToMapPoint(Map, x, y)
        m_CircleRadius = LineLength(pPoint, m_CircleCenter)
        ' update drawing
        Map.ClearDrawing m_DrawHandle
        m_DrawHandle = Map.NewDrawing(dlSpatiallyReferencedList)
        Map.DrawCircleEx m_DrawHandle, m_CircleCenter.x, m_CircleCenter.y, m_CircleRadius, &HFF0000, False
...
        Map.Redraw2 RedrawSkipDataLayers

2 Likes

Hi pmeems and Jerry

Yes, I thought about creating another post, but since it was related to my orig question (in my app at least) I kept it here. Regarding your suggestions, I have just included LockWindow before/after all drawing loops, and let me tell you the difference is HUGE! Now I can plot a detailed track in an instant that took minutes before. This problem I have struggled with for 5 years, making different workarounds (decimation etc) to make it bearable, so a BIG THANK YOU for that! I’m very happy, although a bit annoyed by myself that I didn’t know this easy trick to speed up drawing loops. I will try the Redraw2 to see how that can improve dynamic (mouse driven) drawings which I see Jerry did in his example, which takes a bit more work than the Lock trick. I’ll let you know how it worked out.

Again BIG thanks to both of you!

Hello jerry!

I am currently working on VB Access but I have a lot of doubts when creating shapes and there are not many examples when you work on VB on the internet, could you provide me the complete example that you are showing?

Thanks!, excellent work!

Hello @pcanto

Unfortunately, it’s not quite that simple. This is embedded in some older proprietary code, and I would have to extract portions. I only posted it to show how fast drawing could be in the mouse events.

Are you specifically looking for help with drawing geometries in the Mouse events? or is there something else you are looking for?

Regards,
Jerry.

Hi @jerryfaust

Thanks for your answer.

I briefly tell you what I am trying to implement.

I could already program the events required to program with the mouse, I show you the image.

Now my question is, is there any internal function so that you can help me to know which geometries cross or are contained in others, I give as an example those that are indicated.

or I just have to manually program the functions and search for those according to their coordinates.

in advance thank you very much!

Hello @pcanto.

Yes, you can use one of the functions, Shapefile.GetRelatedShapes, or Shapefile.GetRelatedShapes2.

Here’s a simple example in VB.NET, using GetRelatedShapes2. You pass in a Shape for which you want to check containment, intersection, etc. Assuming you have a layer (pLayer) and a shape (pShape):

' will hold array of Shape IDs
Dim IDs As Object = Nothing
' find all Shapes in pLayer that intersect the specified pShape
If pLayer.GetRelatedShapes2(pShape, tkSpatialRelation.srIntersects, IDs) Then
    If UBound(IDs) >= 0 Then
        For i As Integer = 0 To UBound(IDs)
            ' get next shape from the layer
            Dim newShape As Shape = pLayer.Shape(IDs(i))
            ' do something with it

        Next
    End If
End If

Hope that helps.
Regards,
Jerry.

Hello @jerryfaust

Thank you for you response.

I try to put this code in VB, and i will give to ypu a feedback.

Greetings.

Hello @jerryfaust again!

First of all thank you very much for the support.

And second, excuse me, but I am new to the use of the tool and I have many doubts, everything I am applying when asking within an MS Access application.

I tell you that I have not been able to apply the code that you tell me, I explain how I am working with the tool.

  1. upload the Map through an image

Set mpIma = New MapWinGIS.image
mpIma.Open (“C:\Users\myUser\Desktop\map.jpg”)
MapCtr.AddLayer(mpIma, True)

  1. I draw the shapes with this function

hndl = Map6.NewDrawing(MapWinGIS.tkDrawReferenceList.dlSpatiallyReferencedList)

if it is circle
Map6.DrawWideCircleEx(hndl, tbl![TR_PJPWCORD_X1], tbl![TR_PJPWCORD_Y1], tbl![TR_PJPWCORD_R], RETURN_PTW_RGB(tbl![TR_PJPTW_ID]), False, 4)

if it is square
Map6.DrawWidePolygonEx(hndl, x_Array, y_Array, 5, RETURN_PTW_RGB(tbl![TR_PJPTW_ID]), False, 4)

  1. I don’t know if I understood correctly, but what you kindly told me is applied to Shapes and not to Drawing Layers, is that correct?

  2. There is something similar, to verify intersections, crossings, etc, but with objects of the Drawing layers type.

  3. Or what I want to do could be done differently?

  4. finally, I can continue asking here or I open a specific question

Thanks and regards!

Hello @pcanto, and sorry for the delayed response.

Yes, you need your shapes to be in an actual layer rather than the drawing layer. It’s a little more work, but it is not difficult to do. And it offers many advantages in terms of geoprocessing and rendering. See this example here.

And this forum is the place to ask questions. It is best, however, if you have a new question to start a new topic.

Regards,
Jerry.