Compare commits

...

11 Commits

Author SHA1 Message Date
Andreas Hocevar
4a73335839 Update package version to 3.14.2 2016-03-04 09:31:35 +01:00
Andreas Hocevar
124badb961 Changelog vor v3.14.2 2016-03-04 09:31:35 +01:00
Tim Schaub
8725b4fcf4 Merge pull request #4963 from tschaub/xhr-failures
Handle more XHR errors in the TileJSON source
2016-03-04 09:26:16 +01:00
Andreas Hocevar
d12dce1c03 Merge pull request #4960 from ahocevar/clip-rendered
Simplify clipping of lower resolution regions
2016-03-04 09:25:37 +01:00
Frédéric Junod
afb8efc0e9 Merge pull request #4958 from fredj/stop_wheel_events
Stop wheel events instead of DOMMouseScroll events
2016-03-04 09:25:14 +01:00
Andreas Hocevar
bef31dc386 Merge pull request #4956 from jonataswalker/fix-layout-examples
Fix Examples layout page
2016-03-04 09:24:54 +01:00
Tim Schaub
e8cd5e322f Merge pull request #4809 from fperucic/multpolygon-clone
Fix multipolygon clone.
2016-03-04 09:24:23 +01:00
Andreas Hocevar
b4c4a81afb Update package version to 3.14.1 2016-03-01 10:10:41 +01:00
Andreas Hocevar
7478e82b9a Changelog for v3.14.1 2016-03-01 10:10:06 +01:00
Andreas Hocevar
4b586df2b5 Merge pull request #4939 from ahocevar/clip-opacity
Fix rendering of opaque layers with opacity != 1
2016-03-01 10:05:07 +01:00
Andreas Hocevar
ed62203527 Merge pull request #4921 from ahocevar/unlisten-earlier-and-bind-to-target
Unlisten before calling listener and bind to target by default
2016-03-01 10:03:51 +01:00
15 changed files with 184 additions and 133 deletions

10
changelog/v3.14.1.md Normal file
View File

