Make code prettier

This updates ESLint and our shared eslint-config-openlayers to use Prettier.  Most formatting changes were automatically applied with this:

    npm run lint -- --fix

A few manual changes were required:

 * In `examples/offscreen-canvas.js`, the `//eslint-disable-line` comment needed to be moved to the appropriate line to disable the error about the `'worker-loader!./offscreen-canvas.worker.js'` import.
 * In `examples/webpack/exapmle-builder.js`, spaces could not be added after a couple `function`s for some reason.  While editing this, I reworked `ExampleBuilder` to be a class.
 * In `src/ol/format/WMSGetFeatureInfo.js`, the `// @ts-ignore` comment needed to be moved down one line so it applied to the `parsersNS` argument.
This commit is contained in:
Tim Schaub
2020-04-06 12:25:12 -06:00
parent 53b48baf62
commit 054af09032
790 changed files with 46833 additions and 33765 deletions
+185 -123
View File
@@ -1,4 +1,10 @@
import BuilderGroup from '../../../../../src/ol/render/canvas/BuilderGroup.js';
import CanvasBuilder from '../../../../../src/ol/render/canvas/Builder.js';
import CanvasLineStringBuilder from '../../../../../src/ol/render/canvas/LineStringBuilder.js';
import CanvasPolygonBuilder from '../../../../../src/ol/render/canvas/PolygonBuilder.js';
import ExecutorGroup from '../../../../../src/ol/render/canvas/ExecutorGroup.js';
import Feature from '../../../../../src/ol/Feature.js';
import Fill from '../../../../../src/ol/style/Fill.js';
import GeometryCollection from '../../../../../src/ol/geom/GeometryCollection.js';
import LineString from '../../../../../src/ol/geom/LineString.js';
import MultiLineString from '../../../../../src/ol/geom/MultiLineString.js';
@@ -6,21 +12,16 @@ import MultiPoint from '../../../../../src/ol/geom/MultiPoint.js';
import MultiPolygon from '../../../../../src/ol/geom/MultiPolygon.js';
import Point from '../../../../../src/ol/geom/Point.js';
import Polygon from '../../../../../src/ol/geom/Polygon.js';
import CanvasLineStringBuilder from '../../../../../src/ol/render/canvas/LineStringBuilder.js';
import CanvasPolygonBuilder from '../../../../../src/ol/render/canvas/PolygonBuilder.js';
import CanvasBuilder from '../../../../../src/ol/render/canvas/Builder.js';
import BuilderGroup from '../../../../../src/ol/render/canvas/BuilderGroup.js';
import ExecutorGroup from '../../../../../src/ol/render/canvas/ExecutorGroup.js';
import {renderFeature} from '../../../../../src/ol/renderer/vector.js';
import Fill from '../../../../../src/ol/style/Fill.js';
import Stroke from '../../../../../src/ol/style/Stroke.js';
import Style from '../../../../../src/ol/style/Style.js';
import {create as createTransform, scale as scaleTransform} from '../../../../../src/ol/transform.js';
describe('ol.render.canvas.BuilderGroup', function() {
describe('#replay', function() {
import {
create as createTransform,
scale as scaleTransform,
} from '../../../../../src/ol/transform.js';
import {renderFeature} from '../../../../../src/ol/renderer/vector.js';
describe('ol.render.canvas.BuilderGroup', function () {
describe('#replay', function () {
let context, builder, fillCount, transform;
let strokeCount, beginPathCount, moveToCount, lineToCount;
let feature0, feature1, feature2, feature3;
@@ -32,36 +33,82 @@ describe('ol.render.canvas.BuilderGroup', function() {
* @param {boolean=} overlaps Whether there is overlaps.
*/
function execute(builder, pixelRatio, overlaps) {
const executor = new ExecutorGroup([-180, -90, 180, 90], 1,
pixelRatio || 1, !!overlaps, builder.finish());
const executor = new ExecutorGroup(
[-180, -90, 180, 90],
1,
pixelRatio || 1,
!!overlaps,
builder.finish()
);
executor.execute(context, transform, 0, false);
}
beforeEach(function() {
beforeEach(function () {
transform = createTransform();
builder = new BuilderGroup(1, [-180, -90, 180, 90], 1, 1, false);
feature0 = new Feature(new Polygon(
[[[-90, 0], [-45, 45], [0, 0], [1, 1], [0, -45], [-90, 0]]]));
feature1 = new Feature(new Polygon(
[[[-90, -45], [-90, 0], [0, 0], [0, -45], [-90, -45]]]));
feature2 = new Feature(new Polygon(
[[[90, 45], [90, 0], [0, 0], [0, 45], [90, 45]]]));
feature3 = new Feature(new Polygon(
[[[-90, -45], [-90, 45], [90, 45], [90, -45], [-90, -45]]]));
feature0 = new Feature(
new Polygon([
[
[-90, 0],
[-45, 45],
[0, 0],
[1, 1],
[0, -45],
[-90, 0],
],
])
);
feature1 = new Feature(
new Polygon([
[
[-90, -45],
[-90, 0],
[0, 0],
[0, -45],
[-90, -45],
],
])
);
feature2 = new Feature(
new Polygon([
[
[90, 45],
[90, 0],
[0, 0],
[0, 45],
[90, 45],
],
])
);
feature3 = new Feature(
new Polygon([
[
[-90, -45],
[-90, 45],
[90, 45],
[90, -45],
[-90, -45],
],
])
);
fill0 = new Style({
fill: new Fill({color: 'black'})
fill: new Fill({color: 'black'}),
});
fill1 = new Style({
fill: new Fill({color: 'red'})
fill: new Fill({color: 'red'}),
});
style1 = new Style({
fill: new Fill({color: 'black'}),
stroke: new Stroke({color: 'white', width: 1})
stroke: new Stroke({color: 'white', width: 1}),
});
style2 = new Style({
fill: new Fill({color: 'white'}),
stroke: new Stroke({color: 'black', width: 1, lineDash: [3, 6],
lineDashOffset: 2})
stroke: new Stroke({
color: 'black',
width: 1,
lineDash: [3, 6],
lineDashOffset: 2,
}),
});
fillCount = 0;
strokeCount = 0;
@@ -69,36 +116,35 @@ describe('ol.render.canvas.BuilderGroup', function() {
moveToCount = 0;
lineToCount = 0;
context = {
fill: function() {
fill: function () {
fillCount++;
},
stroke: function() {
stroke: function () {
strokeCount++;
},
beginPath: function() {
beginPath: function () {
beginPathCount++;
},
clip: function() {
clip: function () {
// remove beginPath, moveTo and lineTo counts for clipping
beginPathCount--;
moveToCount--;
lineToCount -= 3;
},
moveTo: function() {
moveTo: function () {
moveToCount++;
},
lineTo: function() {
lineTo: function () {
lineToCount++;
},
closePath: function() {},
setLineDash: function() {},
save: function() {},
restore: function() {}
closePath: function () {},
setLineDash: function () {},
save: function () {},
restore: function () {},
};
});
it('omits lineTo for repeated coordinates', function() {
it('omits lineTo for repeated coordinates', function () {
renderFeature(builder, feature0, fill0, 1);
execute(builder);
expect(lineToCount).to.be(4);
@@ -108,14 +154,14 @@ describe('ol.render.canvas.BuilderGroup', function() {
expect(lineToCount).to.be(3);
});
it('does not omit moveTo for repeated coordinates', function() {
it('does not omit moveTo for repeated coordinates', function () {
renderFeature(builder, feature0, fill0, 1);
renderFeature(builder, feature1, fill1, 1);
execute(builder);
expect(moveToCount).to.be(2);
});
it('batches fill and stroke instructions for same style', function() {
it('batches fill and stroke instructions for same style', function () {
renderFeature(builder, feature1, style1, 1);
renderFeature(builder, feature2, style1, 1);
renderFeature(builder, feature3, style1, 1);
@@ -125,7 +171,7 @@ describe('ol.render.canvas.BuilderGroup', function() {
expect(beginPathCount).to.be(1);
});
it('batches fill and stroke instructions for different styles', function() {
it('batches fill and stroke instructions for different styles', function () {
renderFeature(builder, feature1, style1, 1);
renderFeature(builder, feature2, style1, 1);
renderFeature(builder, feature3, style2, 1);
@@ -135,7 +181,7 @@ describe('ol.render.canvas.BuilderGroup', function() {
expect(beginPathCount).to.be(2);
});
it('batches fill and stroke instructions for changing styles', function() {
it('batches fill and stroke instructions for changing styles', function () {
renderFeature(builder, feature1, style1, 1);
renderFeature(builder, feature2, style2, 1);
renderFeature(builder, feature3, style1, 1);
@@ -145,7 +191,7 @@ describe('ol.render.canvas.BuilderGroup', function() {
expect(beginPathCount).to.be(3);
});
it('does not batch when overlaps is set to true', function() {
it('does not batch when overlaps is set to true', function () {
builder = new BuilderGroup(1, [-180, -90, 180, 90], 1, 1, true);
renderFeature(builder, feature1, style1, 1);
renderFeature(builder, feature2, style1, 1);
@@ -156,23 +202,25 @@ describe('ol.render.canvas.BuilderGroup', function() {
expect(beginPathCount).to.be(3);
});
it('applies the pixelRatio to the linedash array and offset', function() {
it('applies the pixelRatio to the linedash array and offset', function () {
// replay with a pixelRatio of 2
builder = new BuilderGroup(1, [-180, -90, 180, 90], 1, 2, true);
let lineDash, lineDashCount = 0,
lineDashOffset, lineDashOffsetCount = 0;
let lineDash,
lineDashCount = 0,
lineDashOffset,
lineDashOffsetCount = 0;
context.setLineDash = function(lineDash_) {
context.setLineDash = function (lineDash_) {
lineDashCount++;
lineDash = lineDash_.slice();
};
Object.defineProperty(context, 'lineDashOffset', {
set: function(lineDashOffset_) {
set: function (lineDashOffset_) {
lineDashOffsetCount++;
lineDashOffset = lineDashOffset_;
}
},
});
renderFeature(builder, feature1, style2, 1);
@@ -188,10 +236,10 @@ describe('ol.render.canvas.BuilderGroup', function() {
expect(lineDashOffset).to.be(4);
});
it('calls the renderer function configured for the style', function() {
it('calls the renderer function configured for the style', function () {
const calls = [];
const style = new Style({
renderer: function(coords, state) {
renderer: function (coords, state) {
calls.push({
coords: coords,
geometry: state.geometry,
@@ -199,22 +247,44 @@ describe('ol.render.canvas.BuilderGroup', function() {
context: state.context,
pixelRatio: state.pixelRatio,
rotation: state.rotation,
resolution: state.resolution
resolution: state.resolution,
});
}
},
});
const point = new Feature(new Point([45, 90]));
const multipoint = new Feature(new MultiPoint(
[[45, 90], [90, 45]]));
const linestring = new Feature(new LineString(
[[45, 90], [45, 45], [90, 45]]));
const multilinestring = new Feature(new MultiLineString(
[linestring.getGeometry().getCoordinates(), linestring.getGeometry().getCoordinates()]));
const multipoint = new Feature(
new MultiPoint([
[45, 90],
[90, 45],
])
);
const linestring = new Feature(
new LineString([
[45, 90],
[45, 45],
[90, 45],
])
);
const multilinestring = new Feature(
new MultiLineString([
linestring.getGeometry().getCoordinates(),
linestring.getGeometry().getCoordinates(),
])
);
const polygon = feature1;
const multipolygon = new Feature(new MultiPolygon(
[polygon.getGeometry().getCoordinates(), polygon.getGeometry().getCoordinates()]));
const geometrycollection = new Feature(new GeometryCollection(
[point.getGeometry(), linestring.getGeometry(), polygon.getGeometry()]));
const multipolygon = new Feature(
new MultiPolygon([
polygon.getGeometry().getCoordinates(),
polygon.getGeometry().getCoordinates(),
])
);
const geometrycollection = new Feature(
new GeometryCollection([
point.getGeometry(),
linestring.getGeometry(),
polygon.getGeometry(),
])
);
builder = new BuilderGroup(1, [-180, -90, 180, 90], 1, 1, true);
renderFeature(builder, point, style, 1);
renderFeature(builder, multipoint, style, 1);
@@ -249,54 +319,58 @@ describe('ol.render.canvas.BuilderGroup', function() {
expect(calls[8].geometry.getCoordinates()[0][0]).to.eql([-90, -45]);
});
});
});
describe('ol.render.canvas.Builder', function() {
describe('constructor', function() {
it('creates a new replay batch', function() {
describe('ol.render.canvas.Builder', function () {
describe('constructor', function () {
it('creates a new replay batch', function () {
const tolerance = 10;
const extent = [-180, -90, 180, 90];
const replay = new CanvasBuilder(tolerance, extent, 1, 1, true);
expect(replay).to.be.a(CanvasBuilder);
});
});
describe('#appendFlatCoordinates()', function() {
describe('#appendFlatCoordinates()', function () {
let replay;
beforeEach(function() {
beforeEach(function () {
replay = new CanvasBuilder(1, [-180, -90, 180, 90], 1, 1, true);
});
it('appends coordinates that are within the max extent', function() {
it('appends coordinates that are within the max extent', function () {
const flat = [-110, 45, 110, 45, 110, -45, -110, -45];
replay.appendFlatCoordinates(flat, 0, flat.length, 2, false, false);
expect(replay.coordinates).to.eql(flat);
});
it('appends polygon coordinates that are within the max extent', function() {
it('appends polygon coordinates that are within the max extent', function () {
const flat = [-110, 45, 110, 45, 110, -45, -110, -45, -110, 45];
replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, false);
expect(replay.coordinates).to.eql(flat);
});
it('appends polygon coordinates that are within the max extent (skipping first)', function() {
it('appends polygon coordinates that are within the max extent (skipping first)', function () {
const flat = [-110, 45, 110, 45, 110, -45, -110, -45, -110, 45];
replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, true);
expect(replay.coordinates).to.eql([110, 45, 110, -45, -110, -45, -110, 45]);
expect(replay.coordinates).to.eql([
110,
45,
110,
-45,
-110,
-45,
-110,
45,
]);
});
it('works with a single coordinate (inside)', function() {
it('works with a single coordinate (inside)', function () {
const flat = [-110, 45];
replay.appendFlatCoordinates(flat, 0, flat.length, 2, false, false);
expect(replay.coordinates).to.eql(flat);
});
it('always appends first point (even if outside)', function() {
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
const flat = [-110, 145];
@@ -304,7 +378,7 @@ describe('ol.render.canvas.Builder', function() {
expect(replay.coordinates).to.eql(flat);
});
it('always appends first polygon vertex (even if outside)', function() {
it('always appends first polygon vertex (even if outside)', function () {
// this could be changed, but to make the code simpler for properly
// closing rings, we always add the first point
const flat = [-110, 145, -110, 145];
@@ -312,13 +386,13 @@ describe('ol.render.canvas.Builder', function() {
expect(replay.coordinates).to.eql(flat);
});
it('skips first polygon vertex upon request (also when outside)', function() {
it('skips first polygon vertex upon request (also when outside)', function () {
const flat = [-110, 145, -110, 145];
replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, true);
expect(replay.coordinates).to.eql([-110, 145]);
});
it('appends points when segments cross (top to bottom)', function() {
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
const flat = [0, 200, 0, -200];
@@ -326,13 +400,13 @@ describe('ol.render.canvas.Builder', function() {
expect(replay.coordinates).to.eql(flat);
});
it('appends points when segments cross (top to inside)', function() {
it('appends points when segments cross (top to inside)', function () {
const flat = [0, 200, 0, 0];
replay.appendFlatCoordinates(flat, 0, flat.length, 2, false, false);
expect(replay.coordinates).to.eql(flat);
});
it('always appends the first segment (even when outside)', function() {
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
const flat = [-10, 200, 10, 200];
@@ -340,7 +414,7 @@ describe('ol.render.canvas.Builder', function() {
expect(replay.coordinates).to.eql(flat);
});
it('always appends the first polygon segment (even when outside)', function() {
it('always appends the first polygon 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
const flat = [-10, 200, 10, 200, -10, 200];
@@ -348,110 +422,101 @@ describe('ol.render.canvas.Builder', function() {
expect(replay.coordinates).to.eql(flat);
});
it('skips first polygon segment upon request (also when outside)', function() {
it('skips first polygon segment upon request (also when outside)', function () {
const flat = [-10, 200, 10, 200, -10, 200];
replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, true);
expect(replay.coordinates).to.eql([10, 200, -10, 200]);
});
it('eliminates segments outside (and not changing rel)', function() {
it('eliminates segments outside (and not changing rel)', function () {
const flat = [0, 0, 0, 200, 5, 200, 10, 200];
replay.appendFlatCoordinates(flat, 0, flat.length, 2, false, false);
expect(replay.coordinates).to.eql([0, 0, 0, 200]);
});
it('eliminates polygon segments outside (and not changing rel)', function() {
it('eliminates polygon segments outside (and not changing rel)', function () {
const flat = [0, 0, 0, 200, 5, 200, 10, 200, 0, 0];
replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, false);
expect(replay.coordinates).to.eql([0, 0, 0, 200, 10, 200, 0, 0]);
});
it('eliminates polygon segments outside (skipping first and not changing rel)', function() {
it('eliminates polygon segments outside (skipping first and not changing rel)', function () {
const flat = [0, 0, 0, 10, 0, 200, 5, 200, 10, 200, 0, 0];
replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, true);
expect(replay.coordinates).to.eql([0, 10, 0, 200, 10, 200, 0, 0]);
});
it('eliminates segments outside (and not changing rel)', function() {
it('eliminates segments outside (and not changing rel)', function () {
const flat = [0, 0, 0, 200, 10, 200];
replay.appendFlatCoordinates(flat, 0, flat.length, 2, false, false);
expect(replay.coordinates).to.eql([0, 0, 0, 200]);
});
it('includes polygon segments outside (and not changing rel) when on last segment', function() {
it('includes polygon segments outside (and not changing rel) when on last segment', function () {
const flat = [0, 0, 0, 200, 10, 200, 0, 0];
replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, false);
expect(replay.coordinates).to.eql(flat);
});
it('includes polygon segments outside (skipping first and not changing rel) when on last segment', function() {
it('includes polygon segments outside (skipping first and not changing rel) when on last segment', function () {
const flat = [0, 0, 0, 200, 10, 200, 0, 0];
replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, true);
expect(replay.coordinates).to.eql([0, 200, 10, 200, 0, 0]);
});
it('includes outside segments that change relationship', function() {
it('includes outside segments that change relationship', function () {
const flat = [0, 0, 0, 200, 200, 200, 250, 200];
replay.appendFlatCoordinates(flat, 0, flat.length, 2, false, false);
expect(replay.coordinates).to.eql([0, 0, 0, 200, 200, 200]);
});
it('includes outside polygon segments that change relationship when on last segment', function() {
it('includes outside polygon segments that change relationship when on last segment', function () {
const flat = [0, 0, 0, 200, 200, 200, 250, 200, 0, 0];
replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, false);
expect(replay.coordinates).to.eql(flat);
});
it('includes outside polygon segments that change relationship when on last segment (when skipping first)', function() {
it('includes outside polygon segments that change relationship when on last segment (when skipping first)', function () {
const flat = [0, 0, 0, 200, 200, 200, 250, 200, 0, 0];
replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, true);
expect(replay.coordinates).to.eql([0, 200, 200, 200, 250, 200, 0, 0]);
});
});
});
describe('ol.render.canvas.LineStringBuilder', function() {
describe('#getBufferedMaxExtent()', function() {
it('buffers the max extent to accommodate stroke width', function() {
describe('ol.render.canvas.LineStringBuilder', function () {
describe('#getBufferedMaxExtent()', function () {
it('buffers the max extent to accommodate stroke width', function () {
const tolerance = 1;
const extent = [-180, -90, 180, 90];
const resolution = 10;
const replay = new CanvasLineStringBuilder(tolerance, extent,
resolution);
const replay = new CanvasLineStringBuilder(tolerance, extent, resolution);
const stroke = new Stroke({
width: 2
width: 2,
});
replay.setFillStrokeStyle(null, stroke);
const buffered = replay.getBufferedMaxExtent();
expect(buffered).to.eql([-195, -105, 195, 105]);
});
});
});
describe('ol.render.canvas.PolygonBuilder', function() {
describe('ol.render.canvas.PolygonBuilder', function () {
let replay;
beforeEach(function() {
beforeEach(function () {
const tolerance = 1;
const extent = [-180, -90, 180, 90];
const resolution = 10;
replay = new CanvasPolygonBuilder(tolerance, extent,
resolution);
replay = new CanvasPolygonBuilder(tolerance, extent, resolution);
});
describe('#drawFlatCoordinatess_()', function() {
it('returns correct offset', function() {
describe('#drawFlatCoordinatess_()', function () {
it('returns correct offset', function () {
const coords = [1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2];
const ends = [7, 14];
const stroke = new Stroke({
width: 5
width: 5,
});
replay.setFillStrokeStyle(null, stroke);
let offset = replay.drawFlatCoordinatess_(coords, 0, ends, 2);
@@ -462,17 +527,14 @@ describe('ol.render.canvas.PolygonBuilder', function() {
});
});
describe('#getBufferedMaxExtent()', function() {
it('buffers the max extent to accommodate stroke width', function() {
describe('#getBufferedMaxExtent()', function () {
it('buffers the max extent to accommodate stroke width', function () {
const stroke = new Stroke({
width: 5
width: 5,
});
replay.setFillStrokeStyle(null, stroke);
const buffered = replay.getBufferedMaxExtent();
expect(buffered).to.eql([-210, -120, 210, 120]);
});
});
});
+43 -46
View File
@@ -1,25 +1,22 @@
import Map from '../../../../../src/ol/Map.js';
import View from '../../../../../src/ol/View.js';
import {get as getProj} from '../../../../../src/ol/proj.js';
import ImageLayer from '../../../../../src/ol/layer/Image.js';
import VectorImageLayer from '../../../../../src/ol/layer/VectorImage.js';
import Feature from '../../../../../src/ol/Feature.js';
import ImageLayer from '../../../../../src/ol/layer/Image.js';
import Map from '../../../../../src/ol/Map.js';
import Point from '../../../../../src/ol/geom/Point.js';
import Projection from '../../../../../src/ol/proj/Projection.js';
import Static from '../../../../../src/ol/source/ImageStatic.js';
import VectorImageLayer from '../../../../../src/ol/layer/VectorImage.js';
import VectorSource from '../../../../../src/ol/source/Vector.js';
import View from '../../../../../src/ol/View.js';
import {get as getProj} from '../../../../../src/ol/proj.js';
describe('ol.renderer.canvas.ImageLayer', function() {
describe('#forEachLayerAtCoordinate', function() {
describe('ol.renderer.canvas.ImageLayer', function () {
describe('#forEachLayerAtCoordinate', function () {
let map, target, source;
beforeEach(function(done) {
beforeEach(function (done) {
const projection = new Projection({
code: 'custom-image',
units: 'pixels',
extent: [0, 0, 200, 200]
extent: [0, 0, 200, 200],
});
target = document.createElement('div');
target.style.width = '100px';
@@ -28,32 +25,34 @@ describe('ol.renderer.canvas.ImageLayer', function() {
source = new Static({
url: 'spec/ol/data/dot.png',
projection: projection,
imageExtent: [0, 0, 20, 20]
imageExtent: [0, 0, 20, 20],
});
map = new Map({
pixelRatio: 1,
target: target,
layers: [new ImageLayer({
source: source
})],
layers: [
new ImageLayer({
source: source,
}),
],
view: new View({
projection: projection,
center: [10, 10],
zoom: 2,
maxZoom: 8
})
maxZoom: 8,
}),
});
source.on('imageloadend', function() {
source.on('imageloadend', function () {
done();
});
});
afterEach(function() {
afterEach(function () {
map.setTarget(null);
document.body.removeChild(target);
});
it('properly detects pixels', function() {
it('properly detects pixels', function () {
map.renderSync();
let has = false;
function hasLayer() {
@@ -67,17 +66,17 @@ describe('ol.renderer.canvas.ImageLayer', function() {
});
});
describe('Image rendering', function() {
describe('Image rendering', function () {
let map, div, layer;
beforeEach(function(done) {
beforeEach(function (done) {
const projection = getProj('EPSG:3857');
layer = new ImageLayer({
source: new Static({
url: 'spec/ol/data/osm-0-0-0.png',
imageExtent: projection.getExtent(),
projection: projection
})
projection: projection,
}),
});
div = document.createElement('div');
@@ -89,30 +88,30 @@ describe('ol.renderer.canvas.ImageLayer', function() {
layers: [layer],
view: new View({
center: [0, 0],
zoom: 2
})
zoom: 2,
}),
});
layer.getSource().on('imageloadend', function() {
layer.getSource().on('imageloadend', function () {
done();
});
});
afterEach(function() {
afterEach(function () {
map.setTarget(null);
document.body.removeChild(div);
map.dispose();
});
it('dispatches prerender and postrender events on the image layer', function(done) {
it('dispatches prerender and postrender events on the image layer', function (done) {
let prerender = 0;
let postrender = 0;
layer.on('prerender', function() {
layer.on('prerender', function () {
++prerender;
});
layer.on('postrender', function() {
layer.on('postrender', function () {
++postrender;
});
map.on('postrender', function() {
map.on('postrender', function () {
expect(prerender).to.be(1);
expect(postrender).to.be(1);
done();
@@ -120,15 +119,14 @@ describe('ol.renderer.canvas.ImageLayer', function() {
});
});
describe('Vector image rendering', function() {
describe('Vector image rendering', function () {
let map, div, layer;
beforeEach(function() {
beforeEach(function () {
layer = new VectorImageLayer({
source: new VectorSource({
features: [new Feature(new Point([0, 0]))]
})
features: [new Feature(new Point([0, 0]))],
}),
});
div = document.createElement('div');
@@ -140,32 +138,31 @@ describe('ol.renderer.canvas.ImageLayer', function() {
layers: [layer],
view: new View({
center: [0, 0],
zoom: 2
})
zoom: 2,
}),
});
});
afterEach(function() {
afterEach(function () {
map.setTarget(null);
document.body.removeChild(div);
map.dispose();
});
it('dispatches prerender and postrender events on the vector layer', function(done) {
it('dispatches prerender and postrender events on the vector layer', function (done) {
let prerender = 0;
let postrender = 0;
layer.on('prerender', function() {
layer.on('prerender', function () {
++prerender;
});
layer.on('postrender', function() {
layer.on('postrender', function () {
++postrender;
});
map.once('postrender', function() {
map.once('postrender', function () {
expect(prerender).to.be(1);
expect(postrender).to.be(1);
done();
});
});
});
});
+26 -28
View File
@@ -1,49 +1,48 @@
import Map from '../../../../../src/ol/Map.js';
import View from '../../../../../src/ol/View.js';
import TileLayer from '../../../../../src/ol/layer/Tile.js';
import TileWMS from '../../../../../src/ol/source/TileWMS.js';
import View from '../../../../../src/ol/View.js';
import XYZ from '../../../../../src/ol/source/XYZ.js';
import {fromLonLat} from '../../../../../src/ol/proj.js';
describe('ol.renderer.canvas.TileLayer', function() {
describe('#prepareFrame', function() {
describe('ol.renderer.canvas.TileLayer', function () {
describe('#prepareFrame', function () {
let map, target, source, tile;
beforeEach(function(done) {
beforeEach(function (done) {
target = document.createElement('div');
target.style.width = '100px';
target.style.height = '100px';
document.body.appendChild(target);
source = new TileWMS({
url: 'spec/ol/data/osm-0-0-0.png',
params: {LAYERS: 'foo', TIME: '0'}
params: {LAYERS: 'foo', TIME: '0'},
});
source.once('tileloadend', function(e) {
source.once('tileloadend', function (e) {
tile = e.tile;
done();
});
map = new Map({
target: target,
layers: [new TileLayer({
source: source
})],
layers: [
new TileLayer({
source: source,
}),
],
view: new View({
zoom: 0,
center: [0, 0]
})
center: [0, 0],
}),
});
});
afterEach(function() {
afterEach(function () {
map.setTarget(null);
document.body.removeChild(target);
});
it('properly handles interim tiles', function(done) {
it('properly handles interim tiles', function (done) {
const layer = map.getLayers().item(0);
source.once('tileloadend', function(e) {
source.once('tileloadend', function (e) {
expect(e.tile.inTransition()).to.be(false);
done();
});
@@ -56,38 +55,37 @@ describe('ol.renderer.canvas.TileLayer', function() {
});
});
describe('#renderFrame', function() {
describe('#renderFrame', function () {
let map, layer;
beforeEach(function() {
beforeEach(function () {
layer = new TileLayer({
source: new XYZ({
cacheSize: 1,
url: 'rendering/ol/data/tiles/osm/{z}/{x}/{y}.png'
})
url: 'rendering/ol/data/tiles/osm/{z}/{x}/{y}.png',
}),
});
map = new Map({
target: createMapDiv(100, 100),
layers: [layer],
view: new View({
center: fromLonLat([-122.416667, 37.783333]),
zoom: 5
})
zoom: 5,
}),
});
});
afterEach(function() {
afterEach(function () {
disposeMap(map);
});
it('respects the source\'s zDirection setting', function(done) {
it("respects the source's zDirection setting", function (done) {
layer.getSource().zDirection = 1;
map.getView().setZoom(5.8); // would lead to z6 tile request with the default zDirection
map.once('rendercomplete', function() {
map.once('rendercomplete', function () {
const tileCache = layer.getSource().tileCache;
const keys = tileCache.getKeys();
expect(keys.some(key => key.startsWith('6/'))).to.be(false);
expect(keys.some((key) => key.startsWith('6/'))).to.be(false);
done();
});
});
});
});
@@ -1,39 +1,37 @@
import CanvasVectorImageLayerRenderer from '../../../../../src/ol/renderer/canvas/VectorImageLayer.js';
import VectorImageLayer from '../../../../../src/ol/layer/VectorImage.js';
import VectorSource from '../../../../../src/ol/source/Vector.js';
import CanvasVectorImageLayerRenderer from '../../../../../src/ol/renderer/canvas/VectorImageLayer.js';
import {create} from '../../../../../src/ol/transform.js';
import {get as getProjection} from '../../../../../src/ol/proj.js';
import {scaleFromCenter} from '../../../../../src/ol/extent.js';
import {create} from '../../../../../src/ol/transform.js';
describe('ol/renderer/canvas/VectorImageLayer', function() {
describe('#dispose()', function() {
it('cleans up CanvasVectorRenderer', function() {
describe('ol/renderer/canvas/VectorImageLayer', function () {
describe('#dispose()', function () {
it('cleans up CanvasVectorRenderer', function () {
const layer = new VectorImageLayer({
source: new VectorSource()
source: new VectorSource(),
});
const renderer = new CanvasVectorImageLayerRenderer(layer);
const spy = sinon.spy(renderer.vectorRenderer_, 'dispose');
renderer.dispose();
expect(spy.called).to.be(true);
});
});
describe('#prepareFrame', function() {
it('sets correct extent with imageRatio = 2', function() {
describe('#prepareFrame', function () {
it('sets correct extent with imageRatio = 2', function () {
const layer = new VectorImageLayer({
imageRatio: 2,
source: new VectorSource()
source: new VectorSource(),
});
const renderer = new CanvasVectorImageLayerRenderer(layer);
const projection = getProjection('EPSG:3857');
const projExtent = projection.getExtent();
const extent = [
projExtent[0] - 10000, -10000, projExtent[0] + 10000, 10000
projExtent[0] - 10000,
-10000,
projExtent[0] + 10000,
10000,
];
const frameState = {
layerStatesArray: [layer.getLayerState()],
@@ -45,8 +43,8 @@ describe('ol/renderer/canvas/VectorImageLayer', function() {
center: [0, 0],
projection: projection,
resolution: 1,
rotation: 0
}
rotation: 0,
},
};
renderer.prepareFrame(frameState);
const expected = renderer.image_.getExtent();
@@ -56,5 +54,4 @@ describe('ol/renderer/canvas/VectorImageLayer', function() {
expect(expected).to.eql(extent);
});
});
});
+213 -150
View File
@@ -1,27 +1,28 @@
import Feature from '../../../../../src/ol/Feature.js';
import Map from '../../../../../src/ol/Map.js';
import View from '../../../../../src/ol/View.js';
import {buffer as bufferExtent, getWidth, getCenter} from '../../../../../src/ol/extent.js';
import Circle from '../../../../../src/ol/geom/Circle.js';
import Point from '../../../../../src/ol/geom/Point.js';
import {fromExtent} from '../../../../../src/ol/geom/Polygon.js';
import VectorLayer from '../../../../../src/ol/layer/Vector.js';
import {bbox as bboxStrategy} from '../../../../../src/ol/loadingstrategy.js';
import {get as getProjection} from '../../../../../src/ol/proj.js';
import {checkedFonts} from '../../../../../src/ol/render/canvas.js';
import CanvasVectorLayerRenderer from '../../../../../src/ol/renderer/canvas/VectorLayer.js';
import VectorSource from '../../../../../src/ol/source/Vector.js';
import Circle from '../../../../../src/ol/geom/Circle.js';
import CircleStyle from '../../../../../src/ol/style/Circle.js';
import Feature from '../../../../../src/ol/Feature.js';
import Fill from '../../../../../src/ol/style/Fill.js';
import Map from '../../../../../src/ol/Map.js';
import Point from '../../../../../src/ol/geom/Point.js';
import Stroke from '../../../../../src/ol/style/Stroke.js';
import Style from '../../../../../src/ol/style/Style.js';
import Text from '../../../../../src/ol/style/Text.js';
import VectorLayer from '../../../../../src/ol/layer/Vector.js';
import VectorSource from '../../../../../src/ol/source/Vector.js';
import View from '../../../../../src/ol/View.js';
import {bbox as bboxStrategy} from '../../../../../src/ol/loadingstrategy.js';
import {
buffer as bufferExtent,
getCenter,
getWidth,
} from '../../../../../src/ol/extent.js';
import {checkedFonts} from '../../../../../src/ol/render/canvas.js';
import {fromExtent} from '../../../../../src/ol/geom/Polygon.js';
import {get as getProjection} from '../../../../../src/ol/proj.js';
describe('ol.renderer.canvas.VectorLayer', function() {
describe('constructor', function() {
describe('ol.renderer.canvas.VectorLayer', function () {
describe('constructor', function () {
const head = document.getElementsByTagName('head')[0];
const font = document.createElement('link');
font.href = 'https://fonts.googleapis.com/css?family=Droid+Sans';
@@ -29,26 +30,26 @@ describe('ol.renderer.canvas.VectorLayer', function() {
let target;
beforeEach(function() {
beforeEach(function () {
target = document.createElement('div');
target.style.width = '256px';
target.style.height = '256px';
document.body.appendChild(target);
});
afterEach(function() {
afterEach(function () {
document.body.removeChild(target);
});
it('creates a new instance', function() {
it('creates a new instance', function () {
const layer = new VectorLayer({
source: new VectorSource()
source: new VectorSource(),
});
const renderer = new CanvasVectorLayerRenderer(layer);
expect(renderer).to.be.a(CanvasVectorLayerRenderer);
});
it('gives precedence to feature styles over layer styles', function() {
it('gives precedence to feature styles over layer styles', function () {
const target = document.createElement('div');
target.style.width = '256px';
target.style.height = '256px';
@@ -56,28 +57,32 @@ describe('ol.renderer.canvas.VectorLayer', function() {
const map = new Map({
view: new View({
center: [0, 0],
zoom: 0
zoom: 0,
}),
target: target
target: target,
});
const layerStyle = [new Style({
text: new Text({
text: 'layer'
})
})];
const featureStyle = [new Style({
text: new Text({
text: 'feature'
})
})];
const layerStyle = [
new Style({
text: new Text({
text: 'layer',
}),
}),
];
const featureStyle = [
new Style({
text: new Text({
text: 'feature',
}),
}),
];
const feature1 = new Feature(new Point([0, 0]));
const feature2 = new Feature(new Point([0, 0]));
feature2.setStyle(featureStyle);
const layer = new VectorLayer({
source: new VectorSource({
features: [feature1, feature2]
features: [feature1, feature2],
}),
style: layerStyle
style: layerStyle,
});
map.addLayer(layer);
const spy = sinon.spy(layer.getRenderer(), 'renderFeature');
@@ -87,122 +92,126 @@ describe('ol.renderer.canvas.VectorLayer', function() {
document.body.removeChild(target);
});
it('does not re-render for unavailable fonts', function(done) {
it('does not re-render for unavailable fonts', function (done) {
checkedFonts.values_ = {};
const map = new Map({
view: new View({
center: [0, 0],
zoom: 0
zoom: 0,
}),
target: target
target: target,
});
const layerStyle = new Style({
text: new Text({
text: 'layer',
font: '12px "Unavailable Font",sans-serif'
})
font: '12px "Unavailable Font",sans-serif',
}),
});
const feature = new Feature(new Point([0, 0]));
const layer = new VectorLayer({
source: new VectorSource({
features: [feature]
features: [feature],
}),
style: layerStyle
style: layerStyle,
});
map.addLayer(layer);
const revision = layer.getRevision();
setTimeout(function() {
setTimeout(function () {
expect(layer.getRevision()).to.be(revision);
done();
}, 800);
});
it('does not re-render for available fonts', function(done) {
it('does not re-render for available fonts', function (done) {
checkedFonts.values_ = {};
const map = new Map({
view: new View({
center: [0, 0],
zoom: 0
zoom: 0,
}),
target: target
target: target,
});
const layerStyle = new Style({
text: new Text({
text: 'layer',
font: '12px sans-serif'
})
font: '12px sans-serif',
}),
});
const feature = new Feature(new Point([0, 0]));
const layer = new VectorLayer({
source: new VectorSource({
features: [feature]
features: [feature],
}),
style: layerStyle
style: layerStyle,
});
map.addLayer(layer);
const revision = layer.getRevision();
setTimeout(function() {
setTimeout(function () {
expect(layer.getRevision()).to.be(revision);
done();
}, 800);
});
it('re-renders for fonts that become available', function(done) {
it('re-renders for fonts that become available', function (done) {
checkedFonts.values_ = {};
head.appendChild(font);
const map = new Map({
view: new View({
center: [0, 0],
zoom: 0
zoom: 0,
}),
target: target
target: target,
});
const layerStyle = new Style({
text: new Text({
text: 'layer',
font: '12px "Droid Sans",sans-serif'
})
font: '12px "Droid Sans",sans-serif',
}),
});
const feature = new Feature(new Point([0, 0]));
const layer = new VectorLayer({
source: new VectorSource({
features: [feature]
features: [feature],
}),
style: layerStyle
style: layerStyle,
});
map.addLayer(layer);
const revision = layer.getRevision();
setTimeout(function() {
setTimeout(function () {
expect(layer.getRevision()).to.be(revision + 1);
head.removeChild(font);
done();
}, 1600);
});
});
describe('#forEachFeatureAtCoordinate', function() {
describe('#forEachFeatureAtCoordinate', function () {
let layer, renderer;
beforeEach(function() {
beforeEach(function () {
layer = new VectorLayer({
source: new VectorSource()
source: new VectorSource(),
});
renderer = new CanvasVectorLayerRenderer(layer);
const replayGroup = {};
renderer.replayGroup_ = replayGroup;
replayGroup.forEachFeatureAtCoordinate = function(coordinate,
resolution, rotation, hitTolerance, callback) {
replayGroup.forEachFeatureAtCoordinate = function (
coordinate,
resolution,
rotation,
hitTolerance,
callback
) {
const feature = new Feature();
callback(feature);
callback(feature);
};
});
it('calls callback once per feature with a layer as 2nd arg', function() {
it('calls callback once per feature with a layer as 2nd arg', function () {
const spy = sinon.spy();
const coordinate = [0, 0];
const frameState = {
@@ -210,30 +219,35 @@ describe('ol.renderer.canvas.VectorLayer', function() {
viewState: {
center: [0, 0],
resolution: 1,
rotation: 0
}
rotation: 0,
},
};
renderer.forEachFeatureAtCoordinate(
coordinate, frameState, 0, spy, undefined);
coordinate,
frameState,
0,
spy,
undefined
);
expect(spy.callCount).to.be(1);
expect(spy.getCall(0).args[1]).to.equal(layer);
});
});
describe('#prepareFrame and #compose', function() {
describe('#prepareFrame and #compose', function () {
let frameState, projExtent, renderer, worldWidth, buffer, loadExtents;
function loader(extent) {
loadExtents.push(extent);
}
beforeEach(function() {
beforeEach(function () {
const layer = new VectorLayer({
source: new VectorSource({
wrapX: true,
loader: loader,
strategy: bboxStrategy
})
strategy: bboxStrategy,
}),
});
renderer = new CanvasVectorLayerRenderer(layer);
const projection = getProjection('EPSG:3857');
@@ -246,8 +260,8 @@ describe('ol.renderer.canvas.VectorLayer', function() {
viewState: {
projection: projection,
resolution: 1,
rotation: 0
}
rotation: 0,
},
};
});
@@ -256,75 +270,128 @@ describe('ol.renderer.canvas.VectorLayer', function() {
frameState.viewState.center = getCenter(extent);
}
it('sets correct extent for small viewport near dateline', function() {
it('sets correct extent for small viewport near dateline', function () {
setExtent([projExtent[0] - 10000, -10000, projExtent[0] + 10000, 10000]);
renderer.prepareFrame(frameState);
expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([
projExtent[0] - worldWidth + buffer,
-10000, projExtent[2] + worldWidth - buffer, 10000
], buffer));
expect(renderer.replayGroup_.maxExtent_).to.eql(
bufferExtent(
[
projExtent[0] - worldWidth + buffer,
-10000,
projExtent[2] + worldWidth - buffer,
10000,
],
buffer
)
);
expect(loadExtents.length).to.be(2);
expect(loadExtents[0]).to.eql(bufferExtent(frameState.extent, buffer));
const otherExtent = [projExtent[2] - 10000, -10000, projExtent[2] + 10000, 10000];
const otherExtent = [
projExtent[2] - 10000,
-10000,
projExtent[2] + 10000,
10000,
];
expect(loadExtents[1]).to.eql(bufferExtent(otherExtent, buffer));
});
it('sets correct extent for viewport less than 1 world wide', function() {
it('sets correct extent for viewport less than 1 world wide', function () {
setExtent([projExtent[0] - 10000, -10000, projExtent[2] - 10000, 10000]);
renderer.prepareFrame(frameState);
expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([
projExtent[0] - worldWidth + buffer,
-10000, projExtent[2] + worldWidth - buffer, 10000
], buffer));
expect(renderer.replayGroup_.maxExtent_).to.eql(
bufferExtent(
[
projExtent[0] - worldWidth + buffer,
-10000,
projExtent[2] + worldWidth - buffer,
10000,
],
buffer
)
);
expect(loadExtents.length).to.be(2);
expect(loadExtents[0]).to.eql(bufferExtent(frameState.extent, buffer));
const otherExtent = [projExtent[0] - 10000 + worldWidth, -10000, projExtent[2] - 10000 + worldWidth, 10000];
const otherExtent = [
projExtent[0] - 10000 + worldWidth,
-10000,
projExtent[2] - 10000 + worldWidth,
10000,
];
expect(loadExtents[1]).to.eql(bufferExtent(otherExtent, buffer));
});
it('sets correct extent for viewport more than 1 world wide', function() {
setExtent([2 * projExtent[0] + 10000, -10000, 2 * projExtent[2] - 10000, 10000]);
it('sets correct extent for viewport more than 1 world wide', function () {
setExtent([
2 * projExtent[0] + 10000,
-10000,
2 * projExtent[2] - 10000,
10000,
]);
renderer.prepareFrame(frameState);
expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([
projExtent[0] - worldWidth + buffer,
-10000, projExtent[2] + worldWidth - buffer, 10000
], buffer));
expect(renderer.replayGroup_.maxExtent_).to.eql(
bufferExtent(
[
projExtent[0] - worldWidth + buffer,
-10000,
projExtent[2] + worldWidth - buffer,
10000,
],
buffer
)
);
expect(loadExtents.length).to.be(1);
expect(loadExtents[0]).to.eql(bufferExtent(frameState.extent, buffer));
});
it('sets correct extent for viewport more than 2 worlds wide, one world away', function() {
setExtent([projExtent[0] - 2 * worldWidth - 10000,
-10000, projExtent[0] + 2 * worldWidth + 10000, 10000
it('sets correct extent for viewport more than 2 worlds wide, one world away', function () {
setExtent([
projExtent[0] - 2 * worldWidth - 10000,
-10000,
projExtent[0] + 2 * worldWidth + 10000,
10000,
]);
renderer.prepareFrame(frameState);
expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([
projExtent[0] - 2 * worldWidth - 10000,
-10000, projExtent[2] + 2 * worldWidth + 10000, 10000
], buffer));
expect(renderer.replayGroup_.maxExtent_).to.eql(
bufferExtent(
[
projExtent[0] - 2 * worldWidth - 10000,
-10000,
projExtent[2] + 2 * worldWidth + 10000,
10000,
],
buffer
)
);
expect(loadExtents.length).to.be(1);
const normalizedExtent = [projExtent[0] - 2 * worldWidth + worldWidth - 10000, -10000, projExtent[0] + 2 * worldWidth + worldWidth + 10000, 10000];
const normalizedExtent = [
projExtent[0] - 2 * worldWidth + worldWidth - 10000,
-10000,
projExtent[0] + 2 * worldWidth + worldWidth + 10000,
10000,
];
expect(loadExtents[0]).to.eql(bufferExtent(normalizedExtent, buffer));
});
it('sets correct extent for small viewport, one world away', function() {
it('sets correct extent for small viewport, one world away', function () {
setExtent([-worldWidth - 10000, -10000, -worldWidth + 10000, 10000]);
renderer.prepareFrame(frameState);
expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([
projExtent[0] - worldWidth + buffer,
-10000, projExtent[2] + worldWidth - buffer, 10000
], buffer));
expect(renderer.replayGroup_.maxExtent_).to.eql(
bufferExtent(
[
projExtent[0] - worldWidth + buffer,
-10000,
projExtent[2] + worldWidth - buffer,
10000,
],
buffer
)
);
expect(loadExtents.length).to.be(1);
const normalizedExtent = [-10000, -10000, 10000, 10000];
expect(loadExtents[0]).to.eql(bufferExtent(normalizedExtent, buffer));
});
it('sets replayGroupChanged correctly', function() {
it('sets replayGroupChanged correctly', function () {
setExtent([-10000, -10000, 10000, 10000]);
renderer.prepareFrame(frameState);
expect(renderer.replayGroupChanged).to.be(true);
@@ -332,10 +399,10 @@ describe('ol.renderer.canvas.VectorLayer', function() {
expect(renderer.replayGroupChanged).to.be(false);
});
it('dispatches a postrender event when rendering', function(done) {
it('dispatches a postrender event when rendering', function (done) {
const layer = renderer.getLayer();
layer.getSource().addFeature(new Feature(new Point([0, 0])));
layer.once('postrender', function() {
layer.once('postrender', function () {
expect(true);
done();
});
@@ -351,12 +418,10 @@ describe('ol.renderer.canvas.VectorLayer', function() {
}
expect(rendered).to.be(true);
});
});
describe('hit detection', function() {
it('with no fill and transparent fill', function() {
describe('hit detection', function () {
it('with no fill and transparent fill', function () {
const target = document.createElement('div');
target.style.width = '300px';
target.style.height = '300px';
@@ -365,101 +430,101 @@ describe('ol.renderer.canvas.VectorLayer', function() {
transparent: new Style({
stroke: new Stroke({
color: 'blue',
width: 3
width: 3,
}),
fill: new Fill({
color: 'transparent'
color: 'transparent',
}),
image: new CircleStyle({
radius: 30,
stroke: new Stroke({
color: 'blue',
width: 3
width: 3,
}),
fill: new Fill({
color: 'transparent'
})
})
color: 'transparent',
}),
}),
}),
none: new Style({
stroke: new Stroke({
color: 'blue',
width: 3
width: 3,
}),
image: new CircleStyle({
radius: 30,
stroke: new Stroke({
color: 'blue',
width: 3
})
})
})
width: 3,
}),
}),
}),
};
const source = new VectorSource({
features: [
new Feature({
geometry: fromExtent([0, 10, 3, 13]),
fillType: 'none'
fillType: 'none',
}),
new Feature({
geometry: fromExtent([1, 11, 4, 14]),
fillType: 'none'
fillType: 'none',
}),
new Feature({
geometry: fromExtent([5, 10, 8, 13]),
fillType: 'transparent'
fillType: 'transparent',
}),
new Feature({
geometry: fromExtent([6, 11, 9, 14]),
fillType: 'transparent'
fillType: 'transparent',
}),
new Feature({
geometry: new Circle([1.5, 6.5], 1.5),
fillType: 'none'
fillType: 'none',
}),
new Feature({
geometry: new Circle([2.5, 7.5], 1.5),
fillType: 'none'
fillType: 'none',
}),
new Feature({
geometry: new Circle([6.5, 6.5], 1.5),
fillType: 'transparent'
fillType: 'transparent',
}),
new Feature({
geometry: new Circle([7.5, 7.5], 1.5),
fillType: 'transparent'
fillType: 'transparent',
}),
new Feature({
geometry: new Point([1.5, 1.5]),
fillType: 'none'
fillType: 'none',
}),
new Feature({
geometry: new Point([2.5, 2.5]),
fillType: 'none'
fillType: 'none',
}),
new Feature({
geometry: new Point([6.5, 1.5]),
fillType: 'transparent'
fillType: 'transparent',
}),
new Feature({
geometry: new Point([7.5, 2.5]),
fillType: 'transparent'
})
]
fillType: 'transparent',
}),
],
});
const layer = new VectorLayer({
source: source,
style: function(feature, resolution) {
style: function (feature, resolution) {
return styles[feature.get('fillType')];
}
},
});
const map = new Map({
layers: [layer],
view: new View({
center: [4.5, 7],
resolution: 0.05
resolution: 0.05,
}),
target: target
target: target,
});
map.renderSync();
@@ -568,7 +633,5 @@ describe('ol.renderer.canvas.VectorLayer', function() {
document.body.removeChild(target);
});
});
});
@@ -1,41 +1,46 @@
import CanvasVectorTileLayerRenderer from '../../../../../src/ol/renderer/canvas/VectorTileLayer.js';
import Feature from '../../../../../src/ol/Feature.js';
import MVT from '../../../../../src/ol/format/MVT.js';
import Map from '../../../../../src/ol/Map.js';
import Point from '../../../../../src/ol/geom/Point.js';
import RenderFeature from '../../../../../src/ol/render/Feature.js';
import Style from '../../../../../src/ol/style/Style.js';
import Text from '../../../../../src/ol/style/Text.js';
import TileLayer from '../../../../../src/ol/layer/Tile.js';
import TileState from '../../../../../src/ol/TileState.js';
import VectorRenderTile from '../../../../../src/ol/VectorRenderTile.js';
import VectorTile from '../../../../../src/ol/VectorTile.js';
import View from '../../../../../src/ol/View.js';
import {getCenter} from '../../../../../src/ol/extent.js';
import MVT from '../../../../../src/ol/format/MVT.js';
import Point from '../../../../../src/ol/geom/Point.js';
import VectorTileLayer from '../../../../../src/ol/layer/VectorTile.js';
import {get as getProjection} from '../../../../../src/ol/proj.js';
import {checkedFonts} from '../../../../../src/ol/render/canvas.js';
import RenderFeature from '../../../../../src/ol/render/Feature.js';
import CanvasVectorTileLayerRenderer from '../../../../../src/ol/renderer/canvas/VectorTileLayer.js';
import VectorTileSource from '../../../../../src/ol/source/VectorTile.js';
import Style from '../../../../../src/ol/style/Style.js';
import Text from '../../../../../src/ol/style/Text.js';
import {createXYZ} from '../../../../../src/ol/tilegrid.js';
import VectorTileRenderType from '../../../../../src/ol/layer/VectorTileRenderType.js';
import {getUid} from '../../../../../src/ol/util.js';
import TileLayer from '../../../../../src/ol/layer/Tile.js';
import VectorTileSource from '../../../../../src/ol/source/VectorTile.js';
import View from '../../../../../src/ol/View.js';
import XYZ from '../../../../../src/ol/source/XYZ.js';
import {checkedFonts} from '../../../../../src/ol/render/canvas.js';
import {create} from '../../../../../src/ol/transform.js';
import {createXYZ} from '../../../../../src/ol/tilegrid.js';
import {getCenter} from '../../../../../src/ol/extent.js';
import {get as getProjection} from '../../../../../src/ol/proj.js';
import {getUid} from '../../../../../src/ol/util.js';
describe('ol.renderer.canvas.VectorTileLayer', function() {
describe('constructor', function() {
describe('ol.renderer.canvas.VectorTileLayer', function () {
describe('constructor', function () {
const head = document.getElementsByTagName('head')[0];
const font = document.createElement('link');
font.href = 'https://fonts.googleapis.com/css?family=Dancing+Script';
font.rel = 'stylesheet';
let map, layer, layerStyle, source, feature1, feature2, feature3, target, tileCallback;
let map,
layer,
layerStyle,
source,
feature1,
feature2,
feature3,
target,
tileCallback;
beforeEach(function() {
tileCallback = function() {};
beforeEach(function () {
tileCallback = function () {};
target = document.createElement('div');
target.style.width = '256px';
target.style.height = '256px';
@@ -44,20 +49,24 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
pixelRatio: 1,
view: new View({
center: [0, 0],
zoom: 0
zoom: 0,
}),
target: target
target: target,
});
layerStyle = [new Style({
text: new Text({
text: 'layer'
})
})];
const featureStyle = [new Style({
text: new Text({
text: 'feature'
})
})];
layerStyle = [
new Style({
text: new Text({
text: 'layer',
}),
}),
];
const featureStyle = [
new Style({
text: new Text({
text: 'feature',
}),
}),
];
feature1 = new Feature(new Point([1, -1]));
feature2 = new Feature(new Point([0, 0]));
feature3 = new RenderFeature('Point', [1, -1], []);
@@ -74,14 +83,17 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
format: new MVT(),
tileClass: TileClass,
tileGrid: createXYZ(),
url: '{z}/{x}/{y}.pbf'
url: '{z}/{x}/{y}.pbf',
});
source.getSourceTiles = function() {
source.getSourceTiles = function () {
return [new TileClass([0, 0, 0])];
};
source.getTile = function() {
const tile = VectorTileSource.prototype.getTile.apply(source, arguments);
tile.hasContext = function() {
source.getTile = function () {
const tile = VectorTileSource.prototype.getTile.apply(
source,
arguments
);
tile.hasContext = function () {
return true;
};
tile.setState(TileState.LOADED);
@@ -89,58 +101,65 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
};
layer = new VectorTileLayer({
source: source,
style: layerStyle
style: layerStyle,
});
map.addLayer(layer);
});
afterEach(function() {
afterEach(function () {
document.body.removeChild(target);
map.dispose();
});
it('creates a new instance', function() {
it('creates a new instance', function () {
const renderer = new CanvasVectorTileLayerRenderer(layer);
expect(renderer).to.be.a(CanvasVectorTileLayerRenderer);
expect(renderer.getLayer()).to.equal(layer);
});
it('does not render replays for pure image rendering', function() {
it('does not render replays for pure image rendering', function () {
const testLayer = new VectorTileLayer({
renderMode: VectorTileRenderType.IMAGE,
source: source,
style: layerStyle
style: layerStyle,
});
map.removeLayer(layer);
map.addLayer(testLayer);
const spy = sinon.spy(CanvasVectorTileLayerRenderer.prototype,
'getRenderTransform');
const spy = sinon.spy(
CanvasVectorTileLayerRenderer.prototype,
'getRenderTransform'
);
map.renderSync();
expect(spy.callCount).to.be(0);
spy.restore();
});
it('does not render images for pure vector rendering', function() {
it('does not render images for pure vector rendering', function () {
const testLayer = new VectorTileLayer({
renderMode: VectorTileRenderType.VECTOR,
source: source,
style: layerStyle
style: layerStyle,
});
map.removeLayer(layer);
map.addLayer(testLayer);
const spy = sinon.spy(CanvasVectorTileLayerRenderer.prototype,
'renderTileImage_');
const spy = sinon.spy(
CanvasVectorTileLayerRenderer.prototype,
'renderTileImage_'
);
map.renderSync();
expect(spy.callCount).to.be(0);
spy.restore();
});
it('renders both replays and images for hybrid rendering', function() {
const spy1 = sinon.spy(CanvasVectorTileLayerRenderer.prototype,
'getRenderTransform');
const spy2 = sinon.spy(CanvasVectorTileLayerRenderer.prototype,
'renderTileImage_');
it('renders both replays and images for hybrid rendering', function () {
const spy1 = sinon.spy(
CanvasVectorTileLayerRenderer.prototype,
'getRenderTransform'
);
const spy2 = sinon.spy(
CanvasVectorTileLayerRenderer.prototype,
'renderTileImage_'
);
map.renderSync();
expect(spy1.callCount).to.be(1);
expect(spy2.callCount).to.be(1);
@@ -148,72 +167,75 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
spy2.restore();
});
it('renders replays with custom renderers as direct replays', function() {
layer.setStyle(new Style({
renderer: function() {}
}));
const spy = sinon.spy(CanvasVectorTileLayerRenderer.prototype,
'getRenderTransform');
it('renders replays with custom renderers as direct replays', function () {
layer.setStyle(
new Style({
renderer: function () {},
})
);
const spy = sinon.spy(
CanvasVectorTileLayerRenderer.prototype,
'getRenderTransform'
);
map.renderSync();
expect(spy.callCount).to.be(1);
spy.restore();
});
it('gives precedence to feature styles over layer styles', function() {
const spy = sinon.spy(layer.getRenderer(),
'renderFeature');
it('gives precedence to feature styles over layer styles', function () {
const spy = sinon.spy(layer.getRenderer(), 'renderFeature');
map.renderSync();
expect(spy.getCall(0).args[2]).to.be(layer.getStyle());
expect(spy.getCall(1).args[2]).to.be(feature2.getStyle());
spy.restore();
});
it('does not re-render for unavailable fonts', function(done) {
it('does not re-render for unavailable fonts', function (done) {
map.renderSync();
checkedFonts.values_ = {};
layerStyle[0].getText().setFont('12px "Unavailable font",sans-serif');
layer.changed();
const revision = layer.getRevision();
setTimeout(function() {
setTimeout(function () {
expect(layer.getRevision()).to.be(revision);
done();
}, 800);
});
it('does not re-render for available fonts', function(done) {
it('does not re-render for available fonts', function (done) {
map.renderSync();
checkedFonts.values_ = {};
layerStyle[0].getText().setFont('12px sans-serif');
layer.changed();
const revision = layer.getRevision();
setTimeout(function() {
setTimeout(function () {
expect(layer.getRevision()).to.be(revision);
done();
}, 800);
});
it('re-renders for fonts that become available', function(done) {
it('re-renders for fonts that become available', function (done) {
map.renderSync();
checkedFonts.values_ = {};
head.appendChild(font);
layerStyle[0].getText().setFont('12px "Dancing Script",sans-serif');
layer.changed();
const revision = layer.getRevision();
setTimeout(function() {
setTimeout(function () {
head.removeChild(font);
expect(layer.getRevision()).to.be(revision + 1);
done();
}, 1600);
});
it('works for multiple layers that use the same source', function() {
it('works for multiple layers that use the same source', function () {
const layer2 = new VectorTileLayer({
source: source,
style: new Style({
text: new Text({
text: 'layer2'
})
})
text: 'layer2',
}),
}),
});
map.addLayer(layer2);
@@ -223,13 +245,16 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
expect(Object.keys(tile.executorGroups)[1]).to.be(getUid(layer2));
});
it('reuses render container and adds and removes overlay context', function(done) {
map.getLayers().insertAt(0, new TileLayer({
source: new XYZ({
url: 'rendering/ol/data/tiles/osm/{z}/{x}/{y}.png'
it('reuses render container and adds and removes overlay context', function (done) {
map.getLayers().insertAt(
0,
new TileLayer({
source: new XYZ({
url: 'rendering/ol/data/tiles/osm/{z}/{x}/{y}.png',
}),
})
}));
map.once('rendercomplete', function() {
);
map.once('rendercomplete', function () {
expect(document.querySelector('.ol-layers').childElementCount).to.be(1);
expect(document.querySelector('.ol-layer').childElementCount).to.be(1);
map.removeLayer(map.getLayers().item(1));
@@ -238,33 +263,31 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
done();
});
});
});
describe('#prepareFrame', function() {
it('re-renders when layer changed', function() {
describe('#prepareFrame', function () {
it('re-renders when layer changed', function () {
const layer = new VectorTileLayer({
source: new VectorTileSource({
tileGrid: createXYZ(),
transition: 0
})
transition: 0,
}),
});
const sourceTile = new VectorTile([0, 0, 0], 2);
sourceTile.features_ = [];
sourceTile.getImage = function() {
sourceTile.getImage = function () {
return document.createElement('canvas');
};
const tile = new VectorRenderTile([0, 0, 0], 1, [0, 0, 0],
function() {
return sourceTile;
});
const tile = new VectorRenderTile([0, 0, 0], 1, [0, 0, 0], function () {
return sourceTile;
});
tile.transition_ = 0;
tile.setState(TileState.LOADED);
layer.getSource().getTile = function() {
layer.getSource().getTile = function () {
return tile;
};
const renderer = new CanvasVectorTileLayerRenderer(layer);
renderer.isDrawableTile = function() {
renderer.isDrawableTile = function () {
return true;
};
const proj = getProjection('EPSG:3857');
@@ -279,11 +302,11 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
viewState: {
center: [0, 0],
resolution: 156543.03392804097,
projection: proj
projection: proj,
},
size: [256, 256],
usedTiles: {},
wantedTiles: {}
wantedTiles: {},
};
renderer.renderFrame(frameState);
const replayState = renderer.renderedTiles[0].getReplayState(layer);
@@ -297,7 +320,7 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
});
});
describe('#forEachFeatureAtCoordinate', function() {
describe('#forEachFeatureAtCoordinate', function () {
let layer, renderer, executorGroup, source;
class TileClass extends VectorRenderTile {
constructor() {
@@ -307,34 +330,42 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
}
}
beforeEach(function() {
beforeEach(function () {
const sourceTile = new VectorTile([0, 0, 0]);
sourceTile.setState(TileState.LOADED);
source = new VectorTileSource({
tileClass: TileClass,
tileGrid: createXYZ()
tileGrid: createXYZ(),
});
source.sourceTileCache.set('0/0/0.mvt', sourceTile);
executorGroup = {};
source.getTile = function() {
const tile = VectorTileSource.prototype.getTile.apply(source, arguments);
source.getTile = function () {
const tile = VectorTileSource.prototype.getTile.apply(
source,
arguments
);
tile.sourceTiles = [sourceTile];
tile.executorGroups[getUid(layer)] = [executorGroup];
return tile;
};
layer = new VectorTileLayer({
source: source
source: source,
});
renderer = new CanvasVectorTileLayerRenderer(layer);
executorGroup.forEachFeatureAtCoordinate = function(coordinate,
resolution, rotation, hitTolerance, callback) {
executorGroup.forEachFeatureAtCoordinate = function (
coordinate,
resolution,
rotation,
hitTolerance,
callback
) {
const feature = new Feature();
callback(feature);
callback(feature);
};
});
it('calls callback once per feature with a layer as 2nd arg', function() {
it('calls callback once per feature with a layer as 2nd arg', function () {
const spy = sinon.spy();
const coordinate = [0, 0];
const frameState = {
@@ -342,43 +373,55 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
viewState: {
projection: getProjection('EPSG:3857'),
resolution: 1,
rotation: 0
}
rotation: 0,
},
};
renderer.renderedTiles = [source.getTile(0, 0, 0, 1, getProjection('EPSG:3857'))];
renderer.renderedTiles = [
source.getTile(0, 0, 0, 1, getProjection('EPSG:3857')),
];
renderer.forEachFeatureAtCoordinate(
coordinate, frameState, 0, spy, undefined);
coordinate,
frameState,
0,
spy,
undefined
);
expect(spy.callCount).to.be(1);
expect(spy.getCall(0).args[1]).to.equal(layer);
});
it('does not give false positives when overzoomed', function(done) {
it('does not give false positives when overzoomed', function (done) {
const target = document.createElement('div');
target.style.width = '100px';
target.style.height = '100px';
document.body.appendChild(target);
const extent = [1824704.739223726, 6141868.096770482, 1827150.7241288517, 6144314.081675608];
const extent = [
1824704.739223726,
6141868.096770482,
1827150.7241288517,
6144314.081675608,
];
const source = new VectorTileSource({
format: new MVT(),
url: 'spec/ol/data/14-8938-5680.vector.pbf',
minZoom: 14,
maxZoom: 14
maxZoom: 14,
});
const map = new Map({
target: target,
layers: [
new VectorTileLayer({
extent: extent,
source: source
})
source: source,
}),
],
view: new View({
center: getCenter(extent),
zoom: 19
})
zoom: 19,
}),
});
source.on('tileloadend', function() {
setTimeout(function() {
source.on('tileloadend', function () {
setTimeout(function () {
const features = map.getFeaturesAtPixel([96, 96]);
document.body.removeChild(target);
map.dispose();
@@ -388,6 +431,5 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
}, 200);
});
});
});
});
+37 -38
View File
@@ -1,111 +1,110 @@
import ImageWrapper from '../../../../src/ol/Image.js';
import Map from '../../../../src/ol/Map.js';
import View from '../../../../src/ol/View.js';
import Layer from '../../../../src/ol/layer/Layer.js';
import TileLayer from '../../../../src/ol/layer/Tile.js';
import LayerRenderer from '../../../../src/ol/renderer/Layer.js';
import Map from '../../../../src/ol/Map.js';
import TileLayer from '../../../../src/ol/layer/Tile.js';
import View from '../../../../src/ol/View.js';
import XYZ from '../../../../src/ol/source/XYZ.js';
import {fromKey} from '../../../../src/ol/tilecoord.js';
describe('ol.renderer.Layer', function() {
describe('ol.renderer.Layer', function () {
let renderer;
const eventType = 'change';
beforeEach(function() {
beforeEach(function () {
const layer = new Layer({});
renderer = new LayerRenderer(layer);
});
describe('#loadImage', function() {
describe('#loadImage', function () {
let image;
let imageLoadFunction;
beforeEach(function() {
beforeEach(function () {
const extent = [];
const resolution = 1;
const pixelRatio = 1;
const src = '';
const crossOrigin = '';
imageLoadFunction = sinon.spy();
image = new ImageWrapper(extent, resolution, pixelRatio, src, crossOrigin, imageLoadFunction);
image = new ImageWrapper(
extent,
resolution,
pixelRatio,
src,
crossOrigin,
imageLoadFunction
);
});
describe('load IDLE image', function() {
it('returns false', function() {
describe('load IDLE image', function () {
it('returns false', function () {
const loaded = renderer.loadImage(image);
expect(loaded).to.be(false);
});
it('registers a listener', function() {
it('registers a listener', function () {
renderer.loadImage(image);
const listeners = image.listeners_[eventType];
expect(listeners).to.have.length(1);
});
});
describe('load LOADED image', function() {
it('returns true', function() {
describe('load LOADED image', function () {
it('returns true', function () {
image.state = 2; // LOADED
const loaded = renderer.loadImage(image);
expect(loaded).to.be(true);
});
it('does not register a listener', function() {
it('does not register a listener', function () {
image.state = 2; // LOADED
const loaded = renderer.loadImage(image);
expect(loaded).to.be(true);
});
});
describe('load LOADING image', function() {
beforeEach(function() {
describe('load LOADING image', function () {
beforeEach(function () {
renderer.loadImage(image);
expect(image.getState()).to.be(1); // LOADING
});
it('returns false', function() {
it('returns false', function () {
const loaded = renderer.loadImage(image);
expect(loaded).to.be(false);
});
it('does not register a new listener', function() {
it('does not register a new listener', function () {
renderer.loadImage(image);
const listeners = image.listeners_[eventType];
expect(listeners).to.have.length(1);
});
});
});
describe('manageTilePyramid behavior', function() {
describe('manageTilePyramid behavior', function () {
let target, map, view, source;
beforeEach(function(done) {
beforeEach(function (done) {
target = document.createElement('div');
Object.assign(target.style, {
position: 'absolute',
left: '-1000px',
top: '-1000px',
width: '360px',
height: '180px'
height: '180px',
});
document.body.appendChild(target);
view = new View({
center: [0, 0],
multiWorld: true,
zoom: 0
zoom: 0,
});
source = new XYZ({
url: '#{x}/{y}/{z}'
url: '#{x}/{y}/{z}',
});
map = new Map({
@@ -113,27 +112,27 @@ describe('ol.renderer.Layer', function() {
view: view,
layers: [
new TileLayer({
source: source
})
]
source: source,
}),
],
});
map.once('postrender', function() {
map.once('postrender', function () {
done();
});
});
afterEach(function() {
afterEach(function () {
map.dispose();
document.body.removeChild(target);
});
it('accesses tiles from current zoom level last', function(done) {
it('accesses tiles from current zoom level last', function (done) {
// expect most recent tile in the cache to be from zoom level 0
const key = source.tileCache.peekFirstKey();
const tileCoord = fromKey(key);
expect(tileCoord[0]).to.be(0);
map.once('moveend', function() {
map.once('moveend', function () {
// expect most recent tile in the cache to be from zoom level 4
const key = source.tileCache.peekFirstKey();
const tileCoord = fromKey(key);
+3 -8
View File
@@ -2,12 +2,9 @@ import Disposable from '../../../../src/ol/Disposable.js';
import Map from '../../../../src/ol/Map.js';
import MapRenderer from '../../../../src/ol/renderer/Map.js';
describe('ol.renderer.Map', function() {
describe('constructor', function() {
it('createst an instance', function() {
describe('ol.renderer.Map', function () {
describe('constructor', function () {
it('createst an instance', function () {
const map = new Map({});
const renderer = new MapRenderer(null, map);
expect(renderer).to.be.a(MapRenderer);
@@ -15,7 +12,5 @@ describe('ol.renderer.Map', function() {
renderer.dispose();
map.dispose();
});
});
});
+115 -59
View File
@@ -1,50 +1,48 @@
import {VOID} from '../../../../src/ol/functions.js';
import CanvasBuilderGroup from '../../../../src/ol/render/canvas/BuilderGroup.js';
import Feature from '../../../../src/ol/Feature.js';
import Fill from '../../../../src/ol/style/Fill.js';
import Icon from '../../../../src/ol/style/Icon.js';
import LineString from '../../../../src/ol/geom/LineString.js';
import Point from '../../../../src/ol/geom/Point.js';
import Polygon from '../../../../src/ol/geom/Polygon.js';
import MultiLineString from '../../../../src/ol/geom/MultiLineString.js';
import MultiPoint from '../../../../src/ol/geom/MultiPoint.js';
import MultiPolygon from '../../../../src/ol/geom/MultiPolygon.js';
import CanvasBuilderGroup from '../../../../src/ol/render/canvas/BuilderGroup.js';
import {renderFeature} from '../../../../src/ol/renderer/vector.js';
import Fill from '../../../../src/ol/style/Fill.js';
import Icon from '../../../../src/ol/style/Icon.js';
import Point from '../../../../src/ol/geom/Point.js';
import Polygon from '../../../../src/ol/geom/Polygon.js';
import Stroke from '../../../../src/ol/style/Stroke.js';
import Style from '../../../../src/ol/style/Style.js';
import Feature from '../../../../src/ol/Feature.js';
import {VOID} from '../../../../src/ol/functions.js';
import {renderFeature} from '../../../../src/ol/renderer/vector.js';
describe('ol.renderer.vector', function() {
describe('#renderFeature', function() {
describe('ol.renderer.vector', function () {
describe('#renderFeature', function () {
let builderGroup;
let feature, iconStyle, style, squaredTolerance, listener;
let iconStyleLoadSpy;
beforeEach(function() {
beforeEach(function () {
builderGroup = new CanvasBuilderGroup(1);
feature = new Feature();
iconStyle = new Icon({
src: 'http://example.com/icon.png'
src: 'http://example.com/icon.png',
});
style = new Style({
image: iconStyle,
fill: new Fill({}),
stroke: new Stroke({})
stroke: new Stroke({}),
});
squaredTolerance = 1;
listener = function() {};
iconStyleLoadSpy = sinon.stub(iconStyle, 'load').callsFake(function() {
listener = function () {};
iconStyleLoadSpy = sinon.stub(iconStyle, 'load').callsFake(function () {
iconStyle.iconImage_.imageState_ = 1; // LOADING
});
});
afterEach(function() {
afterEach(function () {
iconStyleLoadSpy.restore();
});
describe('call multiple times', function() {
it('does not set multiple listeners', function() {
describe('call multiple times', function () {
it('does not set multiple listeners', function () {
let listeners;
// call #1
@@ -61,42 +59,58 @@ describe('ol.renderer.vector', function() {
listeners = iconStyle.iconImage_.listeners_['change'];
expect(listeners.length).to.eql(1);
});
});
describe('call renderFeature with a loading icon', function() {
it('does not render the point', function() {
describe('call renderFeature with a loading icon', function () {
it('does not render the point', function () {
feature.setGeometry(new Point([0, 0]));
const imageReplay = builderGroup.getBuilder(
style.getZIndex(), 'Image');
const imageReplay = builderGroup.getBuilder(style.getZIndex(), 'Image');
const setImageStyleSpy = sinon.spy(imageReplay, 'setImageStyle');
const drawPointSpy = sinon.stub(imageReplay, 'drawPoint').callsFake(VOID);
const drawPointSpy = sinon
.stub(imageReplay, 'drawPoint')
.callsFake(VOID);
renderFeature(builderGroup, feature, style, squaredTolerance, listener);
expect(setImageStyleSpy.called).to.be(false);
setImageStyleSpy.restore();
drawPointSpy.restore();
});
it('does not render the multipoint', function() {
feature.setGeometry(new MultiPoint([[0, 0], [1, 1]]));
const imageReplay = builderGroup.getBuilder(
style.getZIndex(), 'Image');
it('does not render the multipoint', function () {
feature.setGeometry(
new MultiPoint([
[0, 0],
[1, 1],
])
);
const imageReplay = builderGroup.getBuilder(style.getZIndex(), 'Image');
const setImageStyleSpy = sinon.spy(imageReplay, 'setImageStyle');
const drawMultiPointSpy = sinon.stub(imageReplay, 'drawMultiPoint').callsFake(VOID);
const drawMultiPointSpy = sinon
.stub(imageReplay, 'drawMultiPoint')
.callsFake(VOID);
renderFeature(builderGroup, feature, style, squaredTolerance, listener);
expect(setImageStyleSpy.called).to.be(false);
setImageStyleSpy.restore();
drawMultiPointSpy.restore();
});
it('does render the linestring', function() {
feature.setGeometry(new LineString([[0, 0], [1, 1]]));
it('does render the linestring', function () {
feature.setGeometry(
new LineString([
[0, 0],
[1, 1],
])
);
const lineStringReplay = builderGroup.getBuilder(
style.getZIndex(), 'LineString');
const setFillStrokeStyleSpy = sinon.spy(lineStringReplay,
'setFillStrokeStyle');
const drawLineStringSpy = sinon.stub(lineStringReplay, 'drawLineString').callsFake(VOID);
style.getZIndex(),
'LineString'
);
const setFillStrokeStyleSpy = sinon.spy(
lineStringReplay,
'setFillStrokeStyle'
);
const drawLineStringSpy = sinon
.stub(lineStringReplay, 'drawLineString')
.callsFake(VOID);
renderFeature(builderGroup, feature, style, squaredTolerance, listener);
expect(setFillStrokeStyleSpy.called).to.be(true);
expect(drawLineStringSpy.called).to.be(true);
@@ -104,13 +118,26 @@ describe('ol.renderer.vector', function() {
drawLineStringSpy.restore();
});
it('does render the multilinestring', function() {
feature.setGeometry(new MultiLineString([[[0, 0], [1, 1]]]));
it('does render the multilinestring', function () {
feature.setGeometry(
new MultiLineString([
[
[0, 0],
[1, 1],
],
])
);
const lineStringReplay = builderGroup.getBuilder(
style.getZIndex(), 'LineString');
const setFillStrokeStyleSpy = sinon.spy(lineStringReplay,
'setFillStrokeStyle');
const drawMultiLineStringSpy = sinon.stub(lineStringReplay, 'drawMultiLineString').callsFake(VOID);
style.getZIndex(),
'LineString'
);
const setFillStrokeStyleSpy = sinon.spy(
lineStringReplay,
'setFillStrokeStyle'
);
const drawMultiLineStringSpy = sinon
.stub(lineStringReplay, 'drawMultiLineString')
.callsFake(VOID);
renderFeature(builderGroup, feature, style, squaredTolerance, listener);
expect(setFillStrokeStyleSpy.called).to.be(true);
expect(drawMultiLineStringSpy.called).to.be(true);
@@ -118,14 +145,28 @@ describe('ol.renderer.vector', function() {
drawMultiLineStringSpy.restore();
});
it('does render the polygon', function() {
feature.setGeometry(new Polygon(
[[[0, 0], [1, 1], [1, 0], [0, 0]]]));
it('does render the polygon', function () {
feature.setGeometry(
new Polygon([
[
[0, 0],
[1, 1],
[1, 0],
[0, 0],
],
])
);
const polygonReplay = builderGroup.getBuilder(
style.getZIndex(), 'Polygon');
const setFillStrokeStyleSpy = sinon.spy(polygonReplay,
'setFillStrokeStyle');
const drawPolygonSpy = sinon.stub(polygonReplay, 'drawPolygon').callsFake(VOID);
style.getZIndex(),
'Polygon'
);
const setFillStrokeStyleSpy = sinon.spy(
polygonReplay,
'setFillStrokeStyle'
);
const drawPolygonSpy = sinon
.stub(polygonReplay, 'drawPolygon')
.callsFake(VOID);
renderFeature(builderGroup, feature, style, squaredTolerance, listener);
expect(setFillStrokeStyleSpy.called).to.be(true);
expect(drawPolygonSpy.called).to.be(true);
@@ -133,14 +174,30 @@ describe('ol.renderer.vector', function() {
drawPolygonSpy.restore();
});
it('does render the multipolygon', function() {
feature.setGeometry(new MultiPolygon(
[[[[0, 0], [1, 1], [1, 0], [0, 0]]]]));
it('does render the multipolygon', function () {
feature.setGeometry(
new MultiPolygon([
[
[
[0, 0],
[1, 1],
[1, 0],
[0, 0],
],
],
])
);
const polygonReplay = builderGroup.getBuilder(
style.getZIndex(), 'Polygon');
const setFillStrokeStyleSpy = sinon.spy(polygonReplay,
'setFillStrokeStyle');
const drawMultiPolygonSpy = sinon.stub(polygonReplay, 'drawMultiPolygon').callsFake(VOID);
style.getZIndex(),
'Polygon'
);
const setFillStrokeStyleSpy = sinon.spy(
polygonReplay,
'setFillStrokeStyle'
);
const drawMultiPolygonSpy = sinon
.stub(polygonReplay, 'drawMultiPolygon')
.callsFake(VOID);
renderFeature(builderGroup, feature, style, squaredTolerance, listener);
expect(setFillStrokeStyleSpy.called).to.be(true);
expect(drawMultiPolygonSpy.called).to.be(true);
@@ -148,6 +205,5 @@ describe('ol.renderer.vector', function() {
drawMultiPolygonSpy.restore();
});
});
});
});
+62 -32
View File
@@ -1,41 +1,37 @@
import Layer from '../../../../../src/ol/layer/Layer.js';
import WebGLLayerRenderer, {
colorDecodeId,
colorEncodeId,
getBlankImageData,
writePointFeatureToBuffers
writePointFeatureToBuffers,
} from '../../../../../src/ol/renderer/webgl/Layer.js';
import Layer from '../../../../../src/ol/layer/Layer.js';
describe('ol.renderer.webgl.Layer', function() {
describe('constructor', function() {
describe('ol.renderer.webgl.Layer', function () {
describe('constructor', function () {
let target;
beforeEach(function() {
beforeEach(function () {
target = document.createElement('div');
target.style.width = '256px';
target.style.height = '256px';
document.body.appendChild(target);
});
afterEach(function() {
afterEach(function () {
document.body.removeChild(target);
});
it('creates a new instance', function() {
it('creates a new instance', function () {
const layer = new Layer({});
const renderer = new WebGLLayerRenderer(layer);
expect(renderer).to.be.a(WebGLLayerRenderer);
});
});
describe('writePointFeatureToBuffers', function() {
describe('writePointFeatureToBuffers', function () {
let vertexBuffer, indexBuffer, instructions;
beforeEach(function() {
beforeEach(function () {
vertexBuffer = new Float32Array(100);
indexBuffer = new Uint32Array(100);
instructions = new Float32Array(100);
@@ -43,9 +39,15 @@ describe('ol.renderer.webgl.Layer', function() {
instructions.set([0, 0, 0, 0, 10, 11]);
});
it('writes correctly to the buffers (without custom attributes)', function() {
it('writes correctly to the buffers (without custom attributes)', function () {
const stride = 3;
const positions = writePointFeatureToBuffers(instructions, 4, vertexBuffer, indexBuffer, 0);
const positions = writePointFeatureToBuffers(
instructions,
4,
vertexBuffer,
indexBuffer,
0
);
expect(vertexBuffer[0]).to.eql(10);
expect(vertexBuffer[1]).to.eql(11);
@@ -74,10 +76,16 @@ describe('ol.renderer.webgl.Layer', function() {
expect(positions.vertexPosition).to.eql(stride * 4);
});
it('writes correctly to the buffers (with 2 custom attributes)', function() {
it('writes correctly to the buffers (with 2 custom attributes)', function () {
instructions.set([0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13]);
const stride = 5;
const positions = writePointFeatureToBuffers(instructions, 8, vertexBuffer, indexBuffer, 2);
const positions = writePointFeatureToBuffers(
instructions,
8,
vertexBuffer,
indexBuffer,
2
);
expect(vertexBuffer[0]).to.eql(10);
expect(vertexBuffer[1]).to.eql(11);
@@ -114,12 +122,32 @@ describe('ol.renderer.webgl.Layer', function() {
expect(positions.vertexPosition).to.eql(stride * 4);
});
it('correctly chains buffer writes', function() {
it('correctly chains buffer writes', function () {
instructions.set([10, 11, 20, 21, 30, 31]);
const stride = 3;
let positions = writePointFeatureToBuffers(instructions, 0, vertexBuffer, indexBuffer, 0);
positions = writePointFeatureToBuffers(instructions, 2, vertexBuffer, indexBuffer, 0, positions);
positions = writePointFeatureToBuffers(instructions, 4, vertexBuffer, indexBuffer, 0, positions);
let positions = writePointFeatureToBuffers(
instructions,
0,
vertexBuffer,
indexBuffer,
0
);
positions = writePointFeatureToBuffers(
instructions,
2,
vertexBuffer,
indexBuffer,
0,
positions
);
positions = writePointFeatureToBuffers(
instructions,
4,
vertexBuffer,
indexBuffer,
0,
positions
);
expect(vertexBuffer[0]).to.eql(10);
expect(vertexBuffer[1]).to.eql(11);
@@ -150,11 +178,10 @@ describe('ol.renderer.webgl.Layer', function() {
expect(positions.indexPosition).to.eql(6 * 3);
expect(positions.vertexPosition).to.eql(stride * 4 * 3);
});
});
describe('getBlankImageData', function() {
it('creates a 1x1 white texture', function() {
describe('getBlankImageData', function () {
it('creates a 1x1 white texture', function () {
const texture = getBlankImageData();
expect(texture.height).to.eql(1);
expect(texture.width).to.eql(1);
@@ -165,8 +192,8 @@ describe('ol.renderer.webgl.Layer', function() {
});
});
describe('colorEncodeId and colorDecodeId', function() {
it('correctly encodes and decodes ids', function() {
describe('colorEncodeId and colorDecodeId', function () {
it('correctly encodes and decodes ids', function () {
expect(colorDecodeId(colorEncodeId(0))).to.eql(0);
expect(colorDecodeId(colorEncodeId(1))).to.eql(1);
expect(colorDecodeId(colorEncodeId(123))).to.eql(123);
@@ -176,24 +203,27 @@ describe('ol.renderer.webgl.Layer', function() {
expect(colorDecodeId(colorEncodeId(1234567890))).to.eql(1234567890);
});
it('correctly reuses array', function() {
it('correctly reuses array', function () {
const arr = [];
expect(colorEncodeId(123, arr)).to.be(arr);
});
it('is compatible with Uint8Array storage', function() {
it('is compatible with Uint8Array storage', function () {
const encoded = colorEncodeId(91612);
const typed = Uint8Array.of(encoded[0] * 255, encoded[1] * 255,
encoded[2] * 255, encoded[3] * 255);
const typed = Uint8Array.of(
encoded[0] * 255,
encoded[1] * 255,
encoded[2] * 255,
encoded[3] * 255
);
const arr = [
typed[0] / 255,
typed[1] / 255,
typed[2] / 255,
typed[3] / 255
typed[3] / 255,
];
const decoded = colorDecodeId(arr);
expect(decoded).to.eql(91612);
});
});
});
+209 -122
View File
@@ -2,11 +2,14 @@ import Feature from '../../../../../src/ol/Feature.js';
import Point from '../../../../../src/ol/geom/Point.js';
import VectorLayer from '../../../../../src/ol/layer/Vector.js';
import VectorSource from '../../../../../src/ol/source/Vector.js';
import WebGLPointsLayerRenderer from '../../../../../src/ol/renderer/webgl/PointsLayer.js';
import {get as getProjection} from '../../../../../src/ol/proj.js';
import ViewHint from '../../../../../src/ol/ViewHint.js';
import WebGLPointsLayerRenderer from '../../../../../src/ol/renderer/webgl/PointsLayer.js';
import {WebGLWorkerMessageType} from '../../../../../src/ol/renderer/webgl/Layer.js';
import {compose as composeTransform, create as createTransform} from '../../../../../src/ol/transform.js';
import {
compose as composeTransform,
create as createTransform,
} from '../../../../../src/ol/transform.js';
import {get as getProjection} from '../../../../../src/ol/proj.js';
import {getUid} from '../../../../../src/ol/util.js';
const baseFrameState = {
@@ -15,11 +18,11 @@ const baseFrameState = {
projection: getProjection('EPSG:3857'),
resolution: 1,
rotation: 0,
center: [0, 0]
center: [0, 0],
},
layerStatesArray: [{}],
layerIndex: 0,
pixelRatio: 1
pixelRatio: 1,
};
const simpleVertexShader = `
@@ -70,140 +73,166 @@ const hitFragmentShader = `
gl_FragColor = v_hitColor;
}`;
describe('ol.renderer.webgl.PointsLayer', function() {
describe('constructor', function() {
describe('ol.renderer.webgl.PointsLayer', function () {
describe('constructor', function () {
let target;
beforeEach(function() {
beforeEach(function () {
target = document.createElement('div');
target.style.width = '256px';
target.style.height = '256px';
document.body.appendChild(target);
});
afterEach(function() {
afterEach(function () {
document.body.removeChild(target);
});
it('creates a new instance', function() {
it('creates a new instance', function () {
const layer = new VectorLayer({
source: new VectorSource()
source: new VectorSource(),
});
const renderer = new WebGLPointsLayerRenderer(layer, {
vertexShader: simpleVertexShader,
fragmentShader: simpleFragmentShader
fragmentShader: simpleFragmentShader,
});
expect(renderer).to.be.a(WebGLPointsLayerRenderer);
});
});
describe('#prepareFrame', function() {
describe('#prepareFrame', function () {
let layer, renderer, frameState;
beforeEach(function() {
beforeEach(function () {
layer = new VectorLayer({
source: new VectorSource(),
renderBuffer: 10
renderBuffer: 10,
});
renderer = new WebGLPointsLayerRenderer(layer, {
vertexShader: simpleVertexShader,
fragmentShader: simpleFragmentShader,
hitVertexShader: hitVertexShader,
hitFragmentShader: hitFragmentShader
hitFragmentShader: hitFragmentShader,
});
frameState = Object.assign({
size: [2, 2],
extent: [-100, -100, 100, 100]
}, baseFrameState);
frameState = Object.assign(
{
size: [2, 2],
extent: [-100, -100, 100, 100],
},
baseFrameState
);
});
it('calls WebGlHelper#prepareDraw', function() {
it('calls WebGlHelper#prepareDraw', function () {
const spy = sinon.spy(renderer.helper, 'prepareDraw');
renderer.prepareFrame(frameState);
expect(spy.called).to.be(true);
});
it('fills up a buffer with 2 triangles per point', function(done) {
layer.getSource().addFeature(new Feature({
geometry: new Point([10, 20])
}));
layer.getSource().addFeature(new Feature({
geometry: new Point([30, 40])
}));
it('fills up a buffer with 2 triangles per point', function (done) {
layer.getSource().addFeature(
new Feature({
geometry: new Point([10, 20]),
})
);
layer.getSource().addFeature(
new Feature({
geometry: new Point([30, 40]),
})
);
renderer.prepareFrame(frameState);
const attributePerVertex = 3;
renderer.worker_.addEventListener('message', function(event) {
renderer.worker_.addEventListener('message', function (event) {
if (event.data.type !== WebGLWorkerMessageType.GENERATE_BUFFERS) {
return;
}
expect(renderer.verticesBuffer_.getArray().length).to.eql(2 * 4 * attributePerVertex);
expect(renderer.verticesBuffer_.getArray().length).to.eql(
2 * 4 * attributePerVertex
);
expect(renderer.indicesBuffer_.getArray().length).to.eql(2 * 6);
expect(renderer.verticesBuffer_.getArray()[0]).to.eql(10);
expect(renderer.verticesBuffer_.getArray()[1]).to.eql(20);
expect(renderer.verticesBuffer_.getArray()[4 * attributePerVertex + 0]).to.eql(30);
expect(renderer.verticesBuffer_.getArray()[4 * attributePerVertex + 1]).to.eql(40);
expect(
renderer.verticesBuffer_.getArray()[4 * attributePerVertex + 0]
).to.eql(30);
expect(
renderer.verticesBuffer_.getArray()[4 * attributePerVertex + 1]
).to.eql(40);
done();
});
});
it('fills up the hit render buffer with 2 triangles per point', function(done) {
layer.getSource().addFeature(new Feature({
geometry: new Point([10, 20])
}));
layer.getSource().addFeature(new Feature({
geometry: new Point([30, 40])
}));
it('fills up the hit render buffer with 2 triangles per point', function (done) {
layer.getSource().addFeature(
new Feature({
geometry: new Point([10, 20]),
})
);
layer.getSource().addFeature(
new Feature({
geometry: new Point([30, 40]),
})
);
renderer.prepareFrame(frameState);
const attributePerVertex = 8;
renderer.worker_.addEventListener('message', function(event) {
renderer.worker_.addEventListener('message', function (event) {
if (event.data.type !== WebGLWorkerMessageType.GENERATE_BUFFERS) {
return;
}
if (!renderer.hitVerticesBuffer_.getArray()) {
return;
}
expect(renderer.hitVerticesBuffer_.getArray().length).to.eql(2 * 4 * attributePerVertex);
expect(renderer.hitVerticesBuffer_.getArray().length).to.eql(
2 * 4 * attributePerVertex
);
expect(renderer.indicesBuffer_.getArray().length).to.eql(2 * 6);
expect(renderer.hitVerticesBuffer_.getArray()[0]).to.eql(10);
expect(renderer.hitVerticesBuffer_.getArray()[1]).to.eql(20);
expect(renderer.hitVerticesBuffer_.getArray()[4 * attributePerVertex + 0]).to.eql(30);
expect(renderer.hitVerticesBuffer_.getArray()[4 * attributePerVertex + 1]).to.eql(40);
expect(
renderer.hitVerticesBuffer_.getArray()[4 * attributePerVertex + 0]
).to.eql(30);
expect(
renderer.hitVerticesBuffer_.getArray()[4 * attributePerVertex + 1]
).to.eql(40);
done();
});
});
it('clears the buffers when the features are gone', function(done) {
it('clears the buffers when the features are gone', function (done) {
const source = layer.getSource();
source.addFeature(new Feature({
geometry: new Point([10, 20])
}));
source.addFeature(
new Feature({
geometry: new Point([10, 20]),
})
);
source.removeFeature(source.getFeatures()[0]);
source.addFeature(new Feature({
geometry: new Point([10, 20])
}));
source.addFeature(
new Feature({
geometry: new Point([10, 20]),
})
);
renderer.prepareFrame(frameState);
renderer.worker_.addEventListener('message', function(event) {
renderer.worker_.addEventListener('message', function (event) {
if (event.data.type !== WebGLWorkerMessageType.GENERATE_BUFFERS) {
return;
}
const attributePerVertex = 3;
expect(renderer.verticesBuffer_.getArray().length).to.eql(4 * attributePerVertex);
expect(renderer.verticesBuffer_.getArray().length).to.eql(
4 * attributePerVertex
);
expect(renderer.indicesBuffer_.getArray().length).to.eql(6);
done();
});
});
it('rebuilds the buffers only when not interacting or animating', function() {
it('rebuilds the buffers only when not interacting or animating', function () {
const spy = sinon.spy(renderer, 'rebuildBuffers_');
frameState.viewHints[ViewHint.INTERACTING] = 1;
@@ -222,7 +251,7 @@ describe('ol.renderer.webgl.PointsLayer', function() {
expect(spy.called).to.be(true);
});
it('rebuilds the buffers only when the frame extent changed', function() {
it('rebuilds the buffers only when the frame extent changed', function () {
const spy = sinon.spy(renderer, 'rebuildBuffers_');
renderer.prepareFrame(frameState);
@@ -236,7 +265,7 @@ describe('ol.renderer.webgl.PointsLayer', function() {
expect(spy.callCount).to.be(2);
});
it('triggers source loading when the extent changes', function() {
it('triggers source loading when the extent changes', function () {
const spy = sinon.spy(layer.getSource(), 'loadFeatures');
renderer.prepareFrame(frameState);
@@ -251,7 +280,7 @@ describe('ol.renderer.webgl.PointsLayer', function() {
expect(spy.getCall(1).args[0]).to.eql([0, 10, 40, 50]); // renderBuffer is 10
});
it('triggers source loading when the source revision changes', function() {
it('triggers source loading when the source revision changes', function () {
const spy = sinon.spy(layer.getSource(), 'loadFeatures');
renderer.prepareFrame(frameState);
@@ -266,39 +295,51 @@ describe('ol.renderer.webgl.PointsLayer', function() {
});
});
describe('#forEachFeatureAtCoordinate', function() {
describe('#forEachFeatureAtCoordinate', function () {
let layer, renderer, feature, feature2;
beforeEach(function() {
beforeEach(function () {
feature = new Feature({geometry: new Point([0, 0]), id: 1});
feature2 = new Feature({geometry: new Point([14, 14]), id: 2});
layer = new VectorLayer({
source: new VectorSource({
features: [feature, feature2]
})
features: [feature, feature2],
}),
});
renderer = new WebGLPointsLayerRenderer(layer, {
vertexShader: simpleVertexShader,
fragmentShader: simpleFragmentShader,
hitVertexShader: hitVertexShader,
hitFragmentShader: hitFragmentShader
hitFragmentShader: hitFragmentShader,
});
});
it('correctly hit detects a feature', function(done) {
const transform = composeTransform(createTransform(), 20, 20, 1, -1, 0, 0, 0);
const frameState = Object.assign({
extent: [-20, -20, 20, 20],
size: [40, 40],
coordinateToPixelTransform: transform
}, baseFrameState);
it('correctly hit detects a feature', function (done) {
const transform = composeTransform(
createTransform(),
20,
20,
1,
-1,
0,
0,
0
);
const frameState = Object.assign(
{
extent: [-20, -20, 20, 20],
size: [40, 40],
coordinateToPixelTransform: transform,
},
baseFrameState
);
let found;
const cb = function(feature) {
const cb = function (feature) {
found = feature;
};
renderer.prepareFrame(frameState);
renderer.worker_.addEventListener('message', function() {
renderer.worker_.addEventListener('message', function () {
if (!renderer.hitRenderInstructions_) {
return;
}
@@ -327,21 +368,33 @@ describe('ol.renderer.webgl.PointsLayer', function() {
});
});
it('correctly hit detects with pixelratio != 1', function(done) {
const transform = composeTransform(createTransform(), 20, 20, 1, -1, 0, 0, 0);
const frameState = Object.assign({
pixelRatio: 3,
extent: [-20, -20, 20, 20],
size: [40, 40],
coordinateToPixelTransform: transform
}, baseFrameState);
it('correctly hit detects with pixelratio != 1', function (done) {
const transform = composeTransform(
createTransform(),
20,
20,
1,
-1,
0,
0,
0
);
const frameState = Object.assign(
{
pixelRatio: 3,
extent: [-20, -20, 20, 20],
size: [40, 40],
coordinateToPixelTransform: transform,
},
baseFrameState
);
let found;
const cb = function(feature) {
const cb = function (feature) {
found = feature;
};
renderer.prepareFrame(frameState);
renderer.worker_.addEventListener('message', function() {
renderer.worker_.addEventListener('message', function () {
if (!renderer.hitRenderInstructions_) {
return;
}
@@ -371,14 +424,14 @@ describe('ol.renderer.webgl.PointsLayer', function() {
});
});
describe('#disposeInternal', function() {
it('terminates the worker and calls dispose on the helper', function() {
describe('#disposeInternal', function () {
it('terminates the worker and calls dispose on the helper', function () {
const layer = new VectorLayer({
source: new VectorSource()
source: new VectorSource(),
});
const renderer = new WebGLPointsLayerRenderer(layer, {
vertexShader: simpleVertexShader,
fragmentShader: simpleFragmentShader
fragmentShader: simpleFragmentShader,
});
const spyHelper = sinon.spy(renderer.helper, 'disposeInternal');
@@ -389,67 +442,79 @@ describe('ol.renderer.webgl.PointsLayer', function() {
});
});
describe('featureCache_', function() {
describe('featureCache_', function () {
let source, layer, features;
function getCache(feature, renderer) {
return renderer.featureCache_[getUid(feature)];
}
beforeEach(function() {
beforeEach(function () {
source = new VectorSource();
layer = new VectorLayer({
source
source,
});
features = [
new Feature({
id: 'A',
test: 'abcd',
geometry: new Point([0, 1])
geometry: new Point([0, 1]),
}),
new Feature({
id: 'D',
test: 'efgh',
geometry: new Point([2, 3])
geometry: new Point([2, 3]),
}),
new Feature({
id: 'C',
test: 'ijkl',
geometry: new Point([4, 5])
})
geometry: new Point([4, 5]),
}),
];
});
it('contains no features initially', function() {
it('contains no features initially', function () {
const renderer = new WebGLPointsLayerRenderer(layer, {
vertexShader: simpleVertexShader,
fragmentShader: simpleFragmentShader
fragmentShader: simpleFragmentShader,
});
expect(renderer.featureCount_).to.be(0);
});
it('contains the features initially present in the source', function() {
it('contains the features initially present in the source', function () {
source.addFeatures(features);
const renderer = new WebGLPointsLayerRenderer(layer, {
vertexShader: simpleVertexShader,
fragmentShader: simpleFragmentShader
fragmentShader: simpleFragmentShader,
});
expect(renderer.featureCount_).to.be(3);
expect(getCache(features[0], renderer).feature).to.be(features[0]);
expect(getCache(features[0], renderer).geometry).to.be(features[0].getGeometry());
expect(getCache(features[0], renderer).properties['test']).to.be(features[0].get('test'));
expect(getCache(features[0], renderer).geometry).to.be(
features[0].getGeometry()
);
expect(getCache(features[0], renderer).properties['test']).to.be(
features[0].get('test')
);
expect(getCache(features[1], renderer).feature).to.be(features[1]);
expect(getCache(features[1], renderer).geometry).to.be(features[1].getGeometry());
expect(getCache(features[1], renderer).properties['test']).to.be(features[1].get('test'));
expect(getCache(features[1], renderer).geometry).to.be(
features[1].getGeometry()
);
expect(getCache(features[1], renderer).properties['test']).to.be(
features[1].get('test')
);
expect(getCache(features[2], renderer).feature).to.be(features[2]);
expect(getCache(features[2], renderer).geometry).to.be(features[2].getGeometry());
expect(getCache(features[2], renderer).properties['test']).to.be(features[2].get('test'));
expect(getCache(features[2], renderer).geometry).to.be(
features[2].getGeometry()
);
expect(getCache(features[2], renderer).properties['test']).to.be(
features[2].get('test')
);
});
it('contains the features added to the source', function() {
it('contains the features added to the source', function () {
const renderer = new WebGLPointsLayerRenderer(layer, {
vertexShader: simpleVertexShader,
fragmentShader: simpleFragmentShader
fragmentShader: simpleFragmentShader,
});
source.addFeature(features[0]);
@@ -459,17 +524,25 @@ describe('ol.renderer.webgl.PointsLayer', function() {
expect(renderer.featureCount_).to.be(2);
expect(getCache(features[0], renderer).feature).to.be(features[0]);
expect(getCache(features[0], renderer).geometry).to.be(features[0].getGeometry());
expect(getCache(features[0], renderer).properties['test']).to.be(features[0].get('test'));
expect(getCache(features[0], renderer).geometry).to.be(
features[0].getGeometry()
);
expect(getCache(features[0], renderer).properties['test']).to.be(
features[0].get('test')
);
expect(getCache(features[1], renderer).feature).to.be(features[1]);
expect(getCache(features[1], renderer).geometry).to.be(features[1].getGeometry());
expect(getCache(features[1], renderer).properties['test']).to.be(features[1].get('test'));
expect(getCache(features[1], renderer).geometry).to.be(
features[1].getGeometry()
);
expect(getCache(features[1], renderer).properties['test']).to.be(
features[1].get('test')
);
});
it('does not contain the features removed to the source', function() {
it('does not contain the features removed to the source', function () {
const renderer = new WebGLPointsLayerRenderer(layer, {
vertexShader: simpleVertexShader,
fragmentShader: simpleFragmentShader
fragmentShader: simpleFragmentShader,
});
source.addFeatures(features);
@@ -479,17 +552,25 @@ describe('ol.renderer.webgl.PointsLayer', function() {
expect(renderer.featureCount_).to.be(2);
expect(getCache(features[0], renderer).feature).to.be(features[0]);
expect(getCache(features[0], renderer).geometry).to.be(features[0].getGeometry());
expect(getCache(features[0], renderer).properties['test']).to.be(features[0].get('test'));
expect(getCache(features[0], renderer).geometry).to.be(
features[0].getGeometry()
);
expect(getCache(features[0], renderer).properties['test']).to.be(
features[0].get('test')
);
expect(getCache(features[2], renderer).feature).to.be(features[2]);
expect(getCache(features[2], renderer).geometry).to.be(features[2].getGeometry());
expect(getCache(features[2], renderer).properties['test']).to.be(features[2].get('test'));
expect(getCache(features[2], renderer).geometry).to.be(
features[2].getGeometry()
);
expect(getCache(features[2], renderer).properties['test']).to.be(
features[2].get('test')
);
});
it('contains up to date properties and geometry', function() {
it('contains up to date properties and geometry', function () {
const renderer = new WebGLPointsLayerRenderer(layer, {
vertexShader: simpleVertexShader,
fragmentShader: simpleFragmentShader
fragmentShader: simpleFragmentShader,
});
source.addFeatures(features);
@@ -499,10 +580,16 @@ describe('ol.renderer.webgl.PointsLayer', function() {
expect(renderer.featureCount_).to.be(3);
expect(getCache(features[0], renderer).feature).to.be(features[0]);
expect(getCache(features[0], renderer).geometry.getCoordinates()).to.eql([10, 20]);
expect(getCache(features[0], renderer).properties['test']).to.be(features[0].get('test'));
expect(getCache(features[0], renderer).properties['added']).to.be(features[0].get('added'));
expect(getCache(features[0], renderer).geometry.getCoordinates()).to.eql([
10,
20,
]);
expect(getCache(features[0], renderer).properties['test']).to.be(
features[0].get('test')
);
expect(getCache(features[0], renderer).properties['added']).to.be(
features[0].get('added')
);
});
});
});