Factor out ol.geom.flat.orient
This commit is contained in:
115
src/ol/geom/flat/orientflatgeom.js
Normal file
115
src/ol/geom/flat/orientflatgeom.js
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
goog.provide('ol.geom.flat.orient');
|
||||||
|
|
||||||
|
goog.require('ol.geom.flat');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||||
|
* @param {number} offset Offset.
|
||||||
|
* @param {number} end End.
|
||||||
|
* @param {number} stride Stride.
|
||||||
|
* @return {boolean} Is clockwise.
|
||||||
|
*/
|
||||||
|
ol.geom.flat.orient.linearRingIsClockwise =
|
||||||
|
function(flatCoordinates, offset, end, stride) {
|
||||||
|
// http://tinyurl.com/clockwise-method
|
||||||
|
// https://github.com/OSGeo/gdal/blob/trunk/gdal/ogr/ogrlinearring.cpp
|
||||||
|
var edge = 0;
|
||||||
|
var x1 = flatCoordinates[end - stride];
|
||||||
|
var y1 = flatCoordinates[end - stride + 1];
|
||||||
|
for (; offset < end; offset += stride) {
|
||||||
|
var x2 = flatCoordinates[offset];
|
||||||
|
var y2 = flatCoordinates[offset + 1];
|
||||||
|
edge += (x2 - x1) * (y2 + y1);
|
||||||
|
x1 = x2;
|
||||||
|
y1 = y2;
|
||||||
|
}
|
||||||
|
return edge > 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||||
|
* @param {number} offset Offset.
|
||||||
|
* @param {Array.<number>} ends Ends.
|
||||||
|
* @param {number} stride Stride.
|
||||||
|
* @return {boolean} `true` if all rings are correctly oriented, `false`
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
ol.geom.flat.orient.linearRingsAreOriented =
|
||||||
|
function(flatCoordinates, offset, ends, stride) {
|
||||||
|
var i, ii;
|
||||||
|
for (i = 0, ii = ends.length; i < ii; ++i) {
|
||||||
|
var end = ends[i];
|
||||||
|
var isClockwise = ol.geom.flat.orient.linearRingIsClockwise(
|
||||||
|
flatCoordinates, offset, end, stride);
|
||||||
|
if (i === 0 ? !isClockwise : isClockwise) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
offset = end;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||||
|
* @param {number} offset Offset.
|
||||||
|
* @param {Array.<Array.<number>>} endss Endss.
|
||||||
|
* @param {number} stride Stride.
|
||||||
|
* @return {boolean} `true` if all rings are correctly oriented, `false`
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
ol.geom.flat.linearRingssAreOriented =
|
||||||
|
function(flatCoordinates, offset, endss, stride) {
|
||||||
|
var i, ii;
|
||||||
|
for (i = 0, ii = endss.length; i < ii; ++i) {
|
||||||
|
if (!ol.geom.flat.orient.linearRingsAreOriented(
|
||||||
|
flatCoordinates, offset, endss[i], stride)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||||
|
* @param {number} offset Offset.
|
||||||
|
* @param {Array.<number>} ends Ends.
|
||||||
|
* @param {number} stride Stride.
|
||||||
|
* @return {number} End.
|
||||||
|
*/
|
||||||
|
ol.geom.flat.orient.orientLinearRings =
|
||||||
|
function(flatCoordinates, offset, ends, stride) {
|
||||||
|
var i, ii;
|
||||||
|
for (i = 0, ii = ends.length; i < ii; ++i) {
|
||||||
|
var end = ends[i];
|
||||||
|
var isClockwise = ol.geom.flat.orient.linearRingIsClockwise(
|
||||||
|
flatCoordinates, offset, end, stride);
|
||||||
|
var reverse = i === 0 ? !isClockwise : isClockwise;
|
||||||
|
if (reverse) {
|
||||||
|
ol.geom.flat.reverseCoordinates(flatCoordinates, offset, end, stride);
|
||||||
|
}
|
||||||
|
offset = end;
|
||||||
|
}
|
||||||
|
return offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||||
|
* @param {number} offset Offset.
|
||||||
|
* @param {Array.<Array.<number>>} endss Endss.
|
||||||
|
* @param {number} stride Stride.
|
||||||
|
* @return {number} End.
|
||||||
|
*/
|
||||||
|
ol.geom.flat.orient.orientLinearRingss =
|
||||||
|
function(flatCoordinates, offset, endss, stride) {
|
||||||
|
var i, ii;
|
||||||
|
for (i = 0, ii = endss.length; i < ii; ++i) {
|
||||||
|
offset = ol.geom.flat.orient.orientLinearRings(
|
||||||
|
flatCoordinates, offset, endss[i], stride);
|
||||||
|
}
|
||||||
|
return offset;
|
||||||
|
};
|
||||||
@@ -228,31 +228,6 @@ ol.geom.flat.linearRingContainsXY =
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
||||||
* @param {number} offset Offset.
|
|
||||||
* @param {number} end End.
|
|
||||||
* @param {number} stride Stride.
|
|
||||||
* @return {boolean} Is clockwise.
|
|
||||||
*/
|
|
||||||
ol.geom.flat.linearRingIsClockwise =
|
|
||||||
function(flatCoordinates, offset, end, stride) {
|
|
||||||
// http://tinyurl.com/clockwise-method
|
|
||||||
// https://github.com/OSGeo/gdal/blob/trunk/gdal/ogr/ogrlinearring.cpp
|
|
||||||
var edge = 0;
|
|
||||||
var x1 = flatCoordinates[end - stride];
|
|
||||||
var y1 = flatCoordinates[end - stride + 1];
|
|
||||||
for (; offset < end; offset += stride) {
|
|
||||||
var x2 = flatCoordinates[offset];
|
|
||||||
var y2 = flatCoordinates[offset + 1];
|
|
||||||
edge += (x2 - x1) * (y2 + y1);
|
|
||||||
x1 = x2;
|
|
||||||
y1 = y2;
|
|
||||||
}
|
|
||||||
return edge > 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||||
* @param {number} offset Offset.
|
* @param {number} offset Offset.
|
||||||
@@ -348,51 +323,6 @@ ol.geom.flat.linearRingsGetInteriorPoint = function(flatCoordinates, offset,
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
||||||
* @param {number} offset Offset.
|
|
||||||
* @param {Array.<number>} ends Ends.
|
|
||||||
* @param {number} stride Stride.
|
|
||||||
* @return {boolean} `true` if all rings are correctly oriented, `false`
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
ol.geom.flat.linearRingsAreOriented =
|
|
||||||
function(flatCoordinates, offset, ends, stride) {
|
|
||||||
var i, ii;
|
|
||||||
for (i = 0, ii = ends.length; i < ii; ++i) {
|
|
||||||
var end = ends[i];
|
|
||||||
var isClockwise = ol.geom.flat.linearRingIsClockwise(
|
|
||||||
flatCoordinates, offset, end, stride);
|
|
||||||
if (i === 0 ? !isClockwise : isClockwise) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
offset = end;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
||||||
* @param {number} offset Offset.
|
|
||||||
* @param {Array.<Array.<number>>} endss Endss.
|
|
||||||
* @param {number} stride Stride.
|
|
||||||
* @return {boolean} `true` if all rings are correctly oriented, `false`
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
ol.geom.flat.linearRingssAreOriented =
|
|
||||||
function(flatCoordinates, offset, endss, stride) {
|
|
||||||
var i, ii;
|
|
||||||
for (i = 0, ii = endss.length; i < ii; ++i) {
|
|
||||||
if (!ol.geom.flat.linearRingsAreOriented(
|
|
||||||
flatCoordinates, offset, endss[i], stride)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||||
* @param {number} offset Offset.
|
* @param {number} offset Offset.
|
||||||
@@ -467,48 +397,6 @@ ol.geom.flat.linearRingssGetFlatCenters =
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
||||||
* @param {number} offset Offset.
|
|
||||||
* @param {Array.<number>} ends Ends.
|
|
||||||
* @param {number} stride Stride.
|
|
||||||
* @return {number} End.
|
|
||||||
*/
|
|
||||||
ol.geom.flat.orientLinearRings =
|
|
||||||
function(flatCoordinates, offset, ends, stride) {
|
|
||||||
var i, ii;
|
|
||||||
for (i = 0, ii = ends.length; i < ii; ++i) {
|
|
||||||
var end = ends[i];
|
|
||||||
var isClockwise = ol.geom.flat.linearRingIsClockwise(
|
|
||||||
flatCoordinates, offset, end, stride);
|
|
||||||
var reverse = i === 0 ? !isClockwise : isClockwise;
|
|
||||||
if (reverse) {
|
|
||||||
ol.geom.flat.reverseCoordinates(flatCoordinates, offset, end, stride);
|
|
||||||
}
|
|
||||||
offset = end;
|
|
||||||
}
|
|
||||||
return offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
||||||
* @param {number} offset Offset.
|
|
||||||
* @param {Array.<Array.<number>>} endss Endss.
|
|
||||||
* @param {number} stride Stride.
|
|
||||||
* @return {number} End.
|
|
||||||
*/
|
|
||||||
ol.geom.flat.orientLinearRingss =
|
|
||||||
function(flatCoordinates, offset, endss, stride) {
|
|
||||||
var i, ii;
|
|
||||||
for (i = 0, ii = endss.length; i < ii; ++i) {
|
|
||||||
offset = ol.geom.flat.orientLinearRings(
|
|
||||||
flatCoordinates, offset, endss[i], stride);
|
|
||||||
}
|
|
||||||
return offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||||
* @param {number} offset Offset.
|
* @param {number} offset Offset.
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ goog.require('ol.geom.SimpleGeometry');
|
|||||||
goog.require('ol.geom.flat');
|
goog.require('ol.geom.flat');
|
||||||
goog.require('ol.geom.flat.area');
|
goog.require('ol.geom.flat.area');
|
||||||
goog.require('ol.geom.flat.closest');
|
goog.require('ol.geom.flat.closest');
|
||||||
|
goog.require('ol.geom.flat.orient');
|
||||||
goog.require('ol.geom.flat.simplify');
|
goog.require('ol.geom.flat.simplify');
|
||||||
|
|
||||||
|
|
||||||
@@ -204,7 +205,8 @@ ol.geom.MultiPolygon.prototype.getOrientedFlatCoordinates = function() {
|
|||||||
this.orientedFlatCoordinates_ = flatCoordinates;
|
this.orientedFlatCoordinates_ = flatCoordinates;
|
||||||
} else {
|
} else {
|
||||||
this.orientedFlatCoordinates_ = flatCoordinates.slice();
|
this.orientedFlatCoordinates_ = flatCoordinates.slice();
|
||||||
this.orientedFlatCoordinates_.length = ol.geom.flat.orientLinearRingss(
|
this.orientedFlatCoordinates_.length =
|
||||||
|
ol.geom.flat.orient.orientLinearRingss(
|
||||||
this.orientedFlatCoordinates_, 0, this.endss_, this.stride);
|
this.orientedFlatCoordinates_, 0, this.endss_, this.stride);
|
||||||
}
|
}
|
||||||
this.orientedRevision_ = this.getRevision();
|
this.orientedRevision_ = this.getRevision();
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ goog.require('ol.geom.SimpleGeometry');
|
|||||||
goog.require('ol.geom.flat');
|
goog.require('ol.geom.flat');
|
||||||
goog.require('ol.geom.flat.area');
|
goog.require('ol.geom.flat.area');
|
||||||
goog.require('ol.geom.flat.closest');
|
goog.require('ol.geom.flat.closest');
|
||||||
|
goog.require('ol.geom.flat.orient');
|
||||||
goog.require('ol.geom.flat.simplify');
|
goog.require('ol.geom.flat.simplify');
|
||||||
|
|
||||||
|
|
||||||
@@ -223,12 +224,13 @@ ol.geom.Polygon.prototype.getLinearRings = function() {
|
|||||||
ol.geom.Polygon.prototype.getOrientedFlatCoordinates = function() {
|
ol.geom.Polygon.prototype.getOrientedFlatCoordinates = function() {
|
||||||
if (this.orientedRevision_ != this.getRevision()) {
|
if (this.orientedRevision_ != this.getRevision()) {
|
||||||
var flatCoordinates = this.flatCoordinates;
|
var flatCoordinates = this.flatCoordinates;
|
||||||
if (ol.geom.flat.linearRingsAreOriented(
|
if (ol.geom.flat.orient.linearRingsAreOriented(
|
||||||
flatCoordinates, 0, this.ends_, this.stride)) {
|
flatCoordinates, 0, this.ends_, this.stride)) {
|
||||||
this.orientedFlatCoordinates_ = flatCoordinates;
|
this.orientedFlatCoordinates_ = flatCoordinates;
|
||||||
} else {
|
} else {
|
||||||
this.orientedFlatCoordinates_ = flatCoordinates.slice();
|
this.orientedFlatCoordinates_ = flatCoordinates.slice();
|
||||||
this.orientedFlatCoordinates_.length = ol.geom.flat.orientLinearRings(
|
this.orientedFlatCoordinates_.length =
|
||||||
|
ol.geom.flat.orient.orientLinearRings(
|
||||||
this.orientedFlatCoordinates_, 0, this.ends_, this.stride);
|
this.orientedFlatCoordinates_, 0, this.ends_, this.stride);
|
||||||
}
|
}
|
||||||
this.orientedRevision_ = this.getRevision();
|
this.orientedRevision_ = this.getRevision();
|
||||||
|
|||||||
26
test/spec/ol/geom/flat/orientflatgeom.test.js
Normal file
26
test/spec/ol/geom/flat/orientflatgeom.test.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
goog.provide('ol.test.geom.flat.orient');
|
||||||
|
|
||||||
|
describe('ol.geom.flat.orient', function() {
|
||||||
|
|
||||||
|
describe('ol.geom.flat.orient.linearRingIsClockwise', function() {
|
||||||
|
|
||||||
|
it('identifies clockwise rings', function() {
|
||||||
|
var flatCoordinates = [0, 1, 1, 4, 4, 3, 3, 0];
|
||||||
|
var isClockwise = ol.geom.flat.orient.linearRingIsClockwise(
|
||||||
|
flatCoordinates, 0, flatCoordinates.length, 2);
|
||||||
|
expect(isClockwise).to.be(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('identifies anti-clockwise rings', function() {
|
||||||
|
var flatCoordinates = [2, 2, 3, 2, 3, 3, 2, 3];
|
||||||
|
var isClockwise = ol.geom.flat.orient.linearRingIsClockwise(
|
||||||
|
flatCoordinates, 0, flatCoordinates.length, 2);
|
||||||
|
expect(isClockwise).to.be(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
goog.require('ol.geom.flat');
|
||||||
|
goog.require('ol.geom.flat.orient');
|
||||||
@@ -85,24 +85,6 @@ describe('ol.geom.flat', function() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('ol.geom.flat.linearRingIsClockwise', function() {
|
|
||||||
|
|
||||||
it('identifies clockwise rings', function() {
|
|
||||||
var flatCoordinates = [0, 1, 1, 4, 4, 3, 3, 0];
|
|
||||||
var isClockwise = ol.geom.flat.linearRingIsClockwise(
|
|
||||||
flatCoordinates, 0, flatCoordinates.length, 2);
|
|
||||||
expect(isClockwise).to.be(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('identifies anti-clockwise rings', function() {
|
|
||||||
var flatCoordinates = [2, 2, 3, 2, 3, 3, 2, 3];
|
|
||||||
var isClockwise = ol.geom.flat.linearRingIsClockwise(
|
|
||||||
flatCoordinates, 0, flatCoordinates.length, 2);
|
|
||||||
expect(isClockwise).to.be(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('ol.geom.flat.reverseCoordinates', function() {
|
describe('ol.geom.flat.reverseCoordinates', function() {
|
||||||
|
|
||||||
describe('with a stride of 2', function() {
|
describe('with a stride of 2', function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user