diff --git a/src/ol/render/canvas/canvasreplay.js b/src/ol/render/canvas/canvasreplay.js index 15fef376c8..5f82fd9e04 100644 --- a/src/ol/render/canvas/canvasreplay.js +++ b/src/ol/render/canvas/canvasreplay.js @@ -2,6 +2,7 @@ // FIXME add option to apply snapToPixel to all coordinates? // FIXME can eliminate empty set styles and strokes (when all geoms skipped) +goog.provide('ol.render.canvas.Replay'); goog.provide('ol.render.canvas.ReplayGroup'); goog.require('goog.array'); @@ -166,6 +167,12 @@ ol.render.canvas.Replay.prototype.appendFlatCoordinates = lastRel = nextRel; } + // handle case where there is only one point to append + if (i === offset + stride) { + this.coordinates[myEnd++] = lastCoord[0]; + this.coordinates[myEnd++] = lastCoord[1]; + } + if (close) { this.coordinates[myEnd++] = flatCoordinates[offset]; this.coordinates[myEnd++] = flatCoordinates[offset + 1]; diff --git a/test/spec/ol/renderer/canvas/canvasreplay.test.js b/test/spec/ol/renderer/canvas/canvasreplay.test.js new file mode 100644 index 0000000000..c9bf316fe7 --- /dev/null +++ b/test/spec/ol/renderer/canvas/canvasreplay.test.js @@ -0,0 +1,81 @@ +goog.provide('ol.test.renderer.canvas.Replay'); + +describe('ol.render.canvas.Replay', function() { + + describe('constructor', function() { + + it('creates a new replay batch', function() { + var tolerance = 10; + var extent = [-180, -90, 180, 90]; + var replay = new ol.render.canvas.Replay(tolerance, extent); + expect(replay).to.be.a(ol.render.canvas.Replay); + }); + + }); + + describe('#appendFlatCoordinates()', function() { + + var replay; + beforeEach(function() { + replay = new ol.render.canvas.Replay(1, [-180, -90, 180, 90]); + }); + + it('appends coordinates that are within the max extent', function() { + var flat = [-110, 45, 110, 45, 110, -45, -110, -45]; + replay.appendFlatCoordinates(flat, 0, flat.length, 2, false); + expect(replay.coordinates).to.eql(flat); + }); + + it('works with a single coordinate (inside)', function() { + var flat = [-110, 45]; + replay.appendFlatCoordinates(flat, 0, flat.length, 2, false); + expect(replay.coordinates).to.eql(flat); + }); + + it('always appends first point (even if outside)', function() { + // this could be changed, but to make the code simpler for properly + // closing rings, we always add the first point + var flat = [-110, 145]; + replay.appendFlatCoordinates(flat, 0, flat.length, 2, false); + expect(replay.coordinates).to.eql(flat); + }); + + it('appends points when segments cross (top to bottom)', function() { + // this means we get a few extra points when coordinates are not + // part of a linestring or ring, but only a few extra + var flat = [0, 200, 0, -200]; + replay.appendFlatCoordinates(flat, 0, flat.length, 2, false); + expect(replay.coordinates).to.eql(flat); + }); + + it('appends points when segments cross (top to inside)', function() { + var flat = [0, 200, 0, 0]; + replay.appendFlatCoordinates(flat, 0, flat.length, 2, false); + expect(replay.coordinates).to.eql(flat); + }); + + it('always appends the first segment (even when outside)', function() { + // this could be changed, but to make the code simpler for properly + // closing rings, we always add the first segment + var flat = [-10, 200, 10, 200]; + replay.appendFlatCoordinates(flat, 0, flat.length, 2, false); + expect(replay.coordinates).to.eql(flat); + }); + + it('eliminates segments outside (and not changing rel)', function() { + var flat = [0, 0, 0, 200, 10, 200]; + replay.appendFlatCoordinates(flat, 0, flat.length, 2, false); + expect(replay.coordinates).to.eql([0, 0, 0, 200]); + }); + + it('includes outside segments that change relationship', function() { + var flat = [0, 0, 0, 200, 200, 200, 250, 200]; + replay.appendFlatCoordinates(flat, 0, flat.length, 2, false); + expect(replay.coordinates).to.eql([0, 0, 0, 200, 200, 200]); + }); + + }); + +}); + +goog.require('ol.render.canvas.Replay');