@math.gl/polygon 3.6.0-alpha.1 → 3.6.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cut-by-grid.d.ts +8 -7
- package/dist/cut-by-grid.d.ts.map +1 -1
- package/dist/cut-by-grid.js +2 -4
- package/dist/cut-by-mercator-bounds.d.ts +5 -4
- package/dist/cut-by-mercator-bounds.d.ts.map +1 -1
- package/dist/cut-by-mercator-bounds.js +0 -1
- package/dist/earcut.js +1 -1
- package/dist/es5/cut-by-grid.js +83 -70
- package/dist/es5/cut-by-grid.js.map +1 -1
- package/dist/es5/cut-by-mercator-bounds.js +89 -52
- package/dist/es5/cut-by-mercator-bounds.js.map +1 -1
- package/dist/es5/earcut.js +95 -89
- package/dist/es5/earcut.js.map +1 -1
- package/dist/es5/index.js +14 -14
- package/dist/es5/lineclip.js +43 -36
- package/dist/es5/lineclip.js.map +1 -1
- package/dist/es5/polygon-utils.js +66 -56
- package/dist/es5/polygon-utils.js.map +1 -1
- package/dist/es5/polygon.js +44 -31
- package/dist/es5/polygon.js.map +1 -1
- package/dist/es5/utils.js +12 -11
- package/dist/es5/utils.js.map +1 -1
- package/dist/esm/cut-by-grid.js +1 -1
- package/dist/esm/cut-by-grid.js.map +1 -1
- package/dist/esm/cut-by-mercator-bounds.js.map +1 -1
- package/dist/esm/earcut.js.map +1 -1
- package/dist/esm/lineclip.js.map +1 -1
- package/dist/esm/polygon-utils.js.map +1 -1
- package/dist/esm/polygon.js.map +1 -1
- package/dist/esm/utils.js.map +1 -1
- package/dist/lineclip.d.ts +1 -2
- package/dist/lineclip.d.ts.map +1 -1
- package/dist/polygon-utils.d.ts.map +1 -1
- package/dist/polygon.d.ts +3 -2
- package/dist/polygon.d.ts.map +1 -1
- package/dist/polygon.js +1 -1
- package/dist/utils.d.ts +4 -3
- package/dist/utils.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/cut-by-grid.ts +57 -39
- package/src/cut-by-mercator-bounds.ts +31 -21
- package/src/earcut.ts +1 -1
- package/src/lineclip.ts +14 -14
- package/src/polygon-utils.ts +4 -1
- package/src/polygon.ts +9 -8
- package/src/utils.ts +11 -3
|
@@ -10,56 +10,82 @@ var _cutByGrid = require("./cut-by-grid");
|
|
|
10
10
|
|
|
11
11
|
var _utils = require("./utils");
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
14
|
+
|
|
15
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
16
|
+
|
|
17
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
18
|
+
|
|
19
|
+
var DEFAULT_MAX_LATITUDE = 85.051129;
|
|
14
20
|
|
|
15
21
|
function cutPolylineByMercatorBounds(positions, options) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
var _ref = options || {},
|
|
23
|
+
_ref$size = _ref.size,
|
|
24
|
+
size = _ref$size === void 0 ? 2 : _ref$size,
|
|
25
|
+
_ref$startIndex = _ref.startIndex,
|
|
26
|
+
startIndex = _ref$startIndex === void 0 ? 0 : _ref$startIndex,
|
|
27
|
+
_ref$endIndex = _ref.endIndex,
|
|
28
|
+
endIndex = _ref$endIndex === void 0 ? positions.length : _ref$endIndex,
|
|
29
|
+
_ref$normalize = _ref.normalize,
|
|
30
|
+
normalize = _ref$normalize === void 0 ? true : _ref$normalize;
|
|
31
|
+
|
|
32
|
+
var newPositions = positions.slice(startIndex, endIndex);
|
|
23
33
|
wrapLongitudesForShortestPath(newPositions, size, 0, endIndex - startIndex);
|
|
24
|
-
|
|
25
|
-
size,
|
|
34
|
+
var parts = (0, _cutByGrid.cutPolylineByGrid)(newPositions, {
|
|
35
|
+
size: size,
|
|
26
36
|
broken: true,
|
|
27
37
|
gridResolution: 360,
|
|
28
38
|
gridOffset: [-180, -180]
|
|
29
39
|
});
|
|
30
40
|
|
|
31
41
|
if (normalize) {
|
|
32
|
-
|
|
33
|
-
|
|
42
|
+
var _iterator = _createForOfIteratorHelper(parts),
|
|
43
|
+
_step;
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
47
|
+
var part = _step.value;
|
|
48
|
+
shiftLongitudesIntoRange(part, size);
|
|
49
|
+
}
|
|
50
|
+
} catch (err) {
|
|
51
|
+
_iterator.e(err);
|
|
52
|
+
} finally {
|
|
53
|
+
_iterator.f();
|
|
34
54
|
}
|
|
35
55
|
}
|
|
36
56
|
|
|
37
57
|
return parts;
|
|
38
58
|
}
|
|
39
59
|
|
|
40
|
-
function cutPolygonByMercatorBounds(positions
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
60
|
+
function cutPolygonByMercatorBounds(positions) {
|
|
61
|
+
var holeIndices = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
62
|
+
var options = arguments.length > 2 ? arguments[2] : undefined;
|
|
63
|
+
|
|
64
|
+
var _ref2 = options || {},
|
|
65
|
+
_ref2$size = _ref2.size,
|
|
66
|
+
size = _ref2$size === void 0 ? 2 : _ref2$size,
|
|
67
|
+
_ref2$normalize = _ref2.normalize,
|
|
68
|
+
normalize = _ref2$normalize === void 0 ? true : _ref2$normalize,
|
|
69
|
+
_ref2$edgeTypes = _ref2.edgeTypes,
|
|
70
|
+
edgeTypes = _ref2$edgeTypes === void 0 ? false : _ref2$edgeTypes;
|
|
71
|
+
|
|
46
72
|
holeIndices = holeIndices || [];
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
73
|
+
var newPositions = [];
|
|
74
|
+
var newHoleIndices = [];
|
|
75
|
+
var srcStartIndex = 0;
|
|
76
|
+
var targetIndex = 0;
|
|
51
77
|
|
|
52
|
-
for (
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
78
|
+
for (var ringIndex = 0; ringIndex <= holeIndices.length; ringIndex++) {
|
|
79
|
+
var srcEndIndex = holeIndices[ringIndex] || positions.length;
|
|
80
|
+
var targetStartIndex = targetIndex;
|
|
81
|
+
var splitIndex = findSplitIndex(positions, size, srcStartIndex, srcEndIndex);
|
|
56
82
|
|
|
57
|
-
for (
|
|
83
|
+
for (var i = splitIndex; i < srcEndIndex; i++) {
|
|
58
84
|
newPositions[targetIndex++] = positions[i];
|
|
59
85
|
}
|
|
60
86
|
|
|
61
|
-
for (
|
|
62
|
-
newPositions[targetIndex++] = positions[
|
|
87
|
+
for (var _i = srcStartIndex; _i < splitIndex; _i++) {
|
|
88
|
+
newPositions[targetIndex++] = positions[_i];
|
|
63
89
|
}
|
|
64
90
|
|
|
65
91
|
wrapLongitudesForShortestPath(newPositions, size, targetStartIndex, targetIndex);
|
|
@@ -69,16 +95,26 @@ function cutPolygonByMercatorBounds(positions, holeIndices = null, options) {
|
|
|
69
95
|
}
|
|
70
96
|
|
|
71
97
|
newHoleIndices.pop();
|
|
72
|
-
|
|
73
|
-
size,
|
|
98
|
+
var parts = (0, _cutByGrid.cutPolygonByGrid)(newPositions, newHoleIndices, {
|
|
99
|
+
size: size,
|
|
74
100
|
gridResolution: 360,
|
|
75
101
|
gridOffset: [-180, -180],
|
|
76
|
-
edgeTypes
|
|
102
|
+
edgeTypes: edgeTypes
|
|
77
103
|
});
|
|
78
104
|
|
|
79
105
|
if (normalize) {
|
|
80
|
-
|
|
81
|
-
|
|
106
|
+
var _iterator2 = _createForOfIteratorHelper(parts),
|
|
107
|
+
_step2;
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
111
|
+
var part = _step2.value;
|
|
112
|
+
shiftLongitudesIntoRange(part.positions, size);
|
|
113
|
+
}
|
|
114
|
+
} catch (err) {
|
|
115
|
+
_iterator2.e(err);
|
|
116
|
+
} finally {
|
|
117
|
+
_iterator2.f();
|
|
82
118
|
}
|
|
83
119
|
}
|
|
84
120
|
|
|
@@ -86,11 +122,11 @@ function cutPolygonByMercatorBounds(positions, holeIndices = null, options) {
|
|
|
86
122
|
}
|
|
87
123
|
|
|
88
124
|
function findSplitIndex(positions, size, startIndex, endIndex) {
|
|
89
|
-
|
|
90
|
-
|
|
125
|
+
var maxLat = -1;
|
|
126
|
+
var pointIndex = -1;
|
|
91
127
|
|
|
92
|
-
for (
|
|
93
|
-
|
|
128
|
+
for (var i = startIndex + 1; i < endIndex; i += size) {
|
|
129
|
+
var lat = Math.abs(positions[i]);
|
|
94
130
|
|
|
95
131
|
if (lat > maxLat) {
|
|
96
132
|
maxLat = lat;
|
|
@@ -101,12 +137,13 @@ function findSplitIndex(positions, size, startIndex, endIndex) {
|
|
|
101
137
|
return pointIndex;
|
|
102
138
|
}
|
|
103
139
|
|
|
104
|
-
function insertPoleVertices(positions, size, startIndex, endIndex
|
|
105
|
-
|
|
106
|
-
|
|
140
|
+
function insertPoleVertices(positions, size, startIndex, endIndex) {
|
|
141
|
+
var maxLatitude = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : DEFAULT_MAX_LATITUDE;
|
|
142
|
+
var firstLng = positions[startIndex];
|
|
143
|
+
var lastLng = positions[endIndex - size];
|
|
107
144
|
|
|
108
145
|
if (Math.abs(firstLng - lastLng) > 180) {
|
|
109
|
-
|
|
146
|
+
var p = (0, _utils.getPointAtIndex)(positions, 0, size, startIndex);
|
|
110
147
|
p[0] += Math.round((lastLng - firstLng) / 360) * 360;
|
|
111
148
|
(0, _utils.push)(positions, p);
|
|
112
149
|
p[1] = Math.sign(p[1]) * maxLatitude;
|
|
@@ -117,12 +154,12 @@ function insertPoleVertices(positions, size, startIndex, endIndex, maxLatitude =
|
|
|
117
154
|
}
|
|
118
155
|
|
|
119
156
|
function wrapLongitudesForShortestPath(positions, size, startIndex, endIndex) {
|
|
120
|
-
|
|
121
|
-
|
|
157
|
+
var prevLng = positions[0];
|
|
158
|
+
var lng;
|
|
122
159
|
|
|
123
|
-
for (
|
|
160
|
+
for (var i = startIndex; i < endIndex; i += size) {
|
|
124
161
|
lng = positions[i];
|
|
125
|
-
|
|
162
|
+
var delta = lng - prevLng;
|
|
126
163
|
|
|
127
164
|
if (delta > 180 || delta < -180) {
|
|
128
165
|
lng -= Math.round(delta / 360) * 360;
|
|
@@ -133,10 +170,10 @@ function wrapLongitudesForShortestPath(positions, size, startIndex, endIndex) {
|
|
|
133
170
|
}
|
|
134
171
|
|
|
135
172
|
function shiftLongitudesIntoRange(positions, size) {
|
|
136
|
-
|
|
137
|
-
|
|
173
|
+
var refLng;
|
|
174
|
+
var pointCount = positions.length / size;
|
|
138
175
|
|
|
139
|
-
for (
|
|
176
|
+
for (var i = 0; i < pointCount; i++) {
|
|
140
177
|
refLng = positions[i * size];
|
|
141
178
|
|
|
142
179
|
if ((refLng + 180) % 360 !== 0) {
|
|
@@ -144,14 +181,14 @@ function shiftLongitudesIntoRange(positions, size) {
|
|
|
144
181
|
}
|
|
145
182
|
}
|
|
146
183
|
|
|
147
|
-
|
|
184
|
+
var delta = -Math.round(refLng / 360) * 360;
|
|
148
185
|
|
|
149
186
|
if (delta === 0) {
|
|
150
187
|
return;
|
|
151
188
|
}
|
|
152
189
|
|
|
153
|
-
for (
|
|
154
|
-
positions[
|
|
190
|
+
for (var _i2 = 0; _i2 < pointCount; _i2++) {
|
|
191
|
+
positions[_i2 * size] += delta;
|
|
155
192
|
}
|
|
156
193
|
}
|
|
157
194
|
//# sourceMappingURL=cut-by-mercator-bounds.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cut-by-mercator-bounds.ts"],"names":["DEFAULT_MAX_LATITUDE","cutPolylineByMercatorBounds","positions","options","size","startIndex","endIndex","length","normalize","newPositions","slice","wrapLongitudesForShortestPath","parts","broken","gridResolution","gridOffset","part","shiftLongitudesIntoRange","cutPolygonByMercatorBounds","holeIndices","edgeTypes","newHoleIndices","srcStartIndex","targetIndex","ringIndex","srcEndIndex","targetStartIndex","splitIndex","findSplitIndex","i","insertPoleVertices","maxLatitude","pop","maxLat","pointIndex","lat","Math","abs","firstLng","lastLng","p","round","sign","prevLng","lng","delta","refLng","pointCount"],"mappings":"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","sourcesContent":["import {cutPolylineByGrid, cutPolygonByGrid} from './cut-by-grid';\nimport {getPointAtIndex, push} from './utils';\nimport type {Polygon} from './cut-by-grid';\n\n// https://en.wikipedia.org/wiki/Web_Mercator_projection\nconst DEFAULT_MAX_LATITUDE = 85.051129;\n\n/** https://user-images.githubusercontent.com/2059298/78465769-938b7a00-76ae-11ea-9b95-1f4c26425ab9.png */\nexport function cutPolylineByMercatorBounds(\n positions: Array<number>,\n options?: {\n size?: number;\n startIndex?: number;\n endIndex?: number;\n normalize?: boolean;\n }\n): Array<number> {\n const {size = 2, startIndex = 0, endIndex = positions.length, normalize = true} = options || {};\n\n // Remap longitudes so that each segment takes the shorter path\n const newPositions = positions.slice(startIndex, endIndex);\n wrapLongitudesForShortestPath(newPositions, size, 0, endIndex - startIndex);\n\n const parts = cutPolylineByGrid(newPositions, {\n size,\n broken: true,\n gridResolution: 360,\n gridOffset: [-180, -180]\n });\n\n if (normalize) {\n // Each part is guaranteed to be in a single copy of the world\n // Map longitudes back to [-180, 180]\n for (const part of parts) {\n shiftLongitudesIntoRange(part, size);\n }\n }\n // @ts-expect-error\n return parts;\n}\n\n/** https://user-images.githubusercontent.com/2059298/78465770-94241080-76ae-11ea-809a-6a8534dac1d9.png */\nexport function cutPolygonByMercatorBounds(\n positions: Array<number>,\n holeIndices: Array<number> | null = null,\n options?: {\n size?: number;\n normalize?: boolean;\n maxLatitude?: number;\n edgeTypes?: boolean;\n }\n): Array<Polygon> {\n const {size = 2, normalize = true, edgeTypes = false} = options || {};\n holeIndices = holeIndices || [];\n const newPositions = [];\n const newHoleIndices = [];\n let srcStartIndex = 0;\n let targetIndex = 0;\n\n for (let ringIndex = 0; ringIndex <= holeIndices.length; ringIndex++) {\n // srcStartIndex/srcEndIndex define the ring in the original positions\n const srcEndIndex = holeIndices[ringIndex] || positions.length;\n // targetStartIndex/targetIndex define the ring in newPositions\n const targetStartIndex = targetIndex;\n\n // In case the ring contains a pole (e.g. Antarctica), we'll have to insert vertices\n // The insertion point is defined by the vertex closest to the pole\n // Split the the ring by the insertion point when copying to newPositions\n const splitIndex = findSplitIndex(positions, size, srcStartIndex, srcEndIndex);\n for (let i = splitIndex; i < srcEndIndex; i++) {\n newPositions[targetIndex++] = positions[i];\n }\n for (let i = srcStartIndex; i < splitIndex; i++) {\n newPositions[targetIndex++] = positions[i];\n }\n\n // Remap longitudes so that each segment takes the shorter path\n wrapLongitudesForShortestPath(newPositions, size, targetStartIndex, targetIndex);\n\n // Handle the case when the ring contains a pole\n insertPoleVertices(newPositions, size, targetStartIndex, targetIndex, options?.maxLatitude);\n\n srcStartIndex = srcEndIndex;\n newHoleIndices[ringIndex] = targetIndex;\n }\n newHoleIndices.pop();\n\n const parts = cutPolygonByGrid(newPositions, newHoleIndices, {\n size,\n gridResolution: 360,\n gridOffset: [-180, -180],\n edgeTypes\n });\n\n if (normalize) {\n // Each part is guaranteed to be in a single copy of the world\n // Map longitudes back to [-180, 180]\n for (const part of parts) {\n shiftLongitudesIntoRange(part.positions, size);\n }\n }\n return parts;\n}\n\n/* Helpers */\n\n// See comments for insertPoleVertices\nfunction findSplitIndex(positions, size, startIndex, endIndex) {\n let maxLat = -1;\n let pointIndex = -1;\n for (let i = startIndex + 1; i < endIndex; i += size) {\n const lat = Math.abs(positions[i]);\n if (lat > maxLat) {\n maxLat = lat;\n pointIndex = i - 1;\n }\n }\n return pointIndex;\n}\n\n// https://user-images.githubusercontent.com/2059298/78857483-5987e400-79de-11ea-98fc-0631287a8431.png\n//\n// If the polygon contains a pole, to tesselate it correctly, we need to insert the edge\n// of map into the polygon. This requires adding two vertices that represent the pole, by\n// drawing a perpendicular line to the Mercator map edge from a selected vertex on the ring.\n//\n// We select the insertion position carefully so that the inserted line segments do not\n// intersect with the ring itself. This is ensured by findSplitIndex, which returns the\n// vertex closest to the pole.\nfunction insertPoleVertices(\n positions,\n size,\n startIndex,\n endIndex,\n maxLatitude = DEFAULT_MAX_LATITUDE\n) {\n // Check if the ring contains a pole\n const firstLng = positions[startIndex];\n const lastLng = positions[endIndex - size];\n if (Math.abs(firstLng - lastLng) > 180) {\n // The ring does not make a round trip\n // Add the nearest pole to the vertices so that the polygon tesselates correctly\n const p = getPointAtIndex(positions, 0, size, startIndex);\n // Copy the first vertex to the world of the last vertex\n p[0] += Math.round((lastLng - firstLng) / 360) * 360;\n push(positions, p);\n // Project the copied vertex to the edge of the map\n p[1] = Math.sign(p[1]) * maxLatitude;\n push(positions, p);\n // Project the first vertex to the edge of the map\n p[0] = firstLng;\n push(positions, p);\n }\n}\n\nfunction wrapLongitudesForShortestPath(positions, size, startIndex, endIndex) {\n let prevLng = positions[0];\n let lng;\n for (let i = startIndex; i < endIndex; i += size) {\n lng = positions[i];\n const delta = lng - prevLng;\n if (delta > 180 || delta < -180) {\n lng -= Math.round(delta / 360) * 360;\n }\n positions[i] = prevLng = lng;\n }\n}\n\nfunction shiftLongitudesIntoRange(positions, size) {\n let refLng;\n const pointCount = positions.length / size;\n\n // Find a longitude that is not on the edge of a world\n // Which we will use to determine which world copy it is\n for (let i = 0; i < pointCount; i++) {\n refLng = positions[i * size];\n if ((refLng + 180) % 360 !== 0) {\n break;\n }\n }\n\n const delta = -Math.round(refLng / 360) * 360;\n if (delta === 0) {\n return;\n }\n for (let i = 0; i < pointCount; i++) {\n positions[i * size] += delta;\n }\n}\n"],"file":"cut-by-mercator-bounds.js"}
|
|
1
|
+
{"version":3,"sources":["../../src/cut-by-mercator-bounds.ts"],"names":["DEFAULT_MAX_LATITUDE","cutPolylineByMercatorBounds","positions","options","size","startIndex","endIndex","length","normalize","newPositions","slice","wrapLongitudesForShortestPath","parts","broken","gridResolution","gridOffset","part","shiftLongitudesIntoRange","cutPolygonByMercatorBounds","holeIndices","edgeTypes","newHoleIndices","srcStartIndex","targetIndex","ringIndex","srcEndIndex","targetStartIndex","splitIndex","findSplitIndex","i","insertPoleVertices","maxLatitude","pop","maxLat","pointIndex","lat","Math","abs","firstLng","lastLng","p","round","sign","prevLng","lng","delta","refLng","pointCount"],"mappings":"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","sourcesContent":["import {cutPolylineByGrid, cutPolygonByGrid} from './cut-by-grid';\nimport {getPointAtIndex, push} from './utils';\nimport type {Polygon} from './cut-by-grid';\nimport type {NumericArray} from '@math.gl/core';\n\n// https://en.wikipedia.org/wiki/Web_Mercator_projection\nconst DEFAULT_MAX_LATITUDE = 85.051129;\n\n/** https://user-images.githubusercontent.com/2059298/78465769-938b7a00-76ae-11ea-9b95-1f4c26425ab9.png */\nexport function cutPolylineByMercatorBounds(\n positions: NumericArray,\n options?: {\n size?: number;\n startIndex?: number;\n endIndex?: number;\n normalize?: boolean;\n }\n): number[][] {\n const {size = 2, startIndex = 0, endIndex = positions.length, normalize = true} = options || {};\n\n // Remap longitudes so that each segment takes the shorter path\n const newPositions = positions.slice(startIndex, endIndex);\n wrapLongitudesForShortestPath(newPositions, size, 0, endIndex - startIndex);\n\n const parts = cutPolylineByGrid(newPositions, {\n size,\n broken: true,\n gridResolution: 360,\n gridOffset: [-180, -180]\n }) as number[][];\n\n if (normalize) {\n // Each part is guaranteed to be in a single copy of the world\n // Map longitudes back to [-180, 180]\n for (const part of parts) {\n shiftLongitudesIntoRange(part, size);\n }\n }\n return parts;\n}\n\n/** https://user-images.githubusercontent.com/2059298/78465770-94241080-76ae-11ea-809a-6a8534dac1d9.png */\nexport function cutPolygonByMercatorBounds(\n positions: number[],\n holeIndices: number[] | null = null,\n options?: {\n size?: number;\n normalize?: boolean;\n maxLatitude?: number;\n edgeTypes?: boolean;\n }\n): Polygon[] {\n const {size = 2, normalize = true, edgeTypes = false} = options || {};\n holeIndices = holeIndices || [];\n const newPositions: number[] = [];\n const newHoleIndices: number[] = [];\n let srcStartIndex = 0;\n let targetIndex = 0;\n\n for (let ringIndex = 0; ringIndex <= holeIndices.length; ringIndex++) {\n // srcStartIndex/srcEndIndex define the ring in the original positions\n const srcEndIndex = holeIndices[ringIndex] || positions.length;\n // targetStartIndex/targetIndex define the ring in newPositions\n const targetStartIndex = targetIndex;\n\n // In case the ring contains a pole (e.g. Antarctica), we'll have to insert vertices\n // The insertion point is defined by the vertex closest to the pole\n // Split the the ring by the insertion point when copying to newPositions\n const splitIndex = findSplitIndex(positions, size, srcStartIndex, srcEndIndex);\n for (let i = splitIndex; i < srcEndIndex; i++) {\n newPositions[targetIndex++] = positions[i];\n }\n for (let i = srcStartIndex; i < splitIndex; i++) {\n newPositions[targetIndex++] = positions[i];\n }\n\n // Remap longitudes so that each segment takes the shorter path\n wrapLongitudesForShortestPath(newPositions, size, targetStartIndex, targetIndex);\n\n // Handle the case when the ring contains a pole\n insertPoleVertices(newPositions, size, targetStartIndex, targetIndex, options?.maxLatitude);\n\n srcStartIndex = srcEndIndex;\n newHoleIndices[ringIndex] = targetIndex;\n }\n newHoleIndices.pop();\n\n const parts = cutPolygonByGrid(newPositions, newHoleIndices, {\n size,\n gridResolution: 360,\n gridOffset: [-180, -180],\n edgeTypes\n });\n\n if (normalize) {\n // Each part is guaranteed to be in a single copy of the world\n // Map longitudes back to [-180, 180]\n for (const part of parts) {\n shiftLongitudesIntoRange(part.positions, size);\n }\n }\n return parts;\n}\n\n/* Helpers */\n\n// See comments for insertPoleVertices\nfunction findSplitIndex(\n positions: number[],\n size: number,\n startIndex: number,\n endIndex: number\n): number {\n let maxLat = -1;\n let pointIndex = -1;\n for (let i = startIndex + 1; i < endIndex; i += size) {\n const lat = Math.abs(positions[i]);\n if (lat > maxLat) {\n maxLat = lat;\n pointIndex = i - 1;\n }\n }\n return pointIndex;\n}\n\n// https://user-images.githubusercontent.com/2059298/78857483-5987e400-79de-11ea-98fc-0631287a8431.png\n//\n// If the polygon contains a pole, to tesselate it correctly, we need to insert the edge\n// of map into the polygon. This requires adding two vertices that represent the pole, by\n// drawing a perpendicular line to the Mercator map edge from a selected vertex on the ring.\n//\n// We select the insertion position carefully so that the inserted line segments do not\n// intersect with the ring itself. This is ensured by findSplitIndex, which returns the\n// vertex closest to the pole.\nfunction insertPoleVertices(\n positions: number[],\n size: number,\n startIndex: number,\n endIndex: number,\n maxLatitude: number = DEFAULT_MAX_LATITUDE\n): void {\n // Check if the ring contains a pole\n const firstLng = positions[startIndex];\n const lastLng = positions[endIndex - size];\n if (Math.abs(firstLng - lastLng) > 180) {\n // The ring does not make a round trip\n // Add the nearest pole to the vertices so that the polygon tesselates correctly\n const p = getPointAtIndex(positions, 0, size, startIndex);\n // Copy the first vertex to the world of the last vertex\n p[0] += Math.round((lastLng - firstLng) / 360) * 360;\n push(positions, p);\n // Project the copied vertex to the edge of the map\n p[1] = Math.sign(p[1]) * maxLatitude;\n push(positions, p);\n // Project the first vertex to the edge of the map\n p[0] = firstLng;\n push(positions, p);\n }\n}\n\nfunction wrapLongitudesForShortestPath(\n positions: NumericArray,\n size: number,\n startIndex: number,\n endIndex: number\n): void {\n let prevLng: number = positions[0];\n let lng: number;\n for (let i = startIndex; i < endIndex; i += size) {\n lng = positions[i];\n const delta = lng - prevLng;\n if (delta > 180 || delta < -180) {\n lng -= Math.round(delta / 360) * 360;\n }\n positions[i] = prevLng = lng;\n }\n}\n\nfunction shiftLongitudesIntoRange(positions: NumericArray, size: number): void {\n let refLng: number;\n const pointCount = positions.length / size;\n\n // Find a longitude that is not on the edge of a world\n // Which we will use to determine which world copy it is\n for (let i = 0; i < pointCount; i++) {\n refLng = positions[i * size];\n if ((refLng + 180) % 360 !== 0) {\n break;\n }\n }\n\n const delta = -Math.round(refLng / 360) * 360;\n if (delta === 0) {\n return;\n }\n for (let i = 0; i < pointCount; i++) {\n positions[i * size] += delta;\n }\n}\n"],"file":"cut-by-mercator-bounds.js"}
|
package/dist/es5/earcut.js
CHANGED
|
@@ -7,26 +7,28 @@ exports.earcut = earcut;
|
|
|
7
7
|
|
|
8
8
|
var _polygonUtils = require("./polygon-utils");
|
|
9
9
|
|
|
10
|
-
function earcut(positions, holeIndices
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
function earcut(positions, holeIndices) {
|
|
11
|
+
var dim = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 2;
|
|
12
|
+
var areas = arguments.length > 3 ? arguments[3] : undefined;
|
|
13
|
+
var hasHoles = holeIndices && holeIndices.length;
|
|
14
|
+
var outerLen = hasHoles ? holeIndices[0] * dim : positions.length;
|
|
15
|
+
var outerNode = linkedList(positions, 0, outerLen, dim, true, areas && areas[0]);
|
|
16
|
+
var triangles = [];
|
|
15
17
|
if (!outerNode || outerNode.next === outerNode.prev) return triangles;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
var invSize;
|
|
19
|
+
var maxX;
|
|
20
|
+
var maxY;
|
|
21
|
+
var minX;
|
|
22
|
+
var minY;
|
|
23
|
+
var x;
|
|
24
|
+
var y;
|
|
23
25
|
if (hasHoles) outerNode = eliminateHoles(positions, holeIndices, outerNode, dim, areas);
|
|
24
26
|
|
|
25
27
|
if (positions.length > 80 * dim) {
|
|
26
28
|
minX = maxX = positions[0];
|
|
27
29
|
minY = maxY = positions[1];
|
|
28
30
|
|
|
29
|
-
for (
|
|
31
|
+
for (var i = dim; i < outerLen; i += dim) {
|
|
30
32
|
x = positions[i];
|
|
31
33
|
y = positions[i + 1];
|
|
32
34
|
if (x < minX) minX = x;
|
|
@@ -44,21 +46,25 @@ function earcut(positions, holeIndices, dim = 2, areas) {
|
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
function linkedList(data, start, end, dim, clockwise, area) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
var i;
|
|
50
|
+
var last;
|
|
49
51
|
|
|
50
52
|
if (area === undefined) {
|
|
51
53
|
area = (0, _polygonUtils.getPolygonSignedArea)(data, {
|
|
52
|
-
start,
|
|
53
|
-
end,
|
|
54
|
+
start: start,
|
|
55
|
+
end: end,
|
|
54
56
|
size: dim
|
|
55
57
|
});
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
if (clockwise === area < 0) {
|
|
59
|
-
for (i = start; i < end; i += dim)
|
|
61
|
+
for (i = start; i < end; i += dim) {
|
|
62
|
+
last = insertNode(i, data[i], data[i + 1], last);
|
|
63
|
+
}
|
|
60
64
|
} else {
|
|
61
|
-
for (i = end - dim; i >= start; i -= dim)
|
|
65
|
+
for (i = end - dim; i >= start; i -= dim) {
|
|
66
|
+
last = insertNode(i, data[i], data[i + 1], last);
|
|
67
|
+
}
|
|
62
68
|
}
|
|
63
69
|
|
|
64
70
|
if (last && equals(last, last.next)) {
|
|
@@ -72,8 +78,8 @@ function linkedList(data, start, end, dim, clockwise, area) {
|
|
|
72
78
|
function filterPoints(start, end) {
|
|
73
79
|
if (!start) return start;
|
|
74
80
|
if (!end) end = start;
|
|
75
|
-
|
|
76
|
-
|
|
81
|
+
var p = start;
|
|
82
|
+
var again;
|
|
77
83
|
|
|
78
84
|
do {
|
|
79
85
|
again = false;
|
|
@@ -94,9 +100,9 @@ function filterPoints(start, end) {
|
|
|
94
100
|
function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
|
|
95
101
|
if (!ear) return;
|
|
96
102
|
if (!pass && invSize) indexCurve(ear, minX, minY, invSize);
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
103
|
+
var stop = ear;
|
|
104
|
+
var prev;
|
|
105
|
+
var next;
|
|
100
106
|
|
|
101
107
|
while (ear.prev !== ear.next) {
|
|
102
108
|
prev = ear.prev;
|
|
@@ -130,11 +136,11 @@ function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
|
|
|
130
136
|
}
|
|
131
137
|
|
|
132
138
|
function isEar(ear) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
139
|
+
var a = ear.prev;
|
|
140
|
+
var b = ear;
|
|
141
|
+
var c = ear.next;
|
|
136
142
|
if (area(a, b, c) >= 0) return false;
|
|
137
|
-
|
|
143
|
+
var p = ear.next.next;
|
|
138
144
|
|
|
139
145
|
while (p !== ear.prev) {
|
|
140
146
|
if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
|
|
@@ -145,18 +151,18 @@ function isEar(ear) {
|
|
|
145
151
|
}
|
|
146
152
|
|
|
147
153
|
function isEarHashed(ear, minX, minY, invSize) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
154
|
+
var a = ear.prev;
|
|
155
|
+
var b = ear;
|
|
156
|
+
var c = ear.next;
|
|
151
157
|
if (area(a, b, c) >= 0) return false;
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
158
|
+
var minTX = a.x < b.x ? a.x < c.x ? a.x : c.x : b.x < c.x ? b.x : c.x;
|
|
159
|
+
var minTY = a.y < b.y ? a.y < c.y ? a.y : c.y : b.y < c.y ? b.y : c.y;
|
|
160
|
+
var maxTX = a.x > b.x ? a.x > c.x ? a.x : c.x : b.x > c.x ? b.x : c.x;
|
|
161
|
+
var maxTY = a.y > b.y ? a.y > c.y ? a.y : c.y : b.y > c.y ? b.y : c.y;
|
|
162
|
+
var minZ = zOrder(minTX, minTY, minX, minY, invSize);
|
|
163
|
+
var maxZ = zOrder(maxTX, maxTY, minX, minY, invSize);
|
|
164
|
+
var p = ear.prevZ;
|
|
165
|
+
var n = ear.nextZ;
|
|
160
166
|
|
|
161
167
|
while (p && p.z >= minZ && n && n.z <= maxZ) {
|
|
162
168
|
if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
|
|
@@ -179,11 +185,11 @@ function isEarHashed(ear, minX, minY, invSize) {
|
|
|
179
185
|
}
|
|
180
186
|
|
|
181
187
|
function cureLocalIntersections(start, triangles, dim) {
|
|
182
|
-
|
|
188
|
+
var p = start;
|
|
183
189
|
|
|
184
190
|
do {
|
|
185
|
-
|
|
186
|
-
|
|
191
|
+
var a = p.prev;
|
|
192
|
+
var b = p.next.next;
|
|
187
193
|
|
|
188
194
|
if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
|
|
189
195
|
triangles.push(a.i / dim);
|
|
@@ -201,14 +207,14 @@ function cureLocalIntersections(start, triangles, dim) {
|
|
|
201
207
|
}
|
|
202
208
|
|
|
203
209
|
function splitEarcut(start, triangles, dim, minX, minY, invSize) {
|
|
204
|
-
|
|
210
|
+
var a = start;
|
|
205
211
|
|
|
206
212
|
do {
|
|
207
|
-
|
|
213
|
+
var b = a.next.next;
|
|
208
214
|
|
|
209
215
|
while (b !== a.prev) {
|
|
210
216
|
if (a.i !== b.i && isValidDiagonal(a, b)) {
|
|
211
|
-
|
|
217
|
+
var c = splitPolygon(a, b);
|
|
212
218
|
a = filterPoints(a, a.next);
|
|
213
219
|
c = filterPoints(c, c.next);
|
|
214
220
|
earcutLinked(a, triangles, dim, minX, minY, invSize);
|
|
@@ -224,12 +230,12 @@ function splitEarcut(start, triangles, dim, minX, minY, invSize) {
|
|
|
224
230
|
}
|
|
225
231
|
|
|
226
232
|
function eliminateHoles(data, holeIndices, outerNode, dim, areas) {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
+
var queue = [];
|
|
234
|
+
var i;
|
|
235
|
+
var len;
|
|
236
|
+
var start;
|
|
237
|
+
var end;
|
|
238
|
+
var list;
|
|
233
239
|
|
|
234
240
|
for (i = 0, len = holeIndices.length; i < len; i++) {
|
|
235
241
|
start = holeIndices[i] * dim;
|
|
@@ -257,22 +263,22 @@ function eliminateHole(hole, outerNode) {
|
|
|
257
263
|
outerNode = findHoleBridge(hole, outerNode);
|
|
258
264
|
|
|
259
265
|
if (outerNode) {
|
|
260
|
-
|
|
266
|
+
var b = splitPolygon(outerNode, hole);
|
|
261
267
|
filterPoints(outerNode, outerNode.next);
|
|
262
268
|
filterPoints(b, b.next);
|
|
263
269
|
}
|
|
264
270
|
}
|
|
265
271
|
|
|
266
272
|
function findHoleBridge(hole, outerNode) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
273
|
+
var p = outerNode;
|
|
274
|
+
var hx = hole.x;
|
|
275
|
+
var hy = hole.y;
|
|
276
|
+
var qx = -Infinity;
|
|
277
|
+
var m;
|
|
272
278
|
|
|
273
279
|
do {
|
|
274
280
|
if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
|
|
275
|
-
|
|
281
|
+
var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
|
|
276
282
|
|
|
277
283
|
if (x <= hx && x > qx) {
|
|
278
284
|
qx = x;
|
|
@@ -291,11 +297,11 @@ function findHoleBridge(hole, outerNode) {
|
|
|
291
297
|
|
|
292
298
|
if (!m) return null;
|
|
293
299
|
if (hx === qx) return m;
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
300
|
+
var stop = m;
|
|
301
|
+
var mx = m.x;
|
|
302
|
+
var my = m.y;
|
|
303
|
+
var tanMin = Infinity;
|
|
304
|
+
var tan;
|
|
299
305
|
p = m;
|
|
300
306
|
|
|
301
307
|
do {
|
|
@@ -319,7 +325,7 @@ function sectorContainsSector(m, p) {
|
|
|
319
325
|
}
|
|
320
326
|
|
|
321
327
|
function indexCurve(start, minX, minY, invSize) {
|
|
322
|
-
|
|
328
|
+
var p = start;
|
|
323
329
|
|
|
324
330
|
do {
|
|
325
331
|
if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, invSize);
|
|
@@ -334,15 +340,15 @@ function indexCurve(start, minX, minY, invSize) {
|
|
|
334
340
|
}
|
|
335
341
|
|
|
336
342
|
function sortLinked(list) {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
343
|
+
var e;
|
|
344
|
+
var i;
|
|
345
|
+
var inSize = 1;
|
|
346
|
+
var numMerges;
|
|
347
|
+
var p;
|
|
348
|
+
var pSize;
|
|
349
|
+
var q;
|
|
350
|
+
var qSize;
|
|
351
|
+
var tail;
|
|
346
352
|
|
|
347
353
|
do {
|
|
348
354
|
p = list;
|
|
@@ -404,8 +410,8 @@ function zOrder(x, y, minX, minY, invSize) {
|
|
|
404
410
|
}
|
|
405
411
|
|
|
406
412
|
function getLeftmost(start) {
|
|
407
|
-
|
|
408
|
-
|
|
413
|
+
var p = start;
|
|
414
|
+
var leftmost = start;
|
|
409
415
|
|
|
410
416
|
do {
|
|
411
417
|
if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y) leftmost = p;
|
|
@@ -432,10 +438,10 @@ function equals(p1, p2) {
|
|
|
432
438
|
}
|
|
433
439
|
|
|
434
440
|
function intersects(p1, q1, p2, q2) {
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
441
|
+
var o1 = sign(area(p1, q1, p2));
|
|
442
|
+
var o2 = sign(area(p1, q1, q2));
|
|
443
|
+
var o3 = sign(area(p2, q2, p1));
|
|
444
|
+
var o4 = sign(area(p2, q2, q1));
|
|
439
445
|
if (o1 !== o2 && o3 !== o4) return true;
|
|
440
446
|
if (o1 === 0 && onSegment(p1, p2, q1)) return true;
|
|
441
447
|
if (o2 === 0 && onSegment(p1, q2, q1)) return true;
|
|
@@ -453,7 +459,7 @@ function sign(num) {
|
|
|
453
459
|
}
|
|
454
460
|
|
|
455
461
|
function intersectsPolygon(a, b) {
|
|
456
|
-
|
|
462
|
+
var p = a;
|
|
457
463
|
|
|
458
464
|
do {
|
|
459
465
|
if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && intersects(p, p.next, a, b)) return true;
|
|
@@ -468,10 +474,10 @@ function locallyInside(a, b) {
|
|
|
468
474
|
}
|
|
469
475
|
|
|
470
476
|
function middleInside(a, b) {
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
477
|
+
var p = a;
|
|
478
|
+
var inside = false;
|
|
479
|
+
var px = (a.x + b.x) / 2;
|
|
480
|
+
var py = (a.y + b.y) / 2;
|
|
475
481
|
|
|
476
482
|
do {
|
|
477
483
|
if (p.y > py !== p.next.y > py && p.next.y !== p.y && px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x) inside = !inside;
|
|
@@ -482,10 +488,10 @@ function middleInside(a, b) {
|
|
|
482
488
|
}
|
|
483
489
|
|
|
484
490
|
function splitPolygon(a, b) {
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
491
|
+
var a2 = new Node(a.i, a.x, a.y);
|
|
492
|
+
var b2 = new Node(b.i, b.x, b.y);
|
|
493
|
+
var an = a.next;
|
|
494
|
+
var bp = b.prev;
|
|
489
495
|
a.next = b;
|
|
490
496
|
b.prev = a;
|
|
491
497
|
a2.next = an;
|
|
@@ -498,7 +504,7 @@ function splitPolygon(a, b) {
|
|
|
498
504
|
}
|
|
499
505
|
|
|
500
506
|
function insertNode(i, x, y, last) {
|
|
501
|
-
|
|
507
|
+
var p = new Node(i, x, y);
|
|
502
508
|
|
|
503
509
|
if (!last) {
|
|
504
510
|
p.prev = p;
|