Merge pull request #1959 from elemoine/feature-box-selection

Add a feature box selection example
This commit is contained in:
Éric Lemoine
2014-09-17 15:02:23 +02:00
18 changed files with 702 additions and 25 deletions

View File

@@ -0,0 +1,59 @@
<!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>Box selection example</title>
</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="span4">
<h4 id="title">Box selection example</h4>
<p id="shortdesc">Using a DragBox interaction to select features.</p>
<div id="docs">
<p>This example shows how to use a <code>DragBox</code> interaction to select features. Selected features are added
to the feature overlay of a select interaction (<code>ol.interaction.Select</code>) for highlighting.</p>
<p>Use <code>SHIFT+drag</code> to draw boxes.</p>
<p>See the <a href="box-selection.js" target="_blank">box-selection.js source</a> to see how this is done.</p>
</div>
<div id="tags">DragBox, feature, selection, box</div>
</div>
<div class="span4 offset4">
<div id="info" class="alert alert-success">
&nbsp;
</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=box-selection" type="text/javascript"></script>
</body>
</html>

81
examples/box-selection.js Normal file
View File

@@ -0,0 +1,81 @@
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.events.condition');
goog.require('ol.interaction');
goog.require('ol.interaction.DragBox');
goog.require('ol.interaction.Select');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
goog.require('ol.source.GeoJSON');
goog.require('ol.source.OSM');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
var vectorSource = new ol.source.GeoJSON({
projection: 'EPSG:3857',
url: 'data/geojson/countries.geojson'
});
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
new ol.layer.Vector({
source: vectorSource
})
],
renderer: 'canvas',
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
// a normal select interaction to handle click
var select = new ol.interaction.Select();
map.addInteraction(select);
var selectedFeatures = select.getFeatures();
// a DragBox interaction used to select features by drawing boxes
var dragBox = new ol.interaction.DragBox({
condition: ol.events.condition.shiftKeyOnly,
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: [0, 0, 255, 1]
})
})
});
map.addInteraction(dragBox);
var infoBox = document.getElementById('info');
dragBox.on('boxend', function(e) {
// features that intersect the box are added to the collection of
// selected features, and their names are displayed in the "info"
// div
var info = [];
var extent = dragBox.getGeometry().getExtent();
vectorSource.forEachFeatureIntersectingExtent(extent, function(feature) {
selectedFeatures.push(feature);
info.push(feature.get('name'));
});
if (info.length > 0) {
infoBox.innerHTML = info.join(', ');
}
});
// clear selection when drawing a new box and when clicking on the map
dragBox.on('boxstart', function(e) {
selectedFeatures.clear();
infoBox.innerHTML = '&nbsp;';
});
map.on('click', function() {
selectedFeatures.clear();
infoBox.innerHTML = '&nbsp;';
});

View File

