Skip to content

Commit 72c784b

Browse files
authored
fix TileLayer with dynamic offset (#1352)
* fix TileLayer with dynamic offset, close #1350, close #1278 * fix import * fix tiles with pitch * fix specs * remove IE9 tests
1 parent fbc510f commit 72c784b

File tree

7 files changed

+104
-107
lines changed

7 files changed

+104
-107
lines changed

appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ environment:
66
- MAPTALKS_BROWSERS: IE
77
# second group
88
# - MAPTALKS_BROWSERS: IE10
9-
- MAPTALKS_BROWSERS: IE9
9+
# - MAPTALKS_BROWSERS: IE9
1010
# Install scripts. (runs after repo cloning)
1111
install:
1212
# Get the latest stable version of Node.js or io.js

src/layer/tile/TileLayer.js

Lines changed: 64 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,15 @@ class TileLayer extends Layer {
166166
* @return {Size}
167167
*/
168168
getTileSize() {
169+
if (this._tileSize) {
170+
return this._tileSize;
171+
}
169172
let size = this.options['tileSize'];
170173
if (isNumber(size)) {
171174
size = [size, size];
172175
}
173-
return new Size(size);
176+
this._tileSize = new Size(size);
177+
return this._tileSize;
174178
}
175179

176180
/**
@@ -430,7 +434,7 @@ class TileLayer extends Layer {
430434
return result;
431435
});
432436
// const innerExtent2D = this._getInnerExtent(z, containerExtent, extent2d)._add(offset);
433-
extent2d._add(offset);
437+
// extent2d._add(offset);
434438

435439
const maskExtent = this._getMask2DExtent();
436440
if (maskExtent) {
@@ -442,20 +446,21 @@ class TileLayer extends Layer {
442446
}
443447
//Get description of center tile including left and top offset
444448
const prjCenter = map._containerPointToPrj(containerExtent.getCenter(), TEMP_POINT0);
445-
const centerPoint = map._prjToPoint(prjCenter, undefined, TEMP_POINT1);
449+
const centerPoint = map._prjToPoint(prjCenter, zoom, TEMP_POINT1);
446450
let c;
447451
if (hasOffset) {
448-
c = this._project(map._pointToPrj(centerPoint._add(offset), undefined, TEMP_POINT1), TEMP_POINT1);
452+
c = this._project(map._pointToPrj(centerPoint._add(offset), zoom, TEMP_POINT1), TEMP_POINT1);
449453
} else {
450454
c = this._project(prjCenter, TEMP_POINT1);
451455
}
452456

453-
TEMP_POINT2.x = extent2d.xmin;
454-
TEMP_POINT2.y = extent2d.ymax;
455-
TEMP_POINT3.x = extent2d.xmax;
456-
TEMP_POINT3.y = extent2d.ymin;
457-
const pmin = this._project(map._pointToPrj(TEMP_POINT2, undefined, TEMP_POINT2), TEMP_POINT2);
458-
const pmax = this._project(map._pointToPrj(TEMP_POINT3, undefined, TEMP_POINT3), TEMP_POINT3);
457+
const extentScale = map.getGLScale() / map.getGLScale(zoom);
458+
TEMP_POINT2.x = extent2d.xmin * extentScale;
459+
TEMP_POINT2.y = extent2d.ymax * extentScale;
460+
TEMP_POINT3.x = extent2d.xmax * extentScale;
461+
TEMP_POINT3.y = extent2d.ymin * extentScale;
462+
const pmin = this._project(map._pointToPrj(TEMP_POINT2._add(offset), zoom, TEMP_POINT2), TEMP_POINT2);
463+
const pmax = this._project(map._pointToPrj(TEMP_POINT3._add(offset), zoom, TEMP_POINT3), TEMP_POINT3);
459464

460465
const centerTile = tileConfig.getTileIndex(c, res, repeatWorld);
461466
const ltTile = tileConfig.getTileIndex(pmin, res, repeatWorld);
@@ -471,6 +476,7 @@ class TileLayer extends Layer {
471476
const renderer = this.getRenderer() || parentRenderer,
472477
scale = this._getTileConfig().tileSystem.scale;
473478
const tiles = [], extent = new PointExtent();
479+
const tilePoint = new Point(0, 0);
474480
for (let i = -top; i <= bottom; i++) {
475481
let j = -left;
476482
let leftVisitEnd = -Infinity;
@@ -496,8 +502,9 @@ class TileLayer extends Layer {
496502

497503
let p;
498504
if (tileInfo) {
499-
const { point } = tileInfo;
500-
p = point;
505+
const { extent2d } = tileInfo;
506+
tilePoint.set(extent2d.xmin, extent2d.ymax);
507+
p = tilePoint;
501508
} else if (!this._hasOwnSR) {
502509
p = tileConfig.getTilePointNW(idx.x, idx.y, res);
503510
// const pnw = tileConfig.getTilePrjNW(idx.x, idx.y, res);
@@ -530,35 +537,35 @@ class TileLayer extends Layer {
530537

531538

532539
const tileExtent = tileInfo && tileInfo.extent2d || new PointExtent(p.x, p.y - height, p.x + width, p.y);
533-
if (hasOffset) {
534-
tileExtent.set(p.x, p.y - height, p.x + width, p.y);
535-
tileExtent._sub(offset);
536-
}
537-
if (allCount <= 4 || rightVisitEnd || this._isTileInExtent(frustumMatrix, tileExtent, glScale)) {
540+
// if (hasOffset) {
541+
// tileExtent.set(p.x, p.y - height, p.x + width, p.y);
542+
// }
543+
if (allCount <= 4 || rightVisitEnd || this._isTileInExtent(frustumMatrix, tileExtent, offset, glScale)) {
538544
if (this._visitedTiles && cascadeLevel === 0) {
539545
this._visitedTiles.add(tileId);
540546
}
541547
if (cascadeLevel === 0) {
542-
tileExtent._add(offset);
543-
this._splitTiles(frustumMatrix, tiles, renderer, idx, z + 1, tileExtent, dx, dy, tileOffsets);
544-
tileExtent._sub(offset);
548+
this._splitTiles(frustumMatrix, tiles, renderer, idx, z + 1, tileExtent, dx, dy, tileOffsets, parentRenderer);
545549
extent._combine(tileExtent);
546550
} else {
547551
if (!tileInfo) {
548552
tileInfo = {
549553
//reserve point caculated by tileConfig
550554
//so add offset because we have p._sub(offset) and p._add(dx, dy) if hasOffset
551-
'point': p,
552555
'z': z,
553556
'x': idx.x,
554557
'y': idx.y,
555-
'extent2d' : tileExtent,
556-
'mask': cascadeLevel,
557-
'size': [width, height],
558+
'extent2d': tileExtent,
559+
'offset': offset,
558560
'id': tileId,
559-
'layer': this.getId(),
560-
'url': this.getTileUrl(idx.x, idx.y, zoom)
561+
'url': this.getTileUrl(idx.x, idx.y, z)
561562
};
563+
if (parentRenderer) {
564+
tileInfo['layer'] = this.getId();
565+
}
566+
} else {
567+
tileInfo.offset[0] = offset[0];
568+
tileInfo.offset[1] = offset[1];
562569
}
563570
tiles.push(tileInfo);
564571
extent._combine(tileExtent);
@@ -579,19 +586,23 @@ class TileLayer extends Layer {
579586
if (tiles.length) {
580587
//sort tiles according to tile's distance to center
581588
const center = map._containerPointToPoint(containerExtent.getCenter(), z, TEMP_POINT)._add(offset);
589+
const point0 = new Point(0, 0);
590+
const point1 = new Point(0, 0);
582591
tiles.sort(function (a, b) {
583-
return a.point.distanceTo(center) - b.point.distanceTo(center);
592+
point0.set((a.extent2d.xmin + a.extent2d.xmax) / 2, (a.extent2d.ymin + a.extent2d.ymax) / 2);
593+
point1.set((b.extent2d.xmin + b.extent2d.xmax) / 2, (b.extent2d.ymin + b.extent2d.ymax) / 2);
594+
return point0.distanceTo(center) - point1.distanceTo(center);
584595
});
585596
}
586597
return {
587-
'offset' : offset,
598+
'offset': offset,
588599
'zoom' : tileZoom,
589-
'extent' : extent,
600+
'extent': extent,
590601
'tiles': tiles
591602
};
592603
}
593604

594-
_splitTiles(frustumMatrix, tiles, renderer, tileIdx, z, tileExtent, dx, dy, tileOffsets) {
605+
_splitTiles(frustumMatrix, tiles, renderer, tileIdx, z, tileExtent, dx, dy, tileOffsets, parentRenderer) {
595606
// const hasOffset = offset[0] || offset[1];
596607
const yOrder = this._getTileConfig().tileSystem.scale.y;
597608
const glScale = this.getMap().getGLScale(z);
@@ -604,17 +615,17 @@ class TileLayer extends Layer {
604615
const x = tileIdx.x * 2;
605616
const y = tileIdx.y * 2;
606617

607-
let tile = this._checkAndAddTile(frustumMatrix, renderer, idx, idy, x, y, z, 0, 0, w, h, corner, glScale, tileOffsets);
618+
let tile = this._checkAndAddTile(frustumMatrix, renderer, idx, idy, x, y, z, 0, 0, w, h, corner, glScale, tileOffsets, parentRenderer);
608619
if (tile) tiles.push(tile);
609-
tile = this._checkAndAddTile(frustumMatrix, renderer, idx, idy, x, y, z, 0, 1, w, h, corner, glScale, tileOffsets);
620+
tile = this._checkAndAddTile(frustumMatrix, renderer, idx, idy, x, y, z, 0, 1, w, h, corner, glScale, tileOffsets, parentRenderer);
610621
if (tile) tiles.push(tile);
611-
tile = this._checkAndAddTile(frustumMatrix, renderer, idx, idy, x, y, z, 1, 0, w, h, corner, glScale, tileOffsets);
622+
tile = this._checkAndAddTile(frustumMatrix, renderer, idx, idy, x, y, z, 1, 0, w, h, corner, glScale, tileOffsets, parentRenderer);
612623
if (tile) tiles.push(tile);
613-
tile = this._checkAndAddTile(frustumMatrix, renderer, idx, idy, x, y, z, 1, 1, w, h, corner, glScale, tileOffsets);
624+
tile = this._checkAndAddTile(frustumMatrix, renderer, idx, idy, x, y, z, 1, 1, w, h, corner, glScale, tileOffsets, parentRenderer);
614625
if (tile) tiles.push(tile);
615626
}
616627

617-
_checkAndAddTile(frustumMatrix, renderer, idx, idy, x, y, z, i, j, w, h, corner, glScale, tileOffsets) {
628+
_checkAndAddTile(frustumMatrix, renderer, idx, idy, x, y, z, i, j, w, h, corner, glScale, tileOffsets, parentRenderer) {
618629
const tileId = this._getTileId(idx + i, idy + j, z);
619630
if (this._visitedTiles && this._visitedTiles.has(tileId)) {
620631
return null;
@@ -625,27 +636,26 @@ class TileLayer extends Layer {
625636
}
626637
const yOrder = this._getTileConfig().tileSystem.scale.y;
627638
const childExtent = new PointExtent(corner.x + i * w, corner.y + yOrder * j * h, corner.x + (i + 1) * w, corner.y + yOrder * (j + 1) * h);
628-
childExtent._sub(offset);
629639
if (/*!rightVisitEnd && */
630-
!this._isSplittedTileInExtent(frustumMatrix, childExtent, glScale)) {
640+
!this._isSplittedTileInExtent(frustumMatrix, childExtent, offset, glScale)) {
631641
return null;
632642
}
633-
childExtent._add(offset);
634643
let tileInfo = renderer && renderer.isTileCachedOrLoading(tileId);
635644
if (!tileInfo) {
636645
//reserve point caculated by tileConfig
637646
//so add offset because we have p._sub(offset) and p._add(dx, dy) if hasOffset
638647
tileInfo = {
639-
'point': new Point(childExtent.xmin, childExtent.ymax),
640648
'z': z,
641-
'x' : x + i,
642-
'y' : y + j,
649+
'x': x + i,
650+
'y': y + j,
643651
'extent2d' : childExtent,
644-
'size': [w, h],
645652
'id': tileId,
646-
'layer': this.getId(),
653+
'offset': offset,
647654
'url': this.getTileUrl(x + i, y + j, z + this.options['zoomOffset'])
648655
};
656+
if (parentRenderer) {
657+
tileInfo['layer'] = this.getId();
658+
}
649659
} else {
650660
tileInfo = tileInfo.info;
651661
}
@@ -735,12 +745,12 @@ class TileLayer extends Layer {
735745
return super._bindMap.apply(this, arguments);
736746
}
737747

738-
_isTileInExtent(frustumMatrix, tileExtent, glScale) {
748+
_isTileInExtent(frustumMatrix, tileExtent, offset, glScale) {
739749
const map = this.getMap();
740750

741751
let matrix;
742752
if (frustumMatrix !== map.projViewMatrix) {
743-
const tileCenter = tileExtent.getCenter(TEMP_POINT6)._multi(glScale);
753+
const tileCenter = tileExtent.getCenter(TEMP_POINT6)._sub(offset[0], offset[1])._multi(glScale);
744754
vec3.set(ARR3, tileCenter.x, tileCenter.y, 0);
745755
const ndc = vec3.transformMat4(ARR3, ARR3, map.projViewMatrix);
746756
//地图中心下方的瓦片与 map.projViewMatrix 比较
@@ -750,19 +760,19 @@ class TileLayer extends Layer {
750760
matrix = map.projViewMatrix;
751761
}
752762

753-
TILE_BOX[0][0] = tileExtent.xmin * glScale;
754-
TILE_BOX[0][1] = tileExtent.ymin * glScale;
755-
TILE_BOX[1][0] = tileExtent.xmax * glScale;
756-
TILE_BOX[1][1] = tileExtent.ymax * glScale;
763+
TILE_BOX[0][0] = (tileExtent.xmin - offset[0]) * glScale;
764+
TILE_BOX[0][1] = (tileExtent.ymin - offset[1]) * glScale;
765+
TILE_BOX[1][0] = (tileExtent.xmax - offset[0]) * glScale;
766+
TILE_BOX[1][1] = (tileExtent.ymax - offset[1]) * glScale;
757767
return intersectsBox(matrix, TILE_BOX);
758768
}
759769

760-
_isSplittedTileInExtent(frustumMatrix, tileExtent, glScale) {
770+
_isSplittedTileInExtent(frustumMatrix, tileExtent, offset, glScale) {
761771
const map = this.getMap();
762-
TILE_BOX[0][0] = tileExtent.xmin * glScale;
763-
TILE_BOX[0][1] = tileExtent.ymin * glScale;
764-
TILE_BOX[1][0] = tileExtent.xmax * glScale;
765-
TILE_BOX[1][1] = tileExtent.ymax * glScale;
772+
TILE_BOX[0][0] = (tileExtent.xmin - offset[0]) * glScale;
773+
TILE_BOX[0][1] = (tileExtent.ymin - offset[1]) * glScale;
774+
TILE_BOX[1][0] = (tileExtent.xmax - offset[0]) * glScale;
775+
TILE_BOX[1][1] = (tileExtent.ymax - offset[1]) * glScale;
766776
return intersectsBox(map.projViewMatrix, TILE_BOX);
767777
}
768778

src/renderer/layer/tilelayer/CanvasTileLayerRenderer.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Canvas2D from '../../../core/Canvas';
33
import TileLayerCanvasRenderer from './TileLayerCanvasRenderer';
44
import TileLayerGLRenderer from './TileLayerGLRenderer';
55
import Extent from '../../../geo/Extent';
6+
import Point from '../../../geo/Point';
67

78
function loadTile(tile) {
89
const tileSize = this.layer.getTileSize(),
@@ -12,11 +13,12 @@ function loadTile(tile) {
1213
const tileCanvas = Canvas2D.createCanvas(tileSize['width'] * r, tileSize['height'] * r, canvasClass);
1314
tileCanvas['layer'] = this.layer;
1415
const me = this;
15-
const extent = new Extent(map.pointToCoordinate(tile['point']), map.pointToCoordinate(tile['point'].add(tileSize.toPoint())), map.getProjection());
16+
const point = new Point(tile['extent2d'].xmin, tile['extent2d'].ymax);
17+
const extent = new Extent(map.pointToCoordinate(point), map.pointToCoordinate(point.add(tileSize.width, tileSize.height)), map.getProjection());
1618
this.layer.drawTile(tileCanvas, {
1719
'url': tile['url'],
18-
'point': tile['point'],
19-
'center' : map.pointToCoordinate(tile['point'].add(tileSize['width'] / 2, tileSize['height'] / 2)),
20+
'point': point,
21+
'center' : map.pointToCoordinate(point.add(tileSize['width'] / 2, tileSize['height'] / 2)),
2022
'extent' : extent,
2123
'z': tile['z'],
2224
'x' : tile['x'],

0 commit comments

Comments
 (0)