title: Openstreetmap Viewer: coordinate-transformation error
body: <p>I'm struggling with a problem: I want to access openstreetmap via my Java application. I wrote a <code>JComponent</code> which is able to show tiles downloaded from openstreetmap. The problem is that in the formula which calculates the y-position (see FIXME in the sourcecode) of the downloaded picture it is an error and I'm not able to find it. Some parts of the code are copied from <a href="http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames" rel="nofollow">http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames</a>. The crazy thing is that the <code>x-position</code> is correct. The <code>goTo()</code> method is used to determine which place of the map should be in the center of the <code>JComponent</code>-View!</p>
  
  <pre><code>package ui;
  
  import java.awt.Graphics;
  import java.awt.Image;
  
  import javax.swing.JComponent;
  
  public class OSMViewer extends JComponent {
  
      private static final long serialVersionUID = 1L;
      protected ImageHandler imagehandler = null;
      protected int zoomlevel = 0;
      protected double center_deg_lon = 0.0;
      protected double center_deg_lat = 0.0;
      final double DEGY = 85.0511;
      final double DEGX = 180.0;
  
      public OSMViewer(ImageHandler imagehandler) {
          this.imagehandler = imagehandler;
          // TODO
          goTo(13, 30.0, 30.0);
      }
  
      public void goTo(final int zoom, final double lon, final double lat) {
          zoomlevel = zoom;
          center_deg_lon = lon;
          center_deg_lat = lat;
          repaint();
      }
  
      // deg
      public int getTileNumberX(final int zoom, final double lon) {
          int xtile = (int) Math.floor((lon + 180) / 360 * (1 &lt;&lt; zoom));
          return xtile;
      }
  
      // deg
      public int getTileNumberY(final int zoom, final double lat) {
          int ytile = (int) Math
                  .floor((1 - Math.log(Math.tan(Math.toRadians(lat)) + 1
                          / Math.cos(Math.toRadians(lat)))
                          / Math.PI)
                          / 2 * (1 &lt;&lt; zoom));
          return ytile;
      }
  
      // deg
      public double getLonDegPx(final int zoom) {
          double deg_px = 2 * DEGX / (Math.pow(2, zoom) * 256);
          return deg_px;
      }
  
      // deg
      public double getLatDegPx(final int zoom) {
          double deg_px = 2 * DEGY / (Math.pow(2, zoom) * 256);
          return deg_px;
      }
  
      // deg
      public int getPxX(final int zoom, final double lon) {
          return (int) (((lon + DEGX) / (2 * DEGX)) * Math.pow(2, zoom) * 256);
      }
  
      // deg
      public int getPxY(final int zoom, final double lat) {
          return (int) (((DEGY - lat) / (2.0 * DEGY)) * Math.pow(2.0, zoom) * 256.0);
      }
  
      public void paintComponent(Graphics g) {
          int x = getTileNumberX(zoomlevel, center_deg_lon);
          int y = getTileNumberY(zoomlevel, center_deg_lat);
          String str = ("" + zoomlevel + "/" + x + "/" + y);
          System.out.println(str);
          int xpos = (x * 256) - getPxX(zoomlevel, center_deg_lon)
                  + (getWidth() / 2);
          // FIXME
          int ypos = (y * 256) - getPxY(zoomlevel, center_deg_lat)
                  + (getHeight() / 2);
          Image image = imagehandler.getImage(str);
          if (image != null) {
              g.drawImage(image, xpos, ypos, this);
          }
          g.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2);
          g.drawLine(getWidth() / 2, 0, getWidth() / 2, getHeight());
      }
  }
  </code></pre>