ofs-dxf-ts 1.0.0

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.
Files changed (97) hide show
  1. package/API.md +411 -0
  2. package/CHANGELOG.md +26 -0
  3. package/LICENSE +21 -0
  4. package/README.md +119 -0
  5. package/dist/core/dxf-builder.d.ts +348 -0
  6. package/dist/core/dxf-builder.js +549 -0
  7. package/dist/core/dxf-document.d.ts +220 -0
  8. package/dist/core/dxf-document.js +529 -0
  9. package/dist/core/dxf-entities.d.ts +327 -0
  10. package/dist/core/dxf-entities.js +22 -0
  11. package/dist/core/dxf-serializer.d.ts +48 -0
  12. package/dist/core/dxf-serializer.js +595 -0
  13. package/dist/core/hatch-patterns.d.ts +15 -0
  14. package/dist/core/hatch-patterns.js +214 -0
  15. package/dist/core/modelspace.d.ts +106 -0
  16. package/dist/core/modelspace.js +351 -0
  17. package/dist/geometry/math.utils.d.ts +8 -0
  18. package/dist/geometry/math.utils.js +43 -0
  19. package/dist/geometry/offset.utils.d.ts +32 -0
  20. package/dist/geometry/offset.utils.js +87 -0
  21. package/dist/geometry/polyline.utils.d.ts +10 -0
  22. package/dist/geometry/polyline.utils.js +63 -0
  23. package/dist/geometry/text.utils.d.ts +15 -0
  24. package/dist/geometry/text.utils.js +28 -0
  25. package/dist/index.d.ts +23 -0
  26. package/dist/index.js +29 -0
  27. package/dist/parser/auto-cad-color-index.d.ts +8 -0
  28. package/dist/parser/auto-cad-color-index.js +265 -0
  29. package/dist/parser/dim-style-codes.d.ts +5 -0
  30. package/dist/parser/dim-style-codes.js +32 -0
  31. package/dist/parser/dxf-parser.d.ts +16 -0
  32. package/dist/parser/dxf-parser.js +824 -0
  33. package/dist/parser/entities/3dface.d.ts +5 -0
  34. package/dist/parser/entities/3dface.js +76 -0
  35. package/dist/parser/entities/arc.d.ts +5 -0
  36. package/dist/parser/entities/arc.js +34 -0
  37. package/dist/parser/entities/attdef.d.ts +5 -0
  38. package/dist/parser/entities/attdef.js +86 -0
  39. package/dist/parser/entities/attribute.d.ts +5 -0
  40. package/dist/parser/entities/attribute.js +106 -0
  41. package/dist/parser/entities/circle.d.ts +5 -0
  42. package/dist/parser/entities/circle.js +40 -0
  43. package/dist/parser/entities/dimension.d.ts +5 -0
  44. package/dist/parser/entities/dimension.js +65 -0
  45. package/dist/parser/entities/ellipse.d.ts +5 -0
  46. package/dist/parser/entities/ellipse.js +42 -0
  47. package/dist/parser/entities/hatch.d.ts +5 -0
  48. package/dist/parser/entities/hatch.js +321 -0
  49. package/dist/parser/entities/insert.d.ts +5 -0
  50. package/dist/parser/entities/insert.js +52 -0
  51. package/dist/parser/entities/line.d.ts +5 -0
  52. package/dist/parser/entities/line.js +30 -0
  53. package/dist/parser/entities/lwpolyline.d.ts +5 -0
  54. package/dist/parser/entities/lwpolyline.js +101 -0
  55. package/dist/parser/entities/mtext.d.ts +5 -0
  56. package/dist/parser/entities/mtext.js +54 -0
  57. package/dist/parser/entities/point.d.ts +5 -0
  58. package/dist/parser/entities/point.js +30 -0
  59. package/dist/parser/entities/polyline.d.ts +5 -0
  60. package/dist/parser/entities/polyline.js +85 -0
  61. package/dist/parser/entities/solid.d.ts +5 -0
  62. package/dist/parser/entities/solid.js +35 -0
  63. package/dist/parser/entities/spline.d.ts +5 -0
  64. package/dist/parser/entities/spline.js +69 -0
  65. package/dist/parser/entities/text.d.ts +5 -0
  66. package/dist/parser/entities/text.js +47 -0
  67. package/dist/parser/entities/vertex.d.ts +5 -0
  68. package/dist/parser/entities/vertex.js +59 -0
  69. package/dist/parser/extended-data-parser.d.ts +18 -0
  70. package/dist/parser/extended-data-parser.js +100 -0
  71. package/dist/parser/index.d.ts +10 -0
  72. package/dist/parser/index.js +9 -0
  73. package/dist/parser/log.d.ts +14 -0
  74. package/dist/parser/log.js +39 -0
  75. package/dist/parser/parse-helpers.d.ts +23 -0
  76. package/dist/parser/parse-helpers.js +128 -0
  77. package/dist/parser/scanner.d.ts +29 -0
  78. package/dist/parser/scanner.js +143 -0
  79. package/dist/parser/types.d.ts +78 -0
  80. package/dist/parser/types.js +5 -0
  81. package/dist/symbols/slope-symbol.d.ts +21 -0
  82. package/dist/symbols/slope-symbol.js +81 -0
  83. package/dist/symbols/structures.d.ts +9 -0
  84. package/dist/symbols/structures.js +120 -0
  85. package/dist/template/blank-document.d.ts +13 -0
  86. package/dist/template/blank-document.js +13 -0
  87. package/dist/template/block-registry.d.ts +16 -0
  88. package/dist/template/block-registry.js +135 -0
  89. package/dist/template/index.d.ts +17 -0
  90. package/dist/template/index.js +17 -0
  91. package/dist/template/template-injector.d.ts +45 -0
  92. package/dist/template/template-injector.js +487 -0
  93. package/dist/template/template-reader.d.ts +28 -0
  94. package/dist/template/template-reader.js +80 -0
  95. package/dist/types/index.d.ts +24 -0
  96. package/dist/types/index.js +8 -0
  97. package/package.json +59 -0
