diff --git a/src/ol/array.js b/src/ol/array.js index e2744ce3b7..a50cd774e9 100644 --- a/src/ol/array.js +++ b/src/ol/array.js @@ -37,6 +37,18 @@ ol.array.binaryFindNearest = function(arr, target) { }; +/** + * Default compare for array sort, will make sure number sort works okay. + * @param {*} a The first object to be compared. + * @param {*} b The second object to be compared. + * @return {number} A negative number, zero, or a positive number as the first + * argument is less than, equal to, or greater than the second. + */ +ol.array.defaultCompare = function(a, b) { + return a > b ? 1 : a < b ? -1 : 0; +}; + + /** * Whether the array contains the given object. * @param {Array.<*>} arr The array to test for the presence of the element. diff --git a/src/ol/geom/flat/interiorpointflatgeom.js b/src/ol/geom/flat/interiorpointflatgeom.js index 59e69242b2..f73e423e14 100644 --- a/src/ol/geom/flat/interiorpointflatgeom.js +++ b/src/ol/geom/flat/interiorpointflatgeom.js @@ -1,6 +1,7 @@ goog.provide('ol.geom.flat.interiorpoint'); goog.require('goog.asserts'); +goog.require('ol.array'); goog.require('ol.geom.flat.contains'); @@ -40,7 +41,7 @@ ol.geom.flat.interiorpoint.linearRings = function(flatCoordinates, offset, // inside the linear ring. var pointX = NaN; var maxSegmentLength = -Infinity; - intersections.sort(); + intersections.sort(ol.array.defaultCompare); x1 = intersections[0]; for (i = 1, ii = intersections.length; i < ii; ++i) { x2 = intersections[i]; diff --git a/src/ol/render/canvas/canvasimmediate.js b/src/ol/render/canvas/canvasimmediate.js index 9d0a156e55..ae13f9def7 100644 --- a/src/ol/render/canvas/canvasimmediate.js +++ b/src/ol/render/canvas/canvasimmediate.js @@ -7,6 +7,7 @@ goog.provide('ol.render.canvas.Immediate'); goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.vec.Mat4'); +goog.require('ol.array'); goog.require('ol.color'); goog.require('ol.extent'); goog.require('ol.geom.flat.transform'); @@ -721,7 +722,7 @@ ol.render.canvas.Immediate.prototype.drawText = goog.abstractMethod; ol.render.canvas.Immediate.prototype.flush = function() { /** @type {Array.} */ var zs = Object.keys(this.callbacksByZIndex_).map(Number); - zs.sort(); + zs.sort(ol.array.defaultCompare); var i, ii, callbacks, j, jj; for (i = 0, ii = zs.length; i < ii; ++i) { callbacks = this.callbacksByZIndex_[zs[i].toString()]; diff --git a/src/ol/render/canvas/canvasreplay.js b/src/ol/render/canvas/canvasreplay.js index af959ea9a5..421fab76db 100644 --- a/src/ol/render/canvas/canvasreplay.js +++ b/src/ol/render/canvas/canvasreplay.js @@ -2001,7 +2001,7 @@ ol.render.canvas.ReplayGroup.prototype.replay = function( /** @type {Array.} */ var zs = Object.keys(this.replaysByZIndex_).map(Number); - zs.sort(); + zs.sort(ol.array.defaultCompare); // setup clipping so that the parts of over-simplified geometries are not // visible outside the current extent when panning diff --git a/src/ol/render/webgl/webglimmediate.js b/src/ol/render/webgl/webglimmediate.js index 4233c16c05..37ca04cb4f 100644 --- a/src/ol/render/webgl/webglimmediate.js +++ b/src/ol/render/webgl/webglimmediate.js @@ -1,4 +1,5 @@ goog.provide('ol.render.webgl.Immediate'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.render.VectorContext'); goog.require('ol.render.webgl.ImageReplay'); @@ -79,7 +80,7 @@ goog.inherits(ol.render.webgl.Immediate, ol.render.VectorContext); ol.render.webgl.Immediate.prototype.flush = function() { /** @type {Array.} */ var zs = Object.keys(this.callbacksByZIndex_).map(Number); - zs.sort(); + zs.sort(ol.array.defaultCompare); var i, ii, callbacks, j, jj; for (i = 0, ii = zs.length; i < ii; ++i) { callbacks = this.callbacksByZIndex_[zs[i].toString()]; diff --git a/src/ol/renderer/canvas/canvastilelayerrenderer.js b/src/ol/renderer/canvas/canvastilelayerrenderer.js index bd11ddaf38..11c404996b 100644 --- a/src/ol/renderer/canvas/canvastilelayerrenderer.js +++ b/src/ol/renderer/canvas/canvastilelayerrenderer.js @@ -8,6 +8,7 @@ goog.require('goog.vec.Mat4'); goog.require('ol.Size'); goog.require('ol.TileRange'); goog.require('ol.TileState'); +goog.require('ol.array'); goog.require('ol.dom'); goog.require('ol.extent'); goog.require('ol.layer.Tile'); @@ -364,7 +365,7 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = /** @type {Array.} */ var zs = Object.keys(tilesToDrawByZ).map(Number); - zs.sort(); + zs.sort(ol.array.defaultCompare); var opaque = tileSource.getOpaque(); var origin = ol.extent.getTopLeft(tileGrid.getTileCoordExtent( [z, canvasTileRange.minX, canvasTileRange.maxY], diff --git a/src/ol/renderer/canvas/canvasvectortilelayerrenderer.js b/src/ol/renderer/canvas/canvasvectortilelayerrenderer.js index 4be1bba678..ad9f8c588d 100644 --- a/src/ol/renderer/canvas/canvasvectortilelayerrenderer.js +++ b/src/ol/renderer/canvas/canvasvectortilelayerrenderer.js @@ -8,6 +8,7 @@ goog.require('ol.TileRange'); goog.require('ol.TileState'); goog.require('ol.VectorTile'); goog.require('ol.ViewHint'); +goog.require('ol.array'); goog.require('ol.dom'); goog.require('ol.extent'); goog.require('ol.layer.VectorTile'); @@ -405,7 +406,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.prepareFrame = /** @type {Array.} */ var zs = Object.keys(tilesToDrawByZ).map(Number); - zs.sort(); + zs.sort(ol.array.defaultCompare); var replayables = []; var i, ii, currentZ, tileCoordKey, tilesToDraw; for (i = 0, ii = zs.length; i < ii; ++i) { diff --git a/src/ol/renderer/dom/domtilelayerrenderer.js b/src/ol/renderer/dom/domtilelayerrenderer.js index 46ee7c2cf2..fbf77cde40 100644 --- a/src/ol/renderer/dom/domtilelayerrenderer.js +++ b/src/ol/renderer/dom/domtilelayerrenderer.js @@ -13,6 +13,7 @@ goog.require('ol.TileCoord'); goog.require('ol.TileRange'); goog.require('ol.TileState'); goog.require('ol.ViewHint'); +goog.require('ol.array'); goog.require('ol.dom'); goog.require('ol.extent'); goog.require('ol.layer.Tile'); @@ -177,7 +178,7 @@ ol.renderer.dom.TileLayer.prototype.prepareFrame = /** @type {Array.} */ var zs = Object.keys(tilesToDrawByZ).map(Number); - zs.sort(); + zs.sort(ol.array.defaultCompare); /** @type {Object.} */ var newTileLayerZKeys = {}; @@ -203,7 +204,7 @@ ol.renderer.dom.TileLayer.prototype.prepareFrame = /** @type {Array.} */ var tileLayerZKeys = Object.keys(this.tileLayerZs_).map(Number); - tileLayerZKeys.sort(); + tileLayerZKeys.sort(ol.array.defaultCompare); var i, ii, j, origin, resolution; var transform = goog.vec.Mat4.createNumber(); diff --git a/src/ol/renderer/webgl/webgltilelayerrenderer.js b/src/ol/renderer/webgl/webgltilelayerrenderer.js index 8b5f4e3df7..a22b653e29 100644 --- a/src/ol/renderer/webgl/webgltilelayerrenderer.js +++ b/src/ol/renderer/webgl/webgltilelayerrenderer.js @@ -9,6 +9,7 @@ goog.require('goog.vec.Vec4'); goog.require('goog.webgl'); goog.require('ol.TileRange'); goog.require('ol.TileState'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.layer.Tile'); goog.require('ol.math'); @@ -296,7 +297,7 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame = /** @type {Array.} */ var zs = Object.keys(tilesToDrawByZ).map(Number); - zs.sort(); + zs.sort(ol.array.defaultCompare); var u_tileOffset = goog.vec.Vec4.createFloat32(); var i, ii, sx, sy, tileKey, tilesToDraw, tx, ty; for (i = 0, ii = zs.length; i < ii; ++i) { diff --git a/test/spec/ol/array.test.js b/test/spec/ol/array.test.js index 4d68a2edea..ae142d3411 100644 --- a/test/spec/ol/array.test.js +++ b/test/spec/ol/array.test.js @@ -2,6 +2,16 @@ goog.provide('ol.test.array'); describe('ol.array', function() { + describe('defaultCompare', function() { + it('sorts as expected', function() { + var arr = [40, 200, 3000]; + var expected = [40, 200, 3000]; + // default sort would yield [200, 3000, 40] + arr.sort(ol.array.defaultCompare); + expect(arr).to.eql(expected); + }); + }); + describe('binaryFindNearest', function() { it('returns expected value', function() { var arr = [1000, 500, 100]; diff --git a/test/spec/ol/render/canvasimmediate.test.js b/test/spec/ol/render/canvasimmediate.test.js index f6046771bf..d972a747dd 100644 --- a/test/spec/ol/render/canvasimmediate.test.js +++ b/test/spec/ol/render/canvasimmediate.test.js @@ -1,6 +1,22 @@ goog.provide('ol.test.render.canvas.Immediate'); describe('ol.render.canvas.Immediate', function() { + + describe('#flush', function() { + it('calls callback in correct z-order', function() { + var canvas = new ol.render.canvas.Immediate(); + var log = []; + canvas.drawAsync(11, function() { + log.push(11); + }); + canvas.drawAsync(5, function() { + log.push(5); + }); + canvas.flush(); + expect(log).to.eql([5, 11]); + }); + }); + describe('#drawMultiPolygonGeometry', function() { it('creates the correct canvas instructions for 3D geometries', function() { var log = {