2016-03-24 14 views
1

私はDBに格納されたデータに基づいてマップタイルを生成し、UrlTemplateImageryProviderを使用してセシウムまで提供しようとしています。マップタイルごとに、一致するデータを見つけるために緯度/経度の境界を知る必要があります。 http://host/tiles/zoom/x/yのようなリクエストで、Googleマップと同じタイルスキームを使用しています。当初、これらのマップタイル座標を方程式を使ってここにある緯度/経度の境界に変換しました:http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Tile_bounding_boxしかし、これが正しい投影法でないかどうか疑問に思っています。セシウムマップタイルの緯度/経度の決定

まず、私が見るWeb Mercatorのすべてのドキュメントでは、タイル0,0 @ zoom lvl 0は世界全体をカバーしていると言われています。それは私がセシウムで見るものではありません(ズームレベル0で2つのタイルがあります)。つまり、私の計算は0,1,2,3のズームレベルで動作するようですが、ズームレベル4に行くと、Latitudeの計算が南に移動し始めます。生成された緯度、経度を2次元Googleマップにプロットすると、正確に見えますが、セシウムから要求されたタイルの境界が異なることがわかります。だから私は今、間違った投影法を使ってタイル境界を計算していると仮定しています。

私はここでも計算を試みました:http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/ ピクセルからメートルに緯度/経度に変換しましたが、ウェブのメルケータの計算と同じ結果に見えます。

だから誰でも私はセシウムによって要求されたタイルの緯度/経度の境界ボックスを計算する方法を考え出すことができますか?

public static Box getLatLonBoundsForTile(int zoom, int x, int y) { 
    double longitudeMin = tile2lon(x, zoom); 
    double longitudeMax = tile2lon(x + 1, zoom); 
    double latitudeMin = tile2lat(y + 1, zoom); 
    double latitudeMax = tile2lat(y, zoom); 

    Point swPoint = new Point(longitudeMin, latitudeMin); 
    Point nePoint = new Point(longitudeMax, latitudeMax); 

    return new Box(swPoint, nePoint); 
} 

public static double getColsForZoomLevel(int zoom) { 
    if (zoom == 0) return 2; 
    int noTiles = 8 * (int) (Math.pow(4, zoom - 1)); 
    return noTiles/getRowsForZoomLevel(zoom); 
} 
public static double getRowsForZoomLevel(int zoom) { 
    if (zoom == 0) return 1; 
    return Math.pow(2, zoom); 
} 
public static double tile2lon(int x, int zoom) { 
    return x/getColsForZoomLevel(zoom) * 360.0 - 180; 
} 

public static double tile2lat(int y, int zoom) { 
    double n = Math.PI - (2.0 * Math.PI * y)/getRowsForZoomLevel(zoom); 
    return Math.toDegrees(Math.atan(Math.sinh(n))); 
} 

答えて

1

セシウムがタイル(ラジアン)緯度/経度値を算出し、クラスWebMercatorTilingSchemesource)を含み、構成可能な数を持つ:

ここで私はスリッピー地図タイルに基づいている方法がありますルートレベルのタイル。

3Dレンダリングの場合、通常、タイルは正方形であり、すべてのレベルで、2のべき乗辺の長さ、たとえば256 x 256ピクセルの画像が使用されます。グローブ自体は通常、長方形のテクスチャ(幅360度、高さ180度)で包まれています。これをカバーするために、タイルスキームのレベル0は通常2タイル幅ですが、1タイルタイル(2 x 1)のみです。次のレベルは4 x 2タイル、次に8 x 4,16 x 8などです。

これをリアルタイムで確認するには、Cesium Inspectorをロードし、ページの右側にあるオプションを探します。 +の横にTerrainと入力し、Show tile coordinatesにチェックマークを付けます。座標はレベルの場合はL、タイルスキームの位置の場合はXおよびYで描画されます。

+0

ありがとうございました。私はWebMercatorTilingSchemeで計算を実装する作業をしていましたが、実際にそのタイルスキームを使用していないことがわかりました。セシウムインスペクタも指摘してくれてありがとう。それは便利なツールです! –

0

私は最初に問題を引き起こしていることを発見しました。セシウムはUrlTemplateImageryProviderでGeographicTilingSchemeを使用するように強制していました。

var layer = new Cesium.UrlTemplateImageryProvider({ 
    url : '/map/tile/{z}/{x}/{y}?debug=true', 
    credit : '© Me', 
    tilingScheme : new Cesium.GeographicTilingScheme(), 
    maximumLevel : 11 
}); 

私はdocsの例からコピーした:私の以前の設定は、このようなものでした。ですから、configからtilingSchemeを削除したので、デフォルトでWebMercatorTilingSchemeになります。ここで新しい設定があります:

var layer = new Cesium.UrlTemplateImageryProvider({ 
    url : '/map/tile/{z}/{x}/{y}?debug=true', 
    credit : '© Me', 
    maximumLevel : 11 
}); 

私はこれをしなかったら、私はズームレベル0 @ 2枚のタイルの私の仮定を削除し、1に戻って、それを変更しなければならなかったし、今ではすべてが上記の方法で正常に動作します!私はそうのように、この方法を変更:

public static double getColsForZoomLevel(int zoom) { 
    return getRowsForZoomLevel(zoom); 
} 

だから、すべては最初のシンプルなものをご確認の年齢古いのレッスンに降りてきました。