Search code examples
javagpsgoogle-earth

Conversion of Latitude/Longitude into image coordinates (Pixel coordinates) on a simple cylindrical projection


I have taken a image from Google earth, whose latitude/longitude of all the 4 corners are known. I am capturing latitude/longitudes using a GPS sensor. I have to convert these captured latitude/longitudes to image coordinates(pixel coordinates) using java. I will use the image coordinates to simulate as if a vehicle is moving on a static map( image taken from Google Earth).

I found this formula and tried to implement it

  1. Determine the left-most longitude in your 1653x1012 image (X)
  2. Determine the east-most longitude in your 1653x1012 image (Y)
  3. Determine Longitude-Diff (Z = Y - X)
  4. Determine north-most latitude in your 1653x1012 image (A)
  5. Determine south-most latitude in your 1653x1012 image (B)
  6. Determine Latitude-Diff (C = A - B) Given a Latitude and Longitude, to determine which pixel they clicked on:

J = Input Longitude K = Input Latitude

Calculate X-pixel

XPixel = CInt(((Y - J) / CDbl(Z)) * 1653)

Calculate Y-pixel

YPixel = CInt(((A - K) / CDbl(C)) * 1012)

This is the code I used.

    import java.awt.geom.Point2D;
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileReader;
    import java.util.ArrayList;
    import java.util.List;

    public class LatLongService {
        private static LatLongService latLangService;
        private BufferedReader reader = null;
        private String st;

        private LatLongService() {
            try {
                reader = new BufferedReader(new FileReader(new File(
                        "resources/GPS_lat_long_2.txt")));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        public static LatLongService getInstance() {
            if (latLangService == null)
                latLangService = new LatLongService();
            return latLangService;
        }

        public List<Point2D> readLatLongList() {
            List<Point2D> pointList = new ArrayList<Point2D>();
            StringBuffer xStr;
            StringBuffer yStr = new StringBuffer();
            try {
                while ((st = reader.readLine()) != null) {
                    xStr = new StringBuffer(st.substring(0, st.indexOf(',')));
                    yStr = new StringBuffer(st.substring(st.indexOf(',') + 2,
                            st.length()));
                    Point2D pt = new Point2D.Double(
                            new Double(xStr.toString()).doubleValue(), new Double(
                                    yStr.toString()).doubleValue());
                    pointList.add(pt);
                }
            } catch (Exception e) {
                e.printStackTrace();
                try {
                    reader.close();
                } catch (Exception e2) {
                    e.printStackTrace();
                }
            }
            return pointList;
        }


    public List<Point2D> convertLatLongToCoord(List<Point2D> coordinate) {
            List<Point2D> latLong = new ArrayList<Point2D>();
            double westMostLong = -79.974642;
            double eastMostLong = -79.971244;
            double longDiff = eastMostLong - westMostLong; // (rightmost_longitude -
                                                            // leftmost_longitude)

            double northMostLat = 39.647556;
            double southMostLat = 39.644675;
            double latDiff = northMostLat - southMostLat; // (topmost_latitude -
                                                            // bottommost_latitude)
            for (Point2D coord : coordinate) {
                double j = coord.getY();
                double k = coord.getX();

                double XPixel = (((eastMostLong - j) / longDiff) * 1653);
                double YPixel = (((northMostLat - k) / latDiff) * 1012);

                Point2D actualCoord = new Point2D.Double(XPixel, YPixel);
                latLong.add(actualCoord);
            }
            return latLong;
        }
    }

Some of the GPS lat/long I got from GPS sensors

Input Latitude Input Longitude (39.64581, -79.97168) (39.64651, -79.97275) (39.646915, -79.97342) (39.646538, -79.97279)

[IMG]http://i59.tinypic.com/nbqkk3.png[/IMG]

The red line in the picture shows the path followed when GPS coordinates were taken by sensor.

However, when I am using this formula to convert the Lat/Long coordinates to pixel coordinates. The pixel coordinates after conversion are not consistent, as you can see the output below:

Image X Image Y (212.0977045, 613.3120444) (732.6127134, 367.4251996) (1058.542672, 225.1620965) (752.0712184, 357.5897258)

The variation in the X,Y (pixel) coordinates are too much. So when I try to move a vehicle based on the pixel coordinates, the vehicle does not follow the red line or atleast near to that.

The vehicle moves either above the red line or below the line, but not on the line.

For smooth movement of the vehicle based on pixel coordinates, ideally I expect the conversion from lat/long to image coordinates to be something like this:

Required Image X Required Image Y (1290, 409) (1289, 409) (1288, 409) (1287, 409)

But I am getting this

Image X Image Y (212.0977045, 613.3120444) (732.6127134, 367.4251996) (1058.542672, 225.1620965) (752.0712184, 357.5897258)

I hope I am able to convey my problem.


Solution

  • Here is a code that compiles and answers your question as

    [1] (39.64581,-79.97168) -> 102,363
    [2] (39.64651,-79.97275) -> 354,217
    [3] (39.646915,-79.97342) -> 512,133
    [4] (39.646538,-79.97279) -> 363,212
    [5] (39.646458,-79.97264) -> 328,228
    

    You might have interchanged the x-y coordinates. In this case, x == longitude, y == latitude.

    import java.util.*;
    import java.awt.geom.*;
    
    public class LatLong {
    
            private  int  imageW,  imageH;
            private final static   double   west = -79.974642,      north = 39.647556,
                                            east = -79.971244,      south = 39.644675;
    
            public LatLong (int w, int h) {
                    imageW = w;
                    imageH = h;
            }
    
            public List<Point2D> convertLatLongToCoord (List<Point2D> coordinate) {
                List<Point2D> latLong = new ArrayList<Point2D>();
                for (Point2D coord : coordinate) {
                    double  x = coord.getY(),       px = imageW * (x-east) / (west-east),
                            y = coord.getX(),       py = imageH * (y-north)/(south-north);
                    latLong.add (new Point2D.Double(px,py));
                }
                return latLong;
            }
    
            public static void main (String[] args) {
                    double[] latit = {39.64581, 39.64651, 39.646915, 39.646538, 39.646458},
                            longit = {-79.97168, -79.97275, -79.97342, -79.97279, -79.97264};
    
                    List<Point2D> pointList = new ArrayList<Point2D>();
                    for (int i = 0 ; i < latit.length ; i++)
                            pointList.add (new Point2D.Double(latit[i], longit[i]));
    
                    List<Point2D> pixels = new LatLong (800,600).convertLatLongToCoord (pointList);
    
                    for (int i = 0 ; i < latit.length ; i++)
                            System.out.println ("[" + (i+1) + "]\t(" + latit[i] + "," + longit[i] + ") -> " +
                                    (int) (pixels.get(i).getX()) + "," + (int) (pixels.get(i).getY()));
    }}