LatLonFromScreenPosition

Apr 2, 2009 at 11:45 PM
I'm using this control on Surface and ran into an issue.  I would like to know the lat/lon of the touched point on the screen.  Using NavigationManager.LatLonAltFromScreenPosistion() doesn't yield the correct lat/lot - it's just about 1-3 inches (screen position) off and depending on the zoom level of the map, this could be very large.  The screen cordinate I used is relative to the "map" control (see code below) which is this VEMap control.  Is their any margin/padding/offset from the edge of the VEMap control to the actual VE3D drawable area?  I don't see any in your code.  Any idea how to correctly get the lat/lon of the touched position?  Thank you in advance.

Here is the sample code.  Note that "e" is of type ContactEventArgs, "map" is of type InfoStrat.VE.NUI.SurfaceVEMap.  I'm pretty sure it's not related to the rounding from WPF Point (type double for X and Y) to WinForm Point (type int for X and Y).
      Point pointerLoc = e.GetPosition(map);
      NavigationManager navMgr = map.GlobeControl.Host.Navigation;
      LatLonAlt? pos = navMgr.LatLonAltFromScreenPosition(
        new SDR.Point((int)(SM.Round(pointerLoc.X)), (int)(SM.Round(pointerLoc.Y))));

      string routeName = "TestRoute";
      string pointLabel = "Tommy";
      PushpinGeometry point = AddPoint(new SDR.Bitmap(@"C:\PointIcon.png"),
        pointLabel, "Test Point",
        pos.Value.LatitudeDegrees, pos.Value.LongitudeDegrees, 0, routeName);
      map.GlobeControl.Host.Geometry.RemoveGeometry("LayerID", routeName + pointLabel);
      map.GlobeControl.Host.Geometry.AddGeometry(point);

      map.GlobeControl.Host.Navigation.FlyTo(new LatLonAlt(pos.Value.Latitude, pos.Value.Longitude, 5000), -90, 0);

Apr 3, 2009 at 12:20 AM
Nevermind, I figured it out.  For those who ran into the same problem, here is the solution:

 

Point pointerLoc = e.GetPosition(map);
double locX = InfoStrat.VE.VEMap.MapValue(pointerLoc.X, 0, map.ActualWidth, 0, map.GlobeControl.Width);
double locY = InfoStrat.VE.VEMap.MapValue(pointerLoc.Y, 0, map.ActualHeight, 0, map.GlobeControl.Height);
//Use the normalized locX and locY instead of pointerLoc.X and pointerLoc.Y.

 

Coordinator
Apr 3, 2009 at 3:42 AM
Tommy,

Yes you can do that yourself if you like, or you could use these functions from the VEMap class that I provided to do this for you:

public Point? LatLongToPoint(VELatLong latLong);
public VELatLong PointToLatLong(Point? point);

This one is also useful:
public bool IsBehindPlanet(VELatLong latLong);
Apr 3, 2009 at 6:24 AM
Thanks for the quick response joshb.  It's good to know those 3 functions.  BTW, it would be useful to make a similar control for Google Earth called GEMap.  Do you see any potential problem with this effort?
Coordinator
Apr 3, 2009 at 2:32 PM
There are no plans for a Google Earth version.  I haven't looked at the technical feasibility of that either. 
Jun 23, 2009 at 4:13 PM

Hi Josh,

Regarding PointToLatLong, I have the same issue. I do reverseGeoCoding as well as drawing of shapes on the map and, depending on the size and zoom level of the control - have a much too large offset.

I'm working with standard WPF application. Any ideas? Thanks

Jun 23, 2009 at 4:43 PM

For your info, I now used <font size="2" color="#2b91af"><font size="2" color="#2b91af">

LatLonAlt

</font></font><font size="2" color="#2b91af">

 

</font>

? lla = this.GlobeControl.Host.Navigation.PointerPosition.Location;

and that works well.

Coordinator
Jun 23, 2009 at 10:24 PM

Check to see if altitudes are set correctly, if appropriate.