diff --git a/src/ol/format/MVT.js b/src/ol/format/MVT.js index 69350830d4..e987911087 100644 --- a/src/ol/format/MVT.js +++ b/src/ol/format/MVT.js @@ -19,7 +19,6 @@ import RenderFeature from '../render/Feature.js'; import Units from '../proj/Units.js'; import {assert} from '../asserts.js'; import {get} from '../proj.js'; -import {linearRingIsClockwise} from '../geom/flat/orient.js'; /** * @typedef {Object} Options @@ -203,10 +202,16 @@ class MVT extends FeatureFormat { let prevEndIndex = 0; for (let i = 0, ii = ends.length; i < ii; ++i) { const end = ends[i]; - if (!linearRingIsClockwise(flatCoordinates, offset, end, 2)) { - endss.push(ends.slice(prevEndIndex, i)); - prevEndIndex = i; + // classifies an array of rings into polygons with outer rings and holes + if (linearRingIsClockwise(flatCoordinates, offset, end, 2)) { + endss.push(ends.slice(prevEndIndex, i + 1)); + } else { + if (endss.length === 0) { + continue; + } + endss[endss.length - 1].push(ends[prevEndIndex]); } + prevEndIndex = i + 1; offset = end; } if (endss.length > 1) { @@ -440,4 +445,28 @@ function getGeometryType(type, numEnds) { return geometryType; } +/** + * Determines Flat coordinates is clockwise in MVT. + * @param {Array} flatCoordinates Flat coordinates. + * @param {number} offset Offset. + * @param {number} end End. + * @param {number} stride Stride. + * @return {boolean} Is clockwise in MVT. + */ +function linearRingIsClockwise(flatCoordinates, offset, end, stride) { + let edge = 0; + let x1 = flatCoordinates[end - stride]; + let y1 = flatCoordinates[end - stride + 1]; + for (; offset < end; offset += stride) { + const x2 = flatCoordinates[offset]; + const y2 = flatCoordinates[offset + 1]; + edge += (x2 - x1) * (y2 + y1); + x1 = x2; + y1 = y2; + } + // http://tinyurl.com/clockwise-method + // MVT has an inverted Y-axis. Then the rule has to be flipped: if the area is negative, the curve is clockwise. + return edge < 0; +} + export default MVT; diff --git a/test/spec/ol/format/mvt.test.js b/test/spec/ol/format/mvt.test.js index 05b4644d69..9041f25da1 100644 --- a/test/spec/ol/format/mvt.test.js +++ b/test/spec/ol/format/mvt.test.js @@ -181,7 +181,7 @@ describe('ol.format.MVT', function () { flatCoordinates, ends ) { - flatCoordinates.push(0, 0, 3, 0, 3, 3, 3, 0, 0, 0); + flatCoordinates.push(0, 0, 3, 0, 3, 3, 0, 4, 0, 0); flatCoordinates.push(1, 1, 1, 2, 2, 2, 2, 1, 1, 1); ends.push(10, 20); }; @@ -207,8 +207,8 @@ describe('ol.format.MVT', function () { flatCoordinates, ends ) { - flatCoordinates.push(0, 0, 1, 0, 1, 1, 1, 0, 0, 0); - flatCoordinates.push(1, 1, 2, 1, 2, 2, 2, 1, 1, 1); + flatCoordinates.push(0, 0, 1, 0, 1, 1, 0, 1, 0, 0); + flatCoordinates.push(1, 1, 2, 1, 2, 2, 1, 2, 1, 1); ends.push(10, 20); }; const feature = format.createFeature_({}, rawFeature);