No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MercatorProjection.java 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package org.insa.graphics.drawing;
  2. import java.awt.Dimension;
  3. import org.insa.graph.GraphStatistics.BoundingBox;
  4. public class MercatorProjection implements Projection {
  5. public static final double MAX_LATITUDE = 82;
  6. public static final double MIN_LATITUDE = -MAX_LATITUDE;
  7. // From Wikipedia... for the above max/min latitude.
  8. private static final double IMAGE_WIDTH = 2058, IMAGE_HEIGHT = 1746;
  9. private static final double MAX_LATITUDE_PROJ = projectY(MAX_LATITUDE);
  10. private static final double MIN_LATITUDE_PROJ = projectY(MIN_LATITUDE);
  11. // Bounding box
  12. private final float minLatitude, minLongitude, maxLatitude, maxLongitude;
  13. // Projection of min and max latitude.
  14. private final double minLatitudeProj, maxLatitudeProj;
  15. // Dimension of the image
  16. private final double width, height;
  17. /**
  18. * Create a new MercatorProjection corresponding to the given BoundingBox and
  19. * maxSize.
  20. *
  21. * @param boundingBox Box for this projection.
  22. * @param maxSize Maximum size of any side (width / height) of the image to
  23. * which this projection should draw.
  24. */
  25. public MercatorProjection(BoundingBox boundingBox, int maxSize) {
  26. // Find minimum/maximum longitude and latitude.
  27. this.minLongitude = boundingBox.getTopLeftPoint().getLongitude();
  28. this.maxLongitude = boundingBox.getBottomRightPoint().getLongitude();
  29. this.minLatitude = boundingBox.getBottomRightPoint().getLatitude();
  30. this.maxLatitude = boundingBox.getTopLeftPoint().getLatitude();
  31. // Compute projection
  32. this.minLatitudeProj = projectY(this.minLatitude);
  33. this.maxLatitudeProj = projectY(this.maxLatitude);
  34. Dimension imageDimension = computeImageSize(maxSize);
  35. this.width = imageDimension.getWidth();
  36. this.height = imageDimension.getHeight();
  37. }
  38. /**
  39. * Compute the projection (without scaling) of the given latitude.
  40. *
  41. * @param latitude Latitude to project.
  42. *
  43. * @return Projection of the given latitude (without scaling).
  44. */
  45. private static double projectY(double latitude) {
  46. double sinLatitude = Math.sin(latitude * Math.PI / 180.0);
  47. return Math.log((1 + sinLatitude) / (1 - sinLatitude)) / 2;
  48. }
  49. /**
  50. * Compute the dimension required for drawing a projection of the given box on
  51. * an image, ensuring that none of the side of image is greater than maxSize.
  52. *
  53. * @param maxSize Maximum side of any side of the image.
  54. *
  55. * @return Dimension corresponding to the preferred size for the image.
  56. */
  57. protected Dimension computeImageSize(int maxSize) {
  58. double propWidth = (maxLongitude - minLongitude) * IMAGE_WIDTH / 360.0;
  59. double propHeight = (this.maxLatitudeProj - this.minLatitudeProj)
  60. / (MAX_LATITUDE_PROJ - MIN_LATITUDE_PROJ) * IMAGE_HEIGHT;
  61. return propWidth < propHeight
  62. ? new Dimension((int) (maxSize * propWidth / propHeight), maxSize)
  63. : new Dimension(maxSize, (int) (maxSize * propHeight / propWidth));
  64. }
  65. @Override
  66. public double getImageWidth() {
  67. return this.width;
  68. }
  69. @Override
  70. public double getImageHeight() {
  71. return this.height;
  72. }
  73. @Override
  74. public int latitudeToPixelY(float latitude) {
  75. return (int) ((this.maxLatitudeProj - projectY(latitude))
  76. / (this.maxLatitudeProj - this.minLatitudeProj) * this.height);
  77. }
  78. @Override
  79. public int longitudeToPixelX(float longitude) {
  80. return (int) (width * (longitude - minLongitude) / (maxLongitude - minLongitude));
  81. }
  82. @Override
  83. public float pixelYToLatitude(double py) {
  84. float y = (float) (this.maxLatitudeProj
  85. - (py / this.height) * (this.maxLatitudeProj - this.minLatitudeProj));
  86. return (float) (180 * (2 * Math.atan(Math.exp(y)) - Math.PI / 2) / Math.PI);
  87. }
  88. @Override
  89. public float pixelXToLongitude(double px) {
  90. return (float) ((px / this.width) * (this.maxLongitude - this.minLongitude)
  91. + this.minLongitude);
  92. }
  93. }