ThinkGeo.com    |     Documentation    |     Premium Support

Convert Screen Coordinates to Map Coordinates

I was wondering if there was an inuitive way to turn Mouse.X and Y and translate them to where they are on the map? I want to display an X and Y on my status bar on MouseMove but can only get coordinats related to my screen pixels?



Hi Nelson, 
  
 Check out the Winforms sample application, there is a "How Do I" section on Screen & World Coordinates, the second example "Convert screen coordinates to world coordinates" shows how to obtain the Lat and Lon.  Try applying that to the MouseMove event in the map control. 
  
 Regards 
  
 John

Yes, typically it probably would make sense to check out these resources first. Haha, thanks John.



Actually, all of those samples seem to rely on the MapClick event. Trying to apply that event to the MouseMove event causes and unable to cast error.


 


Edit: I figured this out. ExtentHelper class is very good :)


Can I just verify that I am using the correct width and heigh values and that they don't actually need to be anything else like the actually users resolution width and height? Or that the extent needs to be the entire maps full extent regardless of zom level? Thank you.


        Dim screenX As Double = e.X
        Dim screenY As Double = e.Y
        Dim screenWidth As Single = mapViewer.Width
        Dim screenHeight As Single = mapViewer.Height
        Dim worldExtent As RectangleShape = mapViewer.CurrentExtent
        Dim worldPoint As PointShape = ExtentHelper.ToWorldCoordinate(worldExtent, screenX, screenY, screenWidth, screenHeight)

        Dim worldX As Single = worldPoint.X
        Dim worldY As Single = worldPoint.Y

        lblMouseXY.Text = "X: " & worldX & " Y: " & worldY



Hi Nelson,


Try something like this:-


 private void winformsMap1_MouseMove(object sender, MouseEventArgs e) { PointShape worldPoint = ExtentHelper.ToWorldCoordinate(winformsMap1.CurrentExtent, e.X, e.Y, winformsMap1.Width, winformsMap1.Height); }


 


worldPoint.X and worldPoint.Y should have what you are looking for.


Regards


John



Hi Nelson, 
  
 Messages crossed over! 
  
 You need the currentExtent and the Width and Height of the control, or at least that’s what works for me. 
  
 Sorry abourt the C#, did’nt realise you where a VB guy. 
  
 John

No problem, John. I appreciate the help. I can read C# pretty well so no worries. Thanks for verifying the info for me.



Thanks for the sharing, John! 
  
 Nelson, I will suggest the development team to add an search engine on the samples so you can easily find the sample you want. 
  
  Thanks, 
  
 Ben

I needed to do this same thing, and tried to do it w/o reading this post.   I was not successful.   I was thrown by the fact that you call the parameters “screen” coordinates, and “screen” height.   So, that’s what I was using.   However, it turns out that you really are using client coordinates and the size of the map client.   This makes much more sense.   I can understand why you use the terms screen, world, and geographic coordinates, but I wonder if you might want to update the help to make it clear that when you say screen coordinates, that you really mean the control coordinates?

Ted, 
  
   I see how you were led astray.  The terms world and screen  were defined before we had a client control to work with.  We devised them while building the Map Suite Core libraries in the Services Edition.  At that time we didn’t have a control per say  but we knew we had numbers that were measures in pixels and in some kind of geographic unit.  The later unit could be feet, meters etc.  We went back and forth on what to name them as using the term pixel didn’t seem to make the API look very good, you would have things like PixelX, PixelY etc.  After awhile we went with Screen because pixels are on screens and I had heard many things referenced in screen coordinates.  We didn’t mean literally the coordinates of your monitor, but the Cartesian system, in contrast to a coordinate system like world.  World came about because it was Geographic.  That term as well failed our API beauty test like GeographicX, GeographicY.  In the end we picked screen and world because they seemed to be very distinct from each other and high level that we though was approachable to non GIS developers.  I see the problem now that you mention it, I am not sure how we didn’t realize that back in planning. :-) 
  
   One thing we did was to pay careful attention to parameter names and try as much as possible to be consistent and explicit in the naming.  Many developers get lazy and assign parameter names that are the type name.  This is really bad as we could have names it PointShape :-)  We have rules that when you name parameters to try and express the context and function of the parameter.  Intellisense with good parameter names is a huge conduit that we can use to communicate to you of our intention, we and use it. 
  
   The one part that really sucks is that parameter changes are breaking in .NET.  VB.NET has a call by parameter name which causes it to be a breaking change.  This means we more than likely cannot change it even though in hindsight control would be a great work we could have used instead of screen.  I think what we can do is to update the intellisense information, in this way we could clarify what is going on.  I will record this for a future release. 
  
 David

Thanks for this help - this works 
  
     Private Sub gisMAP_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles gisMAP.MouseMove 
  
         Dim worldPoint As PointShape = ExtentHelper.ToWorldCoordinate(gisMAP.CurrentExtent, e.X, e.Y, gisMAP.Width, gisMAP.Height) 
  
         latLBL.Text = Round(worldPoint.Y, 4) 
         lonLBL.Text = Round(worldPoint.X, 4) 
  
     End Sub

Ewan, 
  
 Thanks for letting us now your progress. 
  
 Any more questions just let me know. 
  
 Thanks. 
  
 Yale