planscript 1.2.0 → 2.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.
- package/LANGUAGE_REFERENCE.md +507 -7
- package/dist/ast/types.d.ts +95 -5
- package/dist/ast/types.d.ts.map +1 -1
- package/dist/cli.js +28 -6
- package/dist/cli.js.map +1 -1
- package/dist/exporters/svg.d.ts +3 -0
- package/dist/exporters/svg.d.ts.map +1 -1
- package/dist/exporters/svg.js +174 -3
- package/dist/exporters/svg.js.map +1 -1
- package/dist/geometry/index.d.ts.map +1 -1
- package/dist/geometry/index.js +77 -16
- package/dist/geometry/index.js.map +1 -1
- package/dist/geometry/types.d.ts +7 -0
- package/dist/geometry/types.d.ts.map +1 -1
- package/dist/lowering/index.d.ts +23 -1
- package/dist/lowering/index.d.ts.map +1 -1
- package/dist/lowering/index.js +374 -28
- package/dist/lowering/index.js.map +1 -1
- package/dist/parser/grammar.d.ts +63 -9
- package/dist/parser/grammar.d.ts.map +1 -1
- package/dist/parser/grammar.js +5148 -1839
- package/dist/parser/grammar.js.map +1 -1
- package/dist/validation/index.d.ts +5 -0
- package/dist/validation/index.d.ts.map +1 -1
- package/dist/validation/index.js +215 -0
- package/dist/validation/index.js.map +1 -1
- package/examples/advanced_positioning.psc +225 -0
- package/examples/advanced_positioning.svg +76 -0
- package/examples/courtyard_house.psc +141 -0
- package/examples/courtyard_house.svg +93 -0
- package/examples/orientation.psc +141 -0
- package/examples/orientation.svg +88 -0
- package/examples/zones.psc +275 -0
- package/examples/zones.svg +89 -0
- package/package.json +1 -1
package/dist/ast/types.d.ts
CHANGED
|
@@ -39,6 +39,13 @@ export interface DefaultsDeclaration extends ASTNode {
|
|
|
39
39
|
doorWidth?: number;
|
|
40
40
|
windowWidth?: number;
|
|
41
41
|
}
|
|
42
|
+
export type CardinalDirection = 'north' | 'south' | 'east' | 'west';
|
|
43
|
+
export type Hemisphere = 'north' | 'south';
|
|
44
|
+
export interface SiteDeclaration extends ASTNode {
|
|
45
|
+
type: 'SiteDeclaration';
|
|
46
|
+
street: CardinalDirection;
|
|
47
|
+
hemisphere?: Hemisphere;
|
|
48
|
+
}
|
|
42
49
|
export interface FootprintPolygon extends ASTNode {
|
|
43
50
|
type: 'FootprintPolygon';
|
|
44
51
|
points: Point[];
|
|
@@ -70,24 +77,49 @@ export interface RoomRectCenterSize extends ASTNode {
|
|
|
70
77
|
}
|
|
71
78
|
export interface RoomRectSizeOnly extends ASTNode {
|
|
72
79
|
type: 'RoomRectSizeOnly';
|
|
73
|
-
size:
|
|
80
|
+
size: SizeValue;
|
|
81
|
+
}
|
|
82
|
+
export type DimensionValue = number | 'auto';
|
|
83
|
+
export interface SizeValue {
|
|
84
|
+
x: DimensionValue;
|
|
85
|
+
y: DimensionValue;
|
|
74
86
|
}
|
|
75
|
-
export
|
|
87
|
+
export interface RoomFill extends ASTNode {
|
|
88
|
+
type: 'RoomFill';
|
|
89
|
+
between: [string, string];
|
|
90
|
+
width?: number;
|
|
91
|
+
height?: number;
|
|
92
|
+
}
|
|
93
|
+
export type RoomGeometry = RoomPolygon | RoomRectDiagonal | RoomRectAtSize | RoomRectCenterSize | RoomRectSizeOnly | RoomFill;
|
|
76
94
|
export type RelativeDirection = 'north_of' | 'south_of' | 'east_of' | 'west_of';
|
|
77
95
|
export type AlignmentType = 'top' | 'bottom' | 'left' | 'right' | 'center';
|
|
96
|
+
export type AlignEdge = 'top' | 'bottom' | 'left' | 'right';
|
|
78
97
|
export interface AttachDirective extends ASTNode {
|
|
79
98
|
type: 'AttachDirective';
|
|
80
99
|
direction: RelativeDirection;
|
|
81
100
|
target: string;
|
|
82
101
|
}
|
|
83
|
-
export interface
|
|
102
|
+
export interface AlignDirectiveSimple extends ASTNode {
|
|
84
103
|
type: 'AlignDirective';
|
|
85
104
|
alignment: AlignmentType;
|
|
86
105
|
}
|
|
106
|
+
export interface AlignDirectiveExplicit extends ASTNode {
|
|
107
|
+
type: 'AlignDirective';
|
|
108
|
+
myEdge: AlignEdge;
|
|
109
|
+
withRoom: string;
|
|
110
|
+
withEdge: AlignEdge;
|
|
111
|
+
}
|
|
112
|
+
export type AlignDirective = AlignDirectiveSimple | AlignDirectiveExplicit;
|
|
87
113
|
export interface GapDirective extends ASTNode {
|
|
88
114
|
type: 'GapDirective';
|
|
89
115
|
distance: number;
|
|
90
116
|
}
|
|
117
|
+
export interface ExtendDirective extends ASTNode {
|
|
118
|
+
type: 'ExtendDirective';
|
|
119
|
+
axis: 'x' | 'y';
|
|
120
|
+
from: EdgeReference;
|
|
121
|
+
to: EdgeReference;
|
|
122
|
+
}
|
|
91
123
|
export interface SpanX extends ASTNode {
|
|
92
124
|
type: 'SpanX';
|
|
93
125
|
from: EdgeReference;
|
|
@@ -115,6 +147,7 @@ export interface RoomDefinition extends ASTNode {
|
|
|
115
147
|
attach?: AttachDirective;
|
|
116
148
|
align?: AlignDirective;
|
|
117
149
|
gap?: GapDirective;
|
|
150
|
+
extend?: ExtendDirective;
|
|
118
151
|
}
|
|
119
152
|
export type OpeningType = 'door' | 'window';
|
|
120
153
|
export type SwingDirection = string;
|
|
@@ -127,7 +160,7 @@ export interface PositionPercentage {
|
|
|
127
160
|
value: number;
|
|
128
161
|
}
|
|
129
162
|
export type Position = PositionAbsolute | PositionPercentage;
|
|
130
|
-
export interface
|
|
163
|
+
export interface DoorOpeningBetween extends ASTNode {
|
|
131
164
|
type: 'DoorOpening';
|
|
132
165
|
name: string;
|
|
133
166
|
between: [string, string];
|
|
@@ -136,6 +169,16 @@ export interface DoorOpening extends ASTNode {
|
|
|
136
169
|
width: number;
|
|
137
170
|
swing?: SwingDirection;
|
|
138
171
|
}
|
|
172
|
+
export interface DoorOpeningEdge extends ASTNode {
|
|
173
|
+
type: 'DoorOpening';
|
|
174
|
+
name: string;
|
|
175
|
+
room: string;
|
|
176
|
+
edge: EdgeSide;
|
|
177
|
+
at: Position;
|
|
178
|
+
width: number;
|
|
179
|
+
swing?: SwingDirection;
|
|
180
|
+
}
|
|
181
|
+
export type DoorOpening = DoorOpeningBetween | DoorOpeningEdge;
|
|
139
182
|
export type EdgeSide = 'north' | 'south' | 'east' | 'west';
|
|
140
183
|
export interface WindowOpening extends ASTNode {
|
|
141
184
|
type: 'WindowOpening';
|
|
@@ -173,12 +216,58 @@ export interface AssertionMinRoomArea extends ASTNode {
|
|
|
173
216
|
export interface AssertionRoomsConnected extends ASTNode {
|
|
174
217
|
type: 'AssertionRoomsConnected';
|
|
175
218
|
}
|
|
176
|
-
export type
|
|
219
|
+
export type OrientationTarget = 'morning_sun' | 'afternoon_sun' | 'street' | CardinalDirection;
|
|
220
|
+
export interface AssertionOrientationHasWindow extends ASTNode {
|
|
221
|
+
type: 'AssertionOrientationHasWindow';
|
|
222
|
+
room: string;
|
|
223
|
+
target: OrientationTarget;
|
|
224
|
+
}
|
|
225
|
+
export interface AssertionOrientationNearStreet extends ASTNode {
|
|
226
|
+
type: 'AssertionOrientationNearStreet';
|
|
227
|
+
room: string;
|
|
228
|
+
}
|
|
229
|
+
export interface AssertionOrientationAwayFromStreet extends ASTNode {
|
|
230
|
+
type: 'AssertionOrientationAwayFromStreet';
|
|
231
|
+
room: string;
|
|
232
|
+
}
|
|
233
|
+
export interface AssertionOrientationGardenView extends ASTNode {
|
|
234
|
+
type: 'AssertionOrientationGardenView';
|
|
235
|
+
room: string;
|
|
236
|
+
}
|
|
237
|
+
export type OrientationAssertion = AssertionOrientationHasWindow | AssertionOrientationNearStreet | AssertionOrientationAwayFromStreet | AssertionOrientationGardenView;
|
|
238
|
+
export type Assertion = AssertionInsideFootprint | AssertionNoOverlap | AssertionOpeningsOnWalls | AssertionMinRoomArea | AssertionRoomsConnected | OrientationAssertion;
|
|
239
|
+
export interface ZoneDefinition extends ASTNode {
|
|
240
|
+
type: 'ZoneDefinition';
|
|
241
|
+
name: string;
|
|
242
|
+
label?: string;
|
|
243
|
+
rooms: RoomDefinition[];
|
|
244
|
+
attach?: AttachDirective;
|
|
245
|
+
align?: AlignDirective;
|
|
246
|
+
gap?: GapDirective;
|
|
247
|
+
}
|
|
248
|
+
export type CourtyardGeometry = CourtyardRect | CourtyardPolygon;
|
|
249
|
+
export interface CourtyardRect extends ASTNode {
|
|
250
|
+
type: 'CourtyardRect';
|
|
251
|
+
p1: Point;
|
|
252
|
+
p2: Point;
|
|
253
|
+
}
|
|
254
|
+
export interface CourtyardPolygon extends ASTNode {
|
|
255
|
+
type: 'CourtyardPolygon';
|
|
256
|
+
points: Point[];
|
|
257
|
+
}
|
|
258
|
+
export interface CourtyardDefinition extends ASTNode {
|
|
259
|
+
type: 'CourtyardDefinition';
|
|
260
|
+
name: string;
|
|
261
|
+
label?: string;
|
|
262
|
+
geometry: CourtyardGeometry;
|
|
263
|
+
}
|
|
177
264
|
export interface PlanDefinition extends ASTNode {
|
|
178
265
|
type: 'PlanDefinition';
|
|
179
266
|
name: string;
|
|
180
267
|
footprint: Footprint;
|
|
268
|
+
zones: ZoneDefinition[];
|
|
181
269
|
rooms: RoomDefinition[];
|
|
270
|
+
courtyards: CourtyardDefinition[];
|
|
182
271
|
openings: Opening[];
|
|
183
272
|
wallOverrides: WallThicknessOverride[];
|
|
184
273
|
assertions: Assertion[];
|
|
@@ -190,6 +279,7 @@ export interface Program extends ASTNode {
|
|
|
190
279
|
axis?: AxisDeclaration;
|
|
191
280
|
grid?: GridDeclaration;
|
|
192
281
|
defaults?: DefaultsDeclaration;
|
|
282
|
+
site?: SiteDeclaration;
|
|
193
283
|
plan: PlanDefinition;
|
|
194
284
|
}
|
|
195
285
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/ast/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ast/types.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,KAAK;IACpB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,cAAc,CAAC;IACtB,GAAG,EAAE,cAAc,CAAC;CACrB;AAMD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAMD,MAAM,MAAM,QAAQ,GAAG,GAAG,GAAG,QAAQ,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAElE,MAAM,WAAW,gBAAiB,SAAQ,OAAO;IAC/C,IAAI,EAAE,kBAAkB,CAAC;IACzB,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,MAAM,WAAW,iBAAkB,SAAQ,OAAO;IAChD,IAAI,EAAE,mBAAmB,CAAC;IAC1B,KAAK,EAAE,KAAK,CAAC;CACd;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC;AAE7D,MAAM,WAAW,eAAgB,SAAQ,OAAO;IAC9C,IAAI,EAAE,iBAAiB,CAAC;IACxB,CAAC,EAAE,aAAa,CAAC;IACjB,CAAC,EAAE,aAAa,CAAC;CAClB;AAED,MAAM,WAAW,eAAgB,SAAQ,OAAO;IAC9C,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAoB,SAAQ,OAAO;IAClD,IAAI,EAAE,qBAAqB,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAMD,MAAM,WAAW,gBAAiB,SAAQ,OAAO;IAC/C,IAAI,EAAE,kBAAkB,CAAC;IACzB,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,aAAc,SAAQ,OAAO;IAC5C,IAAI,EAAE,eAAe,CAAC;IACtB,EAAE,EAAE,KAAK,CAAC;IACV,EAAE,EAAE,KAAK,CAAC;CACX;AAED,MAAM,MAAM,SAAS,GAAG,gBAAgB,GAAG,aAAa,CAAC;AAMzD,MAAM,WAAW,WAAY,SAAQ,OAAO;IAC1C,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,gBAAiB,SAAQ,OAAO;IAC/C,IAAI,EAAE,kBAAkB,CAAC;IACzB,EAAE,EAAE,KAAK,CAAC;IACV,EAAE,EAAE,KAAK,CAAC;CACX;AAED,MAAM,WAAW,cAAe,SAAQ,OAAO;IAC7C,IAAI,EAAE,gBAAgB,CAAC;IACvB,EAAE,EAAE,KAAK,CAAC;IACV,IAAI,EAAE,KAAK,CAAC;CACb;AAED,MAAM,WAAW,kBAAmB,SAAQ,OAAO;IACjD,IAAI,EAAE,oBAAoB,CAAC;IAC3B,MAAM,EAAE,KAAK,CAAC;IACd,IAAI,EAAE,KAAK,CAAC;CACb;AAED,MAAM,WAAW,gBAAiB,SAAQ,OAAO;IAC/C,IAAI,EAAE,kBAAkB,CAAC;IACzB,IAAI,EAAE,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ast/types.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { readFileSync, writeFileSync } from 'fs';
|
|
3
|
+
import { resolve } from 'path';
|
|
3
4
|
import { compile } from './compiler.js';
|
|
4
5
|
const args = process.argv.slice(2);
|
|
5
6
|
if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
|
|
@@ -24,7 +25,28 @@ Examples:
|
|
|
24
25
|
`);
|
|
25
26
|
process.exit(0);
|
|
26
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Format error in a way that editors can parse for click-to-navigate.
|
|
30
|
+
* Standard format: file:line:column: error: message
|
|
31
|
+
*/
|
|
32
|
+
function formatError(file, error) {
|
|
33
|
+
const parts = [];
|
|
34
|
+
// file:line:column (clickable in most editors/terminals)
|
|
35
|
+
if (error.location) {
|
|
36
|
+
parts.push(`${file}:${error.location.line}:${error.location.column}`);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
parts.push(file);
|
|
40
|
+
}
|
|
41
|
+
// error type with code
|
|
42
|
+
const errorType = error.code ? `error[${error.code}]` : 'error';
|
|
43
|
+
parts.push(errorType);
|
|
44
|
+
// message
|
|
45
|
+
parts.push(error.message);
|
|
46
|
+
return parts.join(': ');
|
|
47
|
+
}
|
|
27
48
|
const inputFile = args[0];
|
|
49
|
+
const absoluteInputFile = resolve(inputFile);
|
|
28
50
|
let svgOutput;
|
|
29
51
|
let jsonOutput;
|
|
30
52
|
let emitSVG = true;
|
|
@@ -62,12 +84,12 @@ try {
|
|
|
62
84
|
jsonOptions: { pretty: true },
|
|
63
85
|
});
|
|
64
86
|
if (!result.success) {
|
|
65
|
-
console.error('
|
|
87
|
+
console.error('');
|
|
66
88
|
for (const error of result.errors) {
|
|
67
|
-
|
|
68
|
-
const code = error.code ? ` [${error.code}]` : '';
|
|
69
|
-
console.error(` ${error.phase}${code}${location}: ${error.message}`);
|
|
89
|
+
console.error(formatError(absoluteInputFile, error));
|
|
70
90
|
}
|
|
91
|
+
console.error('');
|
|
92
|
+
console.error(`Compilation failed with ${result.errors.length} error(s).`);
|
|
71
93
|
process.exit(1);
|
|
72
94
|
}
|
|
73
95
|
console.log('Compilation successful!');
|
|
@@ -90,10 +112,10 @@ try {
|
|
|
90
112
|
}
|
|
91
113
|
catch (e) {
|
|
92
114
|
if (e instanceof Error) {
|
|
93
|
-
console.error(
|
|
115
|
+
console.error(`${absoluteInputFile}: error: ${e.message}`);
|
|
94
116
|
}
|
|
95
117
|
else {
|
|
96
|
-
console.error(
|
|
118
|
+
console.error(`${absoluteInputFile}: error: Unknown error occurred`);
|
|
97
119
|
}
|
|
98
120
|
process.exit(1);
|
|
99
121
|
}
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/exporters/svg.d.ts
CHANGED
|
@@ -13,6 +13,9 @@ export interface SVGExportOptions {
|
|
|
13
13
|
roomFillColor?: string;
|
|
14
14
|
roomStrokeColor?: string;
|
|
15
15
|
roomStrokeWidth?: number;
|
|
16
|
+
courtyardFillColor?: string;
|
|
17
|
+
courtyardStrokeColor?: string;
|
|
18
|
+
courtyardStrokeWidth?: number;
|
|
16
19
|
doorColor?: string;
|
|
17
20
|
windowColor?: string;
|
|
18
21
|
footprintColor?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"svg.d.ts","sourceRoot":"","sources":["../../src/exporters/svg.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"svg.d.ts","sourceRoot":"","sources":["../../src/exporters/svg.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAA2E,MAAM,sBAAsB,CAAC;AAMhI,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAwkCD,wBAAgB,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAwCtF"}
|
package/dist/exporters/svg.js
CHANGED
|
@@ -12,6 +12,9 @@ const defaultOptions = {
|
|
|
12
12
|
roomFillColor: '#ecf0f1',
|
|
13
13
|
roomStrokeColor: '#bdc3c7',
|
|
14
14
|
roomStrokeWidth: 1,
|
|
15
|
+
courtyardFillColor: '#d5f5e3', // Light green for open spaces
|
|
16
|
+
courtyardStrokeColor: '#27ae60', // Darker green stroke
|
|
17
|
+
courtyardStrokeWidth: 2,
|
|
15
18
|
doorColor: '#e74c3c',
|
|
16
19
|
windowColor: '#3498db',
|
|
17
20
|
footprintColor: '#7f8c8d',
|
|
@@ -87,6 +90,131 @@ function calculatePolygonCenter(points) {
|
|
|
87
90
|
const y = points.reduce((sum, p) => sum + p.y, 0) / points.length;
|
|
88
91
|
return { x, y };
|
|
89
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Test if a point is inside a polygon using ray casting algorithm.
|
|
95
|
+
*/
|
|
96
|
+
function isPointInPolygon(point, polygon) {
|
|
97
|
+
const { x, y } = point;
|
|
98
|
+
let inside = false;
|
|
99
|
+
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
|
100
|
+
const xi = polygon[i].x, yi = polygon[i].y;
|
|
101
|
+
const xj = polygon[j].x, yj = polygon[j].y;
|
|
102
|
+
if (((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi)) {
|
|
103
|
+
inside = !inside;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return inside;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Calculate the distance from a point to a line segment.
|
|
110
|
+
*/
|
|
111
|
+
function pointToSegmentDistance(point, p1, p2) {
|
|
112
|
+
const dx = p2.x - p1.x;
|
|
113
|
+
const dy = p2.y - p1.y;
|
|
114
|
+
const lengthSquared = dx * dx + dy * dy;
|
|
115
|
+
if (lengthSquared === 0) {
|
|
116
|
+
// Segment is a point
|
|
117
|
+
return Math.sqrt((point.x - p1.x) ** 2 + (point.y - p1.y) ** 2);
|
|
118
|
+
}
|
|
119
|
+
// Project point onto line, clamped to segment
|
|
120
|
+
let t = ((point.x - p1.x) * dx + (point.y - p1.y) * dy) / lengthSquared;
|
|
121
|
+
t = Math.max(0, Math.min(1, t));
|
|
122
|
+
const projX = p1.x + t * dx;
|
|
123
|
+
const projY = p1.y + t * dy;
|
|
124
|
+
return Math.sqrt((point.x - projX) ** 2 + (point.y - projY) ** 2);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Calculate minimum distance from a point to the polygon boundary.
|
|
128
|
+
*/
|
|
129
|
+
function pointToPolygonDistance(point, polygon) {
|
|
130
|
+
let minDist = Infinity;
|
|
131
|
+
for (let i = 0; i < polygon.length; i++) {
|
|
132
|
+
const p1 = polygon[i];
|
|
133
|
+
const p2 = polygon[(i + 1) % polygon.length];
|
|
134
|
+
const dist = pointToSegmentDistance(point, p1, p2);
|
|
135
|
+
minDist = Math.min(minDist, dist);
|
|
136
|
+
}
|
|
137
|
+
return minDist;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Find the visual center of a polygon using a "pole of inaccessibility" algorithm.
|
|
141
|
+
* This finds the point inside the polygon that is furthest from any edge.
|
|
142
|
+
* Uses an iterative grid-based approach for better accuracy.
|
|
143
|
+
*/
|
|
144
|
+
function findVisualCenter(points) {
|
|
145
|
+
// Calculate bounding box
|
|
146
|
+
const xs = points.map(p => p.x);
|
|
147
|
+
const ys = points.map(p => p.y);
|
|
148
|
+
const minX = Math.min(...xs);
|
|
149
|
+
const maxX = Math.max(...xs);
|
|
150
|
+
const minY = Math.min(...ys);
|
|
151
|
+
const maxY = Math.max(...ys);
|
|
152
|
+
const width = maxX - minX;
|
|
153
|
+
const height = maxY - minY;
|
|
154
|
+
// Start with centroid as fallback
|
|
155
|
+
const centroid = calculatePolygonCenter(points);
|
|
156
|
+
// If centroid is inside, use iterative refinement
|
|
157
|
+
// Otherwise, find a point inside first
|
|
158
|
+
let bestPoint = centroid;
|
|
159
|
+
let bestDistance = isPointInPolygon(centroid, points)
|
|
160
|
+
? pointToPolygonDistance(centroid, points)
|
|
161
|
+
: -Infinity;
|
|
162
|
+
// Initial grid search
|
|
163
|
+
const gridSize = 10;
|
|
164
|
+
const cellWidth = width / gridSize;
|
|
165
|
+
const cellHeight = height / gridSize;
|
|
166
|
+
for (let i = 0; i <= gridSize; i++) {
|
|
167
|
+
for (let j = 0; j <= gridSize; j++) {
|
|
168
|
+
const testPoint = {
|
|
169
|
+
x: minX + i * cellWidth,
|
|
170
|
+
y: minY + j * cellHeight
|
|
171
|
+
};
|
|
172
|
+
if (isPointInPolygon(testPoint, points)) {
|
|
173
|
+
const dist = pointToPolygonDistance(testPoint, points);
|
|
174
|
+
if (dist > bestDistance) {
|
|
175
|
+
bestDistance = dist;
|
|
176
|
+
bestPoint = testPoint;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Refinement: search around best point with smaller grid
|
|
182
|
+
const refineRadius = Math.max(cellWidth, cellHeight);
|
|
183
|
+
const refineSteps = 5;
|
|
184
|
+
for (let iteration = 0; iteration < 3; iteration++) {
|
|
185
|
+
const searchRadius = refineRadius / Math.pow(2, iteration);
|
|
186
|
+
const step = searchRadius / refineSteps;
|
|
187
|
+
for (let dx = -refineSteps; dx <= refineSteps; dx++) {
|
|
188
|
+
for (let dy = -refineSteps; dy <= refineSteps; dy++) {
|
|
189
|
+
const testPoint = {
|
|
190
|
+
x: bestPoint.x + dx * step,
|
|
191
|
+
y: bestPoint.y + dy * step
|
|
192
|
+
};
|
|
193
|
+
if (isPointInPolygon(testPoint, points)) {
|
|
194
|
+
const dist = pointToPolygonDistance(testPoint, points);
|
|
195
|
+
if (dist > bestDistance) {
|
|
196
|
+
bestDistance = dist;
|
|
197
|
+
bestPoint = testPoint;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return bestPoint;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Get the best label position for a polygon.
|
|
207
|
+
* Uses centroid for convex polygons, visual center for concave ones.
|
|
208
|
+
*/
|
|
209
|
+
function getLabelPosition(points) {
|
|
210
|
+
const centroid = calculatePolygonCenter(points);
|
|
211
|
+
// If centroid is inside the polygon, it's good enough for most cases
|
|
212
|
+
if (isPointInPolygon(centroid, points)) {
|
|
213
|
+
return centroid;
|
|
214
|
+
}
|
|
215
|
+
// For concave polygons where centroid is outside, find the visual center
|
|
216
|
+
return findVisualCenter(points);
|
|
217
|
+
}
|
|
90
218
|
function calculatePolygonBounds(points) {
|
|
91
219
|
const xs = points.map(p => p.x);
|
|
92
220
|
const ys = points.map(p => p.y);
|
|
@@ -113,14 +241,26 @@ function generateRoomsSVG(rooms, t, opts) {
|
|
|
113
241
|
}
|
|
114
242
|
return elements.join('\n ');
|
|
115
243
|
}
|
|
116
|
-
function
|
|
244
|
+
function generateCourtyardsSVG(courtyards, t, opts) {
|
|
245
|
+
const elements = [];
|
|
246
|
+
for (const courtyard of courtyards) {
|
|
247
|
+
const points = transformPolygon(courtyard.polygon.points, t);
|
|
248
|
+
const path = pointsToPath(points);
|
|
249
|
+
// Courtyard fill with distinct styling
|
|
250
|
+
elements.push(`<path d="${path}" fill="${opts.courtyardFillColor}" stroke="${opts.courtyardStrokeColor}" ` +
|
|
251
|
+
`stroke-width="${opts.courtyardStrokeWidth}" stroke-dasharray="4,2" />`);
|
|
252
|
+
}
|
|
253
|
+
return elements.join('\n ');
|
|
254
|
+
}
|
|
255
|
+
function generateLabelsSVG(rooms, courtyards, t, opts) {
|
|
117
256
|
if (!opts.showLabels)
|
|
118
257
|
return '';
|
|
119
258
|
const elements = [];
|
|
259
|
+
// Room labels
|
|
120
260
|
for (const room of rooms) {
|
|
121
261
|
if (!room.label)
|
|
122
262
|
continue;
|
|
123
|
-
const worldCenter =
|
|
263
|
+
const worldCenter = getLabelPosition(room.polygon.points);
|
|
124
264
|
const screenCenter = transformPoint(worldCenter, t);
|
|
125
265
|
// Calculate room size in screen coordinates to adapt font size
|
|
126
266
|
const worldBounds = calculatePolygonBounds(room.polygon.points);
|
|
@@ -149,6 +289,34 @@ function generateLabelsSVG(rooms, t, opts) {
|
|
|
149
289
|
`text-anchor="middle" dominant-baseline="middle" font-family="Arial, sans-serif">` +
|
|
150
290
|
`${escapeXml(label)}</text>`);
|
|
151
291
|
}
|
|
292
|
+
// Courtyard labels
|
|
293
|
+
for (const courtyard of courtyards) {
|
|
294
|
+
if (!courtyard.label)
|
|
295
|
+
continue;
|
|
296
|
+
const worldCenter = getLabelPosition(courtyard.polygon.points);
|
|
297
|
+
const screenCenter = transformPoint(worldCenter, t);
|
|
298
|
+
// Calculate courtyard size in screen coordinates to adapt font size
|
|
299
|
+
const worldBounds = calculatePolygonBounds(courtyard.polygon.points);
|
|
300
|
+
const screenWidth = worldBounds.width * t.scale;
|
|
301
|
+
const screenHeight = worldBounds.height * t.scale;
|
|
302
|
+
const label = courtyard.label;
|
|
303
|
+
const baseFontSize = opts.labelFontSize;
|
|
304
|
+
const estimatedTextWidth = 0.6 * baseFontSize * label.length;
|
|
305
|
+
const maxTextWidth = screenWidth * 0.85;
|
|
306
|
+
const maxTextHeight = screenHeight * 0.4;
|
|
307
|
+
let fontSize = baseFontSize;
|
|
308
|
+
if (estimatedTextWidth > maxTextWidth) {
|
|
309
|
+
fontSize = Math.floor((maxTextWidth / label.length) / 0.6);
|
|
310
|
+
}
|
|
311
|
+
fontSize = Math.min(fontSize, maxTextHeight);
|
|
312
|
+
fontSize = Math.max(fontSize, 6);
|
|
313
|
+
fontSize = Math.min(fontSize, baseFontSize);
|
|
314
|
+
// Use courtyard stroke color for label to match the style
|
|
315
|
+
elements.push(`<text x="${screenCenter.x.toFixed(2)}" y="${screenCenter.y.toFixed(2)}" ` +
|
|
316
|
+
`font-size="${fontSize}" fill="${opts.courtyardStrokeColor}" ` +
|
|
317
|
+
`text-anchor="middle" dominant-baseline="middle" font-family="Arial, sans-serif" font-style="italic">` +
|
|
318
|
+
`${escapeXml(label)}</text>`);
|
|
319
|
+
}
|
|
152
320
|
return elements.join('\n ');
|
|
153
321
|
}
|
|
154
322
|
function generateWallsSVG(walls, t, opts) {
|
|
@@ -667,6 +835,9 @@ export function exportSVG(geometry, options = {}) {
|
|
|
667
835
|
<!-- Rooms -->
|
|
668
836
|
${generateRoomsSVG(geometry.rooms, transform, opts)}
|
|
669
837
|
|
|
838
|
+
<!-- Courtyards -->
|
|
839
|
+
${generateCourtyardsSVG(geometry.courtyards, transform, opts)}
|
|
840
|
+
|
|
670
841
|
<!-- Walls -->
|
|
671
842
|
${generateWallsSVG(geometry.walls, transform, opts)}
|
|
672
843
|
|
|
@@ -674,7 +845,7 @@ export function exportSVG(geometry, options = {}) {
|
|
|
674
845
|
${generateOpeningsSVG(geometry.openings, geometry.walls, transform, opts)}
|
|
675
846
|
|
|
676
847
|
<!-- Labels -->
|
|
677
|
-
${generateLabelsSVG(geometry.rooms, transform, opts)}
|
|
848
|
+
${generateLabelsSVG(geometry.rooms, geometry.courtyards, transform, opts)}
|
|
678
849
|
|
|
679
850
|
<!-- Dimensions -->
|
|
680
851
|
${dimensionsSVG}
|