From 20b2958c10e4c057b69775650eb66f4b9c7be5c9 Mon Sep 17 00:00:00 2001 From: Anand Thakker Date: Thu, 6 Apr 2017 10:18:48 -0400 Subject: [PATCH] Fix bug calculating image source tile coordinates Closes #4550 Using `Math.round` on the `centerCoord` value here causes a coordinate like `{zoom: 2, column: 1.5, row: 1.5}` to become `{zoom: 2, column: 2, row: 2}`, which is out of bounds for a z2 tile; the correct tile for containing those coordinates is `{zoom: 2, column: 1, row: 1}` --- src/source/image_source.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/source/image_source.js b/src/source/image_source.js index c48740ed973..6946595d3bc 100644 --- a/src/source/image_source.js +++ b/src/source/image_source.js @@ -106,16 +106,28 @@ class ImageSource extends Evented { // may be outside the tile, because raster tiles aren't clipped when rendering. const map = this.map; + + // transform the geo coordinates into (zoom 0) tile space coordinates const cornerZ0Coords = coordinates.map((coord) => { return map.transform.locationCoordinate(LngLat.convert(coord)).zoomTo(0); }); + // Compute the coordinates of the tile we'll use to hold this image's + // render data const centerCoord = this.centerCoord = util.getCoordinatesCenter(cornerZ0Coords); - centerCoord.column = Math.round(centerCoord.column); - centerCoord.row = Math.round(centerCoord.row); + // `column` and `row` may be fractional; round them down so that they + // represent integer tile coordinates + centerCoord.column = Math.floor(centerCoord.column); + centerCoord.row = Math.floor(centerCoord.row); + this.coord = new TileCoord(centerCoord.zoom, centerCoord.column, centerCoord.row); + // Constrain min/max zoom to our tile's zoom level in order to force + // SourceCache to request this tile (no matter what the map's zoom + // level) this.minzoom = this.maxzoom = centerCoord.zoom; - this.coord = new TileCoord(centerCoord.zoom, centerCoord.column, centerCoord.row); + + // Transform the corner coordinates into the coordinate space of our + // tile. this._tileCoords = cornerZ0Coords.map((coord) => { const zoomedCoord = coord.zoomTo(centerCoord.zoom); return new Point(