Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Converting X, Y to Lat, Long

Posted on 2009-04-02
15
Medium Priority
?
1,799 Views
Last Modified: 2013-12-27
Hi All,

I am creating a golf scorer for a windows mobile 5 device and used some of the posts from the following thread to use for the conversion of x,y to lat and long co ordinates:

http://www.experts-exchange.com/Programming/Languages/Visual_Basic/Q_24135663.html?sfQueryTermInfo=1+10+convert+lat+lon+x+y

The piece of code in particular which i am trying to get working for my cropped image is :
Dim XDim As Integer, yDim As Integer, delX As Decimal, _
        tlLon As Double, brLon As Double, delY As Decimal, _
        tlLat As Double, brLat As Double
        Dim myLattitude As Double, myLon As Double
 
        XDim = 640
        yDim = 425
 
        tlLon = -95.97630500793457
        brLon = -95.921287536621108
 
        tlLat = 36.060964648518294
        brLat = 36.031470597983571
 
        delX = (tlLon - (brLon)) / XDim
       
        txtLon.Text = delX
 
        delY = (tlLat - brLat) / yDim
       
        txtLat.Text = delY
        Dim y As Integer = 212
        myLattitude = tlLat - y * delY
        Dim X As Integer = 132
        myLon = tlLon + X * delX
        txt1.Text = myLattitude
        txt2.Text = myLon

For the life of me, I cannot seem to get it working for any of the course layouts (which are all cropped images)

i will post what my version of the code looks like and as you will find, the lat long co ordinates are not miles off but very wide off the mark in terms of accuracy. If anyone can have a look through the coding and find where i am going wrong i would be eternally grateful!!

the picturebox is a 210x806 dimensioned control

the bitmap has been cropped and 'straightened' but the lat and long of the two corners are for the final image so to speak.

the x and y valye of 58 and 95 respectively is the location of the Green and when i get the co-ordinates from the calculations, its quite a way off.

i will be giving the full 500 points for this as i have spent along time trying to look into this and try to recalculate it but to no avail.

thanks in advance

Baz
Dim XDim As Integer, yDim As Integer, delX As Decimal, _
        tlLon As Double, brLon As Double, delY As Decimal, _
        tlLat As Double, brLat As Double
        Dim myLattitude As Double, myLon As Double
 
        XDim = 640
        yDim = 425
 
        tlLon = -1.136182
        brLon = -1.133490
 
        tlLat = 52.668572
        brLat = 52.666803
 
        delX = (tlLon - (brLon)) / XDim
       
        txtLon.Text = delX
 
        delY = (tlLat - brLat) / yDim
        
 
        txtLat.Text = delY
        Dim y As Integer = 95
        myLattitude = tlLat - y * delY
        Dim X As Integer = 58
        myLon = tlLon - X * delX
        txt1.Text = myLattitude
        txt2.Text = myLon

Open in new window

0
Comment
Question by:baz86
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 4
15 Comments
 

Author Comment

by:baz86
ID: 24054841
Correction to code snippet above:
xDim= 210
yDim = 806
0
 

Author Comment

by:baz86
ID: 24055359
The Lat and Long co-ordinates i should be getting are 52.668575lat and -1.135770long
0
 

Author Comment

by:baz86
ID: 24059318
The formula works fine for the first hole:
Xdim=210,
Ydim=908,
TLLong = -1.133241666
TLLat  = 52.6674027
BRLong = -1.134216666
BRLat = 52.6703861
 
But as soon as i enter he details from the database for the second hole (and anyh hole thereafter, the co-ordinates are wrong).
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:baz86
ID: 24067024
Can anyone please help?
0
 
LVL 15

Expert Comment

by:oobayly
ID: 24089790
When you say you want to convert x, y to Lat, Lon, you need to chose what projection to use, as mapping from spherical coordinates to planar coordinates isn't as simple as the code you have provided. Basically you're not taking into account the the distance between meridians changes you move away form the equator.

