Merge pull request #1959 from elemoine/feature-box-selection
Add a feature box selection example
This commit is contained in:
59
examples/box-selection.html
Normal file
59
examples/box-selection.html
Normal 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">
|
||||
|
||||
</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
81
examples/box-selection.js
Normal 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 = ' ';
|
||||
});
|
||||
map.on('click', function() {
|
||||
selectedFeatures.clear();
|
||||
infoBox.innerHTML = ' ';
|
||||
});
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
|
||||
154
src/ol/geom/flat/intersectsextent.js
Normal file
154
src/ol/geom/flat/intersectsextent.js
Normal 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;
|
||||
};
|
||||
33
src/ol/geom/flat/segmentsflatgeom.js
Normal file
33
src/ol/geom/flat/segmentsflatgeom.js
Normal 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;
|
||||
};
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
|
||||
92
test/spec/ol/geom/flat/intersectsextentflatgeom.test.js
Normal file
92
test/spec/ol/geom/flat/intersectsextentflatgeom.test.js
Normal 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');
|
||||
57
test/spec/ol/geom/flat/segmentsflatgeom.test.js
Normal file
57
test/spec/ol/geom/flat/segmentsflatgeom.test.js
Normal 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');
|
||||
Reference in New Issue
Block a user