2016-03-24 11 views
1

Я пытаюсь создать плитки на основе данных, хранящихся в БД, и обслуживать их до цезия с помощью UrlTemplateImageryProvider. Для каждой плитки карты мне нужно знать границы lat/long, чтобы найти соответствующие данные. Я использую ту же схему, что и Google Maps, с запросом, например http://host/tiles/zoom/x/y. Вначале я использовал уравнения для преобразования этих координат карты в лат/длинные границы, найденные здесь: http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Tile_bounding_box, но теперь мне интересно, не является ли это неправильной проекцией для использования.Определение лат/длинных границ для плиток карты цезия

Для начала, вся документация Web Mercator, которую я вижу, гласит, что плитка 0,0 @ zoom lvl 0 должна охватывать весь мир. Это не то, что я вижу с цезием (есть 2 плитки на уровне масштабирования 0). Тем не менее, мои расчеты, похоже, работают для уровней масштабирования 0, 1, 2 и 3, но по мере того как я иду на уровень увеличения 4, расчет Локатора начинает двигаться на юг. Если я рисую свои сгенерированные латы, длинные точки на 2D-карте Google, они выглядят правильными, но я ясно вижу, что плитки, запрошенные цезием, имеют разные границы. Поэтому я теперь предполагаю, что я использую неправильную проекцию для вычисления границ плитки.

Я также пробовал вычисления здесь: http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/ конвертирования из пикселей в метры, до lat/long, но они, похоже, совпадают с вычислениями веб-меркатора.

Может ли кто-нибудь помочь мне разобраться, как рассчитать шкалу ширины/длины для плиток, запрошенных цезием?

Вот методы, я на основе скользкий тайлов:

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

Цезий включает класс WebMercatorTilingScheme (source), который вычисляет Lat значения/Lon (в радианах) для плитки, с настраиваемым числом плитки на корневом уровне.

Для 3D-рендеринга, как правило, плитки являются квадратными, с длиной края длины 2, например 256 х 256-пиксельных изображений, на всех уровнях. Сам глобус обычно обернут прямоугольной текстурой (360 градусов в ширину, на 180 градусов). Чтобы покрыть это, Уровень 0 схемы разбиения обычно имеет две плитки шириной, но только одну плиту высотой (2 х 1). Следующий уровень - 4 x 2 плитки, затем 8 x 4, 16 x 8 и т. Д.

Чтобы увидеть это в действии в реальном времени, загрузите Cesium Inspector, найдите некоторые параметры в правой части страницы, нажмите немного + рядом с Terrain, а затем поставьте галочку на Show tile coordinates. Координаты рисуются с L для уровня и X и Y для размещения в схеме черепицы.

+0

Спасибо за информацию. Я работал над выполнением вычислений в WebMercatorTilingScheme, когда обнаружил, что я вообще не использовал эту схему черепицы! Спасибо за указание инспектора цезия. Это удобный инструмент! –

0

Я только что обнаружил, что я был причиной проблемы в первую очередь. Я заставлял Цезию использовать GeographicTilingScheme в UrlTemplateImageryProvider. Мой предыдущий конфиг было так:

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

Что я скопировал из примера в docs. Итак, теперь, когда я удалил tilingScheme из конфигурации, по умолчанию используется WebMercatorTilingScheme. Вот новая конфигурация:

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

После того, как я сделал это, я должен был удалить мое предположение 2 плитки @ уровня масштабирования 0 и изменить его обратно на 1 и теперь все отлично работает с вышеперечисленными методами!Я только что изменил этот метод следующим образом:

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

Таким образом, все это сводилось к вековому уроку проверки простых вещей первым.

 Смежные вопросы

  • Нет связанных вопросов^_^