Merge pull request #3801 from ahocevar/tilevector-extent

Respect the tile grid's extent in ol.source.TileVector
This commit is contained in:
Andreas Hocevar
2015-06-18 10:46:48 +02:00
3 changed files with 93 additions and 7 deletions

View File

@@ -4027,7 +4027,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;
@@ -4090,6 +4091,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),

View File

@@ -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_,

View File

@@ -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');