Respect the tile grid's extent
By adding a getTileCoordForTileUrlFuction method like for ol.source.Tile, we can now properly handle extent and resolution restrictions, and reuse tiles on wrapped worlds. Also adds the missing wrapX option to ol.source.TileVector.
This commit is contained in:
@@ -4045,7 +4045,8 @@ olx.source.TileImageOptions.prototype.wrapX;
|
||||
* tileGrid: ol.tilegrid.TileGrid,
|
||||
* tileUrlFunction: (ol.TileUrlFunctionType|undefined),
|
||||
* url: (string|undefined),
|
||||
* urls: (Array.<string>|undefined)}}
|
||||
* urls: (Array.<string>|undefined),
|
||||
* wrapX: (boolean|undefined)}}
|
||||
* @api
|
||||
*/
|
||||
olx.source.TileVectorOptions;
|
||||
@@ -4108,6 +4109,16 @@ olx.source.TileVectorOptions.prototype.url;
|
||||
olx.source.TileVectorOptions.prototype.urls;
|
||||
|
||||
|
||||
/**
|
||||
* Wrap the world horizontally. Default is `true`. For vector editing across the
|
||||
* -180° and 180° meridians to work properly, this should be set to `false`. The
|
||||
* resulting geometry coordinates will then exceed the world bounds.
|
||||
* @type {boolean|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.source.TileVectorOptions.prototype.wrapX;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{url: (string|undefined),
|
||||
* displayDpi: (number|undefined),
|
||||
|
||||
@@ -7,6 +7,7 @@ goog.require('ol.TileUrlFunction');
|
||||
goog.require('ol.featureloader');
|
||||
goog.require('ol.source.State');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.tilecoord');
|
||||
goog.require('ol.tilegrid.TileGrid');
|
||||
|
||||
|
||||
@@ -27,7 +28,8 @@ ol.source.TileVector = function(options) {
|
||||
attributions: options.attributions,
|
||||
logo: options.logo,
|
||||
projection: undefined,
|
||||
state: ol.source.State.READY
|
||||
state: ol.source.State.READY,
|
||||
wrapX: options.wrapX
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -230,6 +232,28 @@ ol.source.TileVector.prototype.getFeaturesAtCoordinateAndResolution =
|
||||
ol.source.TileVector.prototype.getFeaturesInExtent = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Handles x-axis wrapping and returns a tile coordinate transformed from the
|
||||
* internal tile scheme to the tile grid's tile scheme. When the tile coordinate
|
||||
* is outside the resolution and extent range of the tile grid, `null` will be
|
||||
* returned.
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @return {ol.TileCoord} Tile coordinate to be passed to the tileUrlFunction or
|
||||
* null if no tile URL should be created for the passed `tileCoord`.
|
||||
*/
|
||||
ol.source.TileVector.prototype.getTileCoordForTileUrlFunction =
|
||||
function(tileCoord, projection) {
|
||||
var tileGrid = this.tileGrid_;
|
||||
goog.asserts.assert(!goog.isNull(tileGrid), 'tile grid needed');
|
||||
if (this.getWrapX()) {
|
||||
tileCoord = ol.tilecoord.wrapX(tileCoord, tileGrid, projection);
|
||||
}
|
||||
return ol.tilecoord.withinExtentAndZ(tileCoord, tileGrid) ?
|
||||
tileGrid.transformTileCoord(tileCoord) : null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} z Z.
|
||||
* @param {number} x X.
|
||||
@@ -267,11 +291,12 @@ ol.source.TileVector.prototype.loadFeatures =
|
||||
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||
var tileKey = this.getTileKeyZXY_(z, x, y);
|
||||
if (!(tileKey in tiles)) {
|
||||
tileCoord[0] = z;
|
||||
tileCoord[1] = x;
|
||||
tileCoord[2] = y;
|
||||
tileGrid.transformTileCoord(tileCoord, tileCoord);
|
||||
var url = tileUrlFunction(tileCoord, 1, projection);
|
||||
var urlTileCoord = this.getTileCoordForTileUrlFunction(
|
||||
tileCoord, projection);
|
||||
var url = goog.isNull(urlTileCoord) ? undefined :
|
||||
tileUrlFunction(urlTileCoord, 1, projection);
|
||||
if (goog.isDef(url)) {
|
||||
tiles[tileKey] = [];
|
||||
var loader = ol.featureloader.loadFeaturesXhr(url, this.format_,
|
||||
|
||||
@@ -9,7 +9,6 @@ describe('ol.source.TileVector', function() {
|
||||
var tileCoords = [];
|
||||
var source = new ol.source.TileVector({
|
||||
format: new ol.format.TopoJSON(),
|
||||
projection: 'EPSG:3857',
|
||||
tileGrid: ol.tilegrid.createXYZ({
|
||||
maxZoom: 19
|
||||
}),
|
||||
@@ -18,8 +17,9 @@ describe('ol.source.TileVector', function() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
var projection = ol.proj.get('EPSG:3857');
|
||||
source.loadFeatures(
|
||||
[-8238854, 4969777, -8237854, 4970777], 4.8, source.getProjection());
|
||||
[-8238854, 4969777, -8237854, 4970777], 4.8, projection);
|
||||
expect(tileCoords[0]).to.eql([15, 9647, 12320]);
|
||||
expect(tileCoords[1]).to.eql([15, 9647, 12319]);
|
||||
expect(tileCoords[2]).to.eql([15, 9648, 12320]);
|
||||
@@ -28,8 +28,58 @@ describe('ol.source.TileVector', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('#getTileCoordForTileUrlFunction()', function() {
|
||||
|
||||
it('returns the expected tile coordinate - {wrapX: true}', function() {
|
||||
var tileSource = new ol.source.TileVector({
|
||||
format: new ol.format.TopoJSON(),
|
||||
tileGrid: ol.tilegrid.createXYZ({
|
||||
maxZoom: 19
|
||||
}),
|
||||
wrapX: true
|
||||
});
|
||||
var projection = ol.proj.get('EPSG:3857');
|
||||
|
||||
var tileCoord = tileSource.getTileCoordForTileUrlFunction(
|
||||
[6, -31, 41], projection);
|
||||
expect(tileCoord).to.eql([6, 33, 22]);
|
||||
|
||||
tileCoord = tileSource.getTileCoordForTileUrlFunction(
|
||||
[6, 33, 41], projection);
|
||||
expect(tileCoord).to.eql([6, 33, 22]);
|
||||
|
||||
tileCoord = tileSource.getTileCoordForTileUrlFunction(
|
||||
[6, 97, 41], projection);
|
||||
expect(tileCoord).to.eql([6, 33, 22]);
|
||||
});
|
||||
|
||||
it('returns the expected tile coordinate - {wrapX: false}', function() {
|
||||
var tileSource = new ol.source.TileVector({
|
||||
format: new ol.format.TopoJSON(),
|
||||
tileGrid: ol.tilegrid.createXYZ({
|
||||
maxZoom: 19
|
||||
}),
|
||||
wrapX: false
|
||||
});
|
||||
var projection = ol.proj.get('EPSG:3857');
|
||||
|
||||
var tileCoord = tileSource.getTileCoordForTileUrlFunction(
|
||||
[6, -31, 41], projection);
|
||||
expect(tileCoord).to.eql(null);
|
||||
|
||||
tileCoord = tileSource.getTileCoordForTileUrlFunction(
|
||||
[6, 33, 41], projection);
|
||||
expect(tileCoord).to.eql([6, 33, 22]);
|
||||
|
||||
tileCoord = tileSource.getTileCoordForTileUrlFunction(
|
||||
[6, 97, 41], projection);
|
||||
expect(tileCoord).to.eql(null);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
goog.require('ol.format.TopoJSON');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.TileVector');
|
||||
|
||||
Reference in New Issue
Block a user