1. 程式人生 > >4.01WorldWindAndroid載入切片解析

4.01WorldWindAndroid載入切片解析

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,這樣就能解決上面的非等經緯差切片的問題了!

雖然,第一層級載入成功,但子層級卻出現問題,將在後續談到!