简介
在切片地图服务(TMS)中定义的全局地图切片。生成Web上使用的全局切片所需的函数。包含实现坐标转换的类:
- GlobalMercator (基于 EPSG:900913=EPSG:3857)
用户Google Map,Yahoo Maps,Microsoft Maps 兼容切片
- GlobalGeodetic (基于EPSG:4326)
用于 Openlayers底图和Google Earth兼容切片
1、地理坐标下切片系统的计算
地理坐标下切片系统的计算,主要适用于google地球中切片系统,以及目标底图参考系统为EPSG:4326的情况。
Functions necessary for generation of global tiles in Plate Carre projection,
EPSG:4326, "unprojected profile".
Such tiles are compatible with Google Earth (as any other EPSG:4326 rasters)
and you can overlay the tiles on top of OpenLayers base map.
Pixel and tile coordinates are in TMS notation (origin [0,0] in bottom-left).
What coordinate conversions do we need for TMS Global Geodetic tiles?
Global Geodetic tiles are using geodetic coordinates (latitude,longitude)
directly as planar coordinates XY (it is also called Unprojected or Plate
Carre). We need only scaling to pixel pyramid and cutting to tiles.
Pyramid has on top level two tiles, so it is not square but rectangle.
Area [-180,-90,180,90] is scaled to 512x256 pixels.
TMS has coordinate origin (for pixels and tiles) in bottom-left corner.
Rasters are in EPSG:4326 and therefore are compatible with Google Earth.
LatLon <-> Pixels <-> Tiles
WGS84 coordinates Pixels in pyramid Tiles in pyramid
lat/lon XY pixels Z zoom XYZ from TMS
EPSG:4326
.----. ----
/ \ <-> /--------/ <-> TMS
\ / /--------------/
----- /--------------------/
WMS, KML Web Clients, Google Earth TileMapService
public class GlobalGeodetic {
private int tileSize;
private double resFact;
public GlobalGeodetic(String tmscompatible, int tileSize) {
this.tileSize = tileSize;
if (tmscompatible != null && tmscompatible.length() > 0) {
// Defaults the resolution factor to 0.703125 (2 tiles @ level 0)
this.resFact = 180.0D / (double)this.tileSize;
} else {
//Defaults the resolution factor to 1.40625 (1 tile @ level 0)
this.resFact = 360.0D / (double)this.tileSize;
}
}
public double[] lonlatToPixels(double lon, double lat, int zoom) {
double res = this.resFact / Math.pow(2.0D, (double)zoom);
return new double[]{
(180.0D + lon) / res, (90.0D + lat) / res};
}
public int[] pixelsToTile(double px, double py) {
int tx = (int)(Math.ceil(px / (double)this.tileSize) - 1.0D);
int ty = (int)(Math.ceil(py / (double)this.tileSize) - 1.0D);
return new int[]{
tx, ty};
}
public int[] lonlatToTile(double lon, double lat, int zoom) {
double[] pxpy = this.lonlatToPixels(lon, lat, zoom);
return this.pixelsToTile(pxpy[0], pxpy[1]);
}
public double resolution(int zoom) {
return this.resFact / Math.pow(2.0D, (double)zoom);
}
public int zoomForPixelSize(double pixelSize) {
for(int i = 0; i < 32; ++i) {
if (pixelSize > this.resolution(i)) {
if (i != 0) {
return i - 1;
}
return 0;
}
}
return 0;
}
public double[] tileBounds(int tx, int ty, int zoom) {
double res = this.resFact / Math.pow(2.0D, (