The simplest project to use would be Sinusoidal, which is an equal area projection.
http://en.wikipedia.org/wiki/Sinusoidal_projection
As you're dealing with only a small area, you wouldn't see the kind of deformation you see in the wiki images.

I'll dig out some code I wrote a while ago for generating aviation charts that should do proper mapping for you.
0
 

Author Comment

by:baz86
ID: 24162002
oobayly thanks for your reply and apologies for my delayed one!
would you be able to advice how i can alter my code so that i can rotate it and still having the co-ordinates be correct?
0
 
LVL 15

Expert Comment

by:oobayly
ID: 24163372
I may have been a bit hasty saying that you needed a non-linear transform. You're dealing with such small areas that it shouldn't be an issue using the linear transform you're using.

Where is the x, y origin, Top-left corner (like a System.Drawing.Graphics object), or Bottom-left?
From your code, I assume it in the bottom-left corner.

For the coordinates you gave in the question, there's no way that area can fit in an image 210x806 as the aspect ratios are completely different.

For the 2nd set of coordinates and the image shape of 210x908 the aspect ratios are similar.

I'm using Google Earth to get get an idea of what you're looking at, so your images will be slightly different.

Can you upload a sample image, saying what the lat/lon position of a certain point on the image is.
0
 

Author Comment

by:baz86
ID: 24163452
the origin for the picturebox is top left corner at (0,0)
and the picturebox resizes to the dimensions of the bitmap automatically one the form is loaded......
what i found is that when the image is rotated then the formula doesnt give the correct co-ordinates..ie Pic1
but when the image is not rotated and North is true north, the formula gives the corrrect co-ordinates. ie Pic2
the problem i have with this(Pic2) is that im creating an application for a windows mobile device and having Pic1 would only cause me to have a vertical scrollbar on the panel which i can live with, but Pic2 would have the inconvenience of vertical and horzontal....

Untitled-4-copy.bmp
test1unmoved.bmp
0
 

Author Comment

by:baz86
ID: 24163463
apologies for the enlarged pictures!!! didn't realise them to be so large
0
 

Author Comment

by:baz86
ID: 24163603
an example of this:

for Pic1...point(107,87) on a 210X860 bitmap is the bright white bunker near the green...this results in the lat long of (52.6686080837,-1.1348202380) which places the mark 60 yards to the right.
for Pic 2...point (84,98) on a 413X678 is the bright white bunker right near the green....this results in the lat long of (52.6685142094,-1.1354876101) which is correct.
 
 
0
 
LVL 15

Accepted Solution

by:
oobayly earned 2000 total points
ID: 24169675
Ah, that'd be your problem. Your transforming, rotating & scaling your image coordinates to geoditic coordinates. That'll always be tricky.

First, you need to be able to determine through what angle the image has been rotated. This is relatively easy as you're dealing with a small area, so you can use the Rhumb bearing between points.

The easiest way to do all this is to use the System.Draw.Drawing2D.Matrix. You tell it what transforms to do, and then just feed it an array of points to transform.

For all this to work, you need to pick 2 distinct points on the image, ideally top-left & bottom-right as the further they are apart the better. ie.for the example below I've picked:
Lat, Lon: (x, y)
52.668572, -1.136182: (0, 0)
52.666803, -1.13349: (88, 666)

Then use the code below to create a Transformation matrix. I've also uploaded the image I've based the bounds on
public static void Test() {
  Matrix imgToGeo = Transform(
    new PointF(-1.136182f, 52.668572f),
    new PointF(-1.13349f, 52.666803f),
    new Point(0, 0),
    new Point(88, 666)
    );
  Matrix geoToImg = imgToGeo.Clone();
  geoToImg.Invert();
 
  // Create a set of points inside the image
  PointF[] pOrig = new PointF[] { 
    new PointF(0, 0),
    new PointF(68, 79) ,
    new PointF(88, 666) 
  };
 
  // Transform the image points to geoditic
  PointF[] pGeo = (PointF[])pOrig.Clone();
  imgToGeo.TransformPoints(pGeo);
 
  // Transform the geoditic points back to image points
  PointF[] pImage = (PointF[])pGeo.Clone();
  geoToImg.TransformPoints(pImage);
}
 
