From 87ce763ccbf7e4af46cf7221dddc42f524232836 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Mon, 14 Jan 2013 16:10:55 +0100 Subject: [PATCH] Use validity extent to generate default resolutions Previously, the TiledWMS source generated a resolutions array derived from the world extent in meters, to match the default Web Mercator resolutions of the map. This wouldn't work for projections with distance units different than meters. It is better to commit to a default resolutions array where zoom level 0 is the validity extent of the projection (not the Web Mercator world extent!) at a 256 pixel tile size. --- examples/wms-custom-proj.js | 4 ++-- src/ol/source/tiledwmssource.js | 16 ++-------------- src/ol/tilegrid/tilegrid.js | 23 +++++++++++++++++++++++ src/ol/view2d.js | 13 ++++++++++--- 4 files changed, 37 insertions(+), 19 deletions(-) diff --git a/examples/wms-custom-proj.js b/examples/wms-custom-proj.js index 2ab93080fe..759660043e 100644 --- a/examples/wms-custom-proj.js +++ b/examples/wms-custom-proj.js @@ -51,14 +51,14 @@ var layers = new ol.Collection([ ]); var map = new ol.Map({ - projection: epsg21781, // By setting userProjection to the same as projection, we do not need // proj4js because we do not need any transforms. userProjection: epsg21781, layers: layers, target: 'map', view: new ol.View2D({ + projection: epsg21781, center: new ol.Coordinate(660000, 190000), - zoom: 9 + zoom: 2 }) }); diff --git a/src/ol/source/tiledwmssource.js b/src/ol/source/tiledwmssource.js index e6d61e520d..40b0c699ff 100644 --- a/src/ol/source/tiledwmssource.js +++ b/src/ol/source/tiledwmssource.js @@ -35,20 +35,8 @@ ol.source.TiledWMS = function(tiledWMSOptions) { if (goog.isDef(tiledWMSOptions.tileGrid)) { tileGrid = tiledWMSOptions.tileGrid; } else { - // FIXME Factor this out to a more central/generic place. - var size = Math.max( - projectionExtent.maxX - projectionExtent.minX, - projectionExtent.maxY - projectionExtent.minY); - var maxZoom = goog.isDef(tiledWMSOptions.maxZoom) ? - tiledWMSOptions.maxZoom : 18; - var resolutions = new Array(maxZoom + 1); - for (var z = 0, zz = resolutions.length; z < zz; ++z) { - resolutions[z] = ol.Projection.EPSG_3857_HALF_SIZE / (128 << z); - } - tileGrid = new ol.tilegrid.TileGrid({ - origin: projectionExtent.getTopLeft(), - resolutions: resolutions - }); + tileGrid = ol.tilegrid.createForProjection(projection, + tiledWMSOptions.maxZoom); } var baseParams = { diff --git a/src/ol/tilegrid/tilegrid.js b/src/ol/tilegrid/tilegrid.js index bdce78ae2d..8c0f0a1e5d 100644 --- a/src/ol/tilegrid/tilegrid.js +++ b/src/ol/tilegrid/tilegrid.js @@ -316,3 +316,26 @@ ol.tilegrid.TileGrid.prototype.getTileSize = function() { ol.tilegrid.TileGrid.prototype.getZForResolution = function(resolution) { return ol.array.linearFindNearest(this.resolutions_, resolution); }; + + +/** + * @param {ol.Projection} projection Projection. + * @param {number=} opt_maxZoom Maximum zoom level (optional). Default is 18. + * @return {ol.tilegrid.TileGrid} TileGrid instance. + */ +ol.tilegrid.createForProjection = function(projection, opt_maxZoom) { + var projectionExtent = projection.getExtent(); + var size = Math.max( + projectionExtent.maxX - projectionExtent.minX, + projectionExtent.maxY - projectionExtent.minY); + var maxZoom = goog.isDef(opt_maxZoom) ? + opt_maxZoom : 18; + var resolutions = new Array(maxZoom + 1); + for (var z = 0, zz = resolutions.length; z < zz; ++z) { + resolutions[z] = size / (256 << z); + } + return new ol.tilegrid.TileGrid({ + origin: projectionExtent.getTopLeft(), + resolutions: resolutions + }); +}; diff --git a/src/ol/view2d.js b/src/ol/view2d.js index f07f560ad6..d9e256b881 100644 --- a/src/ol/view2d.js +++ b/src/ol/view2d.js @@ -48,8 +48,11 @@ ol.View2D = function(opt_view2DOptions) { if (goog.isDef(view2DOptions.resolution)) { values[ol.View2DProperty.RESOLUTION] = view2DOptions.resolution; } else if (goog.isDef(view2DOptions.zoom)) { - values[ol.View2DProperty.RESOLUTION] = - ol.Projection.EPSG_3857_HALF_SIZE / (128 << view2DOptions.zoom); + var projectionExtent = values[ol.View2DProperty.PROJECTION].getExtent(); + var size = Math.max( + projectionExtent.maxX - projectionExtent.minX, + projectionExtent.maxY - projectionExtent.minY); + values[ol.View2DProperty.RESOLUTION] = size / (256 << view2DOptions.zoom); } values[ol.View2DProperty.ROTATION] = view2DOptions.rotation; this.setValues(values); @@ -322,7 +325,11 @@ ol.View2D.createConstraints_ = function(view2DOptions) { numZoomLevels = view2DOptions.numZoomLevels; zoomFactor = view2DOptions.zoomFactor; } else { - maxResolution = ol.Projection.EPSG_3857_HALF_SIZE / 128; + var projectionExtent = ol.Projection.createProjection( + view2DOptions.projection, 'EPSG:3857').getExtent(); + maxResolution = Math.max( + projectionExtent.maxX - projectionExtent.minX, + projectionExtent.maxY - projectionExtent.minY) / 256; // number of steps we want between two data resolutions var numSteps = 4; numZoomLevels = 29 * numSteps;