diff --git a/examples/wms-custom-proj.js b/examples/wms-custom-proj.js index 357235d5c5..d6da12b1e4 100644 --- a/examples/wms-custom-proj.js +++ b/examples/wms-custom-proj.js @@ -13,11 +13,12 @@ if (goog.DEBUG) { goog.debug.Logger.getLogger('ol').setLevel(goog.debug.Logger.Level.INFO); } +var epsg21781 = new ol.Projection('EPSG:21781', ol.ProjectionUnits.METERS, + // Validity extent from http://spatialreference.org + new ol.Extent(485869.5728, 76443.1884, 837076.5648, 299941.7864)); +ol.Projection.addProjection(epsg21781); + var extent = new ol.Extent(420000, 30000, 900000, 350000); - -var epsg21781 = new ol.Projection('EPSG:21781', - ol.ProjectionUnits.METERS, extent); - var layers = new ol.Collection([ new ol.layer.TileLayer({ source: new ol.source.TiledWMS({ @@ -28,7 +29,8 @@ var layers = new ol.Collection([ 'Pixelmap 1:1000000 / geo.admin.ch')], crossOrigin: null, params: {'LAYERS': 'ch.swisstopo.pixelkarte-farbe-pk1000.noscale'}, - projection: epsg21781 + projection: epsg21781, + extent: extent }) }), new ol.layer.TileLayer({ @@ -40,7 +42,8 @@ var layers = new ol.Collection([ 'National parks / geo.admin.ch')], crossOrigin: null, params: {'LAYERS': 'ch.bafu.schutzgebiete-paerke_nationaler_bedeutung'}, - projection: epsg21781 + projection: epsg21781, + extent: extent }) }) ]); @@ -49,6 +52,9 @@ var map = new ol.Map({ renderer: ol.RendererHint.DOM, center: new ol.Coordinate(660000, 190000), 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', zoom: 9 diff --git a/src/ol/map.js b/src/ol/map.js index b3242ff03b..6ad2e77d52 100644 --- a/src/ol/map.js +++ b/src/ol/map.js @@ -980,7 +980,7 @@ ol.Map.createOptionsInternal = function(mapOptions) { values[ol.MapProperty.LAYERS] = goog.isDef(mapOptions.layers) ? mapOptions.layers : new ol.Collection(); - values[ol.MapProperty.PROJECTION] = ol.Map.createProjection_( + values[ol.MapProperty.PROJECTION] = ol.Projection.createProjection( mapOptions.projection, 'EPSG:3857'); if (goog.isDef(mapOptions.resolution)) { @@ -990,7 +990,7 @@ ol.Map.createOptionsInternal = function(mapOptions) { ol.Projection.EPSG_3857_HALF_SIZE / (128 << mapOptions.zoom); } - values[ol.MapProperty.USER_PROJECTION] = ol.Map.createProjection_( + values[ol.MapProperty.USER_PROJECTION] = ol.Projection.createProjection( mapOptions.userProjection, 'EPSG:4326'); /** @@ -1183,21 +1183,3 @@ ol.Map.createInteractions_ = function(mapOptions) { return interactions; }; - - -/** - * @private - * @param {ol.Projection|string|undefined} projection Projection. - * @param {string} defaultCode Default code. - * @return {ol.Projection} Projection. - */ -ol.Map.createProjection_ = function(projection, defaultCode) { - if (!goog.isDefAndNotNull(projection)) { - return ol.Projection.getFromCode(defaultCode); - } else if (goog.isString(projection)) { - return ol.Projection.getFromCode(projection); - } else { - goog.asserts.assert(projection instanceof ol.Projection); - return projection; - } -}; diff --git a/src/ol/projection.js b/src/ol/projection.js index 2dee26c18c..d64c2d68e0 100644 --- a/src/ol/projection.js +++ b/src/ol/projection.js @@ -137,8 +137,10 @@ ol.Projection.addEquivalentProjections_ = function(projections) { ol.Projection.addProjections(projections); goog.array.forEach(projections, function(source) { goog.array.forEach(projections, function(destination) { - ol.Projection.addTransform( - source, destination, ol.Projection.cloneTransform); + if (source !== destination) { + ol.Projection.addTransform( + source, destination, ol.Projection.cloneTransform); + } }); }); }; @@ -181,6 +183,8 @@ ol.Projection.addProjection = function(projection) { var code = projection.getCode(); goog.asserts.assert(!goog.object.containsKey(projections, code)); projections[code] = projection; + ol.Projection.addTransform( + projection, projection, ol.Projection.cloneTransform); }; @@ -194,6 +198,23 @@ ol.Projection.addProjections = function(projections) { }; +/** + * @param {ol.Projection|string|undefined} projection Projection. + * @param {string} defaultCode Default code. + * @return {ol.Projection} Projection. + */ +ol.Projection.createProjection = function(projection, defaultCode) { + if (!goog.isDefAndNotNull(projection)) { + return ol.Projection.getFromCode(defaultCode); + } else if (goog.isString(projection)) { + return ol.Projection.getFromCode(projection); + } else { + goog.asserts.assert(projection instanceof ol.Projection); + return projection; + } +}; + + /** * @param {ol.Projection} source Source. * @param {ol.Projection} destination Destination. diff --git a/src/ol/source/tiledwmssource.js b/src/ol/source/tiledwmssource.js index 37f9156928..0e1e43b42f 100644 --- a/src/ol/source/tiledwmssource.js +++ b/src/ol/source/tiledwmssource.js @@ -2,6 +2,7 @@ goog.provide('ol.source.TiledWMS'); + goog.require('goog.asserts'); goog.require('goog.object'); goog.require('ol.Attribution'); @@ -19,8 +20,8 @@ goog.require('ol.tilegrid.TileGrid'); * @param {ol.source.TiledWMSOptions} tiledWMSOptions options. */ ol.source.TiledWMS = function(tiledWMSOptions) { - var projection = goog.isDef(tiledWMSOptions.projection) ? - tiledWMSOptions.projection : ol.Projection.getFromCode('EPSG:3857'); + var projection = ol.Projection.createProjection( + tiledWMSOptions.projection, 'EPSG:3857'); var projectionExtent = projection.getExtent(); var extent = goog.isDef(tiledWMSOptions.extent) ? @@ -39,7 +40,7 @@ ol.source.TiledWMS = function(tiledWMSOptions) { tiledWMSOptions.maxZoom : 18; var resolutions = new Array(maxZoom + 1); for (var z = 0, zz = resolutions.length; z < zz; ++z) { - resolutions[z] = size / (256 << z); + resolutions[z] = ol.Projection.EPSG_3857_HALF_SIZE / (128 << z); } tileGrid = new ol.tilegrid.TileGrid({ origin: projectionExtent.getTopLeft(), @@ -85,15 +86,17 @@ ol.source.TiledWMS = function(tiledWMSOptions) { return null; } var x = tileCoord.x; + var tileExtent = tileGrid.getTileCoordExtent(tileCoord); // FIXME do we want a wrapDateLine param? The code below will break maps // with projections that do not span the whole world width. if (extent.minX === projectionExtent.minX && extent.maxX === projectionExtent.maxX) { - var n = 1 << tileCoord.z; - x = goog.math.modulo(x, n); + var numCols = Math.ceil( + (extent.maxX - extent.minX) / (tileExtent.maxX - tileExtent.minX)); + x = goog.math.modulo(x, numCols); + tileExtent = tileGrid.getTileCoordExtent( + new ol.TileCoord(tileCoord.z, x, tileCoord.y)); } - var tileExtent = tileGrid.getTileCoordExtent( - new ol.TileCoord(tileCoord.z, x, tileCoord.y)); // FIXME We shouldn't need a typecast here. if (!tileExtent.intersects(/** @type {ol.Extent} */ (extent))) { return null;