@zurigo/maps 1.0.0 → 1.0.2

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 (57) hide show
  1. package/dist/components/error-display.d.ts +33 -0
  2. package/dist/components/error-display.d.ts.map +1 -0
  3. package/dist/components/error-display.js +188 -0
  4. package/dist/components/error-display.js.map +1 -0
  5. package/dist/components/google-maps.d.ts +31 -0
  6. package/dist/components/google-maps.d.ts.map +1 -0
  7. package/dist/components/google-maps.js +1709 -0
  8. package/dist/components/google-maps.js.map +1 -0
  9. package/dist/index.d.ts +8 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +35 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/lib/google-maps/china-fallback.d.ts +64 -0
  14. package/dist/lib/google-maps/china-fallback.d.ts.map +1 -0
  15. package/dist/lib/google-maps/china-fallback.js +212 -0
  16. package/dist/lib/google-maps/china-fallback.js.map +1 -0
  17. package/dist/lib/google-maps/config.d.ts +51 -0
  18. package/dist/lib/google-maps/config.d.ts.map +1 -0
  19. package/dist/lib/google-maps/config.js +73 -0
  20. package/dist/lib/google-maps/config.js.map +1 -0
  21. package/dist/lib/google-maps/error-handler.d.ts +30 -0
  22. package/dist/lib/google-maps/error-handler.d.ts.map +1 -0
  23. package/dist/lib/google-maps/error-handler.js +224 -0
  24. package/dist/lib/google-maps/error-handler.js.map +1 -0
  25. package/dist/lib/google-maps/geocoding-service.d.ts +47 -0
  26. package/dist/lib/google-maps/geocoding-service.d.ts.map +1 -0
  27. package/dist/lib/google-maps/geocoding-service.js +224 -0
  28. package/dist/lib/google-maps/geocoding-service.js.map +1 -0
  29. package/dist/lib/google-maps/hooks.d.ts +35 -0
  30. package/dist/lib/google-maps/hooks.d.ts.map +1 -0
  31. package/dist/lib/google-maps/hooks.js +207 -0
  32. package/dist/lib/google-maps/hooks.js.map +1 -0
  33. package/dist/lib/google-maps/index.d.ts +7 -0
  34. package/dist/lib/google-maps/index.d.ts.map +1 -0
  35. package/dist/lib/google-maps/index.js +23 -0
  36. package/dist/lib/google-maps/index.js.map +1 -0
  37. package/dist/lib/google-maps/types.d.ts +96 -0
  38. package/dist/lib/google-maps/types.d.ts.map +1 -0
  39. package/dist/lib/google-maps/types.js +41 -0
  40. package/dist/lib/google-maps/types.js.map +1 -0
  41. package/dist/lib/google-maps/utils.d.ts +20 -0
  42. package/dist/lib/google-maps/utils.d.ts.map +1 -0
  43. package/dist/lib/google-maps/utils.js +176 -0
  44. package/dist/lib/google-maps/utils.js.map +1 -0
  45. package/dist/lib/solar-panel/constraints.d.ts +62 -0
  46. package/dist/lib/solar-panel/constraints.d.ts.map +1 -0
  47. package/dist/lib/solar-panel/constraints.js +166 -0
  48. package/dist/lib/solar-panel/constraints.js.map +1 -0
  49. package/dist/lib/solar-panel/orientation.d.ts +56 -0
  50. package/dist/lib/solar-panel/orientation.d.ts.map +1 -0
  51. package/dist/lib/solar-panel/orientation.js +255 -0
  52. package/dist/lib/solar-panel/orientation.js.map +1 -0
  53. package/dist/lib/solar-panel-calculator.d.ts +126 -0
  54. package/dist/lib/solar-panel-calculator.d.ts.map +1 -0
  55. package/dist/lib/solar-panel-calculator.js +450 -0
  56. package/dist/lib/solar-panel-calculator.js.map +1 -0
  57. package/package.json +2 -2
