我遇到了一个问题:我想通过Java应用程序访问openstreetmap。我写了一个JComponent
,它可以显示从openstreetmap下载的图块。问题是在计算下载图片的y位置的公式中(请参见源代码中的FIXME),这是一个错误,我无法找到它。代码的某些部分是从http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames复制的。疯狂的是x-position
是正确的。 goTo()
方法用于确定地图的哪个位置应位于JComponent
-视图的中心!
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 << 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 << 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());
}
}
最佳答案
很高兴得知您能够解决您的问题:)
另请注意,OSM在捐赠资源上运行,并且对人们访问渲染器地图图块的方式有限制:http://wiki.openstreetmap.org/wiki/Tile_usage_policy请注意您的应用程序尊重它,以避免给社区服务器造成压力。