@@ -0,0 +1,10 @@
# v3.14.1
## Summary
The v3.14.1 release is a patch release that addresses a few regressions in the v3.14.0 release. See the [v3.14.0 release notes](https://github.com/openlayers/ol3/releases/tag/v3.14.0) for details on upgrading from v3.13.x.
## Fixes
* [#4939](https://github.com/openlayers/ol3/pull/4939) - Fix rendering of opaque layers with opacity != 1 ([@ahocevar](https://github.com/ahocevar))
* [#4921](https://github.com/openlayers/ol3/pull/4921) - Unlisten before calling listener and bind to target by default ([@ahocevar](https://github.com/ahocevar))

13
changelog/v3.14.2.md Normal file
View File

@@ -0,0 +1,13 @@
# v3.14.2
## Summary
The v3.14.2 release is a patch release that addresses a few regressions in the v3.14.1 release. See the [v3.14.0 release notes](https://github.com/openlayers/ol3/releases/tag/v3.14.0) for details on upgrading from v3.13.x.
## Fixes
* [#4963](https://github.com/openlayers/ol3/pull/4963) - Handle more XHR errors in the TileJSON source ([@tschaub](https://github.com/tschaub))
* [#4960](https://github.com/openlayers/ol3/pull/4960) - Simplify clipping of lower resolution regions ([@ahocevar](https://github.com/ahocevar))
* [#4958](https://github.com/openlayers/ol3/pull/4958) - Stop wheel events instead of DOMMouseScroll events ([@fredj](https://github.com/fredj))
* [#4956](https://github.com/openlayers/ol3/pull/4956) - Fix Examples layout page ([@jonataswalker](https://github.com/jonataswalker))
* [#4809](https://github.com/openlayers/ol3/pull/4809) - Fix multipolygon clone. ([@fperucic](https://github.com/fperucic))

View File

@@ -18,8 +18,10 @@
<body>
<header class="navbar" role="navigation">
<div class="container" id="navbar-inner-container">
<a class="navbar-brand" href="./"><img src="./resources/logo-70x70.png">&nbsp;OpenLayers 3 Examples</a>
<div class="container">
<div class="display-table pull-left" id="navbar-logo-container">
<a class="navbar-brand" href="./"><img src="./resources/logo-70x70.png">&nbsp;OpenLayers 3 Examples</a>
</div>
<ul class="nav navbar-nav pull-right">
<li><a href="../doc">Docs</a></li>
<li><a class="active" href="index.html">Examples</a></li>

View File

@@ -11,9 +11,6 @@
body {
padding-top: 70px;
}
.navbar-form {
margin-top: 12px;
}
input.search-query {
color: #333;
}
@@ -186,11 +183,13 @@
<header class="navbar navbar-fixed-top" role="navigation">
<div class="container">
<a class="navbar-brand" href="./"><img src="./resources/logo-70x70.png">&nbsp;OpenLayers 3 Examples</a>
<form class="navbar-form navbar-left search-form" role="search">
<input name="q" type="text" id="keywords" class="search-query" placeholder="Search" autofocus>
<span id="count"></span>
</form>
<div class="display-table pull-left">
<a class="navbar-brand" href="./"><img src="./resources/logo-70x70.png">&nbsp;OpenLayers 3 Examples</a>
<form class="navbar-form" role="search">
<input name="q" type="text" id="keywords" class="search-query" placeholder="Search" autofocus>
<span id="count"></span>
</form>
</div>
<ul class="nav navbar-nav pull-right">
<li><a href="../doc">Docs</a></li>
<li><a class="active" href="index.html">Examples</a></li>

View File

@@ -22,7 +22,7 @@
return;
}
var container = document.getElementById('navbar-inner-container');
var container = document.getElementById('navbar-logo-container');
if (!container) {
return;
}
@@ -74,7 +74,7 @@
select.className = 'input-medium';
form.className = 'navbar-form pull-right version-form';
form.className = 'navbar-form version-form';
form.appendChild(select);
container.appendChild(form);

View File

@@ -32,12 +32,15 @@ body {
.navbar-nav>li>a {
color: white;
}
.search-form, .version-form {
position: absolute;
left: 450px;
.display-table {
display: table;
}
.version-form, .navbar-form {
display: table-cell;
vertical-align: middle;
}
.version-form {
top: 5px;
color: #333;
}
#title {

View File

@@ -1,6 +1,6 @@
{
"name": "openlayers",
"version": "3.14.0",
"version": "3.14.2",
"description": "Build tools and sources for developing OpenLayers based mapping applications",
"keywords": [
"map",

View File

@@ -107,11 +107,12 @@ ol.events.ListenerObjType;
*/
ol.events.bindListener_ = function(listenerObj) {
var boundListener = function(evt) {
var rv = listenerObj.listener.call(listenerObj.bindTo, evt);
var listener = listenerObj.listener;
var bindTo = listenerObj.bindTo || listenerObj.target;
if (listenerObj.callOnce) {
ol.events.unlistenByKey(listenerObj);
}
return rv;
return listener.call(bindTo, evt);
}
listenerObj.boundListener = boundListener;
return boundListener;

View File

@@ -122,7 +122,7 @@ ol.geom.MultiPolygon.prototype.clone = function() {
var len = this.endss_.length;
var newEndss = new Array(len);
for (var i = 0; i < len; ++i) {
newEndss[i] = this.endss_.slice();
newEndss[i] = this.endss_[i].slice();
}
multiPolygon.setFlatCoordinates(

View File

@@ -291,7 +291,8 @@ ol.Map = function(options) {
ol.events.EventType.TOUCHSTART,
ol.events.EventType.MSPOINTERDOWN,
ol.MapBrowserEvent.EventType.POINTERDOWN,
goog.userAgent.GECKO ? 'DOMMouseScroll' : ol.events.EventType.MOUSEWHEEL
ol.events.EventType.MOUSEWHEEL,
ol.events.EventType.WHEEL
];
for (var i = 0, ii = overlayEvents.length; i < ii; ++i) {
ol.events.listen(this.overlayContainerStopEvent_, overlayEvents[i],

View File

@@ -23,12 +23,6 @@ ol.renderer.canvas.TileLayer = function(tileLayer) {
goog.base(this, tileLayer);
/**
* @private
* @type {Object.<string, Array.<ol.Extent>>}
*/
this.clipExtents_ = null;
/**
* @private
* @type {CanvasRenderingContext2D}
@@ -68,7 +62,6 @@ ol.renderer.canvas.TileLayer.prototype.composeFrame = function(
goog.asserts.assertInstanceof(source, ol.source.Tile,
'source is an ol.source.Tile');
var tileGutter = source.getGutter(projection);
var opaque = source.getOpaque(projection);
var transform = this.getTransform(frameState, 0);
@@ -95,60 +88,56 @@ ol.renderer.canvas.TileLayer.prototype.composeFrame = function(
var tileGrid = source.getTileGridForProjection(projection);
var tilesToDraw = this.renderedTiles_;
var clipExtents, clipExtent, currentZ, i, ii, j, jj, insertPoint;
var origin, tile, tileExtent, tileHeight, tileOffsetX, tileOffsetY;
var tilePixelSize, tileWidth;
for (i = 0, ii = tilesToDraw.length; i < ii; ++i) {
tile = tilesToDraw[i];
tileExtent = tileGrid.getTileCoordExtent(
tile.getTileCoord(), this.tmpExtent_);
clipExtents = !opaque && this.clipExtents_[tile.tileCoord.toString()];
if (clipExtents) {
// Create a clip mask for regions in this low resolution tile that will be
// filled by a higher resolution tile
renderContext.save();
renderContext.beginPath();
renderContext.moveTo((tileExtent[0] - center[0]) * pixelScale + offsetX,
(center[1] - tileExtent[1]) * pixelScale + offsetY);
renderContext.lineTo((tileExtent[2] - center[0]) * pixelScale + offsetX,
(center[1] - tileExtent[1]) * pixelScale + offsetY);
renderContext.lineTo((tileExtent[2] - center[0]) * pixelScale + offsetX,
(center[1] - tileExtent[3]) * pixelScale + offsetY);
renderContext.lineTo((tileExtent[0] - center[0]) * pixelScale + offsetX,
(center[1] - tileExtent[3]) * pixelScale + offsetY);
renderContext.closePath();
for (j = 0, jj = clipExtents.length; j < jj; ++j) {
clipExtent = clipExtents[j];
renderContext.moveTo((clipExtent[0] - center[0]) * pixelScale + offsetX,
(center[1] - clipExtent[1]) * pixelScale + offsetY);
renderContext.lineTo((clipExtent[0] - center[0]) * pixelScale + offsetX,
(center[1] - clipExtent[3]) * pixelScale + offsetY);
renderContext.lineTo((clipExtent[2] - center[0]) * pixelScale + offsetX,
(center[1] - clipExtent[3]) * pixelScale + offsetY);
renderContext.lineTo((clipExtent[2] - center[0]) * pixelScale + offsetX,
(center[1] - clipExtent[1]) * pixelScale + offsetY);
renderContext.closePath();
}
renderContext.clip();
}
currentZ = tile.getTileCoord()[0];
tilePixelSize = source.getTilePixelSize(currentZ, pixelRatio, projection);
insertPoint = ol.extent.getTopLeft(tileExtent);
tileWidth = Math.round(ol.extent.getWidth(tileExtent) * pixelScale);
tileHeight = Math.round(ol.extent.getHeight(tileExtent) * pixelScale);
// Calculate all insert points from a common origin and tile widths to avoid
var pixelExtents;
var opaque = source.getOpaque(projection) && layerState.opacity == 1;
if (!opaque) {
tilesToDraw.reverse();
pixelExtents = [];
}
for (var i = 0, ii = tilesToDraw.length; i < ii; ++i) {
var tile = tilesToDraw[i];
var tileCoord = tile.getTileCoord();
var tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent_);
var currentZ = tileCoord[0];
// Calculate all insert points by tile widths from a common origin to avoid
// gaps caused by rounding
origin = ol.extent.getBottomLeft(tileGrid.getTileCoordExtent(
var origin = ol.extent.getBottomLeft(tileGrid.getTileCoordExtent(
tileGrid.getTileCoordForCoordAndZ(center, currentZ)));
tileOffsetX = offsetX + Math.round((origin[0] - center[0]) * pixelScale);
tileOffsetY = offsetY + Math.round((center[1] - origin[1]) * pixelScale);
var w = Math.round(ol.extent.getWidth(tileExtent) * pixelScale);
var h = Math.round(ol.extent.getHeight(tileExtent) * pixelScale);
var left = Math.round((tileExtent[0] - origin[0]) * pixelScale / w) * w +
offsetX + Math.round((origin[0] - center[0]) * pixelScale);
var top = Math.round((origin[1] - tileExtent[3]) * pixelScale / h) * h +
offsetY + Math.round((center[1] - origin[1]) * pixelScale);
if (!opaque) {
var pixelExtent = [left, top, left + w, top + h];
// Create a clip mask for regions in this low resolution tile that are
// already filled by a higher resolution tile
renderContext.save();
for (var j = 0, jj = pixelExtents.length; j < jj; ++j) {
var clipExtent = pixelExtents[j];
if (ol.extent.intersects(pixelExtent, clipExtent)) {
renderContext.beginPath();
// counter-clockwise (outer ring) for current tile
renderContext.moveTo(pixelExtent[0], pixelExtent[1]);
renderContext.lineTo(pixelExtent[0], pixelExtent[3]);
renderContext.lineTo(pixelExtent[2], pixelExtent[3]);
renderContext.lineTo(pixelExtent[2], pixelExtent[1]);
// clockwise (inner ring) for higher resolution tile
renderContext.moveTo(clipExtent[0], clipExtent[1]);
renderContext.lineTo(clipExtent[2], clipExtent[1]);
renderContext.lineTo(clipExtent[2], clipExtent[3]);
renderContext.lineTo(clipExtent[0], clipExtent[3]);
renderContext.closePath();
renderContext.clip();
}
}
pixelExtents.push(pixelExtent);
}
var tilePixelSize = source.getTilePixelSize(currentZ, pixelRatio, projection);
renderContext.drawImage(tile.getImage(), tileGutter, tileGutter,
tilePixelSize[0], tilePixelSize[1],
Math.round((insertPoint[0] - origin[0]) * pixelScale / tileWidth) *
tileWidth + tileOffsetX,
Math.round((origin[1] - insertPoint[1]) * pixelScale / tileHeight) *
tileHeight + tileOffsetY, tileWidth, tileHeight);
if (clipExtents) {
tilePixelSize[0], tilePixelSize[1], left, top, w, h);
if (!opaque) {
renderContext.restore();
}
}
@@ -266,33 +255,6 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = function(
}
}
this.renderedTiles_ = renderables;
if (!tileSource.getOpaque(projection)) {
var clipExtents = {};
var tileCoord;
for (i = renderables.length - 1; i >= 0; --i) {
tileCoord = renderables[i].getTileCoord();
tileGrid.forEachTileCoordParentTileRange(tileCoord,
function(z, tileRange) {
var tiles = tilesToDrawByZ[z];
if (tiles) {
var key, tile;
for (key in tiles) {
tile = tiles[key];
if (tileRange.contains(tile.getTileCoord()) &&
tile.getState() == ol.TileState.LOADED) {
if (!(key in clipExtents)) {
clipExtents[key] = [];
}
clipExtents[key].push(tileGrid.getTileCoordExtent(tileCoord));
return true;
}
}
}
return false;
}, this, tmpTileRange, tmpExtent);
}
this.clipExtents_ = clipExtents;
}
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
this.manageTilePyramid(frameState, tileSource, tileGrid, pixelRatio,

View File

@@ -43,23 +43,47 @@ ol.source.TileJSON = function(options) {
ol.net.jsonp(options.url, this.handleTileJSONResponse.bind(this),
this.handleTileJSONError.bind(this));
} else {
var xhr = new XMLHttpRequest();
xhr.open('GET', options.url, true);
xhr.onload = function(e) {
if (xhr.status >= 200 && xhr.status < 300) {
var response = /** @type {TileJSON} */(JSON.parse(xhr.responseText));
this.handleTileJSONResponse(response);
} else {
this.handleTileJSONError();
}
}.bind(this);
xhr.send();
var client = new XMLHttpRequest();
client.addEventListener('load', this.onXHRLoad_.bind(this));
client.addEventListener('error', this.onXHRError_.bind(this));
client.open('GET', options.url);
client.send();
}
};
goog.inherits(ol.source.TileJSON, ol.source.TileImage);
/**
* @private
* @param {Event} event The load event.
*/
ol.source.TileJSON.prototype.onXHRLoad_ = function(event) {
var client = /** @type {XMLHttpRequest} */ (event.target);
if (client.status >= 200 && client.status < 300) {
var response;
try {
response = /** @type {TileJSON} */(JSON.parse(client.responseText));
} catch (err) {
this.handleTileJSONError();
return;
}
this.handleTileJSONResponse(response);
} else {
this.handleTileJSONError();
}
};
/**
* @private
* @param {Event} event The error event.
*/
ol.source.TileJSON.prototype.onXHRError_ = function(event) {
this.handleTileJSONError();
};
/**
* @protected
* @param {TileJSON} tileJSON Tile JSON.

View File

@@ -24,23 +24,32 @@ describe('ol.events', function() {
boundListener();
expect(listenerObj.listener.thisValues[0]).to.equal(listenerObj.bindTo);
});
it('binds a self-unregistering listener when callOnce is true', function() {
var bindTo = {id: 1};
var listener = sinon.spy();
target.removeEventListener = function() {};
it('binds to the target when bindTo is not provided', function() {
var listenerObj = {
type: 'foo',
target: target,
listener: listener,
bindTo: bindTo,
callOnce: true
listener: sinon.spy(),
target: {id: 1}
};
var boundListener = ol.events.bindListener_(listenerObj);
expect(listenerObj.boundListener).to.equal(boundListener);
var spy = sinon.spy(ol.events, 'unlistenByKey');
boundListener();
expect(listener.thisValues[0]).to.equal(bindTo);
expect(spy.firstCall.args[0]).to.eql(listenerObj);
expect(listenerObj.listener.thisValues[0]).to.equal(listenerObj.target);
});
it('binds a self-unregistering listener when callOnce is true', function() {
var bindTo = {id: 1};
var listenerObj = {
type: 'foo',
target: target,
bindTo: bindTo,
callOnce: true
};
var unlistenSpy = sinon.spy(ol.events, 'unlistenByKey');
listenerObj.listener = function() {
expect(this).to.equal(bindTo);
expect(unlistenSpy.firstCall.args[0]).to.eql(listenerObj);
}
var boundListener = ol.events.bindListener_(listenerObj);
expect(listenerObj.boundListener).to.equal(boundListener);
boundListener();
ol.events.unlistenByKey.restore();
});
});

View File

@@ -88,6 +88,15 @@ describe('ol.geom.MultiPolygon', function() {
[[[3, 0], [4, 1], [5, 2], [5, 0]]]);
});
describe('#clone()', function() {
it('has the expected endss_', function() {
var clone = multiPolygon.clone();
expect(multiPolygon.endss_).to.eql(clone.endss_);
});
});
describe('#getCoordinates()', function() {
var cw = [[-180, -90], [-180, 90], [180, 90], [180, -90], [-180, -90]];

View File

@@ -4,14 +4,32 @@ goog.provide('ol.test.source.TileJSON');
describe('ol.source.TileJSON', function() {
describe('#getState', function() {
it('returns ol.source.State.ERROR on HTTP 404', function() {
var changeSpy = sinon.spy(function(event) {
expect(event.target.getState()).to.eql('error');
});
var source = new ol.source.TileJSON({
url: 'invalid.jsonp'
});
ol.events.listen(source, 'change', changeSpy);
source.on('change', function() {
expect(source.getState()).to.eql('error');
});
});
it('returns ol.source.State.ERROR on CORS issues', function() {
var source = new ol.source.TileJSON({
url: 'http://example.com'
});
source.on('change', function() {
expect(source.getState()).to.eql('error');
});
});
it('returns ol.source.State.ERROR on JSON parsing issues', function() {
var source = new ol.source.TileJSON({
url: '/'
});
source.on('change', function() {
expect(source.getState()).to.eql('error');
});
});
});