diff --git a/src/ol/extent.js b/src/ol/extent.js index baff0fc59b..989b889212 100644 --- a/src/ol/extent.js +++ b/src/ol/extent.js @@ -1,5 +1,6 @@ goog.provide('ol.Extent'); goog.provide('ol.extent'); +goog.provide('ol.extent.Relationship'); goog.require('goog.asserts'); goog.require('ol.Coordinate'); @@ -15,6 +16,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 +165,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 diff --git a/test/spec/ol/extent.test.js b/test/spec/ol/extent.test.js index 3bc115bb98..f6fee8f1f6 100644 --- a/test/spec/ol/extent.test.js +++ b/test/spec/ol/extent.test.js @@ -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]; @@ -267,4 +346,5 @@ describe('ol.extent', function() { goog.require('ol.extent'); +goog.require('ol.extent.Relationship'); goog.require('ol.proj');