Permalink
Browse files

Always add first segment when appending coordinates

When we have only a single point, we want to make sure it gets added (fixes #1821).

Because this code doesn't differentiate coordinates that are part of a linestring or linearring from those that are independent points, we always add the first segment (or pair of points).  In addition, coordinates for segments are appended whenever they represent a change in relationship with respect to the extent.  This keeps the code simpler for handling fills and properly capturing intersection points for linestrings.  This could be modified to save a few extra coordinates, but it provides for simpler code at a very minimal cost.
  • Loading branch information...
1 parent 7da18bd commit 8317317127cb424dbd883c80dc301106df3d6e2a @tschaub tschaub committed Mar 7, 2014
Showing with 88 additions and 0 deletions.
  1. +7 −0 src/ol/render/canvas/canvasreplay.js
  2. +81 −0 test/spec/ol/renderer/canvas/canvasreplay.test.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];
@@ -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');

0 comments on commit 8317317

Please sign in to comment.