Tile类
public static Collection<Tile> assembleTilesForLevel(Level level, TileFactory tileFactory, Collection<Tile> result) {
if (level == null) {
throw new IllegalArgumentException(
Logger.logMessage(Logger.ERROR, "Tile", "assembleTilesForLevel", "missingLevel"));
}
if (tileFactory == null) {
throw new IllegalArgumentException(
Logger.logMessage(Logger.ERROR, "Tile", "assembleTilesForLevel", "missingTileFactory"));
}
if (result == null) {
throw new IllegalArgumentException(
Logger.logMessage(Logger.ERROR, "Tile", "assembleTilesForLevel", "missingResult"));
}
Sector sector = level.parent.sector;
double tileDelta = level.tileDelta;
int firstRow = Tile.computeRow(tileDelta, sector.minLatitude());
int lastRow = Tile.computeLastRow(tileDelta, sector.maxLatitude());
int firstCol = Tile.computeColumn(tileDelta, sector.minLongitude());
int lastCol = Tile.computeLastColumn(tileDelta, sector.maxLongitude());
double firstRowLat = -90 + firstRow * tileDelta;
double firstRowLon = -180 + firstCol * tileDelta;
double lat = firstRowLat;
double lon;
for (int row = firstRow; row <= lastRow; row++) {
lon = firstRowLon;
for (int col = firstCol; col <= lastCol; col++) {
Sector tileSector = new Sector(lat, lon, tileDelta, tileDelta);
result.add(tileFactory.createTile(tileSector, level, row, col));
lon += tileDelta;
}
lat += tileDelta;
}
return result;
}
从这一方法中不难看出,WorldWindAndroid默认加载切片的模式是从经纬度(-180,-90)为起点开始加载切片,而且,每张切片都是对应经纬差均为tileDelta的正切片,这意味着每一层级的行列比为1:2,而且层级和行列号都是从0开始的!
而一般我们的切片都是从(-180,90)开始的,层级也是从1开始,这就需要在加载的时候进行转换,比如
public Tile createTile(Sector sector, Level level, int row, int column) {
ImageTile tile = new ImageTile(sector, level, row, column);
//String urlString = urlAddress;//this.urlForTile(level.levelNumber, row, column);
int row1 = (int) Math.pow(2, (level.levelNumber + 2)) - 1 - row;//计算行列和级数
int col1 = column;
int level1 = level.levelNumber+3;
String serverURL = urlAddress.replaceFirst("0", String.valueOf((int)(Math.random() * 8)));//由于服务器端采用了集群技术,http://tile0/同http://tile7/取的是同一图片
//瓦片URL串
String urlString = serverURL + "?request=GetTile&service=wmts&version=1.0.0&serviceMode=kvp&layer=img&Style=default&Format=tiles&TileMatrixSet=c&TileMatrix="+level1+"&TileRow="+row1+"&TileCol=" + col1;
if (urlString != null) {
tile.setImageSource(ImageSource.fromUrl(urlString));
}
return tile;
}
我们要从tileDelta为45度对应的层级(4X8),实际是切片服务的第三级,对应Worldwind加载的第0级(4X8),而worldwind加载的切片(row,column)实际上是切片服务的(row1,column)对应的切片!
这种情况下,切片服务是按照经纬差相等的方式进行切片的,所以,切片的规格能够对应上,但是如果切片服务是按照(nXn)的方式进行切片的,也就是切片的经纬差之比为:2:1,这样一来就意味着如果要正确加载就需要将横向的两张切片合为一张,加载的时候只需要加载第一张,同时,切片的宽高比也应设为2:1,还有就是层级和起始切片的转换,这样才能正确加载!
@Override
public Tile createTile(Sector sector, Level level, int row, int column) {
Sector sector1 = new Sector(sector.minLatitude(),sector.minLongitude()*2+180,sector.deltaLatitude(),sector.deltaLongitude()*2);
ImageTile tile = new ImageTile(sector1, level, row, column);
//urlAddress= "http://t0.tianditu.com/DataServer";
//String urlString = urlAddress;//this.urlForTile(level.levelNumber, row, column);
int row1 = (int) Math.pow(2, (level.levelNumber + 2)) - 1 - row;//计算行列和jishu
int col1 = column;
/* if(column%2!=0){
return null;
}else{
col1 = column/2;
}*/
int level1 = level.levelNumber + 2;
String serverURL = urlAddress.replaceFirst("0", String.valueOf((int) (Math.random() * 8)));//由于服务器端采用了集群技术,http://tile0/同http://tile7/取的是同一图片
//瓦片URL串
String urlString = serverURL + "?T=vec_w&x="+col1+"&y="+row1+"&l="+level1;
if (urlString != null) {
tile.setImageSource(ImageSource.fromUrl(urlString));
}
return tile;
}
而事实的关键是Sector这个对象,它是设定切片对应范围的关键,我们直接重新自定义一下Sector,然后再创建ImageTile,这样就能解决上面的非等经纬差切片的问题了!
虽然,第一层级加载成功,但子层级却出现问题,将在后续谈到!