@@ -159,8 +159,7 @@ ol.extent.closestSquaredDistanceXY = function(extent, x, y) {
* @api stable
*/
ol.extent.containsCoordinate = function(extent, coordinate) {
return extent[0] <= coordinate[0] && coordinate[0] <= extent[2] &&
extent[1] <= coordinate[1] && coordinate[1] <= extent[3];
return ol.extent.containsXY(extent, coordinate[0], coordinate[1]);
};
@@ -178,6 +177,20 @@ ol.extent.containsExtent = function(extent1, extent2) {
};
/**
* Checks if the passed coordinate is contained or on the edge of the extent.
*
* @param {ol.Extent} extent Extent.
* @param {number} x X coordinate.
* @param {number} y Y coordinate.
* @return {boolean} Contains.
* @api stable
*/
ol.extent.containsXY = function(extent, x, y) {
return extent[0] <= x && x <= extent[2] && extent[1] <= y && y <= extent[3];
};
/**
* Get the relationship between a coordinate and extent.
* @param {ol.Extent} extent The extent.
@@ -426,6 +439,38 @@ ol.extent.extendXY = function(extent, x, y) {
};
/**
* This function calls `callback` for each corner of the extent. If the
* callback returns a truthy value the function returns that value
* immediately. Otherwise the function returns `false`.
* @param {ol.Extent} extent Extent.
* @param {function(this:T, ol.Coordinate): S} callback Callback.
* @param {T=} opt_this Value to use as `this` when executing `callback`.
* @return {S|boolean} Value.
* @template S, T
*/
ol.extent.forEachCorner = function(extent, callback, opt_this) {
var val;
val = callback.call(opt_this, ol.extent.getBottomLeft(extent));
if (val) {
return val;
}
val = callback.call(opt_this, ol.extent.getBottomRight(extent));
if (val) {
return val;
}
val = callback.call(opt_this, ol.extent.getTopRight(extent));
if (val) {
return val;
}
val = callback.call(opt_this, ol.extent.getBottomRight(extent));
if (val) {
return val;
}
return false;
};
/**
* @param {ol.Extent} extent Extent.
* @return {number} Area.
@@ -729,7 +774,7 @@ ol.extent.scaleFromCenter = function(extent, value) {
* @param {ol.Coordinate} end Segment end coordinate.
* @return {boolean} The segment intersects the extent.
*/
ol.extent.segmentIntersects = function(extent, start, end) {
ol.extent.intersectsSegment = function(extent, start, end) {
var intersects = false;
var startRel = ol.extent.coordinateRelationship(extent, start);
var endRel = ol.extent.coordinateRelationship(extent, end);

View File

@@ -1,6 +1,29 @@
goog.provide('ol.geom.flat.contains');
goog.require('goog.asserts');
goog.require('ol.extent');
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {number} end End.
* @param {number} stride Stride.
* @param {ol.Extent} extent Extent.
* @return {boolean} Contains extent.
*/
ol.geom.flat.contains.linearRingContainsExtent =
function(flatCoordinates, offset, end, stride, extent) {
var outside = ol.extent.forEachCorner(extent,
/**
* @param {ol.Coordinate} coordinate Coordinate.
*/
function(coordinate) {
return !ol.geom.flat.contains.linearRingContainsXY(flatCoordinates,
offset, end, stride, coordinate[0], coordinate[1]);
});
return !outside;
};
/**

View File

@@ -0,0 +1,154 @@
goog.provide('ol.geom.flat.intersectsextent');
goog.require('goog.asserts');
goog.require('ol.extent');
goog.require('ol.geom.flat.contains');
goog.require('ol.geom.flat.segments');
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {number} end End.
* @param {number} stride Stride.
* @param {ol.Extent} extent Extent.
* @return {boolean} True if the geometry and the extent intersect.
*/
ol.geom.flat.intersectsextent.lineString =
function(flatCoordinates, offset, end, stride, extent) {
var coordinatesExtent = ol.extent.extendFlatCoordinates(
ol.extent.createEmpty(), flatCoordinates, offset, end, stride);
if (!ol.extent.intersects(extent, coordinatesExtent)) {
return false;
}
if (ol.extent.containsExtent(extent, coordinatesExtent)) {
return true;
}
if (coordinatesExtent[0] >= extent[0] &&
coordinatesExtent[2] <= extent[2]) {
return true;
}
if (coordinatesExtent[1] >= extent[1] &&
coordinatesExtent[3] <= extent[3]) {
return true;
}
return ol.geom.flat.segments.forEach(flatCoordinates, offset, end, stride,
/**
* @param {ol.Coordinate} point1 Start point.
* @param {ol.Coordinate} point2 End point.
* @return {boolean} `true` if the segment and the extent intersect,
* `false` otherwise.
*/
function(point1, point2) {
return ol.extent.intersectsSegment(extent, point1, point2);
});
};
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {Array.<number>} ends Ends.
* @param {number} stride Stride.
* @param {ol.Extent} extent Extent.
* @return {boolean} True if the geometry and the extent intersect.
*/
ol.geom.flat.intersectsextent.lineStrings =
function(flatCoordinates, offset, ends, stride, extent) {
var i, ii;
for (i = 0, ii = ends.length; i < ii; ++i) {
if (ol.geom.flat.intersectsextent.lineString(
flatCoordinates, offset, ends[i], stride, extent)) {
return true;
}
offset = ends[i];
}
return false;
};
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {number} end End.
* @param {number} stride Stride.
* @param {ol.Extent} extent Extent.
* @return {boolean} True if the geometry and the extent intersect.
*/
ol.geom.flat.intersectsextent.linearRing =
function(flatCoordinates, offset, end, stride, extent) {
if (ol.geom.flat.intersectsextent.lineString(
flatCoordinates, offset, end, stride, extent)) {
return true;
}
if (ol.geom.flat.contains.linearRingContainsXY(
flatCoordinates, offset, end, stride, extent[0], extent[1])) {
return true;
}
if (ol.geom.flat.contains.linearRingContainsXY(
flatCoordinates, offset, end, stride, extent[0], extent[3])) {
return true;
}
if (ol.geom.flat.contains.linearRingContainsXY(
flatCoordinates, offset, end, stride, extent[2], extent[1])) {
return true;
}
if (ol.geom.flat.contains.linearRingContainsXY(
flatCoordinates, offset, end, stride, extent[2], extent[3])) {
return true;
}
return false;
};
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {Array.<number>} ends Ends.
* @param {number} stride Stride.
* @param {ol.Extent} extent Extent.
* @return {boolean} True if the geometry and the extent intersect.
*/
ol.geom.flat.intersectsextent.linearRings =
function(flatCoordinates, offset, ends, stride, extent) {
goog.asserts.assert(ends.length > 0);
if (!ol.geom.flat.intersectsextent.linearRing(
flatCoordinates, offset, ends[0], stride, extent)) {
return false;
}
if (ends.length === 1) {
return true;
}
var i, ii;
for (i = 1, ii = ends.length; i < ii; ++i) {
if (ol.geom.flat.contains.linearRingContainsExtent(
flatCoordinates, ends[i - 1], ends[i], stride, extent)) {
return false;
}
}
return true;
};
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {Array.<Array.<number>>} endss Endss.
* @param {number} stride Stride.
* @param {ol.Extent} extent Extent.
* @return {boolean} True if the geometry and the extent intersect.
*/
ol.geom.flat.intersectsextent.linearRingss =
function(flatCoordinates, offset, endss, stride, extent) {
goog.asserts.assert(endss.length > 0);
var i, ii;
for (i = 0, ii = endss.length; i < ii; ++i) {
var ends = endss[i];
if (ol.geom.flat.intersectsextent.linearRings(
flatCoordinates, offset, ends, stride, extent)) {
return true;
}
offset = ends[ends.length - 1];
}
return false;
};

View File

@@ -0,0 +1,33 @@
goog.provide('ol.geom.flat.segments');
/**
* This function calls `callback` for each segment of the flat coordinates
* array. If the callback returns a truthy value the function returns that
* value immediately. Otherwise the function returns `false`.
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {number} end End.
* @param {number} stride Stride.
* @param {function(ol.Coordinate, ol.Coordinate): T} callback Function
* called for each segment.
* @return {T|boolean} Value.
* @template T
*/
ol.geom.flat.segments.forEach =
function(flatCoordinates, offset, end, stride, callback) {
var point1 = [flatCoordinates[offset], flatCoordinates[offset + 1]];
var point2 = [];
var ret;
for (; (offset + stride) < end; offset += stride) {
point2[0] = flatCoordinates[offset + stride];
point2[1] = flatCoordinates[offset + stride + 1];
ret = callback(point1, point2);
if (ret) {
return ret;
}
point1[0] = point2[0];
point1[1] = point2[1];
}
return false;
};

View File

@@ -184,6 +184,16 @@ ol.geom.Geometry.prototype.getType = goog.abstractMethod;
ol.geom.Geometry.prototype.applyTransform = goog.abstractMethod;
/**
* Test if the geometry and the passed extent intersect.
* @param {ol.Extent} extent Extent.
* @return {boolean} `true` if the geometry and the extent intersect.
* @function
* @api
*/
ol.geom.Geometry.prototype.intersectsExtent = goog.abstractMethod;
/**
* Transform each coordinate of the geometry from one coordinate reference
* system to another. The geometry is modified in place.

View File

@@ -218,6 +218,22 @@ ol.geom.GeometryCollection.prototype.getType = function() {
};
/**
* @inheritDoc
* @api
*/
ol.geom.GeometryCollection.prototype.intersectsExtent = function(extent) {
var geometries = this.geometries_;
var i, ii;
for (i = 0, ii = geometries.length; i < ii; ++i) {
if (geometries[i].intersectsExtent(extent)) {
return true;
}
}
return false;
};
/**
* @return {boolean} Is empty.
*/

View File

@@ -9,6 +9,7 @@ goog.require('ol.geom.flat.closest');
goog.require('ol.geom.flat.deflate');
goog.require('ol.geom.flat.inflate');
goog.require('ol.geom.flat.interpolate');
goog.require('ol.geom.flat.intersectsextent');
goog.require('ol.geom.flat.length');
goog.require('ol.geom.flat.simplify');
@@ -190,6 +191,17 @@ ol.geom.LineString.prototype.getType = function() {
};
/**
* @inheritDoc
* @api
*/
ol.geom.LineString.prototype.intersectsExtent = function(extent) {
return ol.geom.flat.intersectsextent.lineString(
this.flatCoordinates, 0, this.flatCoordinates.length, this.stride,
extent);
};
/**
* @param {Array.<ol.Coordinate>} coordinates Coordinates.
* @param {ol.geom.GeometryLayout=} opt_layout Layout.

View File

@@ -10,6 +10,7 @@ goog.require('ol.geom.flat.closest');
goog.require('ol.geom.flat.deflate');
goog.require('ol.geom.flat.inflate');
goog.require('ol.geom.flat.interpolate');
goog.require('ol.geom.flat.intersectsextent');
goog.require('ol.geom.flat.simplify');
@@ -244,6 +245,16 @@ ol.geom.MultiLineString.prototype.getType = function() {
};
/**
* @inheritDoc
* @api
*/
ol.geom.MultiLineString.prototype.intersectsExtent = function(extent) {
return ol.geom.flat.intersectsextent.lineStrings(
this.flatCoordinates, 0, this.ends_, this.stride, extent);
};
/**
* @param {Array.<Array.<ol.Coordinate>>} coordinates Coordinates.
* @param {ol.geom.GeometryLayout=} opt_layout Layout.

View File

@@ -142,6 +142,25 @@ ol.geom.MultiPoint.prototype.getType = function() {
};
/**
* @inheritDoc
* @api
*/
ol.geom.MultiPoint.prototype.intersectsExtent = function(extent) {
var flatCoordinates = this.flatCoordinates;
var stride = this.stride;
var i, ii, x, y;
for (i = 0, ii = flatCoordinates.length; i < ii; i += stride) {
x = flatCoordinates[i];
y = flatCoordinates[i + 1];
if (ol.extent.containsXY(extent, x, y)) {
return true;
}
}
return false;
};
/**
* @param {Array.<ol.Coordinate>} coordinates Coordinates.
* @param {ol.geom.GeometryLayout=} opt_layout Layout.

View File

@@ -14,6 +14,7 @@ goog.require('ol.geom.flat.contains');
goog.require('ol.geom.flat.deflate');
goog.require('ol.geom.flat.inflate');
goog.require('ol.geom.flat.interiorpoint');
goog.require('ol.geom.flat.intersectsextent');
goog.require('ol.geom.flat.orient');
goog.require('ol.geom.flat.simplify');
@@ -315,6 +316,16 @@ ol.geom.MultiPolygon.prototype.getType = function() {
};
/**
* @inheritDoc
* @api
*/
ol.geom.MultiPolygon.prototype.intersectsExtent = function(extent) {
return ol.geom.flat.intersectsextent.linearRingss(
this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, extent);
};
/**
* @param {Array.<Array.<Array.<ol.Coordinate>>>} coordinates Coordinates.
* @param {ol.geom.GeometryLayout=} opt_layout Layout.

View File

@@ -93,6 +93,16 @@ ol.geom.Point.prototype.getType = function() {
};
/**
* @inheritDoc
* @api
*/
ol.geom.Point.prototype.intersectsExtent = function(extent) {
return ol.extent.containsXY(extent,
this.flatCoordinates[0], this.flatCoordinates[1]);
};
/**
* @param {ol.Coordinate} coordinates Coordinates.
* @param {ol.geom.GeometryLayout=} opt_layout Layout.

View File

@@ -14,6 +14,7 @@ goog.require('ol.geom.flat.contains');
goog.require('ol.geom.flat.deflate');
goog.require('ol.geom.flat.inflate');
goog.require('ol.geom.flat.interiorpoint');
goog.require('ol.geom.flat.intersectsextent');
goog.require('ol.geom.flat.orient');
goog.require('ol.geom.flat.simplify');
@@ -296,6 +297,16 @@ ol.geom.Polygon.prototype.getType = function() {
};
/**
* @inheritDoc
* @api
*/
ol.geom.Polygon.prototype.intersectsExtent = function(extent) {
return ol.geom.flat.intersectsextent.linearRings(
this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride, extent);
};
/**
* @param {Array.<Array.<ol.Coordinate>>} coordinates Coordinates.
* @param {ol.geom.GeometryLayout=} opt_layout Layout.

View File

@@ -247,6 +247,39 @@ ol.source.Vector.prototype.forEachFeatureInExtentAtResolution =
};
/**
* This function executes the `callback` function once for each feature
* intersecting the `extent` until `callback` returns a truthy value. When
* `callback` returns a truthy value the function immediately returns that
* value. Otherwise the function returns `undefined`.
* @param {ol.Extent} extent Extent.
* @param {function(this: T, ol.Feature): S} f Callback.
* @param {T=} opt_this The object to use as `this` in `f`.
* @return {S|undefined}
* @template T,S
* @api
*/
ol.source.Vector.prototype.forEachFeatureIntersectingExtent =
function(extent, f, opt_this) {
return this.forEachFeatureInExtent(extent,
/**
* @param {ol.Feature} feature Feature.
* @return {S|undefined}
* @template S
*/
function(feature) {
var geometry = feature.getGeometry();
goog.asserts.assert(goog.isDefAndNotNull(geometry));
if (geometry.intersectsExtent(extent)) {
var result = f.call(opt_this, feature);
if (result) {
return result;
}
}
});
};
/**
* @return {Array.<ol.Feature>} Features.
* @api stable

View File

@@ -349,7 +349,7 @@ describe('ol.extent', function() {
});
});
describe('segmentIntersects()', function() {
describe('intersectsSegment()', function() {
var extent = [-180, -90, 180, 90];
var north = [0, 100];
@@ -368,107 +368,107 @@ describe('ol.extent', function() {
var inside = [10, 10];
it('returns true if contained', function() {
var intersects = ol.extent.segmentIntersects(extent, center, inside);
var intersects = ol.extent.intersectsSegment(extent, center, inside);
expect(intersects).to.be(true);
});
it('returns true if crosses top', function() {
var intersects = ol.extent.segmentIntersects(extent, center, north);
var intersects = ol.extent.intersectsSegment(extent, center, north);
expect(intersects).to.be(true);
});
it('returns true if crosses right', function() {
var intersects = ol.extent.segmentIntersects(extent, center, east);
var intersects = ol.extent.intersectsSegment(extent, center, east);
expect(intersects).to.be(true);
});
it('returns true if crosses bottom', function() {
var intersects = ol.extent.segmentIntersects(extent, center, south);
var intersects = ol.extent.intersectsSegment(extent, center, south);
expect(intersects).to.be(true);
});
it('returns true if crosses left', function() {
var intersects = ol.extent.segmentIntersects(extent, center, west);
var intersects = ol.extent.intersectsSegment(extent, center, west);
expect(intersects).to.be(true);
});
it('returns false if above', function() {
var intersects = ol.extent.segmentIntersects(extent, northwest, north);
var intersects = ol.extent.intersectsSegment(extent, northwest, north);
expect(intersects).to.be(false);
});
it('returns false if right', function() {
var intersects = ol.extent.segmentIntersects(extent, northeast, east);
var intersects = ol.extent.intersectsSegment(extent, northeast, east);
expect(intersects).to.be(false);
});
it('returns false if below', function() {
var intersects = ol.extent.segmentIntersects(extent, south, southwest);
var intersects = ol.extent.intersectsSegment(extent, south, southwest);
expect(intersects).to.be(false);
});
it('returns false if left', function() {
var intersects = ol.extent.segmentIntersects(extent, west, southwest);
var intersects = ol.extent.intersectsSegment(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);
var intersects = ol.extent.intersectsSegment(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);
var intersects = ol.extent.intersectsSegment(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);
var intersects = ol.extent.intersectsSegment(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);
var intersects = ol.extent.intersectsSegment(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);
var intersects = ol.extent.intersectsSegment(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);
var intersects = ol.extent.intersectsSegment(extent, south, west);
expect(intersects).to.be(true);
});
it('returns true if touches top', function() {
var intersects = ol.extent.segmentIntersects(extent, northwest, top);
var intersects = ol.extent.intersectsSegment(extent, northwest, top);
expect(intersects).to.be(true);
});
it('returns true if touches right', function() {
var intersects = ol.extent.segmentIntersects(extent, southeast, right);
var intersects = ol.extent.intersectsSegment(extent, southeast, right);
expect(intersects).to.be(true);
});
it('returns true if touches bottom', function() {
var intersects = ol.extent.segmentIntersects(extent, bottom, south);
var intersects = ol.extent.intersectsSegment(extent, bottom, south);
expect(intersects).to.be(true);
});
it('returns true if touches left', function() {
var intersects = ol.extent.segmentIntersects(extent, left, west);
var intersects = ol.extent.intersectsSegment(extent, left, west);
expect(intersects).to.be(true);
});
it('works for zero length inside', function() {
var intersects = ol.extent.segmentIntersects(extent, center, center);
var intersects = ol.extent.intersectsSegment(extent, center, center);
expect(intersects).to.be(true);
});
it('works for zero length outside', function() {
var intersects = ol.extent.segmentIntersects(extent, north, north);
var intersects = ol.extent.intersectsSegment(extent, north, north);
expect(intersects).to.be(false);
});

View File

@@ -0,0 +1,92 @@
goog.provide('ol.test.geom.flat.intersectsextent');
describe('ol.geom.flat.intersectsextent', function() {
describe('ol.geom.flat.intersectsextent.lineString', function() {
var flatCoordinates;
beforeEach(function() {
flatCoordinates = [0, 0, 1, 1, 2, 2];
});
describe('linestring envelope does not intersect the extent', function() {
it('returns false', function() {
var extent = [3, 3, 4, 4];
var r = ol.geom.flat.intersectsextent.lineString(
flatCoordinates, 0, flatCoordinates.length, 2, extent);
expect(r).to.be(false);
});
});
describe('linestring envelope within the extent', function() {
it('returns true', function() {
var extent = [-1, -1, 3, 3];
var r = ol.geom.flat.intersectsextent.lineString(
flatCoordinates, 0, flatCoordinates.length, 2, extent);
expect(r).to.be(true);
});
});
describe('linestring envelope bisected by an edge of the extent',
function() {
it('returns true', function() {
var extent = [-0.1, 0.1, 2.1, 0.1];
var r = ol.geom.flat.intersectsextent.lineString(
flatCoordinates, 0, flatCoordinates.length, 2, extent);
expect(r).to.be(true);
});
});
describe('a segment intersects the extent', function() {
it('returns true', function() {
var extent = [-0.5, -0.5, 0.5, 0.5];
var r = ol.geom.flat.intersectsextent.lineString(
flatCoordinates, 0, flatCoordinates.length, 2, extent);
expect(r).to.be(true);
});
});
describe('no segments intersect the extent', function() {
it('returns false', function() {
var extent = [0.5, 1.5, 1, 1.75];
var r = ol.geom.flat.intersectsextent.lineString(
flatCoordinates, 0, flatCoordinates.length, 2, extent);
expect(r).to.be(false);
});
it('returns false', function() {
var extent = [1, 0.25, 1.5, 0.5];
var r = ol.geom.flat.intersectsextent.lineString(
flatCoordinates, 0, flatCoordinates.length, 2, extent);
expect(r).to.be(false);
});
});
});
describe('ol.geom.flat.intersectsextent.linearRing', function() {
var flatCoordinates;
beforeEach(function() {
flatCoordinates = [0, 0, 1, 1, 2, 0, 1, -1, 0, 0];
});
describe('boundary intersects the extent', function() {
it('returns true', function() {
var extent = [1.5, 0.0, 2.5, 1.0];
var r = ol.geom.flat.intersectsextent.linearRing(
flatCoordinates, 0, flatCoordinates.length, 2, extent);
expect(r).to.be(true);
});
});
describe('boundary does not intersect the extent and ring does not ' +
'contain a corner of the extent', function() {
it('returns false', function() {
var extent = [2.0, 0.5, 3, 1.5];
var r = ol.geom.flat.intersectsextent.linearRing(
flatCoordinates, 0, flatCoordinates.length, 2, extent);
expect(r).to.be(false);
});
});
describe('ring contains the extent', function() {
it('returns true', function() {
var extent = [0.75, -0.25, 1.25, 0.25];
var r = ol.geom.flat.intersectsextent.linearRing(
flatCoordinates, 0, flatCoordinates.length, 2, extent);
expect(r).to.be(true);
});
});
});
});
goog.require('ol.geom.flat.intersectsextent');

View File

@@ -0,0 +1,57 @@
goog.provide('ol.test.geom.flat.segments');
describe('ol.geom.flat.segments', function() {
describe('ol.geom.flat.segments.forEach', function() {
var flatCoordinates, offset, end, stride;
beforeEach(function() {
flatCoordinates = [0, 0, 1, 1, 2, 2, 3, 3];
offset = 0;
end = 8;
stride = 2;
});
describe('callback returns undefined', function() {
it('executes the callback for each segment', function() {
var args = [];
var spy = sinon.spy(function(point1, point2) {
args.push([point1[0], point1[1], point2[0], point2[1]]);
});
var ret = ol.geom.flat.segments.forEach(
flatCoordinates, offset, end, stride, spy);
expect(spy.callCount).to.be(3);
expect(args[0][0]).to.be(0);
expect(args[0][1]).to.be(0);
expect(args[0][2]).to.be(1);
expect(args[0][3]).to.be(1);
expect(args[1][0]).to.be(1);
expect(args[1][1]).to.be(1);
expect(args[1][2]).to.be(2);
expect(args[1][3]).to.be(2);
expect(args[2][0]).to.be(2);
expect(args[2][1]).to.be(2);
expect(args[2][2]).to.be(3);
expect(args[2][3]).to.be(3);
expect(ret).to.be(false);
});
});
describe('callback returns true', function() {
it('executes the callback for the first segment', function() {
var args = [];
var spy = sinon.spy(function(point1, point2) {
args.push([point1[0], point1[1], point2[0], point2[1]]);
return true;
});
var ret = ol.geom.flat.segments.forEach(
flatCoordinates, offset, end, stride, spy);
expect(spy.callCount).to.be(1);
expect(args[0][0]).to.be(0);
expect(args[0][1]).to.be(0);
expect(args[0][2]).to.be(1);
expect(args[0][3]).to.be(1);
expect(ret).to.be(true);
});
});
});
});
goog.require('ol.geom.flat.segments');