private static void Rhumb(PointF p1, PointF p2, out double distance, out double heading) {
  // Average Radius of the earth in metres
  double R = 6371000;
 
  // Natively use radians
  p1.X = (float)(p1.X * Math.PI / 180);
  p1.Y = (float)(p1.Y * Math.PI / 180);
  p2.X = (float)(p2.X * Math.PI / 180);
  p2.Y = (float)(p2.Y * Math.PI / 180);
 
  /* Phi = Latitude
   * Lambda = Longitude
   */
  double dPhi = (p2.Y - p1.Y);
  double dLambda = (p2.X - p1.X);
 
  double dX = dLambda;
  double dY = Math.Log(
    Math.Tan((Math.PI / 4) + ((double)p2.Y / 2))
    / Math.Tan((Math.PI / 4) + ((double)p1.Y / 2))
    );
 
  double q;
  if (p1.Y == p2.Y) {
    q = Math.Cos(p1.Y);
  } else {
    q = dPhi / dY;
  }
 
  // Distance between points in metres
  distance = Math.Sqrt(
    Math.Pow(dPhi, 2) + Math.Pow(q * dLambda, 2)
    ) * R;
 
  // Heading from p1 -> p2 in degrees
  heading = ((Math.Atan2(dX, dY) * 180 / Math.PI) + 360) % 360;
}
 
private static Matrix Transform(PointF geoTL, PointF geoBR, Point imgTL, Point imgBR ) {
  /* Calculate the angle that image has been rotated
   * Can use Rhumb bearing between 2 geoditic points as the scale
   * is small.
   * Using rhumb bearing will cause inacuracies over larger scales
   */
  float rotate;
  {
    // Rhumb bearing
    double d, thetaRhumb;
    Rhumb(geoTL, geoBR, out d, out thetaRhumb);
 
    // Angle from Top-left -> bottom-right on the image
    double thetaImage = (Math.Atan2(imgBR.X - imgTL.X, imgBR.Y - imgTL.Y) * 180 / Math.PI);
 
    rotate = (float)(180 - thetaImage - thetaRhumb);
  }
 
  /* Create Transformation matrix
   * 1). Translate image point to origin
   * 2). Rotate the the point about the origin
   *     Negative, as we're rotating back
   */
  Matrix m = new Matrix();
  m.Translate(-imgTL.X, -imgTL.Y);
  m.Rotate(-rotate, MatrixOrder.Append);
 
  /* Calcualate the scale
   * 1). Get the transformed & rotated value for Point2
   * 2). Use this new point to determine the X & Y axis scales
   */
  float sX, sY;
  {
    PointF[] pTemp = new PointF[] { new PointF(imgBR.X, imgBR.Y) };
    m.TransformPoints(pTemp);
    sX = (float)((geoBR.X - geoTL.X) / pTemp[0].X);
    sY = (float)((geoBR.Y - geoTL.Y) / pTemp[0].Y);
  }
 
  /* Final part of the transformation matrix
   * 1). Set the X & Y scaling
   * 2). Translate transformed point back to geoditic coordinate
   */
  m.Scale(sX, sY, MatrixOrder.Append);
  m.Translate(geoTL.X, geoTL.Y, MatrixOrder.Append);
 
  return m;
}

Open in new window

Foo.jpg
0
 
LVL 15

Expert Comment

by:oobayly
ID: 24241559
Was my code any help?
0

Featured Post

What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

You should read OS supplied guidelines before developing. I can't stress that enough. The guidelines will help you understand the reasons mobile app developers do what they do.  Apple is very particular when they review appstore submissions.
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
This tutorial demonstrates how to identify and create boundary or building outlines in Google Maps. In this example, I outline the boundaries of an enclosed skatepark within a community park.  Login to your Google Account, then  Google for "Google M…
This tutorial walks through the best practices in adding a local business to Google Maps including how to properly search for duplicates, marker placement, and inputing business details. Login to your Google Account, then search for "Google Mapmaker…
Suggested Courses

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question