Merge pull request #793 from ahocevar/proj-no-extent

Making extent optional for projections. r=@twpayne
This commit is contained in:
ahocevar
2013-06-17 08:40:22 -07:00
8 changed files with 148 additions and 30 deletions

View File

@@ -7,7 +7,7 @@
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap.min.css" type="text/css">
<link rel="stylesheet" href="../resources/layout.css" type="text/css">
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap-responsive.min.css" type="text/css">
<title>Tiled WMS with custom projection example</title>
<title>Tiled WMS with Proj4js projection example</title>
</head>
<body>
@@ -36,12 +36,12 @@
<div class="row-fluid">
<div class="span4">
<h4 id="title">Tiled WMS with custom projection example</h4>
<h4 id="title">Tiled WMS with Proj4js projection example</h4>
<p id="shortdesc">Example of two tiled WMS layers (Pixelmap 1:1'000'000 and national parks) using the projection EPSG:21781.</p>
<div id="docs">
<p>See the <a href="wms-custom-proj.js" target="_blank">wms-custom-proj.js source</a> to see how this is done.</p>
</div>
<div id="tags">wms, tile, tilelayer, projection</div>
<div id="tags">wms, tile, tilelayer, proj4js, projection</div>
</div>
</div>

55
examples/wms-no-proj.html Normal file
View File

@@ -0,0 +1,55 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap.min.css" type="text/css">
<link rel="stylesheet" href="../resources/layout.css" type="text/css">
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap-responsive.min.css" type="text/css">
<title>WMS without client projection example</title>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="brand" href="./">OpenLayers 3 Examples</a>
<ul class="nav pull-right">
<li><iframe class="github-watch-button" src="http://ghbtns.com/github-btn.html?user=openlayers&repo=ol3&type=watch&count=true"
allowtransparency="true" frameborder="0" scrolling="0" height="20" width="90"></iframe></li>
<li><a href="https://twitter.com/share" class="twitter-share-button" data-count="none" data-hashtags="openlayers">&nbsp;</a></li>
<li><div class="g-plusone-wrapper"><div class="g-plusone" data-size="medium" data-annotation="none"></div></div></li>
</ul>
</div>
</div>
</div>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<div id="map" class="map"></div>
</div>
</div>
<div class="row-fluid">
<div class="span4">
<h4 id="title">WMS without client projection example</h4>
<p id="shortdesc">Example of two WMS layers using the projection EPSG:21781, which is unknown to the client.</p>
<div id="docs">
<p>See the <a href="wms-no-proj.js" target="_blank">wms-no-proj.js source</a> to see how this is done.</p>
</div>
<div id="tags">wms, projection</div>
</div>
</div>
</div>
<script src="loader.js?id=wms-no-proj" type="text/javascript"></script>
<script src="../resources/social-links.js" type="text/javascript"></script>
</body>
</html>

58
examples/wms-no-proj.js Normal file
View File

@@ -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(
'&copy; ' +
'<a href="http://www.geo.admin.ch/internet/geoportal/en/home.html">' +
'Pixelmap 1:1000000 / geo.admin.ch</a>')],
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(
'&copy; ' +
'<a href="http://www.geo.admin.ch/internet/geoportal/en/home.html">' +
'National parks / geo.admin.ch</a>')],
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
})
});

View File

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

View File

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

View File

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

View File

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

View File

@@ -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)) {