wkt-parse-and-geojson 1.0.1 → 1.0.3

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/index.cjs.js CHANGED
@@ -1,5 +1,10 @@
1
1
  'use strict';
2
2
 
3
+ // Precompiled regex for better performance
4
+ const RE_WHITESPACE = /\s/;
5
+ const RE_NUMBER_START = /[0-9\-]/;
6
+ const RE_NUMBER_BODY = /[0-9\.\-eE\+]/;
7
+ const RE_WORD_CHAR = /[a-zA-Z_]/;
3
8
  class Lexer {
4
9
  constructor(input) {
5
10
  this.pos = 0;
@@ -12,14 +17,13 @@ class Lexer {
12
17
  return this.input[this.pos++] || '';
13
18
  }
14
19
  isWhitespace(c) {
15
- return /\s/.test(c);
20
+ return RE_WHITESPACE.test(c);
16
21
  }
17
- /** 数字开头字符:数字 或 负号 */
18
22
  isNumberStart(c) {
19
- return /[0-9\-]/.test(c);
23
+ return RE_NUMBER_START.test(c);
20
24
  }
21
25
  isNumberBody(c) {
22
- return /[0-9\.\-eE\+]/.test(c);
26
+ return RE_NUMBER_BODY.test(c);
23
27
  }
24
28
  nextToken() {
25
29
  // skip whitespace
@@ -44,18 +48,18 @@ class Lexer {
44
48
  }
45
49
  // Number: starts with digit or minus
46
50
  if (this.isNumberStart(c)) {
47
- let num = '';
51
+ const start = this.pos;
48
52
  while (this.pos < this.input.length && this.isNumberBody(this.peek())) {
49
- num += this.advance();
53
+ this.pos++;
50
54
  }
51
- return { type: 'NUMBER', value: num };
55
+ return { type: 'NUMBER', value: this.input.slice(start, this.pos) };
52
56
  }
53
57
  // Word (geometry type or EMPTY/Z/M keyword)
54
- let word = '';
55
- while (this.pos < this.input.length && /[a-zA-Z_]/.test(this.peek())) {
56
- word += this.advance();
58
+ const start = this.pos;
59
+ while (this.pos < this.input.length && RE_WORD_CHAR.test(this.peek())) {
60
+ this.pos++;
57
61
  }
58
- return { type: 'WORD', value: word.toUpperCase() };
62
+ return { type: 'WORD', value: this.input.slice(start, this.pos).toUpperCase() };
59
63
  }
60
64
  }
61
65
  class WKTParser {
@@ -94,6 +98,15 @@ class WKTParser {
94
98
  }
95
99
  return this.advance();
96
100
  }
101
+ skipComma() {
102
+ if (this.peek().type === 'COMMA') {
103
+ this.advance();
104
+ }
105
+ }
106
+ isDone() {
107
+ const t = this.peek();
108
+ return t.type === 'RPAREN' || t.type === 'EOF';
109
+ }
97
110
  parseGeometry() {
98
111
  const token = this.peek();
99
112
  if (token.type !== 'WORD') {
@@ -166,7 +179,13 @@ class WKTParser {
166
179
  if (this.isEmptyGeometry()) {
167
180
  return { type: 'Polygon', coordinates: [] };
168
181
  }
169
- const rings = this.parseCoordinateListList();
182
+ this.consume('LPAREN');
183
+ const rings = [];
184
+ while (!this.isDone()) {
185
+ rings.push(this.parseCoordinatesList());
186
+ this.skipComma();
187
+ }
188
+ this.consume('RPAREN');
170
189
  return { type: 'Polygon', coordinates: rings };
171
190
  }
172
191
  // ── MULTIPOINT ───────────────────────────────────────────────────
@@ -178,7 +197,7 @@ class WKTParser {
178
197
  }
179
198
  this.advance(); // consume outer (
180
199
  const coords = [];
181
- while (this.peek().type !== 'RPAREN' && this.peek().type !== 'EOF') {
200
+ while (!this.isDone()) {
182
201
  if (this.peek().type === 'LPAREN') {
183
202
  // 标准写法: MULTIPOINT ((x y), (x y))
184
203
  this.advance(); // consume (
@@ -189,9 +208,7 @@ class WKTParser {
189
208
  // 非标准写法: MULTIPOINT (x y, x y)
190
209
  coords.push(this.parseCoordinates());
191
210
  }
192
- if (this.peek().type === 'COMMA') {
193
- this.advance();
194
- }
211
+ this.skipComma();
195
212
  }
196
213
  this.consume('RPAREN');
197
214
  return { type: 'MultiPoint', coordinates: coords };
@@ -205,11 +222,9 @@ class WKTParser {
205
222
  }
206
223
  this.advance(); // consume outer (
207
224
  const lines = [];
208
- while (this.peek().type !== 'RPAREN' && this.peek().type !== 'EOF') {
225
+ while (!this.isDone()) {
209
226
  lines.push(this.parseCoordinatesList());
210
- if (this.peek().type === 'COMMA') {
211
- this.advance();
212
- }
227
+ this.skipComma();
213
228
  }
214
229
  this.consume('RPAREN');
215
230
  return { type: 'MultiLineString', coordinates: lines };
@@ -221,7 +236,13 @@ class WKTParser {
221
236
  if (this.isEmptyGeometry()) {
222
237
  return { type: 'MultiPolygon', coordinates: [] };
223
238
  }
224
- const polys = this.parseCoordinateListListList();
239
+ this.consume('LPAREN');
240
+ const polys = [];
241
+ while (!this.isDone()) {
242
+ polys.push(this.parseCoordinateListList());
243
+ this.skipComma();
244
+ }
245
+ this.consume('RPAREN');
225
246
  return { type: 'MultiPolygon', coordinates: polys };
226
247
  }
227
248
  // ── GEOMETRYCOLLECTION ───────────────────────────────────────────
@@ -233,11 +254,9 @@ class WKTParser {
233
254
  }
234
255
  this.advance(); // consume (
235
256
  const geometries = [];
236
- while (this.peek().type !== 'RPAREN' && this.peek().type !== 'EOF') {
257
+ while (!this.isDone()) {
237
258
  geometries.push(this.parseGeometry());
238
- if (this.peek().type === 'COMMA') {
239
- this.advance();
240
- }
259
+ this.skipComma();
241
260
  }
242
261
  this.consume('RPAREN');
243
262
  return { type: 'GeometryCollection', geometries };
@@ -270,11 +289,9 @@ class WKTParser {
270
289
  parseCoordinatesList() {
271
290
  this.consume('LPAREN');
272
291
  const coords = [];
273
- while (this.peek().type !== 'RPAREN' && this.peek().type !== 'EOF') {
292
+ while (!this.isDone()) {
274
293
  coords.push(this.parseCoordinates());
275
- if (this.peek().type === 'COMMA') {
276
- this.advance();
277
- }
294
+ this.skipComma();
278
295
  }
279
296
  this.consume('RPAREN');
280
297
  return coords;
@@ -285,26 +302,9 @@ class WKTParser {
285
302
  return [];
286
303
  this.advance(); // consume outer (
287
304
  const lists = [];
288
- while (this.peek().type !== 'RPAREN' && this.peek().type !== 'EOF') {
305
+ while (!this.isDone()) {
289
306
  lists.push(this.parseCoordinatesList());
290
- if (this.peek().type === 'COMMA') {
291
- this.advance();
292
- }
293
- }
294
- this.consume('RPAREN');
295
- return lists;
296
- }
297
- /** 解析多边形列表(MultiPolygon 级别):( ((...)), ((...)) ) */
298
- parseCoordinateListListList() {
299
- if (this.peek().type !== 'LPAREN')
300
- return [];
301
- this.advance(); // consume outer (
302
- const lists = [];
303
- while (this.peek().type !== 'RPAREN' && this.peek().type !== 'EOF') {
304
- lists.push(this.parseCoordinateListList());
305
- if (this.peek().type === 'COMMA') {
306
- this.advance();
307
- }
307
+ this.skipComma();
308
308
  }
309
309
  this.consume('RPAREN');
310
310
  return lists;
package/dist/index.esm.js CHANGED
@@ -1,3 +1,8 @@
1
+ // Precompiled regex for better performance
2
+ const RE_WHITESPACE = /\s/;
3
+ const RE_NUMBER_START = /[0-9\-]/;
4
+ const RE_NUMBER_BODY = /[0-9\.\-eE\+]/;
5
+ const RE_WORD_CHAR = /[a-zA-Z_]/;
1
6
  class Lexer {
2
7
  constructor(input) {
3
8
  this.pos = 0;
@@ -10,14 +15,13 @@ class Lexer {
10
15
  return this.input[this.pos++] || '';
11
16
  }
12
17
  isWhitespace(c) {
13
- return /\s/.test(c);
18
+ return RE_WHITESPACE.test(c);
14
19
  }
15
- /** 数字开头字符:数字 或 负号 */
16
20
  isNumberStart(c) {
17
- return /[0-9\-]/.test(c);
21
+ return RE_NUMBER_START.test(c);
18
22
  }
19
23
  isNumberBody(c) {
20
- return /[0-9\.\-eE\+]/.test(c);
24
+ return RE_NUMBER_BODY.test(c);
21
25
  }
22
26
  nextToken() {
23
27
  // skip whitespace
@@ -42,18 +46,18 @@ class Lexer {
42
46
  }
43
47
  // Number: starts with digit or minus
44
48
  if (this.isNumberStart(c)) {
45
- let num = '';
49
+ const start = this.pos;
46
50
  while (this.pos < this.input.length && this.isNumberBody(this.peek())) {
47
- num += this.advance();
51
+ this.pos++;
48
52
  }
49
- return { type: 'NUMBER', value: num };
53
+ return { type: 'NUMBER', value: this.input.slice(start, this.pos) };
50
54
  }
51
55
  // Word (geometry type or EMPTY/Z/M keyword)
52
- let word = '';
53
- while (this.pos < this.input.length && /[a-zA-Z_]/.test(this.peek())) {
54
- word += this.advance();
56
+ const start = this.pos;
57
+ while (this.pos < this.input.length && RE_WORD_CHAR.test(this.peek())) {
58
+ this.pos++;
55
59
  }
56
- return { type: 'WORD', value: word.toUpperCase() };
60
+ return { type: 'WORD', value: this.input.slice(start, this.pos).toUpperCase() };
57
61
  }
58
62
  }
59
63
  class WKTParser {
@@ -92,6 +96,15 @@ class WKTParser {
92
96
  }
93
97
  return this.advance();
94
98
  }
99
+ skipComma() {
100
+ if (this.peek().type === 'COMMA') {
101
+ this.advance();
102
+ }
103
+ }
104
+ isDone() {
105
+ const t = this.peek();
106
+ return t.type === 'RPAREN' || t.type === 'EOF';
107
+ }
95
108
  parseGeometry() {
96
109
  const token = this.peek();
97
110
  if (token.type !== 'WORD') {
@@ -164,7 +177,13 @@ class WKTParser {
164
177
  if (this.isEmptyGeometry()) {
165
178
  return { type: 'Polygon', coordinates: [] };
166
179
  }
167
- const rings = this.parseCoordinateListList();
180
+ this.consume('LPAREN');
181
+ const rings = [];
182
+ while (!this.isDone()) {
183
+ rings.push(this.parseCoordinatesList());
184
+ this.skipComma();
185
+ }
186
+ this.consume('RPAREN');
168
187
  return { type: 'Polygon', coordinates: rings };
169
188
  }
170
189
  // ── MULTIPOINT ───────────────────────────────────────────────────
@@ -176,7 +195,7 @@ class WKTParser {
176
195
  }
177
196
  this.advance(); // consume outer (
178
197
  const coords = [];
179
- while (this.peek().type !== 'RPAREN' && this.peek().type !== 'EOF') {
198
+ while (!this.isDone()) {
180
199
  if (this.peek().type === 'LPAREN') {
181
200
  // 标准写法: MULTIPOINT ((x y), (x y))
182
201
  this.advance(); // consume (
@@ -187,9 +206,7 @@ class WKTParser {
187
206
  // 非标准写法: MULTIPOINT (x y, x y)
188
207
  coords.push(this.parseCoordinates());
189
208
  }
190
- if (this.peek().type === 'COMMA') {
191
- this.advance();
192
- }
209
+ this.skipComma();
193
210
  }
194
211
  this.consume('RPAREN');
195
212
  return { type: 'MultiPoint', coordinates: coords };
@@ -203,11 +220,9 @@ class WKTParser {
203
220
  }
204
221
  this.advance(); // consume outer (
205
222
  const lines = [];
206
- while (this.peek().type !== 'RPAREN' && this.peek().type !== 'EOF') {
223
+ while (!this.isDone()) {
207
224
  lines.push(this.parseCoordinatesList());
208
- if (this.peek().type === 'COMMA') {
209
- this.advance();
210
- }
225
+ this.skipComma();
211
226
  }
212
227
  this.consume('RPAREN');
213
228
  return { type: 'MultiLineString', coordinates: lines };
@@ -219,7 +234,13 @@ class WKTParser {
219
234
  if (this.isEmptyGeometry()) {
220
235
  return { type: 'MultiPolygon', coordinates: [] };
221
236
  }
222
- const polys = this.parseCoordinateListListList();
237
+ this.consume('LPAREN');
238
+ const polys = [];
239
+ while (!this.isDone()) {
240
+ polys.push(this.parseCoordinateListList());
241
+ this.skipComma();
242
+ }
243
+ this.consume('RPAREN');
223
244
  return { type: 'MultiPolygon', coordinates: polys };
224
245
  }
225
246
  // ── GEOMETRYCOLLECTION ───────────────────────────────────────────
@@ -231,11 +252,9 @@ class WKTParser {
231
252
  }
232
253
  this.advance(); // consume (
233
254
  const geometries = [];
234
- while (this.peek().type !== 'RPAREN' && this.peek().type !== 'EOF') {
255
+ while (!this.isDone()) {
235
256
  geometries.push(this.parseGeometry());
236
- if (this.peek().type === 'COMMA') {
237
- this.advance();
238
- }
257
+ this.skipComma();
239
258
  }
240
259
  this.consume('RPAREN');
241
260
  return { type: 'GeometryCollection', geometries };
@@ -268,11 +287,9 @@ class WKTParser {
268
287
  parseCoordinatesList() {
269
288
  this.consume('LPAREN');
270
289
  const coords = [];
271
- while (this.peek().type !== 'RPAREN' && this.peek().type !== 'EOF') {
290
+ while (!this.isDone()) {
272
291
  coords.push(this.parseCoordinates());
273
- if (this.peek().type === 'COMMA') {
274
- this.advance();
275
- }
292
+ this.skipComma();
276
293
  }
277
294
  this.consume('RPAREN');
278
295
  return coords;
@@ -283,26 +300,9 @@ class WKTParser {
283
300
  return [];
284
301
  this.advance(); // consume outer (
285
302
  const lists = [];
286
- while (this.peek().type !== 'RPAREN' && this.peek().type !== 'EOF') {
303
+ while (!this.isDone()) {
287
304
  lists.push(this.parseCoordinatesList());
288
- if (this.peek().type === 'COMMA') {
289
- this.advance();
290
- }
291
- }
292
- this.consume('RPAREN');
293
- return lists;
294
- }
295
- /** 解析多边形列表(MultiPolygon 级别):( ((...)), ((...)) ) */
296
- parseCoordinateListListList() {
297
- if (this.peek().type !== 'LPAREN')
298
- return [];
299
- this.advance(); // consume outer (
300
- const lists = [];
301
- while (this.peek().type !== 'RPAREN' && this.peek().type !== 'EOF') {
302
- lists.push(this.parseCoordinateListList());
303
- if (this.peek().type === 'COMMA') {
304
- this.advance();
305
- }
305
+ this.skipComma();
306
306
  }
307
307
  this.consume('RPAREN');
308
308
  return lists;
package/dist/index.umd.js CHANGED
@@ -4,6 +4,11 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.WKTGeoJSON = {}));
5
5
  })(this, (function (exports) { 'use strict';
6
6
 
7
+ // Precompiled regex for better performance
8
+ const RE_WHITESPACE = /\s/;
9
+ const RE_NUMBER_START = /[0-9\-]/;
10
+ const RE_NUMBER_BODY = /[0-9\.\-eE\+]/;
11
+ const RE_WORD_CHAR = /[a-zA-Z_]/;
7
12
  class Lexer {
8
13
  constructor(input) {
9
14
  this.pos = 0;
@@ -16,14 +21,13 @@
16
21
  return this.input[this.pos++] || '';
17
22
  }
18
23
  isWhitespace(c) {
19
- return /\s/.test(c);
24
+ return RE_WHITESPACE.test(c);
20
25
  }
21
- /** 数字开头字符:数字 或 负号 */
22
26
  isNumberStart(c) {
23
- return /[0-9\-]/.test(c);
27
+ return RE_NUMBER_START.test(c);
24
28
  }
25
29
  isNumberBody(c) {
26
- return /[0-9\.\-eE\+]/.test(c);
30
+ return RE_NUMBER_BODY.test(c);
27
31
  }
28
32
  nextToken() {
29
33
  // skip whitespace
@@ -48,18 +52,18 @@
48
52
  }
49
53
  // Number: starts with digit or minus
50
54
  if (this.isNumberStart(c)) {
51
- let num = '';
55
+ const start = this.pos;
52
56
  while (this.pos < this.input.length && this.isNumberBody(this.peek())) {
53
- num += this.advance();
57
+ this.pos++;
54
58
  }
55
- return { type: 'NUMBER', value: num };
59
+ return { type: 'NUMBER', value: this.input.slice(start, this.pos) };
56
60
  }
57
61
  // Word (geometry type or EMPTY/Z/M keyword)
58
- let word = '';
59
- while (this.pos < this.input.length && /[a-zA-Z_]/.test(this.peek())) {
60
- word += this.advance();
62
+ const start = this.pos;
63
+ while (this.pos < this.input.length && RE_WORD_CHAR.test(this.peek())) {
64
+ this.pos++;
61
65
  }
62
- return { type: 'WORD', value: word.toUpperCase() };
66
+ return { type: 'WORD', value: this.input.slice(start, this.pos).toUpperCase() };
63
67
  }
64
68
  }
65
69
  class WKTParser {
@@ -98,6 +102,15 @@
98
102
  }
99
103
  return this.advance();
100
104
  }
105
+ skipComma() {
106
+ if (this.peek().type === 'COMMA') {
107
+ this.advance();
108
+ }
109
+ }
110
+ isDone() {
111
+ const t = this.peek();
112
+ return t.type === 'RPAREN' || t.type === 'EOF';
113
+ }
101
114
  parseGeometry() {
102
115
  const token = this.peek();
103
116
  if (token.type !== 'WORD') {
@@ -170,7 +183,13 @@
170
183
  if (this.isEmptyGeometry()) {
171
184
  return { type: 'Polygon', coordinates: [] };
172
185
  }
173
- const rings = this.parseCoordinateListList();
186
+ this.consume('LPAREN');
187
+ const rings = [];
188
+ while (!this.isDone()) {
189
+ rings.push(this.parseCoordinatesList());
190
+ this.skipComma();
191
+ }
192
+ this.consume('RPAREN');
174
193
  return { type: 'Polygon', coordinates: rings };
175
194
  }
176
195
  // ── MULTIPOINT ───────────────────────────────────────────────────
@@ -182,7 +201,7 @@
182
201
  }
183
202
  this.advance(); // consume outer (
184
203
  const coords = [];
185
- while (this.peek().type !== 'RPAREN' && this.peek().type !== 'EOF') {
204
+ while (!this.isDone()) {
186
205
  if (this.peek().type === 'LPAREN') {
187
206
  // 标准写法: MULTIPOINT ((x y), (x y))
188
207
  this.advance(); // consume (
@@ -193,9 +212,7 @@
193
212
  // 非标准写法: MULTIPOINT (x y, x y)
194
213
  coords.push(this.parseCoordinates());
195
214
  }
196
- if (this.peek().type === 'COMMA') {
197
- this.advance();
198
- }
215
+ this.skipComma();
199
216
  }
200
217
  this.consume('RPAREN');
201
218
  return { type: 'MultiPoint', coordinates: coords };
@@ -209,11 +226,9 @@
209
226
  }
210
227
  this.advance(); // consume outer (
211
228
  const lines = [];
212
- while (this.peek().type !== 'RPAREN' && this.peek().type !== 'EOF') {
229
+ while (!this.isDone()) {
213
230
  lines.push(this.parseCoordinatesList());
214
- if (this.peek().type === 'COMMA') {
215
- this.advance();
216
- }
231
+ this.skipComma();
217
232
  }
218
233
  this.consume('RPAREN');
219
234
  return { type: 'MultiLineString', coordinates: lines };
@@ -225,7 +240,13 @@
225
240
  if (this.isEmptyGeometry()) {
226
241
  return { type: 'MultiPolygon', coordinates: [] };
227
242
  }
228
- const polys = this.parseCoordinateListListList();
243
+ this.consume('LPAREN');
244
+ const polys = [];
245
+ while (!this.isDone()) {
246
+ polys.push(this.parseCoordinateListList());
247
+ this.skipComma();
248
+ }
249
+ this.consume('RPAREN');
229
250
  return { type: 'MultiPolygon', coordinates: polys };
230
251
  }
231
252
  // ── GEOMETRYCOLLECTION ───────────────────────────────────────────
@@ -237,11 +258,9 @@
237
258
  }
238
259
  this.advance(); // consume (
239
260
  const geometries = [];
240
- while (this.peek().type !== 'RPAREN' && this.peek().type !== 'EOF') {
261
+ while (!this.isDone()) {
241
262
  geometries.push(this.parseGeometry());
242
- if (this.peek().type === 'COMMA') {
243
- this.advance();
244
- }
263
+ this.skipComma();
245
264
  }
246
265
  this.consume('RPAREN');
247
266
  return { type: 'GeometryCollection', geometries };
@@ -274,11 +293,9 @@
274
293
  parseCoordinatesList() {
275
294
  this.consume('LPAREN');
276
295
  const coords = [];
277
- while (this.peek().type !== 'RPAREN' && this.peek().type !== 'EOF') {
296
+ while (!this.isDone()) {
278
297
  coords.push(this.parseCoordinates());
279
- if (this.peek().type === 'COMMA') {
280
- this.advance();
281
- }
298
+ this.skipComma();
282
299
  }
283
300
  this.consume('RPAREN');
284
301
  return coords;
@@ -289,26 +306,9 @@
289
306
  return [];
290
307
  this.advance(); // consume outer (
291
308
  const lists = [];
292
- while (this.peek().type !== 'RPAREN' && this.peek().type !== 'EOF') {
309
+ while (!this.isDone()) {
293
310
  lists.push(this.parseCoordinatesList());
294
- if (this.peek().type === 'COMMA') {
295
- this.advance();
296
- }
297
- }
298
- this.consume('RPAREN');
299
- return lists;
300
- }
301
- /** 解析多边形列表(MultiPolygon 级别):( ((...)), ((...)) ) */
302
- parseCoordinateListListList() {
303
- if (this.peek().type !== 'LPAREN')
304
- return [];
305
- this.advance(); // consume outer (
306
- const lists = [];
307
- while (this.peek().type !== 'RPAREN' && this.peek().type !== 'EOF') {
308
- lists.push(this.parseCoordinateListList());
309
- if (this.peek().type === 'COMMA') {
310
- this.advance();
311
- }
311
+ this.skipComma();
312
312
  }
313
313
  this.consume('RPAREN');
314
314
  return lists;
@@ -7,6 +7,8 @@ export declare class WKTParser {
7
7
  private advance;
8
8
  /** 消费当前 token 并返回,若类型不匹配则抛出错误 */
9
9
  private consume;
10
+ private skipComma;
11
+ private isDone;
10
12
  private parseGeometry;
11
13
  private skipDimensionKeyword;
12
14
  private isEmptyGeometry;
@@ -26,8 +28,6 @@ export declare class WKTParser {
26
28
  private parseCoordinatesList;
27
29
  /** 解析环列表(Polygon 级别):( (...), (...) ) */
28
30
  private parseCoordinateListList;
29
- /** 解析多边形列表(MultiPolygon 级别):( ((...)), ((...)) ) */
30
- private parseCoordinateListListList;
31
31
  }
32
32
  /** 将 WKT 字符串解析为 GeoJSON Geometry 对象 */
33
33
  export declare function parse(wkt: string): Geometry;
package/package.json CHANGED
@@ -1,13 +1,23 @@
1
1
  {
2
2
  "name": "wkt-parse-and-geojson",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "type": "module",
5
- "description": "Parse WKT and build GeoJSON, convert between WKT and GeoJSON",
5
+ "description": "Zero-dependency WKT parser/builder and WKT↔GeoJSON converter",
6
6
  "main": "dist/index.cjs.js",
7
7
  "module": "dist/index.esm.js",
8
+ "browser": "dist/index.umd.js",
8
9
  "types": "dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "import": "./dist/index.esm.js",
13
+ "require": "./dist/index.cjs.js",
14
+ "types": "./dist/index.d.ts"
15
+ }
16
+ },
9
17
  "files": [
10
- "dist"
18
+ "dist",
19
+ "README.md",
20
+ "LICENSE"
11
21
  ],
12
22
  "scripts": {
13
23
  "build": "rollup -c",
@@ -19,7 +29,10 @@
19
29
  "geojson",
20
30
  "geometry",
21
31
  "parser",
22
- "gis"
32
+ "builder",
33
+ "gis",
34
+ "ogc",
35
+ "spatial"
23
36
  ],
24
37
  "author": "",
25
38
  "license": "MIT",
@@ -28,8 +41,5 @@
28
41
  "rollup": "^4.40.0",
29
42
  "tslib": "^2.8.1",
30
43
  "typescript": "^5.8.3"
31
- },
32
- "dependencies": {
33
- "wkt-parse-and-geojson": "^1.0.0"
34
44
  }
35
45
  }