diff --git a/examples/wms-custom-proj.html b/examples/wms-custom-proj.html index c560e433bf..82f6e868e1 100644 --- a/examples/wms-custom-proj.html +++ b/examples/wms-custom-proj.html @@ -7,7 +7,7 @@ - Tiled WMS with custom projection example + Tiled WMS with Proj4js projection example @@ -36,12 +36,12 @@
-

Tiled WMS with custom projection example

+

Tiled WMS with Proj4js projection example

Example of two tiled WMS layers (Pixelmap 1:1'000'000 and national parks) using the projection EPSG:21781.

See the wms-custom-proj.js source to see how this is done.

-
wms, tile, tilelayer, projection
+
wms, tile, tilelayer, proj4js, projection
diff --git a/examples/wms-no-proj.html b/examples/wms-no-proj.html new file mode 100644 index 0000000000..9f050ca19e --- /dev/null +++ b/examples/wms-no-proj.html @@ -0,0 +1,55 @@ + + + + + + + + + + WMS without client projection example + + + + + +
+ +
+
+
+
+
+ +
+ +
+

WMS without client projection example

+

Example of two WMS layers using the projection EPSG:21781, which is unknown to the client.

+
+

See the wms-no-proj.js source to see how this is done.

+
+
wms, projection
+
+ +
+ +
+ + + + + + diff --git a/examples/wms-no-proj.js b/examples/wms-no-proj.js new file mode 100644 index 0000000000..1bb50d5454 --- /dev/null +++ b/examples/wms-no-proj.js @@ -0,0 +1,58 @@ +goog.require('ol.Attribution'); +goog.require('ol.Map'); +goog.require('ol.Projection'); +goog.require('ol.ProjectionUnits'); +goog.require('ol.RendererHints'); +goog.require('ol.View2D'); +goog.require('ol.layer.ImageLayer'); +goog.require('ol.layer.TileLayer'); +goog.require('ol.source.SingleImageWMS'); +goog.require('ol.source.TiledWMS'); + + +var layers = [ + new ol.layer.TileLayer({ + source: new ol.source.TiledWMS({ + attributions: [new ol.Attribution( + '© ' + + '' + + 'Pixelmap 1:1000000 / geo.admin.ch')], + crossOrigin: 'anonymous', + params: { + 'LAYERS': 'ch.swisstopo.pixelkarte-farbe-pk1000.noscale', + 'FORMAT': 'image/jpeg' + }, + url: 'http://wms.geo.admin.ch/' + }) + }), + new ol.layer.ImageLayer({ + source: new ol.source.SingleImageWMS({ + attributions: [new ol.Attribution( + '© ' + + '' + + 'National parks / geo.admin.ch')], + crossOrigin: 'anonymous', + params: {'LAYERS': 'ch.bafu.schutzgebiete-paerke_nationaler_bedeutung'}, + url: 'http://wms.geo.admin.ch/' + }) + }) +]; + +// A minimal projection object is configured with only the SRS code and the map +// units. No client side coordinate transforms are possible with such a +// projection object. +var projection = new ol.Projection({ + code: 'EPSG:21781', + units: ol.ProjectionUnits.METERS +}); + +var map = new ol.Map({ + layers: layers, + renderers: ol.RendererHints.createFromQueryData(), + target: 'map', + view: new ol.View2D({ + center: [660000, 190000], + projection: projection, + zoom: 9 + }) +}); diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index e2e1245013..bc61df1fcb 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -68,7 +68,7 @@ * Object literal with config options for the Proj4js projection. * @typedef {Object} ol.Proj4jsProjectionOptions * @property {string} code The SRS identifier code, e.g. 'EPSG:31256'. - * @property {ol.Extent} extent The validity extent for the SRS. + * @property {ol.Extent|undefined} extent The validity extent for the SRS. * @property {boolean|undefined} global Whether the projection is valid for the * whole globe. Default is false. */ @@ -78,7 +78,7 @@ * @typedef {Object} ol.ProjectionOptions * @property {string} code The SRS identifier code, e.g. 'EPSG:4326'. * @property {ol.ProjectionUnits} units Units. - * @property {ol.Extent} extent The validity extent for the SRS. + * @property {ol.Extent|undefined} extent The validity extent for the SRS. * @property {string|undefined} axisOrientation The axis orientation as * specified in Proj4. The default is 'enu'. * @property {boolean|undefined} global Whether the projection is valid for the diff --git a/src/ol/proj/proj.js b/src/ol/proj/proj.js index f25d59a1aa..21d244f2be 100644 --- a/src/ol/proj/proj.js +++ b/src/ol/proj/proj.js @@ -74,7 +74,7 @@ ol.Projection = function(options) { * @private * @type {ol.Extent} */ - this.extent_ = options.extent; + this.extent_ = goog.isDef(options.extent) ? options.extent : null; /** * @private diff --git a/src/ol/source/tiledwmssource.js b/src/ol/source/tiledwmssource.js index 6597c64a4e..b2ee6562f7 100644 --- a/src/ol/source/tiledwmssource.js +++ b/src/ol/source/tiledwmssource.js @@ -64,7 +64,7 @@ ol.source.TiledWMS = function(options) { tileExtent = tileGrid.getTileCoordExtent( new ol.TileCoord(tileCoord.z, x, tileCoord.y)); } - if (!ol.extent.intersects(tileExtent, extent)) { + if (!goog.isNull(extent) && !ol.extent.intersects(tileExtent, extent)) { return null; } return new ol.TileCoord(tileCoord.z, x, tileCoord.y); diff --git a/src/ol/tilegrid/tilegrid.js b/src/ol/tilegrid/tilegrid.js index fabd8db081..5811beebce 100644 --- a/src/ol/tilegrid/tilegrid.js +++ b/src/ol/tilegrid/tilegrid.js @@ -4,6 +4,7 @@ goog.require('goog.array'); goog.require('goog.asserts'); goog.require('ol.Coordinate'); goog.require('ol.Projection'); +goog.require('ol.ProjectionUnits'); goog.require('ol.Size'); goog.require('ol.TileCoord'); goog.require('ol.TileRange'); @@ -410,21 +411,23 @@ ol.tilegrid.getForProjection = function(projection) { ol.tilegrid.createForProjection = function(projection, opt_maxZoom, opt_tileSize) { var projectionExtent = projection.getExtent(); - var size = Math.max( - projectionExtent[1] - projectionExtent[0], - projectionExtent[3] - projectionExtent[2]); + var size = goog.isNull(projectionExtent) ? + 360 * ol.METERS_PER_UNIT[ol.ProjectionUnits.DEGREES] / + ol.METERS_PER_UNIT[projection.getUnits()] : + Math.max(projectionExtent[1] - projectionExtent[0], + projectionExtent[3] - projectionExtent[2]); var maxZoom = goog.isDef(opt_maxZoom) ? opt_maxZoom : ol.DEFAULT_MAX_ZOOM; var tileSize = goog.isDef(opt_tileSize) ? opt_tileSize : [ol.DEFAULT_TILE_SIZE, ol.DEFAULT_TILE_SIZE]; var resolutions = new Array(maxZoom + 1); - goog.asserts.assert(tileSize[0] == tileSize[1]); - size = size / tileSize[0]; + size = size / Math.max(tileSize[0], tileSize[1]); for (var z = 0, zz = resolutions.length; z < zz; ++z) { resolutions[z] = size / Math.pow(2, z); } return new ol.tilegrid.TileGrid({ - origin: ol.extent.getBottomLeft(projectionExtent), + origin: goog.isNull(projectionExtent) ? [0, 0] : + ol.extent.getBottomLeft(projectionExtent), resolutions: resolutions, tileSize: tileSize }); diff --git a/src/ol/view2d.js b/src/ol/view2d.js index 5a52c18931..68730a4dfe 100644 --- a/src/ol/view2d.js +++ b/src/ol/view2d.js @@ -8,6 +8,7 @@ goog.require('ol.Constraints'); goog.require('ol.IView2D'); goog.require('ol.IView3D'); goog.require('ol.Projection'); +goog.require('ol.ProjectionUnits'); goog.require('ol.ResolutionConstraint'); goog.require('ol.RotationConstraint'); goog.require('ol.RotationConstraintType'); @@ -57,18 +58,6 @@ ol.View2D = function(opt_options) { options.center : null; values[ol.View2DProperty.PROJECTION] = ol.proj.createProjection( options.projection, 'EPSG:3857'); - if (goog.isDef(options.resolution)) { - values[ol.View2DProperty.RESOLUTION] = options.resolution; - } else if (goog.isDef(options.zoom)) { - var projectionExtent = values[ol.View2DProperty.PROJECTION].getExtent(); - var size = Math.max( - projectionExtent[1] - projectionExtent[0], - projectionExtent[3] - projectionExtent[2]); - values[ol.View2DProperty.RESOLUTION] = - size / (ol.DEFAULT_TILE_SIZE * Math.pow(2, options.zoom)); - } - values[ol.View2DProperty.ROTATION] = options.rotation; - this.setValues(values); var parts = ol.View2D.createResolutionConstraint_(options); @@ -94,6 +83,14 @@ ol.View2D = function(opt_options) { this.constraints_ = new ol.Constraints(resolutionConstraint, rotationConstraint); + if (goog.isDef(options.resolution)) { + values[ol.View2DProperty.RESOLUTION] = options.resolution; + } else if (goog.isDef(options.zoom)) { + values[ol.View2DProperty.RESOLUTION] = resolutionConstraint( + this.maxResolution_, options.zoom); + } + values[ol.View2DProperty.ROTATION] = options.rotation; + this.setValues(values); }; goog.inherits(ol.View2D, ol.View); @@ -421,11 +418,16 @@ ol.View2D.createResolutionConstraint_ = function(options) { } else { maxResolution = options.maxResolution; if (!goog.isDef(maxResolution)) { - var projectionExtent = ol.proj.createProjection( - options.projection, 'EPSG:3857').getExtent(); - maxResolution = Math.max( - projectionExtent[1] - projectionExtent[0], - projectionExtent[3] - projectionExtent[2]) / ol.DEFAULT_TILE_SIZE; + var projection = options.projection; + var projectionExtent = ol.proj.createProjection(projection, 'EPSG:3857') + .getExtent(); + var size = goog.isNull(projectionExtent) ? + // use an extent that can fit the whole world if need be + 360 * ol.METERS_PER_UNIT[ol.ProjectionUnits.DEGREES] / + ol.METERS_PER_UNIT[projection.getUnits()] : + Math.max(projectionExtent[1] - projectionExtent[0], + projectionExtent[3] - projectionExtent[2]); + maxResolution = size / ol.DEFAULT_TILE_SIZE; } var maxZoom = options.maxZoom; if (!goog.isDef(maxZoom)) {