trackswap 0.0.1
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 +21 -0
- package/README.md +383 -0
- package/dist/GPX/base.d.ts +84 -0
- package/dist/GPX/base.js +83 -0
- package/dist/GPX/converters.d.ts +108 -0
- package/dist/GPX/converters.js +444 -0
- package/dist/GPX/decoder.d.ts +109 -0
- package/dist/GPX/decoder.js +403 -0
- package/dist/GPX/encoder.d.ts +150 -0
- package/dist/GPX/encoder.js +510 -0
- package/dist/GPX/extensions/index.d.ts +14 -0
- package/dist/GPX/extensions/index.js +14 -0
- package/dist/GPX/index.d.ts +12 -0
- package/dist/GPX/index.js +11 -0
- package/dist/GPX/processor.d.ts +48 -0
- package/dist/GPX/processor.js +187 -0
- package/dist/GPX/types.d.ts +230 -0
- package/dist/GPX/types.js +1 -0
- package/dist/GPX/util.d.ts +1 -0
- package/dist/GPX/util.js +18 -0
- package/dist/TrackSwap.d.ts +47 -0
- package/dist/TrackSwap.js +84 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +5 -0
- package/dist/types.d.ts +34 -0
- package/dist/types.js +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
import { BaseConverter, BaseMiddleware } from "./base.js";
|
|
2
|
+
// ============ 核心转换器 ============
|
|
3
|
+
/**
|
|
4
|
+
* WPT转换器
|
|
5
|
+
*/
|
|
6
|
+
export class WptConverter extends BaseConverter {
|
|
7
|
+
constructor() {
|
|
8
|
+
super(...arguments);
|
|
9
|
+
this.name = "wpt-converter";
|
|
10
|
+
this.supportedTags = ["wpt", "trkpt", "rtept"];
|
|
11
|
+
this.version = "1.0.0";
|
|
12
|
+
}
|
|
13
|
+
convert(ast, context) {
|
|
14
|
+
if (!this.hasRequiredAttributes(ast, ["lat", "lon"])) {
|
|
15
|
+
console.error(`${this.name}: 缺少必需的lat或lon属性`);
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
const wpt = {
|
|
19
|
+
lat: this.parseFloat(ast.attributes["lat"]),
|
|
20
|
+
lon: this.parseFloat(ast.attributes["lon"]),
|
|
21
|
+
};
|
|
22
|
+
// 处理其他属性
|
|
23
|
+
this.extractAttributes(ast, wpt, {
|
|
24
|
+
lat: "lat",
|
|
25
|
+
lon: "lon",
|
|
26
|
+
});
|
|
27
|
+
// 处理子节点
|
|
28
|
+
this.processChildren(ast, wpt, {
|
|
29
|
+
ele: (child, target) => (target.ele = this.parseFloat(child.value)),
|
|
30
|
+
time: (child, target) => (target.time = new Date(this.parseString(child.value))),
|
|
31
|
+
speed: (child, target) => (target.speed = this.parseFloat(child.value)),
|
|
32
|
+
course: (child, target) => (target.course = this.parseFloat(child.value)),
|
|
33
|
+
name: (child, target) => (target.name = this.parseString(child.value)),
|
|
34
|
+
cmt: (child, target) => (target.cmt = this.parseString(child.value)),
|
|
35
|
+
desc: (child, target) => (target.desc = this.parseString(child.value)),
|
|
36
|
+
src: (child, target) => (target.src = this.parseString(child.value)),
|
|
37
|
+
sym: (child, target) => (target.sym = this.parseString(child.value)),
|
|
38
|
+
type: (child, target) => (target.type = this.parseString(child.value)),
|
|
39
|
+
fix: (child, target) => (target.fix = this.parseString(child.value)),
|
|
40
|
+
sat: (child, target) => (target.sat = this.parseString(child.value)),
|
|
41
|
+
hdop: (child, target) => (target.hdop = this.parseFloat(child.value)),
|
|
42
|
+
vdop: (child, target) => (target.vdop = this.parseFloat(child.value)),
|
|
43
|
+
pdop: (child, target) => (target.pdop = this.parseFloat(child.value)),
|
|
44
|
+
ageofdgpsdata: (child, target) => (target.ageofdgpsdata = this.parseFloat(child.value)),
|
|
45
|
+
geoidheight: (child, target) => (target.geoidheight = this.parseFloat(child.value)),
|
|
46
|
+
magvar: (child, target) => (target.magvar = this.parseFloat(child.value)),
|
|
47
|
+
dgpsid: (child, target) => (target.dgpsid = this.parseFloat(child.value)),
|
|
48
|
+
extensions: (child, target) => {
|
|
49
|
+
// 查找extensions转换器
|
|
50
|
+
const decoder = context.metadata.get("decoder");
|
|
51
|
+
if (decoder) {
|
|
52
|
+
target.extensions = decoder.convertExtensions(child);
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
link: (child, target) => {
|
|
56
|
+
if (!target.link)
|
|
57
|
+
target.link = [];
|
|
58
|
+
const decoder = context.metadata.get("decoder");
|
|
59
|
+
const link = decoder?.getConverter("link")?.convert(child, context);
|
|
60
|
+
if (link && target.link)
|
|
61
|
+
target.link.push(link);
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
return wpt;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Route转换器
|
|
69
|
+
*/
|
|
70
|
+
export class RteConverter extends BaseConverter {
|
|
71
|
+
constructor() {
|
|
72
|
+
super(...arguments);
|
|
73
|
+
this.name = "rte-converter";
|
|
74
|
+
this.supportedTags = ["rte"];
|
|
75
|
+
}
|
|
76
|
+
convert(ast, context) {
|
|
77
|
+
const rte = { rtept: [] };
|
|
78
|
+
this.processChildren(ast, rte, {
|
|
79
|
+
name: (child, target) => (target.name = this.parseString(child.value)),
|
|
80
|
+
cmt: (child, target) => (target.cmt = this.parseString(child.value)),
|
|
81
|
+
desc: (child, target) => (target.desc = this.parseString(child.value)),
|
|
82
|
+
src: (child, target) => (target.src = this.parseString(child.value)),
|
|
83
|
+
number: (child, target) => (target.number = this.parseFloat(child.value)),
|
|
84
|
+
type: (child, target) => (target.type = this.parseString(child.value)),
|
|
85
|
+
rtept: (child, target) => {
|
|
86
|
+
const decoder = context.metadata.get("decoder");
|
|
87
|
+
const wpt = decoder?.getConverter("wpt")?.convert(child, context);
|
|
88
|
+
if (wpt && target.rtept) {
|
|
89
|
+
target.rtept.push(wpt);
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
extensions: (child, target) => {
|
|
93
|
+
const decoder = context.metadata.get("decoder");
|
|
94
|
+
if (decoder) {
|
|
95
|
+
target.extensions = decoder.convertExtensions(child);
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
link: (child, target) => {
|
|
99
|
+
if (!target.link)
|
|
100
|
+
target.link = [];
|
|
101
|
+
const decoder = context.metadata.get("decoder");
|
|
102
|
+
child.children?.forEach((linkChild) => {
|
|
103
|
+
const link = decoder
|
|
104
|
+
?.getConverter("link")
|
|
105
|
+
?.convert(linkChild, context);
|
|
106
|
+
if (link && target.link)
|
|
107
|
+
target.link.push(link);
|
|
108
|
+
});
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
return rte;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Track转换器
|
|
116
|
+
*/
|
|
117
|
+
export class TrkConverter extends BaseConverter {
|
|
118
|
+
constructor() {
|
|
119
|
+
super(...arguments);
|
|
120
|
+
this.name = "trk-converter";
|
|
121
|
+
this.supportedTags = ["trk"];
|
|
122
|
+
}
|
|
123
|
+
convert(ast, context) {
|
|
124
|
+
const trk = { trkseg: [] };
|
|
125
|
+
this.processChildren(ast, trk, {
|
|
126
|
+
name: (child, target) => (target.name = this.parseString(child.value)),
|
|
127
|
+
cmt: (child, target) => (target.cmt = this.parseString(child.value)),
|
|
128
|
+
desc: (child, target) => (target.desc = this.parseString(child.value)),
|
|
129
|
+
src: (child, target) => (target.src = this.parseString(child.value)),
|
|
130
|
+
number: (child, target) => (target.number = this.parseFloat(child.value)),
|
|
131
|
+
type: (child, target) => (target.type = this.parseString(child.value)),
|
|
132
|
+
trkseg: (child, target) => {
|
|
133
|
+
const decoder = context.metadata.get("decoder");
|
|
134
|
+
const trkseg = decoder?.getConverter("trkseg")?.convert(child, context);
|
|
135
|
+
if (trkseg && target.trkseg) {
|
|
136
|
+
target.trkseg.push(trkseg);
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
extensions: (child, target) => {
|
|
140
|
+
const decoder = context.metadata.get("decoder");
|
|
141
|
+
if (decoder) {
|
|
142
|
+
target.extensions = decoder.convertExtensions(child);
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
link: (child, target) => {
|
|
146
|
+
if (!target.link)
|
|
147
|
+
target.link = [];
|
|
148
|
+
const decoder = context.metadata.get("decoder");
|
|
149
|
+
child.children?.forEach((linkChild) => {
|
|
150
|
+
const link = decoder
|
|
151
|
+
?.getConverter("link")
|
|
152
|
+
?.convert(linkChild, context);
|
|
153
|
+
if (link && target.link)
|
|
154
|
+
target.link.push(link);
|
|
155
|
+
});
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
return trk;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Track Segment转换器
|
|
163
|
+
*/
|
|
164
|
+
export class TrksegConverter extends BaseConverter {
|
|
165
|
+
constructor() {
|
|
166
|
+
super(...arguments);
|
|
167
|
+
this.name = "trkseg-converter";
|
|
168
|
+
this.supportedTags = ["trkseg"];
|
|
169
|
+
}
|
|
170
|
+
convert(ast, context) {
|
|
171
|
+
const trkseg = { trkpt: [] };
|
|
172
|
+
this.processChildren(ast, trkseg, {
|
|
173
|
+
trkpt: (child, target) => {
|
|
174
|
+
const decoder = context.metadata.get("decoder");
|
|
175
|
+
const wpt = decoder?.getConverter("wpt")?.convert(child, context);
|
|
176
|
+
if (wpt && target.trkpt) {
|
|
177
|
+
target.trkpt.push(wpt);
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
extensions: (child, target) => {
|
|
181
|
+
const decoder = context.metadata.get("decoder");
|
|
182
|
+
if (decoder) {
|
|
183
|
+
target.extensions = decoder.convertExtensions(child);
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
return trkseg;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Link转换器
|
|
192
|
+
*/
|
|
193
|
+
export class LinkConverter extends BaseConverter {
|
|
194
|
+
constructor() {
|
|
195
|
+
super(...arguments);
|
|
196
|
+
this.name = "link-converter";
|
|
197
|
+
this.supportedTags = ["link"];
|
|
198
|
+
}
|
|
199
|
+
convert(ast, context) {
|
|
200
|
+
const link = {};
|
|
201
|
+
if (ast.attributes?.href) {
|
|
202
|
+
link.href = ast.attributes.href;
|
|
203
|
+
}
|
|
204
|
+
this.processChildren(ast, link, {
|
|
205
|
+
text: (child, target) => (target.text = this.parseString(child.value)),
|
|
206
|
+
type: (child, target) => (target.type = this.parseString(child.value)),
|
|
207
|
+
});
|
|
208
|
+
return link;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Metadata转换器
|
|
213
|
+
*/
|
|
214
|
+
export class MetadataConverter extends BaseConverter {
|
|
215
|
+
constructor() {
|
|
216
|
+
super(...arguments);
|
|
217
|
+
this.name = "metadata-converter";
|
|
218
|
+
this.supportedTags = ["metadata"];
|
|
219
|
+
}
|
|
220
|
+
convert(ast, context) {
|
|
221
|
+
const metadata = {};
|
|
222
|
+
this.processChildren(ast, metadata, {
|
|
223
|
+
name: (child, target) => (target.name = this.parseString(child.value)),
|
|
224
|
+
desc: (child, target) => (target.desc = this.parseString(child.value)),
|
|
225
|
+
keywords: (child, target) => (target.keywords = this.parseString(child.value)),
|
|
226
|
+
time: (child, target) => (target.time = new Date(this.parseString(child.value))),
|
|
227
|
+
author: (child, target) => {
|
|
228
|
+
const decoder = context.metadata.get("decoder");
|
|
229
|
+
target.author = decoder
|
|
230
|
+
?.getConverter("author")
|
|
231
|
+
?.convert(child, context);
|
|
232
|
+
},
|
|
233
|
+
copyright: (child, target) => {
|
|
234
|
+
const decoder = context.metadata.get("decoder");
|
|
235
|
+
target.copyright = decoder
|
|
236
|
+
?.getConverter("copyright")
|
|
237
|
+
?.convert(child, context);
|
|
238
|
+
},
|
|
239
|
+
bounds: (child, target) => {
|
|
240
|
+
const decoder = context.metadata.get("decoder");
|
|
241
|
+
target.bounds = decoder
|
|
242
|
+
?.getConverter("bounds")
|
|
243
|
+
?.convert(child, context);
|
|
244
|
+
},
|
|
245
|
+
extensions: (child, target) => {
|
|
246
|
+
const decoder = context.metadata.get("decoder");
|
|
247
|
+
if (decoder) {
|
|
248
|
+
target.extensions = decoder.convertExtensions(child);
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
link: (child, target) => {
|
|
252
|
+
if (!target.link)
|
|
253
|
+
target.link = [];
|
|
254
|
+
const decoder = context.metadata.get("decoder");
|
|
255
|
+
const link = decoder?.getConverter("link")?.convert(child, context);
|
|
256
|
+
if (link && target.link)
|
|
257
|
+
target.link.push(link);
|
|
258
|
+
},
|
|
259
|
+
});
|
|
260
|
+
return metadata;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Person转换器
|
|
265
|
+
*/
|
|
266
|
+
export class PersonConverter extends BaseConverter {
|
|
267
|
+
constructor() {
|
|
268
|
+
super(...arguments);
|
|
269
|
+
this.name = "person-converter";
|
|
270
|
+
this.supportedTags = ["author"];
|
|
271
|
+
}
|
|
272
|
+
convert(ast, context) {
|
|
273
|
+
const person = {};
|
|
274
|
+
// 如果author标签直接包含文本值(如 <author>Matschi1000</author>)
|
|
275
|
+
if (ast.value && !ast.children?.length) {
|
|
276
|
+
person.name = this.parseString(ast.value);
|
|
277
|
+
return person;
|
|
278
|
+
}
|
|
279
|
+
// 处理包含子元素的情况(如 <author><name>...</name><email>...</email></author>)
|
|
280
|
+
this.processChildren(ast, person, {
|
|
281
|
+
name: (child, target) => (target.name = this.parseString(child.value)),
|
|
282
|
+
email: (child, target) => {
|
|
283
|
+
const decoder = context.metadata.get("decoder");
|
|
284
|
+
target.email = decoder?.getConverter("email")?.convert(child, context);
|
|
285
|
+
},
|
|
286
|
+
link: (child, target) => {
|
|
287
|
+
const decoder = context.metadata.get("decoder");
|
|
288
|
+
target.link = decoder?.getConverter("link")?.convert(child, context);
|
|
289
|
+
},
|
|
290
|
+
});
|
|
291
|
+
return person;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Email转换器
|
|
296
|
+
*/
|
|
297
|
+
export class EmailConverter extends BaseConverter {
|
|
298
|
+
constructor() {
|
|
299
|
+
super(...arguments);
|
|
300
|
+
this.name = "email-converter";
|
|
301
|
+
this.supportedTags = ["email"];
|
|
302
|
+
}
|
|
303
|
+
convert(ast, context) {
|
|
304
|
+
const email = {};
|
|
305
|
+
this.processChildren(ast, email, {
|
|
306
|
+
id: (child, target) => (target.id = this.parseString(child.value)),
|
|
307
|
+
domain: (child, target) => (target.domain = this.parseString(child.value)),
|
|
308
|
+
});
|
|
309
|
+
return email;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Copyright转换器
|
|
314
|
+
*/
|
|
315
|
+
export class CopyrightConverter extends BaseConverter {
|
|
316
|
+
constructor() {
|
|
317
|
+
super(...arguments);
|
|
318
|
+
this.name = "copyright-converter";
|
|
319
|
+
this.supportedTags = ["copyright"];
|
|
320
|
+
}
|
|
321
|
+
convert(ast, context) {
|
|
322
|
+
const copyright = {};
|
|
323
|
+
if (ast.attributes?.author) {
|
|
324
|
+
copyright.author = ast.attributes.author;
|
|
325
|
+
}
|
|
326
|
+
this.processChildren(ast, copyright, {
|
|
327
|
+
year: (child, target) => (target.year = this.parseString(child.value)),
|
|
328
|
+
license: (child, target) => (target.license = this.parseString(child.value)),
|
|
329
|
+
});
|
|
330
|
+
return copyright;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Bounds转换器
|
|
335
|
+
*/
|
|
336
|
+
export class BoundsConverter extends BaseConverter {
|
|
337
|
+
constructor() {
|
|
338
|
+
super(...arguments);
|
|
339
|
+
this.name = "bounds-converter";
|
|
340
|
+
this.supportedTags = ["bounds"];
|
|
341
|
+
}
|
|
342
|
+
convert(ast, context) {
|
|
343
|
+
const bounds = {};
|
|
344
|
+
this.extractAttributes(ast, bounds, {
|
|
345
|
+
minlat: "minlat",
|
|
346
|
+
minlon: "minlon",
|
|
347
|
+
maxlat: "maxlat",
|
|
348
|
+
maxlon: "maxlon",
|
|
349
|
+
});
|
|
350
|
+
return bounds;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
// ============ 示例中间件 ============
|
|
354
|
+
/**
|
|
355
|
+
* 性能监控中间件
|
|
356
|
+
*/
|
|
357
|
+
export class PerformanceMiddleware extends BaseMiddleware {
|
|
358
|
+
constructor() {
|
|
359
|
+
super(...arguments);
|
|
360
|
+
this.name = "performance-middleware";
|
|
361
|
+
this.description = "监控解析性能";
|
|
362
|
+
}
|
|
363
|
+
async onTokenize(tokens, context) {
|
|
364
|
+
console.log(`Token化完成,生成了 ${tokens.length} 个token`);
|
|
365
|
+
return tokens;
|
|
366
|
+
}
|
|
367
|
+
async onAstGenerate(ast, context) {
|
|
368
|
+
const nodeCount = this.countNodes(ast);
|
|
369
|
+
console.log(`AST生成完成,包含 ${nodeCount} 个节点`);
|
|
370
|
+
return ast;
|
|
371
|
+
}
|
|
372
|
+
async onComplete(result, context) {
|
|
373
|
+
const performance = context.metadata.get("performance");
|
|
374
|
+
console.log("解析性能统计:", performance);
|
|
375
|
+
return result;
|
|
376
|
+
}
|
|
377
|
+
countNodes(ast) {
|
|
378
|
+
let count = 1;
|
|
379
|
+
if (ast.children) {
|
|
380
|
+
for (const child of ast.children) {
|
|
381
|
+
count += this.countNodes(child);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return count;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* 验证中间件
|
|
389
|
+
*/
|
|
390
|
+
export class ValidationMiddleware extends BaseMiddleware {
|
|
391
|
+
constructor() {
|
|
392
|
+
super(...arguments);
|
|
393
|
+
this.name = "validation-middleware";
|
|
394
|
+
this.description = "验证GPX数据的完整性";
|
|
395
|
+
}
|
|
396
|
+
async onComplete(result, context) {
|
|
397
|
+
const errors = this.validateGPX(result);
|
|
398
|
+
if (errors.length > 0) {
|
|
399
|
+
console.warn("GPX验证发现问题:", errors);
|
|
400
|
+
context.metadata.set("validation-errors", errors);
|
|
401
|
+
}
|
|
402
|
+
else {
|
|
403
|
+
console.log("GPX验证通过");
|
|
404
|
+
}
|
|
405
|
+
return result;
|
|
406
|
+
}
|
|
407
|
+
validateGPX(gpx) {
|
|
408
|
+
const errors = [];
|
|
409
|
+
if (!gpx.version) {
|
|
410
|
+
errors.push("缺少GPX版本信息");
|
|
411
|
+
}
|
|
412
|
+
if (!gpx.creator) {
|
|
413
|
+
errors.push("缺少GPX创建者信息");
|
|
414
|
+
}
|
|
415
|
+
// 验证轨迹点
|
|
416
|
+
if (gpx.trk) {
|
|
417
|
+
for (const track of gpx.trk) {
|
|
418
|
+
if (track.trkseg) {
|
|
419
|
+
for (const segment of track.trkseg) {
|
|
420
|
+
if (segment.trkpt) {
|
|
421
|
+
for (const point of segment.trkpt) {
|
|
422
|
+
if (typeof point.lat !== "number" ||
|
|
423
|
+
typeof point.lon !== "number") {
|
|
424
|
+
errors.push("轨迹点坐标无效");
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
return errors;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
// ============ 默认转换器注册函数 ============
|
|
436
|
+
/**
|
|
437
|
+
* 注册所有默认中间件
|
|
438
|
+
*/
|
|
439
|
+
export async function registerDefaultMiddlewares(decoder) {
|
|
440
|
+
const middlewares = [new PerformanceMiddleware(), new ValidationMiddleware()];
|
|
441
|
+
for (const middleware of middlewares) {
|
|
442
|
+
await decoder.registerMiddleware(middleware);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { ExtensionsType, TokenAST } from "../types.js";
|
|
2
|
+
import { IConverterPlugin, IMiddlewarePlugin } from "./base.js";
|
|
3
|
+
import { GPX11Type } from "./types.js";
|
|
4
|
+
/**
|
|
5
|
+
* GPX解码器主类
|
|
6
|
+
*/
|
|
7
|
+
export declare class GPXDecoder {
|
|
8
|
+
private converterPlugins;
|
|
9
|
+
private registeredPlugins;
|
|
10
|
+
private middlewarePlugins;
|
|
11
|
+
private processors;
|
|
12
|
+
private initialized;
|
|
13
|
+
private defaultConvertersRegistered;
|
|
14
|
+
constructor();
|
|
15
|
+
/**
|
|
16
|
+
* 初始化流水线 - 注册固定的核心处理器
|
|
17
|
+
*/
|
|
18
|
+
private initializePipeline;
|
|
19
|
+
/**
|
|
20
|
+
* 自动注册默认转换器 - 处理标准GPX标签
|
|
21
|
+
*/
|
|
22
|
+
private registerDefaultConverters;
|
|
23
|
+
/**
|
|
24
|
+
* 为指定标签添加转换器,按优先级排序
|
|
25
|
+
*/
|
|
26
|
+
private addConverterForTag;
|
|
27
|
+
/**
|
|
28
|
+
* 注册转换器插件
|
|
29
|
+
*/
|
|
30
|
+
registerConverter(plugin: IConverterPlugin): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* 注册中间件插件 - 真正的扩展点
|
|
33
|
+
*/
|
|
34
|
+
registerMiddleware(plugin: IMiddlewarePlugin): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* 获取转换器(返回优先级最高的)
|
|
37
|
+
*/
|
|
38
|
+
getConverter(tag: string): IConverterPlugin | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* 获取指定标签的所有转换器(按优先级排序)
|
|
41
|
+
*/
|
|
42
|
+
getAllConverters(tag: string): IConverterPlugin[];
|
|
43
|
+
/**
|
|
44
|
+
* 移除转换器
|
|
45
|
+
*/
|
|
46
|
+
unregisterConverter(pluginName: string): void;
|
|
47
|
+
/**
|
|
48
|
+
* 移除中间件
|
|
49
|
+
*/
|
|
50
|
+
unregisterMiddleware(name: string): void;
|
|
51
|
+
/**
|
|
52
|
+
* 列出所有已注册的转换器标签
|
|
53
|
+
*/
|
|
54
|
+
listConverters(): string[];
|
|
55
|
+
/**
|
|
56
|
+
* 列出所有已注册的转换器插件
|
|
57
|
+
*/
|
|
58
|
+
listConverterPlugins(): string[];
|
|
59
|
+
/**
|
|
60
|
+
* 列出所有已注册的中间件
|
|
61
|
+
*/
|
|
62
|
+
listMiddlewares(): string[];
|
|
63
|
+
/**
|
|
64
|
+
* 列出核心处理器(只读)
|
|
65
|
+
*/
|
|
66
|
+
listProcessors(): string[];
|
|
67
|
+
/**
|
|
68
|
+
* 获取标签的转换器详情(包括优先级信息)
|
|
69
|
+
*/
|
|
70
|
+
getConverterDetails(tag?: string): Record<string, Array<{
|
|
71
|
+
name: string;
|
|
72
|
+
priority: number;
|
|
73
|
+
}>>;
|
|
74
|
+
/**
|
|
75
|
+
* 获取中间件详情(包括支持的钩子)
|
|
76
|
+
*/
|
|
77
|
+
getMiddlewareDetails(): Array<{
|
|
78
|
+
name: string;
|
|
79
|
+
hooks: string[];
|
|
80
|
+
}>;
|
|
81
|
+
/**
|
|
82
|
+
* 初始化解码器
|
|
83
|
+
*/
|
|
84
|
+
initialize(): Promise<void>;
|
|
85
|
+
/**
|
|
86
|
+
* 销毁解码器
|
|
87
|
+
*/
|
|
88
|
+
destroy(): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* 创建解码上下文
|
|
91
|
+
*/
|
|
92
|
+
private createContext;
|
|
93
|
+
/**
|
|
94
|
+
* 执行中间件钩子
|
|
95
|
+
*/
|
|
96
|
+
private executeMiddlewareHook;
|
|
97
|
+
/**
|
|
98
|
+
* 主解析方法 - 固定的流水线 + 灵活的中间件
|
|
99
|
+
*/
|
|
100
|
+
parserByBuffer(buffer: Buffer): Promise<GPX11Type | undefined>;
|
|
101
|
+
/**
|
|
102
|
+
* 转换Extensions(向后兼容)
|
|
103
|
+
*/
|
|
104
|
+
convertExtensions(extensionsAST: TokenAST): ExtensionsType;
|
|
105
|
+
}
|
|
106
|
+
declare const _default: {
|
|
107
|
+
GPXDecoder: typeof GPXDecoder;
|
|
108
|
+
};
|
|
109
|
+
export default _default;
|