add TileGrid getTileCoordForArbitraryResolution and getTileCoordPixelBoundsForArbitraryResolution + tests, based on @tschaub work

This commit is contained in:
Éric Lemoine
2012-07-19 17:48:39 +02:00
parent 45c067dfda
commit 404d123623
2 changed files with 245 additions and 0 deletions

View File

@@ -4,6 +4,7 @@ goog.require('goog.array');
goog.require('goog.asserts');
goog.require('ol.Coordinate');
goog.require('ol.Extent');
goog.require('ol.PixelBounds');
goog.require('ol.Size');
goog.require('ol.TileBounds');
goog.require('ol.TileCoord');
@@ -156,6 +157,52 @@ ol.TileGrid.prototype.getTileCoord = function(z, coordinate) {
};
/**
* @param {number} z Z.
* @param {number} resolution Resolution.
* @param {goog.math.Coordinate} coordinate Coordinate.
* @return {ol.TileCoord} Tile coordinate.
*/
ol.TileGrid.prototype.getTileCoordForArbitraryResolution = function(
z, resolution, coordinate) {
var resolutionForZ = this.getResolution(z);
var scale = resolution / resolutionForZ;
var origin = this.getOrigin(z);
var offsetFromOrigin = new goog.math.Coordinate(
Math.floor((coordinate.x - origin.x) / resolution),
Math.floor((coordinate.y - origin.y) / resolution));
var tileSize = this.getTileSize();
tileSize = new goog.math.Size(tileSize.width / scale,
tileSize.height / scale);
var x, y;
x = Math.floor(offsetFromOrigin.x / tileSize.width);
y = Math.floor(offsetFromOrigin.y / tileSize.height);
var tileCoord = new ol.TileCoord(z, x, y);
var tileCoordPixelBounds =
this.getTileCoordPixelBoundsForArbitraryResolution(
tileCoord, resolution);
// adjust x to allow for stretched tiles
if (offsetFromOrigin.x < tileCoordPixelBounds.minX) {
tileCoord.x -= 1;
} else if (offsetFromOrigin.x >= tileCoordPixelBounds.maxX) {
tileCoord.x += 1;
}
// adjust y to allow for stretched tiles
if (offsetFromOrigin.y < tileCoordPixelBounds.minY) {
tileCoord.y -= 1;
} else if (offsetFromOrigin.y >= tileCoordPixelBounds.maxY) {
tileCoord.y += 1;
}
return tileCoord;
};
/**
* @param {ol.TileCoord} tileCoord Tile coordinate.
* @return {ol.Coordinate} Tile center.
@@ -203,6 +250,28 @@ ol.TileGrid.prototype.getTileCoordExtent = function(tileCoord) {
};
/**
* @param {ol.TileCoord} tileCoord Tile coordinate.
* @param {number} resolution Resolution.
* @return {ol.PixelBounds} Pixel bounds.
*/
ol.TileGrid.prototype.getTileCoordPixelBoundsForArbitraryResolution = function(
tileCoord, resolution) {
var resolutionForZ = this.getResolution(tileCoord.z);
var scale = resolution / resolutionForZ;
var tileSize = this.getTileSize();
tileSize = new goog.math.Size(tileSize.width / scale,
tileSize.height / scale);
var minX, maxX, minY, maxY;
minX = Math.round(tileCoord.x * tileSize.width);
maxX = Math.round((tileCoord.x + 1) * tileSize.width);
minY = Math.round(tileCoord.y * tileSize.height);
maxY = Math.round((tileCoord.y + 1) * tileSize.height);
return new ol.PixelBounds(minX, minY, maxX, maxY);
};
/**
* @param {ol.TileCoord} tileCoord Tile coordinate.
* @return {number} Tile resolution.

View File

@@ -129,6 +129,181 @@ function testGetTileCoordYSouth() {
}
function testGetTileCoordForArbitraryResolution() {
var tileSize = new ol.Size(256, 256);
var tileGrid = new ol.TileGrid([10], extent, origin, tileSize);
var coordinate;
var tileCoord;
// gets the first tile at the origin
coordinate = new ol.Coordinate(0, 0);
tileCoord = tileGrid.getTileCoordForArbitraryResolution(
0, 10, coordinate);
assertEquals(0, tileCoord.z);
assertEquals(0, tileCoord.x);
assertEquals(0, tileCoord.y);
// gets one tile northwest of the origin
coordinate = new ol.Coordinate(-1280, 1280);
tileCoord = tileGrid.getTileCoordForArbitraryResolution(
0, 10, coordinate);
assertEquals(0, tileCoord.z);
assertEquals(-1, tileCoord.x);
assertEquals(0, tileCoord.y);
// gets one tile northeast of the origin
coordinate = new ol.Coordinate(1280, 1280);
tileCoord = tileGrid.getTileCoordForArbitraryResolution(
0, 10, coordinate);
assertEquals(0, tileCoord.z);
assertEquals(0, tileCoord.x);
assertEquals(0, tileCoord.y);
// gets one tile southeast of the origin
coordinate = new ol.Coordinate(1280, -1280);
tileCoord = tileGrid.getTileCoordForArbitraryResolution(
0, 10, coordinate);
assertEquals(0, tileCoord.z);
assertEquals(0, tileCoord.x);
assertEquals(-1, tileCoord.y);
// gets one tile southwest of the origin
coordinate = new ol.Coordinate(-1280, -1280);
tileCoord = tileGrid.getTileCoordForArbitraryResolution(
0, 10, coordinate);
assertEquals(0, tileCoord.z);
assertEquals(-1, tileCoord.x);
assertEquals(-1, tileCoord.y);
// gets the tile to the east when on the edge
coordinate = new ol.Coordinate(2560, -1280);
tileCoord = tileGrid.getTileCoordForArbitraryResolution(
0, 10, coordinate);
assertEquals(0, tileCoord.z);
assertEquals(1, tileCoord.x);
assertEquals(-1, tileCoord.y);
// gets the tile to the north when on the edge
coordinate = new ol.Coordinate(1280, -2560);
tileCoord = tileGrid.getTileCoordForArbitraryResolution(
0, 10, coordinate);
assertEquals(0, tileCoord.z);
assertEquals(0, tileCoord.x);
assertEquals(-1, tileCoord.y);
// pixels are top aligned to the origin
coordinate = new ol.Coordinate(1280, -2559.999);
tileCoord = tileGrid.getTileCoordForArbitraryResolution(
0, 10, coordinate);
assertEquals(0, tileCoord.z);
assertEquals(0, tileCoord.x);
assertEquals(-1, tileCoord.y);
// pixels are left aligned to the origin
coordinate = new ol.Coordinate(2559.999, -1280);
tileCoord = tileGrid.getTileCoordForArbitraryResolution(
0, 10, coordinate);
assertEquals(0, tileCoord.z);
assertEquals(0, tileCoord.x);
assertEquals(-1, tileCoord.y);
}
function testGetTileCoordForArbitraryResolutionFractional() {
var tileSize = new ol.Size(256, 256);
var tileGrid = new ol.TileGrid([1 / 3], extent, origin, tileSize);
var coordinate;
var tileCoord;
// These tests render at a resolution of 1. Because the layer's
// closest resolution is 1/3, the images are scaled by 1/3.
// In this scenario, every third tile will be one pixel wider when
// rendered (0,0 is normal; 1,0 is wider; 0,1 is taller; etc.)
// gets the first tile at the origin
coordinate = new ol.Coordinate(0, 0);
tileCoord = tileGrid.getTileCoordForArbitraryResolution(
0, 1, coordinate);
assertEquals(0, tileCoord.z);
assertEquals(0, tileCoord.x);
assertEquals(0, tileCoord.y);
// gets the 1,0 tile at 256/3,0
coordinate = new ol.Coordinate(256 / 3, 0);
tileCoord = tileGrid.getTileCoordForArbitraryResolution(
0, 1, coordinate);
assertEquals(0, tileCoord.z);
assertEquals(1, tileCoord.x);
assertEquals(0, tileCoord.y);
// still gets the 1,0 tile at 512/3,0 - wider tile
coordinate = new ol.Coordinate(512 / 3, 0);
tileCoord = tileGrid.getTileCoordForArbitraryResolution(
0, 1, coordinate);
assertEquals(0, tileCoord.z);
assertEquals(1, tileCoord.x);
assertEquals(0, tileCoord.y);
// gets the 2,0 tile at 513/3,0
coordinate = new ol.Coordinate(513 / 3, 0);
tileCoord = tileGrid.getTileCoordForArbitraryResolution(
0, 1, coordinate);
assertEquals(0, tileCoord.z);
assertEquals(2, tileCoord.x);
assertEquals(0, tileCoord.y);
// gets the 3,0 tile at 768/3,0
coordinate = new ol.Coordinate(768 / 3, 0);
tileCoord = tileGrid.getTileCoordForArbitraryResolution(
0, 1, coordinate);
assertEquals(0, tileCoord.z);
assertEquals(3, tileCoord.x);
assertEquals(0, tileCoord.y);
// gets the 4,0 tile at 1024/3,0
coordinate = new ol.Coordinate(1024 / 3, 0);
tileCoord = tileGrid.getTileCoordForArbitraryResolution(
0, 1, coordinate);
assertEquals(0, tileCoord.z);
assertEquals(4, tileCoord.x);
assertEquals(0, tileCoord.y);
// still gets the 4,0 tile at 1280/3,0 - wider tile
coordinate = new ol.Coordinate(1280 / 3, 0);
tileCoord = tileGrid.getTileCoordForArbitraryResolution(
0, 1, coordinate);
assertEquals(0, tileCoord.z);
assertEquals(4, tileCoord.x);
assertEquals(0, tileCoord.y);
// gets the 5,0 tile at 1281/3,0
coordinate = new ol.Coordinate(1281 / 3, 0);
tileCoord = tileGrid.getTileCoordForArbitraryResolution(
0, 1, coordinate);
assertEquals(0, tileCoord.z);
assertEquals(5, tileCoord.x);
assertEquals(0, tileCoord.y);
// gets the 0,1 tile at 0,-256/3
coordinate = new ol.Coordinate(0, -256 / 3);
tileCoord = tileGrid.getTileCoordForArbitraryResolution(
0, 1, coordinate);
assertEquals(0, tileCoord.z);
assertEquals(0, tileCoord.x);
assertEquals(-2, tileCoord.y);
// still gets the 0,1 tile at 0,-512/3 - taller tile
coordinate = new ol.Coordinate(0, -512 / 3);
tileCoord = tileGrid.getTileCoordForArbitraryResolution(
0, 1, coordinate);
assertEquals(0, tileCoord.z);
assertEquals(0, tileCoord.x);
assertEquals(-2, tileCoord.y);
}
function testGetTileCoordCenter() {
@@ -150,6 +325,7 @@ function testGetTileCoordCenter() {
}
function testGetTileCoordExtent() {
var tileGrid = new ol.TileGrid(resolutions, extent, origin, tileSize);