Correctly getting tile data for a location.
The UTFGrid layer's `getTileInfo` method was not correctly handling dateline wrapping (and was a bit more complicated than it needed to be). Since it would be useful to all grid layers to be able to retrieve a tile and pixel offset for any map location, this functionality deserves to be on the Grid layer. The WMTS layer currently exposes a `getTileInfo` method that is used within the layer and by the WMTSGetFeatureInfo control. This method could be renamed to `getRemoteTileInfo` or something to differentiate it from a method that gets locally cached tile info. Until that change is made, the method on the Grid layer will be called `getGridData`.
This commit is contained in:
@@ -6,7 +6,7 @@ var osm = new OpenLayers.Layer.XYZ(
|
|||||||
"http://otile3.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png",
|
"http://otile3.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png",
|
||||||
"http://otile4.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png"
|
"http://otile4.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png"
|
||||||
],
|
],
|
||||||
{transitionEffect: "resize"}
|
{transitionEffect: "resize", wrapDateLine: true}
|
||||||
);
|
);
|
||||||
|
|
||||||
var utfgrid = new OpenLayers.Layer.UTFGrid({
|
var utfgrid = new OpenLayers.Layer.UTFGrid({
|
||||||
|
|||||||
@@ -417,6 +417,64 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: getTileData
|
||||||
|
* Given a map location, retrieve a tile and the pixel offset within that
|
||||||
|
* tile corresponding to the location. If there is not an existing
|
||||||
|
* tile in the grid that covers the given location, null will be
|
||||||
|
* returned.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* loc - {<OpenLayers.LonLat>} map location
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* {Object} Object with the following properties: tile ({<OpenLayers.Tile>}),
|
||||||
|
* i ({Number} x-pixel offset from top left), and j ({Integer} y-pixel
|
||||||
|
* offset from top left).
|
||||||
|
*/
|
||||||
|
getTileData: function(loc) {
|
||||||
|
var data = null,
|
||||||
|
x = loc.lon,
|
||||||
|
y = loc.lat,
|
||||||
|
numRows = this.grid.length;
|
||||||
|
|
||||||
|
if (this.map && numRows) {
|
||||||
|
var res = this.map.getResolution(),
|
||||||
|
tileWidth = this.tileSize.w,
|
||||||
|
tileHeight = this.tileSize.h,
|
||||||
|
bounds = this.grid[0][0].bounds,
|
||||||
|
left = bounds.left,
|
||||||
|
top = bounds.top;
|
||||||
|
|
||||||
|
if (x < left) {
|
||||||
|
// deal with multiple worlds
|
||||||
|
if (this.map.baseLayer.wrapDateLine) {
|
||||||
|
var worldWidth = this.map.getMaxExtent().getWidth();
|
||||||
|
var worldsAway = Math.ceil((left - x) / worldWidth);
|
||||||
|
x += worldWidth * worldsAway;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// tile distance to location (fractional number of tiles);
|
||||||
|
var dtx = (x - left) / (res * tileWidth);
|
||||||
|
var dty = (top - y) / (res * tileHeight);
|
||||||
|
// index of tile in grid
|
||||||
|
var col = Math.floor(dtx);
|
||||||
|
var row = Math.floor(dty);
|
||||||
|
if (row < numRows) {
|
||||||
|
var tile = this.grid[row][col];
|
||||||
|
if (tile) {
|
||||||
|
data = {
|
||||||
|
tile: tile,
|
||||||
|
// pixel index within tile
|
||||||
|
i: Math.floor((dtx - col) * tileWidth),
|
||||||
|
j: Math.floor((dty - row) * tileHeight)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method: queueTileDraw
|
* Method: queueTileDraw
|
||||||
* Adds a tile to the animation queue that will draw it.
|
* Adds a tile to the animation queue that will draw it.
|
||||||
|
|||||||
@@ -131,74 +131,6 @@ OpenLayers.Layer.UTFGrid = OpenLayers.Class(OpenLayers.Layer.XYZ, {
|
|||||||
return obj;
|
return obj;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Method: getTileInfo
|
|
||||||
* Get tile information for a given location at the current map resolution.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* loc - {<OpenLayers.LonLat} A location in map coordinates.
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
* {Object} An object with the following properties
|
|
||||||
*
|
|
||||||
* globalCol: the tile's X
|
|
||||||
*
|
|
||||||
* globalRow: the tile's Y
|
|
||||||
*
|
|
||||||
* gridCol: the viewport grid X
|
|
||||||
*
|
|
||||||
* gridRow: the viewpoirt grid Y
|
|
||||||
*
|
|
||||||
* tile: the associated OpenLayers.Tile.UTFGrid object
|
|
||||||
*
|
|
||||||
* zoom: the tile zoom level
|
|
||||||
*
|
|
||||||
* i: the pixel X position relative to the current tile origin
|
|
||||||
*
|
|
||||||
* j: the pixel Y position relative to the current tile origin
|
|
||||||
*/
|
|
||||||
getTileInfo: function(loc) {
|
|
||||||
var res = this.getServerResolution();
|
|
||||||
|
|
||||||
// Get the global XY for the tile at this zoomlevel
|
|
||||||
var fx = (loc.lon - this.tileOrigin.lon) / (res * this.tileSize.w);
|
|
||||||
var fy = (this.tileOrigin.lat - loc.lat) / (res * this.tileSize.h);
|
|
||||||
var globalCol = Math.floor(fx);
|
|
||||||
var globalRow = Math.floor(fy);
|
|
||||||
|
|
||||||
// Get the current grid offset
|
|
||||||
var gridOrigin = this.grid[0][0].bounds;
|
|
||||||
// Floating point math can cause problems (4.9999 should be 5)
|
|
||||||
// flooring will cause big problems (4.999 becomes 4)...
|
|
||||||
// Do round or toFixed later?
|
|
||||||
var gridColOffset =
|
|
||||||
(gridOrigin.left - this.tileOrigin.lon) / (res * this.tileSize.w);
|
|
||||||
var gridRowOffset =
|
|
||||||
(this.tileOrigin.lat - gridOrigin.top) / (res * this.tileSize.h);
|
|
||||||
|
|
||||||
// Calculate the grid XY for the tile
|
|
||||||
var gridCol = globalCol - Math.round(gridColOffset);
|
|
||||||
var gridRow = globalRow - Math.round(gridRowOffset);
|
|
||||||
|
|
||||||
var resolutions = this.serverResolutions || this.resolutions;
|
|
||||||
var zoom = this.zoomOffset == 0 ?
|
|
||||||
OpenLayers.Util.indexOf(resolutions, res) :
|
|
||||||
this.getServerZoom() + this.zoomOffset;
|
|
||||||
|
|
||||||
var tile = this.grid[gridRow][gridCol];
|
|
||||||
|
|
||||||
return {
|
|
||||||
globalCol: globalCol,
|
|
||||||
globalRow: globalRow,
|
|
||||||
gridCol: gridCol,
|
|
||||||
gridRow: gridRow,
|
|
||||||
tile: tile,
|
|
||||||
zoom: zoom,
|
|
||||||
i: Math.floor((fx - globalCol) * this.tileSize.w),
|
|
||||||
j: Math.floor((fy - globalRow) * this.tileSize.h)
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APIProperty: getFeatureInfo
|
* APIProperty: getFeatureInfo
|
||||||
* Get details about a feature associated with a map location. The object
|
* Get details about a feature associated with a map location. The object
|
||||||
@@ -215,7 +147,7 @@ OpenLayers.Layer.UTFGrid = OpenLayers.Class(OpenLayers.Layer.XYZ, {
|
|||||||
*/
|
*/
|
||||||
getFeatureInfo: function(location) {
|
getFeatureInfo: function(location) {
|
||||||
var info = null;
|
var info = null;
|
||||||
var tileInfo = this.getTileInfo(location);
|
var tileInfo = this.getTileData(location);
|
||||||
if (tileInfo.tile) {
|
if (tileInfo.tile) {
|
||||||
info = tileInfo.tile.getFeatureInfo(tileInfo.i, tileInfo.j);
|
info = tileInfo.tile.getFeatureInfo(tileInfo.i, tileInfo.j);
|
||||||
}
|
}
|
||||||
@@ -235,7 +167,7 @@ OpenLayers.Layer.UTFGrid = OpenLayers.Class(OpenLayers.Layer.XYZ, {
|
|||||||
*/
|
*/
|
||||||
getFeatureId: function(location) {
|
getFeatureId: function(location) {
|
||||||
var id = null;
|
var id = null;
|
||||||
var info = this.getTileInfo(location);
|
var info = this.getTileData(location);
|
||||||
if (info.tile) {
|
if (info.tile) {
|
||||||
id = info.tile.getFeatureId(info.i, info.j);
|
id = info.tile.getFeatureId(info.i, info.j);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user