0

I have a list of latitude/longitude pairs in degrees (think turning points in directions) and I want to draw them as lines in a 2D JPanel within limits of the path (not the whole world). Latitude values are +/-90.0 and longitude values are +/-180.0. I don't know how to convert the lat,lon coordinates to an x,y pixel coordinates based on the width and height of a JPanel and scale to the max/min lat/lon.

I found this answer, but it is expecting to map all lat/lon into a given width/height panel. So, if I have a list of lat/lon coordinates that cover around 100 miles, the conversion results in all points being equal pixel coordinates because of the scale. Following the referenced answer, I'd like to know if it is possible to scale the very small values to something that would draw a visible path, and if so, how?

I found other approaches, but they all break when a path transitions over +/-180 or +/-90 (i.e. equator). I really feel like the first answer will work taking care of the edge cases, but only if I can figure out how to scale the results (maybe something like use Path2D.createTransformedShape()?). I'm happy to provide some code of what I've tried, but I think what I'm asking is a higher level yes/no if the approach would work.

Some sample code, after a suggestion from @Mike.

Code from comment.

abstract class Mercator {
    final static double RADIUS_MAJOR = 6378137.0;
    final static double RADIUS_MINOR = 6356752.3142;

    abstract double yAxisProjection(double input);
    abstract double xAxisProjection(double input);
}

public class SphericalMercator extends Mercator {

    @Override
    double xAxisProjection(double input) {
        return Math.toRadians(input) * RADIUS_MAJOR;
    }

    @Override
    double yAxisProjection(double input) {
        return Math.log(Math.tan(Math.PI / 4 + Math.toRadians(input) / 2)) * RADIUS_MAJOR;
    }
}

Driver creating a Path2D with points in CCS with bounds (-20037508.34, -34619289.37, 20037508.34, 34619289.37).

public class ConvertLatLonToXY {
  public ConvertLatLonToXY() {
  }

  public static void main(String[] args) {
    List<Double> tLatitudes = new ArrayList<>();
    List<Double> tLongitudes = new ArrayList<>();

    // zigzag over equator - Indonesia
    tLatitudes.add(-0.531011); tLongitudes.add(110.811661);
    tLatitudes.add(0.838810); tLongitudes.add(112.176126);
    tLatitudes.add(-0.535924); tLongitudes.add(113.541832);
    tLatitudes.add(0.824974); tLongitudes.add(115.319110);

    Path2D tPath = new Path2D.Double();

    Iterator<Double> tLatIter = tLatitudes.iterator();
    Iterator<Double> tLonIter = tLongitudes.iterator();

    while (tLatIter.hasNext() && tLonIter.hasNext()) {
      SphericalMercator tMercator = new SphericalMercator();
      double tX = tMercator.xAxisProjection(aLon);
      double tY = tMercator.yAxisProjection(aLat);

      System.out.println("(x,y) "+tX+", "+tY);

      if (null == aPath.getCurrentPoint()) {
        tPath.moveTo(tX, tY);
      } else {
        tPath.lineTo(tX, tY);
      }
    }
  }
}

So the results are:

(x,y) 1.2335497676476853E7, -58717.0086085379
(x,y) 1.2487389225482095E7, 92754.16604443597
(x,y) 1.2639418921975415E7, -59260.28388925838
(x,y) 1.2837264603933502E7, 91224.09692837084

How does one go about changing these values to something that can be visualized in say a 320x240 JPanel?

  • I did a quick google and found https://www.baeldung.com/java-convert-latitude-longitude as third result - it sounds like that's exactly what you're looking for? – Mike 'Pomax' Kamermans Apr 28 '22 at 17:09
  • Thanks, I saw that, but it doesn't provide a means to define the "bounding box". It mentions - "This projection will map points into a bounding box of (-20037508.34, -34619289.37, 20037508.34, 34619289.37).", I think this would work, but again I still need to figure out if I can scale the X,Y to a smaller bounding box. – Absent Link Apr 28 '22 at 17:19

0 Answers0