1

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.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Nemesis
  • 13
  • 1
  • 5
  • Do you have your java source code and a couple examples of the algorithm being off? – James Kingsbery Jul 21 '14 at 21:08
  • What do you mean with "it jumps"? Do you need to use an animation framework? Or do you think that the coordinates are totally wrong? And you are sure that the input coordinate sof the vehile is not jumping (which is the case when the coordinate was measured by GPS and the vehicle or person is standing still) – AlexWien Jul 24 '14 at 17:24
  • I have edited my question, hope that helps. – Nemesis Jul 24 '14 at 18:50
  • You should first try using a picture from Google Maps, the sat picture is not well suitable, it is not a shot from above, sometimes in such sat pics there are digital "folding lines" visible. So test it with a nice flat birds eye map. – AlexWien Jul 24 '14 at 22:01
  • I checked with Google map, the vehicle is still not following the red line. I think the conversion from lat/long to pixel coordinates has some problem. The difference in the successive lat/long is very small. The value changes in thousandth and ten thousandth place. However, after conversion to image coordinates, the change in value is quite high. – Nemesis Jul 25 '14 at 20:01
  • you could try http://trimaps.com ? – Gilbou Nov 14 '14 at 15:43

2 Answers2

1

Latitude and Longitude are not distances.

http://geography.about.com/cs/latitudelongitude/a/latlong.htm

I recently worked on a Arduino Project which was using GPS. I followed minigeo API approach that was converting latitude and longitude into northing and easting(UTM).

Using the library in the link you can do this convertion: http://www.ibm.com/developerworks/library/j-coordconvert/

Than get maximum easting and northing and calculate the scale

private synchronized void scale() {
        int w = 800;
        int h = 600;

        this.scale = Math.min(
                w / (maxEasting - minEasting),
                h / (maxNorthing - minNorthing));

        oEasting = minEasting;
        oNorthing = minNorthing;
    }

Than converting to X and Y

private int applyScale(double km) {
        return (int) (km * scale);
    }

    private int convertX(double easting) {
        return applyScale(easting - oEasting);
    }

    private int convertY(double northing, int height) {
        return 600/*height*/ - applyScale(northing - oNorthing);
    }

Source:Minigeo

  • I am using a static image which is captured from Google earth(GE uses simple cylindrical projection). Why do I need to convert to UTM coordinates again ? Can you explain ? – Nemesis Jul 23 '14 at 20:55
  • See the best answer, it is really good in explaining that: http://stackoverflow.com/questions/14329691/covert-latitude-longitude-point-to-a-pixels-x-y-on-mercator-projection?rq=1 – Vinicius Nogueira Sep 06 '14 at 11:22
0

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()));
}}
Manidip Sengupta
  • 3,573
  • 5
  • 25
  • 27
  • If we plot all the latitude/longitude coordinates in Google earth, it will nearly form a straight line. However, when we convert this lat/long using the above formula to pixel coordinates, these are all over the place. The increment/decrements in the pixel coordinates should be sequential, which is absent presently. – Nemesis Jul 23 '14 at 21:01
  • That formula assumes the boundaries of the rectangle formed by the latitudes and longitudes to be a rectangle. For such small sections, I don't think geodesic transformations are relevant. – Manidip Sengupta Jul 23 '14 at 21:28
  • I think that the transformations may be relevant, as I have tried different formulas to convert. But I am not getting the image coordinates, which I require. – Nemesis Jul 24 '14 at 18:53
  • Did you try the code above? It is just a rehash of your alto, and also produces the numbers above. - M. – Manidip Sengupta Jul 25 '14 at 00:50
  • I tried your code. The map width & height for my code is 1653 X 1012. The problem is after conversion the successive pixel coordinates have a hugh difference. While the successive lat/long coordinates difference is very small. – Nemesis Jul 25 '14 at 20:11
  • why you put new LatLong (800,600) , I didn't understand 800 and 600 are what ? I think his image is 1653x1012 – amani92 Jan 26 '17 at 09:39