@@ -0,0 +1,62 @@
1
+ export interface SpacingConstraints {
2
+ minPanelSpacing: number;
3
+ minEdgeDistance: number;
4
+ minObstacleDistance: number;
5
+ minRowSpacing: number;
6
+ maxPanelDensity: number;
7
+ }
8
+ export interface PanelDimensions {
9
+ width: number;
10
+ height: number;
11
+ area: number;
12
+ powerRating: number;
13
+ }
14
+ export interface InstallationConstraints {
15
+ installationType: 'rooftop' | 'ground_mount' | 'carport';
16
+ orientation: 'portrait' | 'landscape';
17
+ tiltAngle: number;
18
+ rowOrientation: number;
19
+ }
20
+ export declare const STANDARD_PANEL_DIMENSIONS: Record<string, PanelDimensions>;
21
+ export declare const DEFAULT_SPACING_CONSTRAINTS: Record<string, SpacingConstraints>;
22
+ export interface SpacingValidationResult {
23
+ isValid: boolean;
24
+ violations: SpacingViolation[];
25
+ suggestions: string[];
26
+ optimizedLayout?: OptimizedLayout;
27
+ }
28
+ export interface SpacingViolation {
29
+ type: 'panel_spacing' | 'edge_distance' | 'obstacle_distance' | 'row_spacing' | 'density';
30
+ severity: 'error' | 'warning' | 'info';
31
+ message: string;
32
+ affectedElements: string[];
33
+ suggestedFix?: string;
34
+ }
35
+ export interface OptimizedLayout {
36
+ recommendedPanelCount: number;
37
+ adjustedSpacing: SpacingConstraints;
38
+ estimatedCapacity: number;
39
+ efficiencyScore: number;
40
+ }
41
+ export declare const CHINA_SOLAR_REGULATIONS: {
42
+ minFireSafetyClearance: number;
43
+ maxRoofCoverage: number;
44
+ minMaintenanceAccess: number;
45
+ windLoadSpacing: number;
46
+ seismicSpacing: number;
47
+ };
48
+ export declare const constraintUtils: {
49
+ calculateShadingSpacing: (tiltAngle: number, latitude: number, panelHeight: number) => number;
50
+ calculateOptimalDensity: (constraints: SpacingConstraints, panelDimensions: PanelDimensions, availableArea: number) => number;
51
+ validatePlacement: (panelPosition: {
52
+ lat: number;
53
+ lng: number;
54
+ }, existingPanels: {
55
+ lat: number;
56
+ lng: number;
57
+ }[], polygonBounds: {
58
+ lat: number;
59
+ lng: number;
60
+ }[], constraints: SpacingConstraints) => SpacingValidationResult;
61
+ };
62
+ //# sourceMappingURL=constraints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constraints.d.ts","sourceRoot":"","sources":["../../../src/lib/solar-panel/constraints.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,kBAAkB;IAEjC,eAAe,EAAE,MAAM,CAAA;IAEvB,eAAe,EAAE,MAAM,CAAA;IAEvB,mBAAmB,EAAE,MAAM,CAAA;IAE3B,aAAa,EAAE,MAAM,CAAA;IAErB,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,eAAe;IAE9B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IAEd,IAAI,EAAE,MAAM,CAAA;IAEZ,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,uBAAuB;IAEtC,gBAAgB,EAAE,SAAS,GAAG,cAAc,GAAG,SAAS,CAAA;IAExD,WAAW,EAAE,UAAU,GAAG,WAAW,CAAA;IAErC,SAAS,EAAE,MAAM,CAAA;IAEjB,cAAc,EAAE,MAAM,CAAA;CACvB;AAGD,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAmBrE,CAAA;AAGD,eAAO,MAAM,2BAA2B,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAsB1E,CAAA;AAGD,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,gBAAgB,EAAE,CAAA;IAC9B,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,eAAe,CAAC,EAAE,eAAe,CAAA;CAClC;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EACA,eAAe,GACf,eAAe,GACf,mBAAmB,GACnB,aAAa,GACb,SAAS,CAAA;IACb,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;IACtC,OAAO,EAAE,MAAM,CAAA;IACf,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,qBAAqB,EAAE,MAAM,CAAA;IAC7B,eAAe,EAAE,kBAAkB,CAAA;IACnC,iBAAiB,EAAE,MAAM,CAAA;IACzB,eAAe,EAAE,MAAM,CAAA;CACxB;AAGD,eAAO,MAAM,uBAAuB;;;;;;CAOnC,CAAA;AAGD,eAAO,MAAM,eAAe;yCAGb,MAAM,YACP,MAAM,eACH,MAAM,KAClB,MAAM;2CAWM,kBAAkB,mBACd,eAAe,iBACjB,MAAM,KACpB,MAAM;uCAaQ;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,kBAC3B;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,iBAC/B;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,eAChC,kBAAkB,KAC9B,uBAAuB;CA2C3B,CAAA"}
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ // Solar panel spacing constraints and validation rules
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.constraintUtils = exports.CHINA_SOLAR_REGULATIONS = exports.DEFAULT_SPACING_CONSTRAINTS = exports.STANDARD_PANEL_DIMENSIONS = void 0;
5
+ // Standard solar panel dimensions and specifications
6
+ exports.STANDARD_PANEL_DIMENSIONS = {
7
+ residential: {
8
+ width: 1.65, // meters
9
+ height: 1.0, // meters
10
+ area: 1.65, // square meters
11
+ powerRating: 300, // watts
12
+ },
13
+ commercial: {
14
+ width: 2.0, // meters
15
+ height: 1.0, // meters
16
+ area: 2.0, // square meters
17
+ powerRating: 400, // watts
18
+ },
19
+ utility: {
20
+ width: 2.1, // meters
21
+ height: 1.25, // meters
22
+ area: 2.625, // square meters
23
+ powerRating: 500, // watts
24
+ },
25
+ };
26
+ // Default spacing constraints based on installation type and local regulations
27
+ exports.DEFAULT_SPACING_CONSTRAINTS = {
28
+ rooftop: {
29
+ minPanelSpacing: 0.5, // 50cm minimum between panels
30
+ minEdgeDistance: 1.0, // 1m from roof edges for safety/maintenance
31
+ minObstacleDistance: 1.5, // 1.5m from chimneys, vents, etc.
32
+ minRowSpacing: 2.0, // 2m between rows for maintenance access
33
+ maxPanelDensity: 0.7, // Max 70% of available roof area
34
+ },
35
+ ground_mount: {
36
+ minPanelSpacing: 0.8, // 80cm minimum between panels
37
+ minEdgeDistance: 2.0, // 2m from property boundaries
38
+ minObstacleDistance: 3.0, // 3m from trees, buildings, etc.
39
+ minRowSpacing: 4.0, // 4m between rows to prevent shading
40
+ maxPanelDensity: 0.6, // Max 60% of available area
41
+ },
42
+ carport: {
43
+ minPanelSpacing: 0.3, // 30cm minimum between panels
44
+ minEdgeDistance: 0.5, // 50cm from carport edges
45
+ minObstacleDistance: 1.0, // 1m from support columns
46
+ minRowSpacing: 1.5, // 1.5m between rows
47
+ maxPanelDensity: 0.8, // Max 80% of carport area
48
+ },
49
+ };
50
+ // China-specific solar installation regulations
51
+ exports.CHINA_SOLAR_REGULATIONS = {
52
+ // National standards for solar installations
53
+ minFireSafetyClearance: 1.0, // 1m clearance for fire safety
54
+ maxRoofCoverage: 0.75, // Maximum 75% roof coverage
55
+ minMaintenanceAccess: 0.8, // 80cm maintenance pathways
56
+ windLoadSpacing: 1.2, // Additional spacing for high wind areas
57
+ seismicSpacing: 0.3, // Additional spacing for seismic zones
58
+ };
59
+ // Utility functions for constraint calculations
60
+ exports.constraintUtils = {
61
+ // Calculate minimum spacing based on tilt angle and latitude
62
+ calculateShadingSpacing: (tiltAngle, latitude, panelHeight) => {
63
+ // Simplified shading calculation for China's latitude range (18°-54°)
64
+ const sunAngle = Math.max(20, 90 - Math.abs(latitude) - 23.5);
65
+ const shadowLength = (panelHeight * Math.sin((tiltAngle * Math.PI) / 180)) /
66
+ Math.tan((sunAngle * Math.PI) / 180);
67
+ return Math.max(2.0, shadowLength * 1.2); // Add 20% buffer
68
+ },
69
+ // Calculate optimal panel density based on constraints
70
+ calculateOptimalDensity: (constraints, panelDimensions, availableArea) => {
71
+ const panelWithSpacing = (panelDimensions.width + constraints.minPanelSpacing) *
72
+ (panelDimensions.height + constraints.minRowSpacing);
73
+ const theoreticalPanels = Math.floor(availableArea / panelWithSpacing);
74
+ const maxAllowedPanels = Math.floor((availableArea * constraints.maxPanelDensity) / panelDimensions.area);
75
+ return Math.min(theoreticalPanels, maxAllowedPanels);
76
+ },
77
+ // Validate panel placement against constraints
78
+ validatePlacement: (panelPosition, existingPanels, polygonBounds, constraints) => {
79
+ const violations = [];
80
+ const suggestions = [];
81
+ // Check spacing between panels
82
+ existingPanels.forEach((existingPanel, index) => {
83
+ const distance = calculateDistance(panelPosition, existingPanel);
84
+ if (distance < constraints.minPanelSpacing) {
85
+ violations.push({
86
+ type: 'panel_spacing',
87
+ severity: 'error',
88
+ message: `Panel too close to existing panel (${distance.toFixed(2)}m < ${constraints.minPanelSpacing}m required)`,
89
+ affectedElements: [`panel_${index}`],
90
+ suggestedFix: `Move panel at least ${(constraints.minPanelSpacing - distance + 0.1).toFixed(2)}m away`,
91
+ });
92
+ }
93
+ });
94
+ // Check distance from polygon edges
95
+ const edgeDistance = calculateDistanceToPolygonEdge(panelPosition, polygonBounds);
96
+ if (edgeDistance < constraints.minEdgeDistance) {
97
+ violations.push({
98
+ type: 'edge_distance',
99
+ severity: 'warning',
100
+ message: `Panel too close to roof edge (${edgeDistance.toFixed(2)}m < ${constraints.minEdgeDistance}m recommended)`,
101
+ affectedElements: ['roof_edge'],
102
+ suggestedFix: `Move panel at least ${(constraints.minEdgeDistance - edgeDistance + 0.1).toFixed(2)}m from edge`,
103
+ });
104
+ }
105
+ if (violations.length === 0) {
106
+ suggestions.push('Panel placement meets all spacing requirements');
107
+ }
108
+ return {
109
+ isValid: violations.filter((v) => v.severity === 'error').length === 0,
110
+ violations,
111
+ suggestions,
112
+ };
113
+ },
114
+ };
115
+ // Helper function to calculate distance between two geographic points
116
+ function calculateDistance(point1, point2) {
117
+ const R = 6371000; // Earth's radius in meters
118
+ const dLat = ((point2.lat - point1.lat) * Math.PI) / 180;
119
+ const dLng = ((point2.lng - point1.lng) * Math.PI) / 180;
120
+ const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
121
+ Math.cos((point1.lat * Math.PI) / 180) *
122
+ Math.cos((point2.lat * Math.PI) / 180) *
123
+ Math.sin(dLng / 2) *
124
+ Math.sin(dLng / 2);
125
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
126
+ return R * c;
127
+ }
128
+ // Helper function to calculate distance from point to polygon edge
129
+ function calculateDistanceToPolygonEdge(point, polygonBounds) {
130
+ let minDistance = Infinity;
131
+ for (let i = 0; i < polygonBounds.length; i++) {
132
+ const edgeStart = polygonBounds[i];
133
+ const edgeEnd = polygonBounds[(i + 1) % polygonBounds.length];
134
+ const distance = distanceToLineSegment(point, edgeStart, edgeEnd);
135
+ minDistance = Math.min(minDistance, distance);
136
+ }
137
+ return minDistance;
138
+ }
139
+ // Helper function to calculate distance from point to line segment
140
+ function distanceToLineSegment(point, lineStart, lineEnd) {
141
+ const A = point.lat - lineStart.lat;
142
+ const B = point.lng - lineStart.lng;
143
+ const C = lineEnd.lat - lineStart.lat;
144
+ const D = lineEnd.lng - lineStart.lng;
145
+ const dot = A * C + B * D;
146
+ const lenSq = C * C + D * D;
147
+ if (lenSq === 0) {
148
+ return calculateDistance(point, lineStart);
149
+ }
150
+ let param = dot / lenSq;
151
+ let closestPoint;
152
+ if (param < 0) {
153
+ closestPoint = lineStart;
154
+ }
155
+ else if (param > 1) {
156
+ closestPoint = lineEnd;
157
+ }
158
+ else {
159
+ closestPoint = {
160
+ lat: lineStart.lat + param * C,
161
+ lng: lineStart.lng + param * D,
162
+ };
163
+ }
164
+ return calculateDistance(point, closestPoint);
165
+ }
166
+ //# sourceMappingURL=constraints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constraints.js","sourceRoot":"","sources":["../../../src/lib/solar-panel/constraints.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ export interface PanelOrientation {
2
+ azimuth: number;
3
+ tilt: number;
4
+ layout: 'portrait' | 'landscape';
5
+ efficiencyFactor: number;
6
+ }
7
+ export interface LocationOptimization {
8
+ latitude: number;
9
+ longitude: number;
10
+ optimalTilt: number;
11
+ optimalAzimuth: number;
12
+ seasonalVariations: {
13
+ summer: {
14
+ tilt: number;
15
+ azimuth: number;
16
+ };
17
+ winter: {
18
+ tilt: number;
19
+ azimuth: number;
20
+ };
21
+ };
22
+ }
23
+ export interface OrientationSettings {
24
+ orientation: PanelOrientation;
25
+ locationOptimization?: LocationOptimization;
26
+ trackingMode: 'fixed' | 'seasonal' | 'manual';
27
+ shadingAware: boolean;
28
+ }
29
+ export declare const CHINA_SOLAR_ANGLES: Record<string, LocationOptimization>;
30
+ export declare const DEFAULT_ORIENTATION: PanelOrientation;
31
+ export declare const orientationUtils: {
32
+ calculateOptimalTilt: (latitude: number) => number;
33
+ calculateOptimalAzimuth: (latitude: number, longitude: number) => number;
34
+ calculateEfficiencyFactor: (azimuth: number, tilt: number, latitude: number, optimalAzimuth?: number, optimalTilt?: number) => number;
35
+ getClosestCityOptimization: (latitude: number, longitude: number) => LocationOptimization;
36
+ getSeasonalRecommendations: (latitude: number) => {
37
+ spring: PanelOrientation;
38
+ summer: PanelOrientation;
39
+ autumn: PanelOrientation;
40
+ winter: PanelOrientation;
41
+ };
42
+ azimuthToCompass: (azimuth: number) => string;
43
+ getOrientationDescription: (orientation: PanelOrientation) => string;
44
+ calculateShadingImpact: (orientation: PanelOrientation, surroundingObstacles: Array<{
45
+ height: number;
46
+ distance: number;
47
+ azimuth: number;
48
+ }>) => number;
49
+ };
50
+ export declare const ORIENTATION_PRESETS: {
51
+ optimal: (latitude: number, longitude: number) => PanelOrientation;
52
+ flat: () => PanelOrientation;
53
+ steep: (latitude: number) => PanelOrientation;
54
+ eastWest: () => PanelOrientation;
55
+ };
56
+ //# sourceMappingURL=orientation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orientation.d.ts","sourceRoot":"","sources":["../../../src/lib/solar-panel/orientation.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAE/B,OAAO,EAAE,MAAM,CAAA;IAEf,IAAI,EAAE,MAAM,CAAA;IAEZ,MAAM,EAAE,UAAU,GAAG,WAAW,CAAA;IAEhC,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,EAAE,MAAM,CAAA;IACtB,kBAAkB,EAAE;QAClB,MAAM,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;QACzC,MAAM,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAC1C,CAAA;CACF;AAED,MAAM,WAAW,mBAAmB;IAElC,WAAW,EAAE,gBAAgB,CAAA;IAE7B,oBAAoB,CAAC,EAAE,oBAAoB,CAAA;IAE3C,YAAY,EAAE,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAA;IAE7C,YAAY,EAAE,OAAO,CAAA;CACtB;AAGD,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAuEnE,CAAA;AAGD,eAAO,MAAM,mBAAmB,EAAE,gBAKjC,CAAA;AAGD,eAAO,MAAM,gBAAgB;qCAEM,MAAM,KAAG,MAAM;wCAgBZ,MAAM,aAAa,MAAM,KAAG,MAAM;yCAiB3D,MAAM,QACT,MAAM,YACF,MAAM,mBACC,MAAM,gBACT,MAAM,KACnB,MAAM;2CAwBG,MAAM,aACL,MAAM,KAChB,oBAAoB;2CAqBX,MAAM,KACf;QACD,MAAM,EAAE,gBAAgB,CAAA;QACxB,MAAM,EAAE,gBAAgB,CAAA;QACxB,MAAM,EAAE,gBAAgB,CAAA;QACxB,MAAM,EAAE,gBAAgB,CAAA;KACzB;gCAoD2B,MAAM,KAAG,MAAM;6CAyBF,gBAAgB,KAAG,MAAM;0CAgBnD,gBAAgB,wBACP,KAAK,CAAC;QAC1B,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,EAAE,MAAM,CAAA;QAChB,OAAO,EAAE,MAAM,CAAA;KAChB,CAAC,KACD,MAAM;CAsBV,CAAA;AAGD,eAAO,MAAM,mBAAmB;wBACV,MAAM,aAAa,MAAM,KAAG,gBAAgB;gBAOtD,gBAAgB;sBAOR,MAAM,KAAG,gBAAgB;oBAO7B,gBAAgB;CAM/B,CAAA"}
@@ -0,0 +1,255 @@
1
+ "use strict";
2
+ // Solar panel orientation and angle optimization utilities
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.ORIENTATION_PRESETS = exports.orientationUtils = exports.DEFAULT_ORIENTATION = exports.CHINA_SOLAR_ANGLES = void 0;
5
+ // China major cities optimal solar panel angles
6
+ exports.CHINA_SOLAR_ANGLES = {
7
+ beijing: {
8
+ latitude: 39.9042,
9
+ longitude: 116.4074,
10
+ optimalTilt: 37, // Approximately equal to latitude for China
11
+ optimalAzimuth: 180, // South-facing
12
+ seasonalVariations: {
13
+ summer: { tilt: 25, azimuth: 180 },
14
+ winter: { tilt: 50, azimuth: 180 },
15
+ },
16
+ },
17
+ shanghai: {
18
+ latitude: 31.2304,
19
+ longitude: 121.4737,
20
+ optimalTilt: 30,
21
+ optimalAzimuth: 180,
22
+ seasonalVariations: {
23
+ summer: { tilt: 18, azimuth: 180 },
24
+ winter: { tilt: 42, azimuth: 180 },
25
+ },
26
+ },
27
+ guangzhou: {
28
+ latitude: 23.1291,
29
+ longitude: 113.2644,
30
+ optimalTilt: 22,
31
+ optimalAzimuth: 180,
32
+ seasonalVariations: {
33
+ summer: { tilt: 10, azimuth: 180 },
34
+ winter: { tilt: 34, azimuth: 180 },
35
+ },
36
+ },
37
+ shenzhen: {
38
+ latitude: 22.5431,
39
+ longitude: 114.0579,
40
+ optimalTilt: 21,
41
+ optimalAzimuth: 180,
42
+ seasonalVariations: {
43
+ summer: { tilt: 9, azimuth: 180 },
44
+ winter: { tilt: 33, azimuth: 180 },
45
+ },
46
+ },
47
+ chengdu: {
48
+ latitude: 30.5728,
49
+ longitude: 104.0668,
50
+ optimalTilt: 29,
51
+ optimalAzimuth: 180,
52
+ seasonalVariations: {
53
+ summer: { tilt: 17, azimuth: 180 },
54
+ winter: { tilt: 41, azimuth: 180 },
55
+ },
56
+ },
57
+ wuhan: {
58
+ latitude: 30.5844,
59
+ longitude: 114.2998,
60
+ optimalTilt: 29,
61
+ optimalAzimuth: 180,
62
+ seasonalVariations: {
63
+ summer: { tilt: 17, azimuth: 180 },
64
+ winter: { tilt: 41, azimuth: 180 },
65
+ },
66
+ },
67
+ xian: {
68
+ latitude: 34.2658,
69
+ longitude: 108.9541,
70
+ optimalTilt: 33,
71
+ optimalAzimuth: 180,
72
+ seasonalVariations: {
73
+ summer: { tilt: 21, azimuth: 180 },
74
+ winter: { tilt: 45, azimuth: 180 },
75
+ },
76
+ },
77
+ };
78
+ // Default orientation settings
79
+ exports.DEFAULT_ORIENTATION = {
80
+ azimuth: 180, // South-facing
81
+ tilt: 30, // 30-degree tilt for China average
82
+ layout: 'landscape',
83
+ efficiencyFactor: 1.0,
84
+ };
85
+ // Orientation calculation utilities
86
+ exports.orientationUtils = {
87
+ // Calculate optimal tilt angle based on latitude
88
+ calculateOptimalTilt: (latitude) => {
89
+ // Rule of thumb: optimal tilt ≈ latitude for fixed installations
90
+ // Adjust for China's specific solar conditions
91
+ const baseTilt = Math.abs(latitude);
92
+ // Adjust for China's latitude range (18°-54°)
93
+ if (baseTilt < 25) {
94
+ return baseTilt - 2; // Slightly flatter for southern China
95
+ }
96
+ else if (baseTilt > 40) {
97
+ return baseTilt - 3; // Reduce tilt for northern China winter snow
98
+ }
99
+ return Math.round(baseTilt);
100
+ },
101
+ // Calculate optimal azimuth (usually south = 180°)
102
+ calculateOptimalAzimuth: (latitude, longitude) => {
103
+ // For China, south-facing (180°) is generally optimal
104
+ // Minor adjustments based on regional factors
105
+ let baseAzimuth = 180;
106
+ // Slight adjustments for western China (different solar time)
107
+ if (longitude < 100) {
108
+ baseAzimuth += 5; // Slightly southeast
109
+ }
110
+ else if (longitude > 120) {
111
+ baseAzimuth -= 5; // Slightly southwest
112
+ }
113
+ return baseAzimuth;
114
+ },
115
+ // Calculate efficiency factor based on orientation
116
+ calculateEfficiencyFactor: (azimuth, tilt, latitude, optimalAzimuth, optimalTilt) => {
117
+ const targetAzimuth = optimalAzimuth !== null && optimalAzimuth !== void 0 ? optimalAzimuth : exports.orientationUtils.calculateOptimalAzimuth(latitude, 116);
118
+ const targetTilt = optimalTilt !== null && optimalTilt !== void 0 ? optimalTilt : exports.orientationUtils.calculateOptimalTilt(latitude);
119
+ // Calculate azimuth deviation penalty
120
+ const azimuthDeviation = Math.abs(azimuth - targetAzimuth);
121
+ const normalizedAzimuthDev = Math.min(azimuthDeviation, 360 - azimuthDeviation) / 180;
122
+ const azimuthFactor = Math.cos((normalizedAzimuthDev * Math.PI) / 2);
123
+ // Calculate tilt deviation penalty
124
+ const tiltDeviation = Math.abs(tilt - targetTilt) / 90;
125
+ const tiltFactor = 1 - tiltDeviation * 0.5; // Less penalty for tilt deviation
126
+ // Combined efficiency factor (0.4 to 1.0 range)
127
+ const efficiency = Math.max(0.4, azimuthFactor * tiltFactor);
128
+ return Math.round(efficiency * 100) / 100;
129
+ },
130
+ // Get closest city optimization data
131
+ getClosestCityOptimization: (latitude, longitude) => {
132
+ let closestCity = 'beijing';
133
+ let minDistance = Infinity;
134
+ Object.entries(exports.CHINA_SOLAR_ANGLES).forEach(([city, data]) => {
135
+ const distance = Math.sqrt(Math.pow(latitude - data.latitude, 2) +
136
+ Math.pow(longitude - data.longitude, 2));
137
+ if (distance < minDistance) {
138
+ minDistance = distance;
139
+ closestCity = city;
140
+ }
141
+ });
142
+ return exports.CHINA_SOLAR_ANGLES[closestCity];
143
+ },
144
+ // Calculate seasonal adjustment recommendations
145
+ getSeasonalRecommendations: (latitude) => {
146
+ const optimalTilt = exports.orientationUtils.calculateOptimalTilt(latitude);
147
+ const optimalAzimuth = exports.orientationUtils.calculateOptimalAzimuth(latitude, 116);
148
+ return {
149
+ spring: {
150
+ azimuth: optimalAzimuth,
151
+ tilt: optimalTilt,
152
+ layout: 'landscape',
153
+ efficiencyFactor: exports.orientationUtils.calculateEfficiencyFactor(optimalAzimuth, optimalTilt, latitude),
154
+ },
155
+ summer: {
156
+ azimuth: optimalAzimuth,
157
+ tilt: Math.max(5, optimalTilt - 15), // Flatter for high summer sun
158
+ layout: 'landscape',
159
+ efficiencyFactor: exports.orientationUtils.calculateEfficiencyFactor(optimalAzimuth, optimalTilt - 15, latitude),
160
+ },
161
+ autumn: {
162
+ azimuth: optimalAzimuth,
163
+ tilt: optimalTilt,
164
+ layout: 'landscape',
165
+ efficiencyFactor: exports.orientationUtils.calculateEfficiencyFactor(optimalAzimuth, optimalTilt, latitude),
166
+ },
167
+ winter: {
168
+ azimuth: optimalAzimuth,
169
+ tilt: Math.min(60, optimalTilt + 15), // Steeper for low winter sun
170
+ layout: 'landscape',
171
+ efficiencyFactor: exports.orientationUtils.calculateEfficiencyFactor(optimalAzimuth, optimalTilt + 15, latitude),
172
+ },
173
+ };
174
+ },
175
+ // Convert orientation to compass direction string
176
+ azimuthToCompass: (azimuth) => {
177
+ const directions = [
178
+ 'N',
179
+ 'NNE',
180
+ 'NE',
181
+ 'ENE',
182
+ 'E',
183
+ 'ESE',
184
+ 'SE',
185
+ 'SSE',
186
+ 'S',
187
+ 'SSW',
188
+ 'SW',
189
+ 'WSW',
190
+ 'W',
191
+ 'WNW',
192
+ 'NW',
193
+ 'NNW',
194
+ ];
195
+ const index = Math.round(azimuth / 22.5) % 16;
196
+ return directions[index];
197
+ },
198
+ // Generate orientation description
199
+ getOrientationDescription: (orientation) => {
200
+ const compass = exports.orientationUtils.azimuthToCompass(orientation.azimuth);
201
+ const tiltDesc = orientation.tilt < 15
202
+ ? 'nearly flat'
203
+ : orientation.tilt < 30
204
+ ? 'moderate tilt'
205
+ : orientation.tilt < 45
206
+ ? 'steep tilt'
207
+ : 'very steep';
208
+ return `${compass}-facing, ${tiltDesc} (${orientation.tilt}°)`;
209
+ },
210
+ // Calculate shading impact
211
+ calculateShadingImpact: (orientation, surroundingObstacles) => {
212
+ let maxShadingFactor = 0;
213
+ surroundingObstacles.forEach((obstacle) => {
214
+ // Calculate sun elevation angle that would be blocked
215
+ const shadowAngle = (Math.atan(obstacle.height / obstacle.distance) * 180) / Math.PI;
216
+ // Check if obstacle is in sun path (considering panel azimuth)
217
+ const azimuthDiff = Math.abs(obstacle.azimuth - orientation.azimuth);
218
+ const normalizedDiff = Math.min(azimuthDiff, 360 - azimuthDiff);
219
+ if (normalizedDiff < 90) {
220
+ // Obstacle affects this panel
221
+ const shadingFactor = Math.min(1, shadowAngle / 60) * (1 - normalizedDiff / 90);
222
+ maxShadingFactor = Math.max(maxShadingFactor, shadingFactor);
223
+ }
224
+ });
225
+ return maxShadingFactor;
226
+ },
227
+ };
228
+ // Preset orientation configurations
229
+ exports.ORIENTATION_PRESETS = {
230
+ optimal: (latitude, longitude) => ({
231
+ azimuth: exports.orientationUtils.calculateOptimalAzimuth(latitude, longitude),
232
+ tilt: exports.orientationUtils.calculateOptimalTilt(latitude),
233
+ layout: 'landscape',
234
+ efficiencyFactor: 1.0,
235
+ }),
236
+ flat: () => ({
237
+ azimuth: 180,
238
+ tilt: 0,
239
+ layout: 'landscape',
240
+ efficiencyFactor: 0.85,
241
+ }),
242
+ steep: (latitude) => ({
243
+ azimuth: 180,
244
+ tilt: Math.min(60, Math.abs(latitude) + 20),
245
+ layout: 'portrait',
246
+ efficiencyFactor: 0.92,
247
+ }),
248
+ eastWest: () => ({
249
+ azimuth: 90, // East-west split system
250
+ tilt: 10,
251
+ layout: 'landscape',
252
+ efficiencyFactor: 0.88,
253
+ }),
254
+ };
255
+ //# sourceMappingURL=orientation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orientation.js","sourceRoot":"","sources":["../../../src/lib/solar-panel/orientation.ts"],"names":[],"mappings":"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"}