@@ -0,0 +1,348 @@
1
+ /**
2
+ * DxfBuilder — Backward-compatible wrapper around DxfDocument.
3
+ *
4
+ * ✅ Works in both Node.js AND Browser/Angular environments.
5
+ *
6
+ * Usage (existing — unchanged):
7
+ * const builder = new DxfBuilder();
8
+ * builder.addPolyline(points, 'MyLayer', 3);
9
+ * builder.addText('Hello', 100, 200, 5, 0, 'TEXT', 7);
10
+ * const dxfString = builder.saveString();
11
+ *
12
+ * NEW: Template-based (Node.js):
13
+ * const builder = new DxfBuilder('./template/template2018.dxf');
14
+ *
15
+ * NEW: Template-based (Browser/Angular):
16
+ * const builder = DxfBuilder.fromString(templateDxfString);
17
+ *
18
+ * NEW: Convenience API:
19
+ * builder.addLayer('MyLayer', 3, 'DASHED');
20
+ * builder.addLine([0,0], [100,100], 'MyLayer', 1);
21
+ * builder.addArc(50, 50, 25, 0, 180, 'MyLayer', 4);
22
+ * builder.addHatch('SOLID', [[[0,0],[100,0],[100,100],[0,100]]], 'MyLayer', 3);
23
+ *
24
+ * NEW: Sheet composition:
25
+ * builder.defineBlock('BM', b => { b.addCircle(0, 0, 1.5, '0'); b.addLine([-2, 0], [2, 0], '0'); });
26
+ * builder.addBlock('BM', 519395.8, 1034018.6, 10, 0, 'SYMBOL');
27
+ * builder.addCallout([519300, 1034000], ['ก่อสร้างอาคารทางน้ำเข้า', 'ขนาด 2-1.75x1.75 ม.'], [519350, 1034150]);
28
+ * builder.addLayout('A1', 841, 594, [0, 0, 0, 0], [{ center: [420, 297], width: 800, height: 560,
29
+ * viewCenter: [519500, 1033500], scale: 12500 }]);
30
+ * builder.onLayout('A1', b => b.addText('แผนที่แสดงตำแหน่งหมุดหลักฐาน', 420, 20, 8));
31
+ */
32
+ import { DxfDocument } from './dxf-document.js';
33
+ import { Modelspace } from './modelspace.js';
34
+ import { Coordinate, Coordinate3D, OnfarmLine } from '../types/index.js';
35
+ import { TableCellDef, GeoReferenceDef, LayoutViewportDef } from './dxf-entities.js';
36
+ import { HatchPatternLine } from './hatch-patterns.js';
37
+ /** Options for `DxfBuilder.addImage`. */
38
+ export interface ImageOptions {
39
+ /** Rotation around the insertion point, degrees counter-clockwise. */
40
+ rotation?: number;
41
+ /** Clip polygon in drawing coordinates. */
42
+ clip?: [number, number][];
43
+ brightness?: number;
44
+ contrast?: number;
45
+ fade?: number;
46
+ }
47
+ /** Options for `DxfBuilder.addCallout`. */
48
+ export interface CalloutOptions {
49
+ layer?: string;
50
+ /** Color of leader, box and text (unless overridden below). */
51
+ color?: number;
52
+ textColor?: number;
53
+ boxColor?: number;
54
+ style?: string;
55
+ /** Text height in drawing units (default 2.5). */
56
+ textHeight?: number;
57
+ /** Baseline-to-baseline distance as a multiple of text height (default 1.6). */
58
+ lineSpacing?: number;
59
+ /** Space between box and text (default 0.8 × text height). */
60
+ padding?: number;
61
+ /** Fixed box width; estimated from the text when omitted. */
62
+ boxWidth?: number;
63
+ /** Average glyph width / text height used for the estimate (default 0.75). */
64
+ widthFactor?: number;
65
+ align?: 'left' | 'center';
66
+ /** Marker at the anchor end of the leader (default 'none'). */
67
+ arrow?: 'none' | 'dot' | 'arrow';
68
+ arrowSize?: number;
69
+ }
70
+ export declare class DxfBuilder {
71
+ private _document;
72
+ /** Current drawing target: model space, a layout, or a block being defined. */
73
+ private _msp;
74
+ /**
75
+ * Create a new DxfBuilder.
76
+ * @param template Optional path to a DXF template file (Node.js only), or a loaded DxfDocument.
77
+ */
78
+ constructor(template?: string | DxfDocument);
79
+ /**
80
+ * Create a DxfBuilder from a DXF template string.
81
+ * ✅ Works in Browser/Angular.
82
+ */
83
+ static fromString(content: string): DxfBuilder;
84
+ /** Access the underlying DxfDocument. */
85
+ get doc(): DxfDocument;
86
+ /** Access the current drawing target directly for ezdxf-style operations. */
87
+ get msp(): Modelspace;
88
+ /**
89
+ * Add or update a layer.
90
+ * @param name Layer name
91
+ * @param color ACI color index (0-256)
92
+ * @param linetype Linetype name (e.g. 'CONTINUOUS', 'DASHED', 'CENTER')
93
+ */
94
+ addLayer(name: string, color?: number, linetype?: string): void;
95
+ /**
96
+ * Add a linetype. Pattern values are in drawing units: positive = dash,
97
+ * negative = gap, 0 = dot. Existing names in the template are kept.
98
+ * @example builder.addLineType('BOUNDARY', '____ . ____', [20, -5, 0, -5]);
99
+ */
100
+ addLineType(name: string, description: string, pattern: number[]): void;
101
+ /**
102
+ * Add a text style. Existing names in the template are kept.
103
+ * @example builder.addTextStyle('THAI', 'THSarabunNew.ttf');
104
+ */
105
+ addTextStyle(name: string, font: string, height?: number): void;
106
+ /**
107
+ * Add a single LINE entity (two-point segment).
108
+ */
109
+ addLine(start: [number, number], end: [number, number], layer?: string, color?: number, linetype?: string): void;
110
+ /**
111
+ * Add a LWPOLYLINE entity (multi-vertex polyline).
112
+ */
113
+ addPolyline(points: Coordinate[] | Coordinate3D[], layer?: string, color?: number, linetype?: string, closed?: boolean): void;
114
+ /**
115
+ * Add a CIRCLE entity.
116
+ */
117
+ addCircle(cx: number, cy: number, radius: number, layer?: string, color?: number): void;
118
+ /**
119
+ * Add an ARC entity.
120
+ * @param cx Center X
121
+ * @param cy Center Y
122
+ * @param radius Radius
123
+ * @param startAngle Start angle in degrees
124
+ * @param endAngle End angle in degrees
125
+ */
126
+ addArc(cx: number, cy: number, radius: number, startAngle: number, endAngle: number, layer?: string, color?: number): void;
127
+ /**
128
+ * Add an ELLIPSE entity.
129
+ * @param cx Center X
130
+ * @param cy Center Y
131
+ * @param majorAxisX Major axis endpoint X (relative to center)
132
+ * @param majorAxisY Major axis endpoint Y (relative to center)
133
+ * @param ratio Ratio of minor to major axis (0..1)
134
+ */
135
+ addEllipse(cx: number, cy: number, majorAxisX: number, majorAxisY: number, ratio: number, layer?: string, color?: number): void;
136
+ /**
137
+ * Add a POINT entity.
138
+ */
139
+ addPoint(x: number, y: number, layer?: string, color?: number): void;
140
+ /**
141
+ * Add a TEXT entity.
142
+ */
143
+ addText(text: string, x: number, y: number, height?: number, rotation?: number, layer?: string, color?: number): void;
144
+ /**
145
+ * Add an MTEXT entity (multi-line text with word wrap).
146
+ */
147
+ addMText(text: string, x: number, y: number, width?: number, height?: number, layer?: string, color?: number): void;
148
+ /**
149
+ * Add a HATCH entity (solid fill or pattern fill).
150
+ *
151
+ * @param patternName 'SOLID', a built-in pattern (see HATCH_PATTERNS, ISO/mm based),
152
+ * or any name together with `opts.patternLines`.
153
+ * @param boundaries Array of boundary polygons, each as an array of [x,y] points.
154
+ * Polygons inside another polygon become holes.
155
+ * @param layer Layer name
156
+ * @param color ACI color
157
+ * @param opts scale (pattern units × scale = drawing units), angle (degrees), patternLines
158
+ *
159
+ * @example
160
+ * // Solid fill
161
+ * builder.addHatch('SOLID', [[[0,0],[100,0],[100,100],[0,100]]], 'MyLayer', 3);
162
+ *
163
+ * // Pattern fill
164
+ * builder.addHatch('ANSI31', [[[0,0],[50,0],[50,50],[0,50]]], 'MyLayer', 7, { scale: 2, angle: 45 });
165
+ */
166
+ addHatch(patternName: string, boundaries: [number, number][][], layer?: string, color?: number, opts?: {
167
+ scale?: number;
168
+ angle?: number;
169
+ patternLines?: HatchPatternLine[];
170
+ }): void;
171
+ /**
172
+ * Add a raster IMAGE, e.g. a scanned topographic map as a background.
173
+ *
174
+ * DXF only references the image file: keep the file next to the .dxf and
175
+ * pass its file name, or pass an absolute path.
176
+ *
177
+ * @param imagePath file name/path as the CAD application should resolve it
178
+ * @param pixelSize image size in pixels [width, height] (DXF cannot read the file)
179
+ * @param insertion lower-left corner in drawing units
180
+ * @param worldSize image size in drawing units [width, height]
181
+ *
182
+ * @example
183
+ * // 1:50,000 sheet scanned at 7087×7087 px covering 15 km
184
+ * builder.addImage('topo_4927II.jpg', [7087, 7087], [513000, 1027000], [15000, 15000], 'RASTER');
185
+ */
186
+ addImage(imagePath: string, pixelSize: [number, number], insertion: [number, number], worldSize: [number, number], layer?: string, opts?: ImageOptions): void;
187
+ /**
188
+ * Add a DIMENSION entity (linear dimension between two points).
189
+ */
190
+ addDimension(point1: [number, number], point2: [number, number], dimLinePosition: [number, number], layer?: string, color?: number, text?: string): void;
191
+ /**
192
+ * Add a LEADER entity (arrow with annotation line).
193
+ */
194
+ addLeader(vertices: [number, number][], layer?: string, color?: number, hasArrowhead?: boolean): void;
195
+ /**
196
+ * Add a SPLINE entity (smooth curve through control points).
197
+ */
198
+ addSpline(controlPoints: [number, number][], degree?: number, layer?: string, color?: number): void;
199
+ /** Add a line from an OnfarmLine structure object. */
200
+ addLineFromObject(onfarmLine: OnfarmLine, layer?: string): void;
201
+ /**
202
+ * Define a reusable block (symbol). Draw it with the normal builder API in
203
+ * block-local coordinates around `basePoint`, then place it with addBlock().
204
+ *
205
+ * @example
206
+ * builder.defineBlock('SCHOOL', b => {
207
+ * b.addPolyline([[-2, -1.5], [2, -1.5], [2, 1.5], [-2, 1.5]], '0', 5, undefined, true);
208
+ * b.addHatch('SOLID', [[[-2, -1.5], [2, -1.5], [2, 1.5], [-2, 1.5]]], '0', 5);
209
+ * });
210
+ * builder.addBlock('SCHOOL', 518807, 1033917, 20, 0, 'POI');
211
+ */
212
+ defineBlock(name: string, draw: (builder: DxfBuilder) => void, basePoint?: [number, number]): void;
213
+ /**
214
+ * Add a block reference (INSERT).
215
+ * Template or defined block → INSERT entity. Registry block → manual drawing. Neither → placeholder.
216
+ */
217
+ addBlock(name: string, x: number, y: number, scale: number, rotation: number, layer?: string, attributes?: Record<string, string>): void;
218
+ /**
219
+ * Auto-zoom to fit all entities with optional padding.
220
+ * Sets $EXTMIN, $EXTMAX, $VIEWCTR, $VIEWSIZE in HEADER.
221
+ * @example builder.zoomExtents(100); // 100 unit padding
222
+ */
223
+ zoomExtents(padding?: number): void;
224
+ /**
225
+ * Zoom to a specific window (rectangle).
226
+ * @example builder.zoomWindow(1000, 2000, 5000, 6000);
227
+ */
228
+ zoomWindow(minX: number, minY: number, maxX: number, maxY: number): void;
229
+ /**
230
+ * Set the drawing extents manually.
231
+ */
232
+ setExtents(minX: number, minY: number, maxX: number, maxY: number): void;
233
+ /**
234
+ * Set initial view center and zoom level.
235
+ */
236
+ setViewCenter(x: number, y: number, viewHeight?: number): void;
237
+ /** Freeze a layer (hidden, not plotted, not selectable). */
238
+ freezeLayer(name: string): void;
239
+ /** Thaw a layer (undo freeze). */
240
+ thawLayer(name: string): void;
241
+ /** Lock a layer (visible but not editable). */
242
+ lockLayer(name: string): void;
243
+ /** Unlock a layer. */
244
+ unlockLayer(name: string): void;
245
+ /** Turn a layer off (hidden but still selectable). */
246
+ setLayerOff(name: string): void;
247
+ /** Turn a layer on. */
248
+ setLayerOn(name: string): void;
249
+ /** Change layer color. */
250
+ setLayerColor(name: string, color: number): void;
251
+ /** Change layer linetype. */
252
+ setLayerLinetype(name: string, linetype: string): void;
253
+ /**
254
+ * Add a callout: a leader from `anchor` to a boxed, multi-line label.
255
+ * The leader attaches to the box edge midpoint nearest the anchor.
256
+ *
257
+ * anchor ●──────────┤ ก่อสร้างอาคารทางน้ำเข้า │
258
+ * │ ขนาด 2-1.75x1.75 ม. │
259
+ *
260
+ * @param anchor the point being annotated
261
+ * @param text lines of text (array, or a string with "\n")
262
+ * @param boxAt top-left corner of the box
263
+ * @returns the box extent [minX, minY, maxX, maxY]
264
+ */
265
+ addCallout(anchor: [number, number], text: string | string[], boxAt: [number, number], opts?: CalloutOptions): [number, number, number, number];
266
+ /**
267
+ * Add an annotation with a leader.
268
+ *
269
+ * @deprecated MULTILEADER entities written by this library were not
270
+ * AutoCAD-compatible. This now draws `addCallout(vertices[0], text, textPosition)`
271
+ * with an arrowhead; use addCallout directly.
272
+ */
273
+ addMLeader(vertices: [number, number][], text: string, textPosition: [number, number], layer?: string, color?: number, opts?: {
274
+ textHeight?: number;
275
+ textWidth?: number;
276
+ arrowSize?: number;
277
+ doglegLength?: number;
278
+ }): void;
279
+ /**
280
+ * Add a TABLE (drawn as grid of LINE + TEXT entities).
281
+ * Cells may span columns/rows with `colSpan` / `rowSpan` (HTML table rules).
282
+ *
283
+ * @example
284
+ * builder.addTable([100, 500], [20, 40, 50, 50], 8, [
285
+ * [{ text: 'ลำดับ', rowSpan: 2 }, { text: 'หมุด', rowSpan: 2 }, { text: 'พิกัด', colSpan: 2 }],
286
+ * [{ text: 'North' }, { text: 'East' }],
287
+ * [{ text: '1' }, { text: 'BM.07' }, { text: '1,034,018.584' }, { text: '519,395.838' }],
288
+ * ], 'TABLE', 2.5);
289
+ */
290
+ addTable(position: [number, number], columnWidths: number[], rowHeight: number, rows: TableCellDef[][], layer?: string, textHeight?: number, opts?: {
291
+ headerColor?: number;
292
+ gridColor?: number;
293
+ textColor?: number;
294
+ rowHeights?: number[];
295
+ }): void;
296
+ /**
297
+ * Add a Paper Space layout for plotting. Paper units are mm; the origin
298
+ * is the lower-left corner of the printable area (inside the margins).
299
+ * A viewport's model-space extent comes from `viewHeight`, or from `scale`
300
+ * (e.g. 12500 for 1:12,500 with the model in meters).
301
+ *
302
+ * @example
303
+ * builder.addLayout('A1', 841, 594, [0, 0, 0, 0], [{
304
+ * center: [420, 297], width: 800, height: 560,
305
+ * viewCenter: [519500, 1033500], scale: 12500,
306
+ * frozenLayers: ['GRID'],
307
+ * }]);
308
+ */
309
+ addLayout(name: string, paperWidth: number, paperHeight: number, margins?: [number, number, number, number], viewports?: LayoutViewportDef[]): void;
310
+ /**
311
+ * Draw into a paper space layout: every builder call made inside `draw`
312
+ * targets that layout. Works with layouts from the template (e.g.
313
+ * 'Layout1') and ones added with addLayout().
314
+ *
315
+ * @example
316
+ * builder.onLayout('A1', b => {
317
+ * b.addText('แผนที่แสดงตำแหน่งหมุดหลักฐาน', 300, 25, 8);
318
+ * b.addTable([560, 200], [15, 30, 45, 45], 7, rows, 'TABLE', 2.5);
319
+ * });
320
+ */
321
+ onLayout(name: string, draw: (builder: DxfBuilder) => void): void;
322
+ /**
323
+ * Set geographic coordinate reference for the drawing.
324
+ * Embeds CRS info into the DXF HEADER for GIS interoperability.
325
+ *
326
+ * @example
327
+ * // UTM Zone 47N (Thailand)
328
+ * builder.setGeoReference({
329
+ * crsId: 'EPSG:32647',
330
+ * designPoint: [0, 0],
331
+ * referencePoint: [600000, 1700000],
332
+ * northDirection: 0,
333
+ * scaleFactor: 1,
334
+ * coordinateType: 2,
335
+ * });
336
+ */
337
+ setGeoReference(geoRef: GeoReferenceDef): void;
338
+ /** Serialize to DXF string. ✅ Works everywhere. */
339
+ saveString(): string;
340
+ /** Save to file (Node.js only). */
341
+ saveas(filePath: string): void;
342
+ /** Download DXF in browser (Angular). */
343
+ downloadAs(filename: string): void;
344
+ private _withTarget;
345
+ private _ensureLayer;
346
+ private _initializeLayers;
347
+ private _drawFromRegistry;
348
+ }