Merge pull request #1754 from tschaub/clip
Track max extent for replay and limit draw instructions outside that extent.
This commit is contained in:
64
examples/fractal.html
Normal file
64
examples/fractal.html
Normal file
@@ -0,0 +1,64 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
|
||||
<link rel="stylesheet" href="../css/ol.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap.min.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/layout.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap-responsive.min.css" type="text/css">
|
||||
<title>Fractal Example</title>
|
||||
<style>
|
||||
.map {
|
||||
background: whitesmoke;
|
||||
}
|
||||
#depth {
|
||||
width: 100px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="brand" href="./"><img src="../resources/logo.png"> OpenLayers 3 Examples</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<div id="map" class="map"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
<div class="span12">
|
||||
<h4 id="title">Fractal Example</h4>
|
||||
<p id="shortdesc">Example of a fractal.</p>
|
||||
<label for="depth">
|
||||
depth:
|
||||
<input id="depth" type="range" min="0" max="9" step="1" value="5">
|
||||
(<span id="count">#</span> points)
|
||||
</label>
|
||||
<div id="docs">
|
||||
<p>See the <a href="fractal.js" target="_blank">fractal.js source</a> to see how this is done.</p>
|
||||
</div>
|
||||
<div id="tags">fractal, vector</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="jquery.min.js" type="text/javascript"></script>
|
||||
<script src="../resources/example-behaviour.js" type="text/javascript"></script>
|
||||
<script src="loader.js?id=fractal" type="text/javascript"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
125
examples/fractal.js
Normal file
125
examples/fractal.js
Normal file
@@ -0,0 +1,125 @@
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View2D');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.Vector');
|
||||
|
||||
var radius = 10e6;
|
||||
var cos30 = Math.cos(Math.PI / 6);
|
||||
var sin30 = Math.sin(Math.PI / 6);
|
||||
var rise = radius * sin30;
|
||||
var run = radius * cos30;
|
||||
|
||||
var triangle = new ol.geom.LineString([
|
||||
[0, radius], [run, -rise], [-run, -rise], [0, radius]
|
||||
]);
|
||||
|
||||
var feature = new ol.Feature(triangle);
|
||||
|
||||
var layer = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
features: [feature]
|
||||
})
|
||||
});
|
||||
|
||||
var map = new ol.Map({
|
||||
layers: [layer],
|
||||
renderer: 'canvas',
|
||||
target: 'map',
|
||||
view: new ol.View2D({
|
||||
center: [0, 0],
|
||||
zoom: 1
|
||||
})
|
||||
});
|
||||
|
||||
function makeFractal(depth) {
|
||||
var geometry = /** @type {ol.geom.LineString} */ (triangle.clone());
|
||||
var graph = coordsToGraph(geometry.getCoordinates());
|
||||
for (var i = 0; i < depth; ++i) {
|
||||
var node = graph;
|
||||
while (node.next) {
|
||||
var next = node.next;
|
||||
injectNodes(node);
|
||||
node = next;
|
||||
}
|
||||
}
|
||||
var coordinates = graphToCoords(graph);
|
||||
document.getElementById('count').innerHTML = coordinates.length;
|
||||
geometry.setCoordinates(coordinates);
|
||||
feature.setGeometry(geometry);
|
||||
}
|
||||
|
||||
function injectNodes(startNode) {
|
||||
var endNode = startNode.next;
|
||||
|
||||
var start = startNode.point;
|
||||
var end = startNode.next.point;
|
||||
var dx = end[0] - start[0];
|
||||
var dy = end[1] - start[1];
|
||||
|
||||
// first point at 1/3 along the segment
|
||||
var firstNode = {
|
||||
point: [start[0] + dx / 3, start[1] + dy / 3]
|
||||
};
|
||||
|
||||
// second point at peak of _/\_
|
||||
var r = Math.sqrt(dx * dx + dy * dy) / (2 * cos30);
|
||||
var a = Math.atan2(dy, dx) + Math.PI / 6;
|
||||
var secondNode = {
|
||||
point: [start[0] + r * Math.cos(a), start[1] + r * Math.sin(a)]
|
||||
};
|
||||
|
||||
// third point at 2/3 along the segment
|
||||
var thirdNode = {
|
||||
point: [end[0] - dx / 3, end[1] - dy / 3]
|
||||
};
|
||||
|
||||
startNode.next = firstNode;
|
||||
firstNode.next = secondNode;
|
||||
secondNode.next = thirdNode;
|
||||
thirdNode.next = endNode;
|
||||
}
|
||||
|
||||
|
||||
function coordsToGraph(coordinates) {
|
||||
var graph = {
|
||||
point: coordinates[0]
|
||||
};
|
||||
var length = coordinates.length;
|
||||
for (var level = 0, node = graph; level < length - 1; ++level) {
|
||||
node.next = {
|
||||
point: coordinates[level + 1]
|
||||
};
|
||||
node = node.next;
|
||||
}
|
||||
return graph;
|
||||
}
|
||||
|
||||
function graphToCoords(graph) {
|
||||
var coordinates = [graph.point];
|
||||
for (var node = graph, i = 1; node.next; node = node.next, ++i) {
|
||||
coordinates[i] = node.next.point;
|
||||
}
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
var depthInput = document.getElementById('depth');
|
||||
|
||||
function update() {
|
||||
makeFractal(Number(depthInput.value));
|
||||
}
|
||||
|
||||
var updateTimer;
|
||||
|
||||
|
||||
/**
|
||||
* Regenerate fractal on depth change. Change events are debounced so updates
|
||||
* only occur every 200ms.
|
||||
*/
|
||||
depthInput.onchange = function() {
|
||||
window.clearTimeout(updateTimer);
|
||||
updateTimer = window.setTimeout(update, 200);
|
||||
};
|
||||
|
||||
update();
|
||||
135
src/ol/extent.js
135
src/ol/extent.js
@@ -1,7 +1,9 @@
|
||||
goog.provide('ol.Extent');
|
||||
goog.provide('ol.extent');
|
||||
goog.provide('ol.extent.Relationship');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.Size');
|
||||
goog.require('ol.TransformFunction');
|
||||
@@ -15,6 +17,20 @@ goog.require('ol.TransformFunction');
|
||||
ol.Extent;
|
||||
|
||||
|
||||
/**
|
||||
* Relationship to an extent.
|
||||
* @enum {number}
|
||||
*/
|
||||
ol.extent.Relationship = {
|
||||
UNKNOWN: 0,
|
||||
INTERSECTING: 1,
|
||||
ABOVE: 2,
|
||||
RIGHT: 4,
|
||||
BELOW: 8,
|
||||
LEFT: 16
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Builds an extent that includes all given coordinates.
|
||||
*
|
||||
@@ -150,6 +166,38 @@ ol.extent.containsExtent = function(extent1, extent2) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the relationship between a coordinate and extent.
|
||||
* @param {ol.Extent} extent The extent.
|
||||
* @param {ol.Coordinate} coordinate The coordinate.
|
||||
* @return {number} The relationship (bitwise compare with
|
||||
* ol.extent.Relationship).
|
||||
*/
|
||||
ol.extent.coordinateRelationship = function(extent, coordinate) {
|
||||
var minX = extent[0];
|
||||
var minY = extent[1];
|
||||
var maxX = extent[2];
|
||||
var maxY = extent[3];
|
||||
var x = coordinate[0];
|
||||
var y = coordinate[1];
|
||||
var relationship = ol.extent.Relationship.UNKNOWN;
|
||||
if (x < minX) {
|
||||
relationship = relationship | ol.extent.Relationship.LEFT;
|
||||
} else if (x > maxX) {
|
||||
relationship = relationship | ol.extent.Relationship.RIGHT;
|
||||
}
|
||||
if (y < minY) {
|
||||
relationship = relationship | ol.extent.Relationship.BELOW;
|
||||
} else if (y > maxY) {
|
||||
relationship = relationship | ol.extent.Relationship.ABOVE;
|
||||
}
|
||||
if (relationship === ol.extent.Relationship.UNKNOWN) {
|
||||
relationship = ol.extent.Relationship.INTERSECTING;
|
||||
}
|
||||
return relationship;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Extent} Empty extent.
|
||||
* @todo stability experimental
|
||||
@@ -596,6 +644,59 @@ ol.extent.scaleFromCenter = function(extent, value) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Determine if the segment between two coordinates intersects (crosses,
|
||||
* touches, or is contained by) the provided extent.
|
||||
* @param {ol.Extent} extent The extent.
|
||||
* @param {ol.Coordinate} start Segment start coordinate.
|
||||
* @param {ol.Coordinate} end Segment end coordinate.
|
||||
* @return {boolean} The segment intersects the extent.
|
||||
*/
|
||||
ol.extent.segmentIntersects = function(extent, start, end) {
|
||||
var intersects = false;
|
||||
var startRel = ol.extent.coordinateRelationship(extent, start);
|
||||
var endRel = ol.extent.coordinateRelationship(extent, end);
|
||||
if (startRel === ol.extent.Relationship.INTERSECTING ||
|
||||
endRel === ol.extent.Relationship.INTERSECTING) {
|
||||
intersects = true;
|
||||
} else {
|
||||
var minX = extent[0];
|
||||
var minY = extent[1];
|
||||
var maxX = extent[2];
|
||||
var maxY = extent[3];
|
||||
var startX = start[0];
|
||||
var startY = start[1];
|
||||
var endX = end[0];
|
||||
var endY = end[1];
|
||||
var slope = (endY - startY) / (endX - startX);
|
||||
var x, y;
|
||||
if (!!(endRel & ol.extent.Relationship.ABOVE) &&
|
||||
!(startRel & ol.extent.Relationship.ABOVE)) {
|
||||
// potentially intersects top
|
||||
x = endX - ((endY - maxY) / slope);
|
||||
intersects = x >= minX && x <= maxX;
|
||||
} else if (!!(endRel & ol.extent.Relationship.RIGHT) &&
|
||||
!(startRel & ol.extent.Relationship.RIGHT)) {
|
||||
// potentially intersects right
|
||||
y = endY - ((endX - maxX) * slope);
|
||||
intersects = y >= minY && y <= maxY;
|
||||
} else if (!!(endRel & ol.extent.Relationship.BELOW) &&
|
||||
!(startRel & ol.extent.Relationship.BELOW)) {
|
||||
// potentially intersects bottom
|
||||
x = endX - ((endY - minY) / slope);
|
||||
intersects = x >= minX && x <= maxX;
|
||||
} else if (!!(endRel & ol.extent.Relationship.LEFT) &&
|
||||
!(startRel & ol.extent.Relationship.LEFT)) {
|
||||
// potentially intersects left
|
||||
y = endY - ((endX - minX) * slope);
|
||||
intersects = y >= minY && y <= maxY;
|
||||
}
|
||||
|
||||
}
|
||||
return intersects;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} extent1 Extent 1.
|
||||
* @param {ol.Extent} extent2 Extent 2.
|
||||
@@ -629,3 +730,37 @@ ol.extent.transform = function(extent, transformFn, opt_extent) {
|
||||
var ys = [coordinates[1], coordinates[3], coordinates[5], coordinates[7]];
|
||||
return ol.extent.boundingExtentXYs_(xs, ys, opt_extent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Apply a 2d transform to an extent.
|
||||
* @param {ol.Extent} extent Input extent.
|
||||
* @param {goog.vec.Mat4.Number} transform The transform matrix.
|
||||
* @param {ol.Extent=} opt_extent Optional extent for return values.
|
||||
* @return {ol.Extent} The transformed extent.
|
||||
*/
|
||||
ol.extent.transform2D = function(extent, transform, opt_extent) {
|
||||
var dest = goog.isDef(opt_extent) ? opt_extent : [];
|
||||
var m00 = goog.vec.Mat4.getElement(transform, 0, 0);
|
||||
var m10 = goog.vec.Mat4.getElement(transform, 1, 0);
|
||||
var m01 = goog.vec.Mat4.getElement(transform, 0, 1);
|
||||
var m11 = goog.vec.Mat4.getElement(transform, 1, 1);
|
||||
var m03 = goog.vec.Mat4.getElement(transform, 0, 3);
|
||||
var m13 = goog.vec.Mat4.getElement(transform, 1, 3);
|
||||
var xi = [0, 2, 0, 2];
|
||||
var yi = [1, 1, 3, 3];
|
||||
var xs = [];
|
||||
var ys = [];
|
||||
var i, x, y;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
x = extent[xi[i]];
|
||||
y = extent[yi[i]];
|
||||
xs[i] = m00 * x + m01 * y + m03;
|
||||
ys[i] = m10 * x + m11 * y + m13;
|
||||
}
|
||||
dest[0] = Math.min.apply(null, xs);
|
||||
dest[1] = Math.min.apply(null, ys);
|
||||
dest[2] = Math.max.apply(null, xs);
|
||||
dest[3] = Math.max.apply(null, ys);
|
||||
return dest;
|
||||
};
|
||||
|
||||
@@ -14,6 +14,7 @@ goog.require('ol.BrowserFeature');
|
||||
goog.require('ol.array');
|
||||
goog.require('ol.color');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.extent.Relationship');
|
||||
goog.require('ol.geom.flat');
|
||||
goog.require('ol.geom.simplify');
|
||||
goog.require('ol.render.IReplayGroup');
|
||||
@@ -47,10 +48,11 @@ ol.render.canvas.Instruction = {
|
||||
* @constructor
|
||||
* @implements {ol.render.IVectorContext}
|
||||
* @param {number} tolerance Tolerance.
|
||||
* @param {ol.Extent} maxExtent Maximum extent.
|
||||
* @protected
|
||||
* @struct
|
||||
*/
|
||||
ol.render.canvas.Replay = function(tolerance) {
|
||||
ol.render.canvas.Replay = function(tolerance, maxExtent) {
|
||||
|
||||
/**
|
||||
* @protected
|
||||
@@ -58,6 +60,12 @@ ol.render.canvas.Replay = function(tolerance) {
|
||||
*/
|
||||
this.tolerance = tolerance;
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @type {ol.Extent}
|
||||
*/
|
||||
this.maxExtent = maxExtent;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<*>}
|
||||
@@ -126,12 +134,38 @@ ol.render.canvas.Replay = function(tolerance) {
|
||||
*/
|
||||
ol.render.canvas.Replay.prototype.appendFlatCoordinates =
|
||||
function(flatCoordinates, offset, end, stride, close) {
|
||||
|
||||
var myEnd = this.coordinates.length;
|
||||
var i;
|
||||
for (i = offset; i < end; i += stride) {
|
||||
this.coordinates[myEnd++] = flatCoordinates[i];
|
||||
this.coordinates[myEnd++] = flatCoordinates[i + 1];
|
||||
var extent = this.maxExtent;
|
||||
var lastCoord = [flatCoordinates[offset], flatCoordinates[offset + 1]];
|
||||
var nextCoord = [NaN, NaN];
|
||||
var skipped = true;
|
||||
|
||||
var i, lastRel, nextRel;
|
||||
for (i = offset + stride; i < end; i += stride) {
|
||||
nextCoord[0] = flatCoordinates[i];
|
||||
nextCoord[1] = flatCoordinates[i + 1];
|
||||
nextRel = ol.extent.coordinateRelationship(extent, nextCoord);
|
||||
if (nextRel !== lastRel) {
|
||||
if (skipped) {
|
||||
this.coordinates[myEnd++] = lastCoord[0];
|
||||
this.coordinates[myEnd++] = lastCoord[1];
|
||||
}
|
||||
this.coordinates[myEnd++] = nextCoord[0];
|
||||
this.coordinates[myEnd++] = nextCoord[1];
|
||||
skipped = false;
|
||||
} else if (nextRel === ol.extent.Relationship.INTERSECTING) {
|
||||
this.coordinates[myEnd++] = nextCoord[0];
|
||||
this.coordinates[myEnd++] = nextCoord[1];
|
||||
skipped = false;
|
||||
} else {
|
||||
skipped = true;
|
||||
}
|
||||
lastCoord[0] = nextCoord[0];
|
||||
lastCoord[1] = nextCoord[1];
|
||||
lastRel = nextRel;
|
||||
}
|
||||
|
||||
if (close) {
|
||||
this.coordinates[myEnd++] = flatCoordinates[offset];
|
||||
this.coordinates[myEnd++] = flatCoordinates[offset + 1];
|
||||
@@ -582,12 +616,13 @@ ol.render.canvas.Replay.prototype.setTextStyle = goog.abstractMethod;
|
||||
* @constructor
|
||||
* @extends {ol.render.canvas.Replay}
|
||||
* @param {number} tolerance Tolerance.
|
||||
* @param {ol.Extent} maxExtent Maximum extent.
|
||||
* @protected
|
||||
* @struct
|
||||
*/
|
||||
ol.render.canvas.ImageReplay = function(tolerance) {
|
||||
ol.render.canvas.ImageReplay = function(tolerance, maxExtent) {
|
||||
|
||||
goog.base(this, tolerance);
|
||||
goog.base(this, tolerance, maxExtent);
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -810,12 +845,13 @@ ol.render.canvas.ImageReplay.prototype.setImageStyle = function(imageStyle) {
|
||||
* @constructor
|
||||
* @extends {ol.render.canvas.Replay}
|
||||
* @param {number} tolerance Tolerance.
|
||||
* @param {ol.Extent} maxExtent Maximum extent.
|
||||
* @protected
|
||||
* @struct
|
||||
*/
|
||||
ol.render.canvas.LineStringReplay = function(tolerance) {
|
||||
ol.render.canvas.LineStringReplay = function(tolerance, maxExtent) {
|
||||
|
||||
goog.base(this, tolerance);
|
||||
goog.base(this, tolerance, maxExtent);
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -1027,12 +1063,13 @@ ol.render.canvas.LineStringReplay.prototype.setFillStrokeStyle =
|
||||
* @constructor
|
||||
* @extends {ol.render.canvas.Replay}
|
||||
* @param {number} tolerance Tolerance.
|
||||
* @param {ol.Extent} maxExtent Maximum extent.
|
||||
* @protected
|
||||
* @struct
|
||||
*/
|
||||
ol.render.canvas.PolygonReplay = function(tolerance) {
|
||||
ol.render.canvas.PolygonReplay = function(tolerance, maxExtent) {
|
||||
|
||||
goog.base(this, tolerance);
|
||||
goog.base(this, tolerance, maxExtent);
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -1360,12 +1397,13 @@ ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyles_ = function() {
|
||||
* @constructor
|
||||
* @extends {ol.render.canvas.Replay}
|
||||
* @param {number} tolerance Tolerance.
|
||||
* @param {ol.Extent} maxExtent Maximum extent.
|
||||
* @protected
|
||||
* @struct
|
||||
*/
|
||||
ol.render.canvas.TextReplay = function(tolerance) {
|
||||
ol.render.canvas.TextReplay = function(tolerance, maxExtent) {
|
||||
|
||||
goog.base(this, tolerance);
|
||||
goog.base(this, tolerance, maxExtent);
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -1659,9 +1697,10 @@ ol.render.canvas.TextReplay.prototype.setTextStyle = function(textStyle) {
|
||||
* @constructor
|
||||
* @implements {ol.render.IReplayGroup}
|
||||
* @param {number} tolerance Tolerance.
|
||||
* @param {ol.Extent} maxExtent Max extent.
|
||||
* @struct
|
||||
*/
|
||||
ol.render.canvas.ReplayGroup = function(tolerance) {
|
||||
ol.render.canvas.ReplayGroup = function(tolerance, maxExtent) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -1669,6 +1708,12 @@ ol.render.canvas.ReplayGroup = function(tolerance) {
|
||||
*/
|
||||
this.tolerance_ = tolerance;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Extent}
|
||||
*/
|
||||
this.maxExtent_ = maxExtent;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string,
|
||||
@@ -1772,6 +1817,23 @@ ol.render.canvas.ReplayGroup.prototype.replayHitDetection_ = function(
|
||||
ol.render.canvas.ReplayGroup.prototype.replay_ = function(
|
||||
zs, context, extent, pixelRatio, transform, viewRotation,
|
||||
renderGeometryFunction) {
|
||||
|
||||
var maxExtent = this.maxExtent_;
|
||||
var minX = maxExtent[0];
|
||||
var minY = maxExtent[1];
|
||||
var maxX = maxExtent[2];
|
||||
var maxY = maxExtent[3];
|
||||
var flatClipCoords = ol.geom.flat.transform2D(
|
||||
[minX, minY, minX, maxY, maxX, maxY, maxX, minY], 2, transform);
|
||||
context.save();
|
||||
context.beginPath();
|
||||
context.moveTo(flatClipCoords[0], flatClipCoords[1]);
|
||||
context.lineTo(flatClipCoords[2], flatClipCoords[3]);
|
||||
context.lineTo(flatClipCoords[4], flatClipCoords[5]);
|
||||
context.lineTo(flatClipCoords[6], flatClipCoords[7]);
|
||||
context.closePath();
|
||||
context.clip();
|
||||
|
||||
var i, ii, j, jj, replays, replayType, replay, result;
|
||||
for (i = 0, ii = zs.length; i < ii; ++i) {
|
||||
replays = this.replaysByZIndex_[zs[i].toString()];
|
||||
@@ -1787,6 +1849,8 @@ ol.render.canvas.ReplayGroup.prototype.replay_ = function(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.restore();
|
||||
return undefined;
|
||||
};
|
||||
|
||||
@@ -1866,9 +1930,9 @@ ol.render.canvas.ReplayGroup.prototype.getReplay =
|
||||
}
|
||||
var replay = replays[replayType];
|
||||
if (!goog.isDef(replay)) {
|
||||
var constructor = ol.render.canvas.BATCH_CONSTRUCTORS_[replayType];
|
||||
goog.asserts.assert(goog.isDef(constructor));
|
||||
replay = new constructor(this.tolerance_);
|
||||
var Constructor = ol.render.canvas.BATCH_CONSTRUCTORS_[replayType];
|
||||
goog.asserts.assert(goog.isDef(Constructor));
|
||||
replay = new Constructor(this.tolerance_, this.maxExtent_);
|
||||
replays[replayType] = replay;
|
||||
}
|
||||
return replay;
|
||||
@@ -1887,7 +1951,7 @@ ol.render.canvas.ReplayGroup.prototype.isEmpty = function() {
|
||||
* @const
|
||||
* @private
|
||||
* @type {Object.<ol.render.ReplayType,
|
||||
* function(new: ol.render.canvas.Replay, number)>}
|
||||
* function(new: ol.render.canvas.Replay, number, ol.Extent)>}
|
||||
*/
|
||||
ol.render.canvas.BATCH_CONSTRUCTORS_ = {
|
||||
'Image': ol.render.canvas.ImageReplay,
|
||||
|
||||
@@ -243,7 +243,7 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame =
|
||||
styleFunction = ol.feature.defaultStyleFunction;
|
||||
}
|
||||
var tolerance = frameStateResolution / (2 * pixelRatio);
|
||||
var replayGroup = new ol.render.canvas.ReplayGroup(tolerance);
|
||||
var replayGroup = new ol.render.canvas.ReplayGroup(tolerance, extent);
|
||||
vectorSource.forEachFeatureInExtent(extent,
|
||||
/**
|
||||
* @param {ol.Feature} feature Feature.
|
||||
|
||||
@@ -111,7 +111,7 @@ ol.source.ImageVector.prototype.canvasFunctionInternal_ =
|
||||
function(extent, resolution, pixelRatio, size, projection) {
|
||||
|
||||
var tolerance = resolution / (2 * pixelRatio);
|
||||
var replayGroup = new ol.render.canvas.ReplayGroup(tolerance);
|
||||
var replayGroup = new ol.render.canvas.ReplayGroup(tolerance, extent);
|
||||
|
||||
var loading = false;
|
||||
this.source_.forEachFeatureInExtent(extent,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
goog.provide('ol.test.extent');
|
||||
|
||||
|
||||
describe('ol.extent', function() {
|
||||
|
||||
describe('buffer', function() {
|
||||
@@ -65,6 +64,86 @@ describe('ol.extent', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('coordinateRelationship()', function() {
|
||||
|
||||
var extent = [-180, -90, 180, 90];
|
||||
var INTERSECTING = ol.extent.Relationship.INTERSECTING;
|
||||
var ABOVE = ol.extent.Relationship.ABOVE;
|
||||
var RIGHT = ol.extent.Relationship.RIGHT;
|
||||
var BELOW = ol.extent.Relationship.BELOW;
|
||||
var LEFT = ol.extent.Relationship.LEFT;
|
||||
|
||||
it('returns intersecting for within', function() {
|
||||
var rel = ol.extent.coordinateRelationship(extent, [0, 0]);
|
||||
expect(rel).to.be(INTERSECTING);
|
||||
});
|
||||
|
||||
it('returns intersecting for touching top', function() {
|
||||
var rel = ol.extent.coordinateRelationship(extent, [0, 90]);
|
||||
expect(rel).to.be(INTERSECTING);
|
||||
});
|
||||
|
||||
it('returns intersecting for touching right', function() {
|
||||
var rel = ol.extent.coordinateRelationship(extent, [180, 0]);
|
||||
expect(rel).to.be(INTERSECTING);
|
||||
});
|
||||
|
||||
it('returns intersecting for touching bottom', function() {
|
||||
var rel = ol.extent.coordinateRelationship(extent, [0, -90]);
|
||||
expect(rel).to.be(INTERSECTING);
|
||||
});
|
||||
|
||||
it('returns intersecting for touching left', function() {
|
||||
var rel = ol.extent.coordinateRelationship(extent, [-180, 0]);
|
||||
expect(rel).to.be(INTERSECTING);
|
||||
});
|
||||
|
||||
it('above for north', function() {
|
||||
var rel = ol.extent.coordinateRelationship(extent, [0, 100]);
|
||||
expect(rel).to.be(ABOVE);
|
||||
});
|
||||
|
||||
it('above and right for northeast', function() {
|
||||
var rel = ol.extent.coordinateRelationship(extent, [190, 100]);
|
||||
expect(rel & ABOVE).to.be(ABOVE);
|
||||
expect(rel & RIGHT).to.be(RIGHT);
|
||||
});
|
||||
|
||||
it('right for east', function() {
|
||||
var rel = ol.extent.coordinateRelationship(extent, [190, 0]);
|
||||
expect(rel).to.be(RIGHT);
|
||||
});
|
||||
|
||||
it('below and right for southeast', function() {
|
||||
var rel = ol.extent.coordinateRelationship(extent, [190, -100]);
|
||||
expect(rel & BELOW).to.be(BELOW);
|
||||
expect(rel & RIGHT).to.be(RIGHT);
|
||||
});
|
||||
|
||||
it('below for south', function() {
|
||||
var rel = ol.extent.coordinateRelationship(extent, [0, -100]);
|
||||
expect(rel).to.be(BELOW);
|
||||
});
|
||||
|
||||
it('below and left for southwest', function() {
|
||||
var rel = ol.extent.coordinateRelationship(extent, [-190, -100]);
|
||||
expect(rel & BELOW).to.be(BELOW);
|
||||
expect(rel & LEFT).to.be(LEFT);
|
||||
});
|
||||
|
||||
it('left for west', function() {
|
||||
var rel = ol.extent.coordinateRelationship(extent, [-190, 0]);
|
||||
expect(rel).to.be(LEFT);
|
||||
});
|
||||
|
||||
it('above and left for northwest', function() {
|
||||
var rel = ol.extent.coordinateRelationship(extent, [-190, 100]);
|
||||
expect(rel & ABOVE).to.be(ABOVE);
|
||||
expect(rel & LEFT).to.be(LEFT);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('getCenter', function() {
|
||||
it('returns the expected center', function() {
|
||||
var extent = [1, 2, 3, 4];
|
||||
@@ -221,6 +300,131 @@ describe('ol.extent', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('segmentIntersects()', function() {
|
||||
|
||||
var extent = [-180, -90, 180, 90];
|
||||
var north = [0, 100];
|
||||
var northeast = [190, 100];
|
||||
var east = [190, 0];
|
||||
var southeast = [190, -100];
|
||||
var south = [0, -100];
|
||||
var southwest = [-190, -100];
|
||||
var west = [-190, 0];
|
||||
var northwest = [-190, 100];
|
||||
var center = [0, 0];
|
||||
var top = [0, 90];
|
||||
var right = [180, 0];
|
||||
var bottom = [-90, 0];
|
||||
var left = [-180, 0];
|
||||
var inside = [10, 10];
|
||||
|
||||
it('returns true if contained', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, center, inside);
|
||||
expect(intersects).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true if crosses top', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, center, north);
|
||||
expect(intersects).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true if crosses right', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, center, east);
|
||||
expect(intersects).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true if crosses bottom', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, center, south);
|
||||
expect(intersects).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true if crosses left', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, center, west);
|
||||
expect(intersects).to.be(true);
|
||||
});
|
||||
|
||||
it('returns false if above', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, northwest, north);
|
||||
expect(intersects).to.be(false);
|
||||
});
|
||||
|
||||
it('returns false if right', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, northeast, east);
|
||||
expect(intersects).to.be(false);
|
||||
});
|
||||
|
||||
it('returns false if below', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, south, southwest);
|
||||
expect(intersects).to.be(false);
|
||||
});
|
||||
|
||||
it('returns false if left', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, west, southwest);
|
||||
expect(intersects).to.be(false);
|
||||
});
|
||||
|
||||
it('returns true if crosses top to bottom', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, north, south);
|
||||
expect(intersects).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true if crosses bottom to top', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, south, north);
|
||||
expect(intersects).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true if crosses left to right', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, west, east);
|
||||
expect(intersects).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true if crosses right to left', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, east, west);
|
||||
expect(intersects).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true if crosses northwest to east', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, northwest, east);
|
||||
expect(intersects).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true if crosses south to west', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, south, west);
|
||||
expect(intersects).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true if touches top', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, northwest, top);
|
||||
expect(intersects).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true if touches right', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, southeast, right);
|
||||
expect(intersects).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true if touches bottom', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, bottom, south);
|
||||
expect(intersects).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true if touches left', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, left, west);
|
||||
expect(intersects).to.be(true);
|
||||
});
|
||||
|
||||
it('works for zero length inside', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, center, center);
|
||||
expect(intersects).to.be(true);
|
||||
});
|
||||
|
||||
it('works for zero length outside', function() {
|
||||
var intersects = ol.extent.segmentIntersects(extent, north, north);
|
||||
expect(intersects).to.be(false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('transform', function() {
|
||||
|
||||
it('does transform', function() {
|
||||
@@ -263,8 +467,50 @@ describe('ol.extent', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('transform2D()', function() {
|
||||
|
||||
var extent;
|
||||
beforeEach(function() {
|
||||
extent = [-180, -90, 180, 90];
|
||||
});
|
||||
|
||||
it('applies a translate transform', function() {
|
||||
var mat = goog.vec.Mat4.createNumber();
|
||||
goog.vec.Mat4.makeTranslate(mat, 10, 20, 0);
|
||||
var transformed = ol.extent.transform2D(extent, mat);
|
||||
expect(transformed).to.eql([-170, -70, 190, 110]);
|
||||
});
|
||||
|
||||
it('applies a rotate transform', function() {
|
||||
var mat = goog.vec.Mat4.createNumber();
|
||||
goog.vec.Mat4.makeRotateZ(mat, Math.PI / 2);
|
||||
var transformed = ol.extent.transform2D(extent, mat);
|
||||
expect(transformed[0]).to.roughlyEqual(-90, 1e-5);
|
||||
expect(transformed[1]).to.roughlyEqual(-180, 1e-5);
|
||||
expect(transformed[2]).to.roughlyEqual(90, 1e-5);
|
||||
expect(transformed[3]).to.roughlyEqual(180, 1e-5);
|
||||
});
|
||||
|
||||
it('does not modify original', function() {
|
||||
var mat = goog.vec.Mat4.createNumber();
|
||||
goog.vec.Mat4.makeRotateZ(mat, Math.PI / 2);
|
||||
ol.extent.transform2D(extent, mat);
|
||||
expect(extent).to.eql([-180, -90, 180, 90]);
|
||||
});
|
||||
|
||||
it('accepts an extent to modify', function() {
|
||||
var mat = goog.vec.Mat4.createNumber();
|
||||
goog.vec.Mat4.makeScale(mat, 2, 0.5);
|
||||
ol.extent.transform2D(extent, mat, extent);
|
||||
expect(extent).to.eql([-360, -45, 360, 45]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.extent.Relationship');
|
||||
goog.require('ol.proj');
|
||||
|
||||
Reference in New Issue
Block a user