@smartnet360/svelte-components 0.0.57 → 0.0.58
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/dist/map-v2/core/components/ViewportSync.svelte +79 -0
- package/dist/map-v2/core/components/ViewportSync.svelte.d.ts +8 -0
- package/dist/map-v2/core/index.d.ts +2 -0
- package/dist/map-v2/core/index.js +3 -0
- package/dist/map-v2/core/stores/viewportStore.svelte.d.ts +51 -0
- package/dist/map-v2/core/stores/viewportStore.svelte.js +120 -0
- package/dist/map-v2/demo/DemoMap.svelte +30 -3
- package/dist/map-v2/demo/demo-cells.d.ts +12 -0
- package/dist/map-v2/demo/demo-cells.js +114 -0
- package/dist/map-v2/demo/index.d.ts +1 -0
- package/dist/map-v2/demo/index.js +1 -0
- package/dist/map-v2/features/cells/constants/colors.d.ts +7 -0
- package/dist/map-v2/features/cells/constants/colors.js +21 -0
- package/dist/map-v2/features/cells/constants/radiusMultipliers.d.ts +8 -0
- package/dist/map-v2/features/cells/constants/radiusMultipliers.js +22 -0
- package/dist/map-v2/features/cells/constants/statusStyles.d.ts +7 -0
- package/dist/map-v2/features/cells/constants/statusStyles.js +49 -0
- package/dist/map-v2/features/cells/constants/zIndex.d.ts +14 -0
- package/dist/map-v2/features/cells/constants/zIndex.js +28 -0
- package/dist/map-v2/features/cells/controls/CellFilterControl.svelte +242 -0
- package/dist/map-v2/features/cells/controls/CellFilterControl.svelte.d.ts +14 -0
- package/dist/map-v2/features/cells/controls/CellStyleControl.svelte +139 -0
- package/dist/map-v2/features/cells/controls/CellStyleControl.svelte.d.ts +14 -0
- package/dist/map-v2/features/cells/index.d.ts +20 -0
- package/dist/map-v2/features/cells/index.js +24 -0
- package/dist/map-v2/features/cells/layers/CellsLayer.svelte +195 -0
- package/dist/map-v2/features/cells/layers/CellsLayer.svelte.d.ts +10 -0
- package/dist/map-v2/features/cells/stores/cellStoreContext.svelte.d.ts +46 -0
- package/dist/map-v2/features/cells/stores/cellStoreContext.svelte.js +137 -0
- package/dist/map-v2/features/cells/types.d.ts +99 -0
- package/dist/map-v2/features/cells/types.js +12 -0
- package/dist/map-v2/features/cells/utils/arcGeometry.d.ts +36 -0
- package/dist/map-v2/features/cells/utils/arcGeometry.js +55 -0
- package/dist/map-v2/features/cells/utils/cellGeoJSON.d.ts +22 -0
- package/dist/map-v2/features/cells/utils/cellGeoJSON.js +81 -0
- package/dist/map-v2/features/cells/utils/cellTree.d.ts +25 -0
- package/dist/map-v2/features/cells/utils/cellTree.js +226 -0
- package/dist/map-v2/features/cells/utils/techBandParser.d.ts +11 -0
- package/dist/map-v2/features/cells/utils/techBandParser.js +17 -0
- package/dist/map-v2/features/cells/utils/zoomScaling.d.ts +42 -0
- package/dist/map-v2/features/cells/utils/zoomScaling.js +53 -0
- package/dist/map-v2/index.d.ts +3 -2
- package/dist/map-v2/index.js +6 -2
- package/package.json +1 -1
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cell Store Context - Bindable reactive state for cell feature
|
|
3
|
+
*
|
|
4
|
+
* Uses Svelte 5 runes ($state) to create a directly bindable reactive object
|
|
5
|
+
* Persists visual settings and grouping configuration to localStorage
|
|
6
|
+
*/
|
|
7
|
+
import type { Cell, CellStatus, CellStatusStyle, CellTreeConfig } from '../types';
|
|
8
|
+
export interface CellStoreValue {
|
|
9
|
+
cells: Cell[];
|
|
10
|
+
filteredCells: Cell[];
|
|
11
|
+
showCells: boolean;
|
|
12
|
+
lineWidth: number;
|
|
13
|
+
fillOpacity: number;
|
|
14
|
+
baseRadius: number;
|
|
15
|
+
statusStyles: Map<CellStatus, CellStatusStyle>;
|
|
16
|
+
groupingConfig: CellTreeConfig;
|
|
17
|
+
groupColorMap: Map<string, string>;
|
|
18
|
+
currentZoom: number;
|
|
19
|
+
}
|
|
20
|
+
export interface CellStoreContext {
|
|
21
|
+
readonly cells: Cell[];
|
|
22
|
+
readonly filteredCells: Cell[];
|
|
23
|
+
readonly showCells: boolean;
|
|
24
|
+
readonly lineWidth: number;
|
|
25
|
+
readonly fillOpacity: number;
|
|
26
|
+
readonly baseRadius: number;
|
|
27
|
+
readonly currentZoom: number;
|
|
28
|
+
readonly groupingConfig: CellTreeConfig;
|
|
29
|
+
readonly groupColorMap: Map<string, string>;
|
|
30
|
+
setFilteredCells(cells: Cell[]): void;
|
|
31
|
+
setShowCells(value: boolean): void;
|
|
32
|
+
setLineWidth(value: number): void;
|
|
33
|
+
setFillOpacity(value: number): void;
|
|
34
|
+
setBaseRadius(value: number): void;
|
|
35
|
+
setCurrentZoom(value: number): void;
|
|
36
|
+
setGroupingConfig(config: CellTreeConfig): void;
|
|
37
|
+
getStatusStyle(status: CellStatus): CellStatusStyle;
|
|
38
|
+
setStatusStyle(status: CellStatus, style: CellStatusStyle): void;
|
|
39
|
+
getGroupColor(groupKey: string): string | undefined;
|
|
40
|
+
setGroupColor(groupKey: string, color: string): void;
|
|
41
|
+
clearGroupColor(groupKey: string): void;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Create a cell store context with reactive state
|
|
45
|
+
*/
|
|
46
|
+
export declare function createCellStoreContext(cells: Cell[]): CellStoreContext;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cell Store Context - Bindable reactive state for cell feature
|
|
3
|
+
*
|
|
4
|
+
* Uses Svelte 5 runes ($state) to create a directly bindable reactive object
|
|
5
|
+
* Persists visual settings and grouping configuration to localStorage
|
|
6
|
+
*/
|
|
7
|
+
import { DEFAULT_CELL_TREE_CONFIG } from '../types';
|
|
8
|
+
import { DEFAULT_STATUS_STYLES } from '../constants/statusStyles';
|
|
9
|
+
const STORAGE_KEY = 'cellVisualSettings';
|
|
10
|
+
function loadSettings() {
|
|
11
|
+
if (typeof window === 'undefined')
|
|
12
|
+
return {};
|
|
13
|
+
try {
|
|
14
|
+
const saved = localStorage.getItem(STORAGE_KEY);
|
|
15
|
+
if (saved) {
|
|
16
|
+
return JSON.parse(saved);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
console.warn('Failed to load cell settings from localStorage:', error);
|
|
21
|
+
}
|
|
22
|
+
return {};
|
|
23
|
+
}
|
|
24
|
+
function saveSettings(settings) {
|
|
25
|
+
if (typeof window === 'undefined')
|
|
26
|
+
return;
|
|
27
|
+
try {
|
|
28
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(settings));
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.warn('Failed to save cell settings to localStorage:', error);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create a cell store context with reactive state
|
|
36
|
+
*/
|
|
37
|
+
export function createCellStoreContext(cells) {
|
|
38
|
+
// Load persisted settings
|
|
39
|
+
const persistedSettings = loadSettings();
|
|
40
|
+
// Convert persisted groupColors object back to Map
|
|
41
|
+
const initialColorMap = new Map();
|
|
42
|
+
if (persistedSettings.groupColors) {
|
|
43
|
+
Object.entries(persistedSettings.groupColors).forEach(([key, value]) => {
|
|
44
|
+
initialColorMap.set(key, value);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
// Internal reactive state
|
|
48
|
+
let state = $state({
|
|
49
|
+
cells,
|
|
50
|
+
filteredCells: cells,
|
|
51
|
+
showCells: persistedSettings.showCells ?? true,
|
|
52
|
+
lineWidth: persistedSettings.lineWidth ?? 2,
|
|
53
|
+
fillOpacity: persistedSettings.fillOpacity ?? 0.6,
|
|
54
|
+
baseRadius: persistedSettings.baseRadius ?? 500,
|
|
55
|
+
statusStyles: new Map(Object.entries(DEFAULT_STATUS_STYLES)),
|
|
56
|
+
groupingConfig: persistedSettings.groupingConfig ?? DEFAULT_CELL_TREE_CONFIG,
|
|
57
|
+
groupColorMap: initialColorMap,
|
|
58
|
+
currentZoom: 12 // Default zoom
|
|
59
|
+
});
|
|
60
|
+
// Auto-save settings when they change
|
|
61
|
+
$effect(() => {
|
|
62
|
+
// Convert Map to plain object for serialization
|
|
63
|
+
const groupColorsObj = {};
|
|
64
|
+
state.groupColorMap.forEach((color, key) => {
|
|
65
|
+
groupColorsObj[key] = color;
|
|
66
|
+
});
|
|
67
|
+
const settings = {
|
|
68
|
+
showCells: state.showCells,
|
|
69
|
+
lineWidth: state.lineWidth,
|
|
70
|
+
fillOpacity: state.fillOpacity,
|
|
71
|
+
baseRadius: state.baseRadius,
|
|
72
|
+
groupingConfig: state.groupingConfig,
|
|
73
|
+
groupColors: groupColorsObj
|
|
74
|
+
};
|
|
75
|
+
saveSettings(settings);
|
|
76
|
+
});
|
|
77
|
+
// Return store context
|
|
78
|
+
return {
|
|
79
|
+
// Bindable properties with getters/setters
|
|
80
|
+
get cells() { return state.cells; },
|
|
81
|
+
set cells(value) { state.cells = value; },
|
|
82
|
+
get filteredCells() { return state.filteredCells; },
|
|
83
|
+
set filteredCells(value) { state.filteredCells = value; },
|
|
84
|
+
get showCells() { return state.showCells; },
|
|
85
|
+
set showCells(value) { state.showCells = value; },
|
|
86
|
+
get lineWidth() { return state.lineWidth; },
|
|
87
|
+
set lineWidth(value) { state.lineWidth = value; },
|
|
88
|
+
get fillOpacity() { return state.fillOpacity; },
|
|
89
|
+
set fillOpacity(value) { state.fillOpacity = value; },
|
|
90
|
+
get baseRadius() { return state.baseRadius; },
|
|
91
|
+
set baseRadius(value) { state.baseRadius = value; },
|
|
92
|
+
get currentZoom() { return state.currentZoom; },
|
|
93
|
+
set currentZoom(value) { state.currentZoom = value; },
|
|
94
|
+
get groupingConfig() { return state.groupingConfig; },
|
|
95
|
+
get groupColorMap() { return state.groupColorMap; },
|
|
96
|
+
// Methods
|
|
97
|
+
setFilteredCells(cells) {
|
|
98
|
+
state.filteredCells = cells;
|
|
99
|
+
},
|
|
100
|
+
setShowCells(value) {
|
|
101
|
+
state.showCells = value;
|
|
102
|
+
},
|
|
103
|
+
setLineWidth(value) {
|
|
104
|
+
state.lineWidth = value;
|
|
105
|
+
},
|
|
106
|
+
setFillOpacity(value) {
|
|
107
|
+
state.fillOpacity = value;
|
|
108
|
+
},
|
|
109
|
+
setBaseRadius(value) {
|
|
110
|
+
state.baseRadius = value;
|
|
111
|
+
},
|
|
112
|
+
setCurrentZoom(value) {
|
|
113
|
+
state.currentZoom = value;
|
|
114
|
+
},
|
|
115
|
+
setGroupingConfig(config) {
|
|
116
|
+
state.groupingConfig = config;
|
|
117
|
+
},
|
|
118
|
+
getStatusStyle(status) {
|
|
119
|
+
return state.statusStyles.get(status) || DEFAULT_STATUS_STYLES['On_Air'];
|
|
120
|
+
},
|
|
121
|
+
setStatusStyle(status, style) {
|
|
122
|
+
state.statusStyles.set(status, style);
|
|
123
|
+
},
|
|
124
|
+
getGroupColor(groupKey) {
|
|
125
|
+
return state.groupColorMap.get(groupKey);
|
|
126
|
+
},
|
|
127
|
+
setGroupColor(groupKey, color) {
|
|
128
|
+
state.groupColorMap.set(groupKey, color);
|
|
129
|
+
// Trigger reactivity by reassigning the map
|
|
130
|
+
state.groupColorMap = new Map(state.groupColorMap);
|
|
131
|
+
},
|
|
132
|
+
clearGroupColor(groupKey) {
|
|
133
|
+
state.groupColorMap.delete(groupKey);
|
|
134
|
+
state.groupColorMap = new Map(state.groupColorMap);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cell Feature - Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Core interfaces and types for cellular network visualization
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Cell data model - represents a radio cell/sector
|
|
8
|
+
*/
|
|
9
|
+
export interface Cell {
|
|
10
|
+
id: string;
|
|
11
|
+
txId: string;
|
|
12
|
+
cellID: string;
|
|
13
|
+
cellID2G: string;
|
|
14
|
+
cellName: string;
|
|
15
|
+
siteId: string;
|
|
16
|
+
tech: string;
|
|
17
|
+
fband: string;
|
|
18
|
+
frq: string;
|
|
19
|
+
type: string;
|
|
20
|
+
status: string;
|
|
21
|
+
onAirDate: string;
|
|
22
|
+
bcch: number;
|
|
23
|
+
ctrlid: string;
|
|
24
|
+
dlEarfn: number;
|
|
25
|
+
antenna: string;
|
|
26
|
+
azimuth: number;
|
|
27
|
+
height: number;
|
|
28
|
+
electricalTilt: string;
|
|
29
|
+
beamwidth: number;
|
|
30
|
+
latitude: number;
|
|
31
|
+
longitude: number;
|
|
32
|
+
dx: number;
|
|
33
|
+
dy: number;
|
|
34
|
+
siteLatitude: number;
|
|
35
|
+
siteLongitude: number;
|
|
36
|
+
comment: string;
|
|
37
|
+
planner: string;
|
|
38
|
+
atollETP: number;
|
|
39
|
+
atollPW: number;
|
|
40
|
+
atollRS: number;
|
|
41
|
+
atollBW: number;
|
|
42
|
+
cellId3: string;
|
|
43
|
+
nwtP1: number;
|
|
44
|
+
nwtP2: number;
|
|
45
|
+
pci1: number;
|
|
46
|
+
nwtRS: number;
|
|
47
|
+
nwtBW: number;
|
|
48
|
+
other?: Record<string, any>;
|
|
49
|
+
customSubgroup: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Supported cell sector status values
|
|
53
|
+
*/
|
|
54
|
+
export type CellStatus = 'On_Air' | 'On_Air_UNDER_CONSTRUCTION' | 'On_Air_Locked' | 'RF_Plan_Ready' | 'Re-Planned_RF_Plan_Ready' | 'Tavlati_RF_Plan_Ready';
|
|
55
|
+
/**
|
|
56
|
+
* Status styling configuration for cell sector borders
|
|
57
|
+
*/
|
|
58
|
+
export interface CellStatusStyle {
|
|
59
|
+
/** Line type (solid, dashed, etc.) */
|
|
60
|
+
lineType: 'solid' | 'dashed' | 'dotted';
|
|
61
|
+
/** Line width in pixels */
|
|
62
|
+
lineWidth: number;
|
|
63
|
+
/** Line color in hex format */
|
|
64
|
+
lineColor: string;
|
|
65
|
+
/** Opacity for the line (0–1) */
|
|
66
|
+
opacity: number;
|
|
67
|
+
/** Dash array for creating dashed/dotted lines (e.g., [5, 5] for dashed) */
|
|
68
|
+
dashArray: number[];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Technology-Band combination key
|
|
72
|
+
* Format: '2G_900' | '4G_700' | '5G_3500'
|
|
73
|
+
*/
|
|
74
|
+
export type TechnologyBandKey = '2G_900' | '2G_1800' | '4G_700' | '4G_800' | '4G_900' | '4G_1800' | '4G_2100' | '4G_2600' | '5G_700' | '5G_2100' | '5G_3500';
|
|
75
|
+
/**
|
|
76
|
+
* Parsed technology and band from fband string
|
|
77
|
+
*/
|
|
78
|
+
export interface ParsedTechBand {
|
|
79
|
+
tech: string;
|
|
80
|
+
band: string;
|
|
81
|
+
key: TechnologyBandKey;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Available fields for grouping cells in the filter tree
|
|
85
|
+
*/
|
|
86
|
+
export type CellGroupingField = 'tech' | 'band' | 'status' | 'siteId' | 'customSubgroup' | 'type' | 'planner' | 'none';
|
|
87
|
+
/**
|
|
88
|
+
* Configuration for dynamic tree grouping
|
|
89
|
+
*/
|
|
90
|
+
export interface CellTreeConfig {
|
|
91
|
+
/** Primary grouping field (required) */
|
|
92
|
+
level1: Exclude<CellGroupingField, 'none'>;
|
|
93
|
+
/** Secondary grouping field (optional, can be 'none') */
|
|
94
|
+
level2: CellGroupingField;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Default tree configuration
|
|
98
|
+
*/
|
|
99
|
+
export declare const DEFAULT_CELL_TREE_CONFIG: CellTreeConfig;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Arc Geometry Utilities
|
|
3
|
+
*
|
|
4
|
+
* Calculate arc polygons for cell sectors using Turf.js
|
|
5
|
+
*/
|
|
6
|
+
import type { Feature, Polygon } from 'geojson';
|
|
7
|
+
/**
|
|
8
|
+
* Create an arc polygon representing a cell sector
|
|
9
|
+
*
|
|
10
|
+
* @param center - Center point [longitude, latitude]
|
|
11
|
+
* @param azimuth - Direction in degrees (0 = North, clockwise)
|
|
12
|
+
* @param beamwidth - Coverage angle in degrees (e.g., 65°)
|
|
13
|
+
* @param radius - Sector radius in meters
|
|
14
|
+
* @param steps - Number of points in the arc (more = smoother, default 64)
|
|
15
|
+
* @returns GeoJSON Polygon feature representing the sector arc
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // Create a 65° sector pointing north with 500m radius
|
|
19
|
+
* const arc = createArcPolygon(
|
|
20
|
+
* [-122.4194, 37.7749], // San Francisco
|
|
21
|
+
* 0, // North
|
|
22
|
+
* 65, // 65° beamwidth
|
|
23
|
+
* 500, // 500 meters
|
|
24
|
+
* 64 // 64 points
|
|
25
|
+
* );
|
|
26
|
+
*/
|
|
27
|
+
export declare function createArcPolygon(center: [number, number], azimuth: number, beamwidth: number, radius: number, steps?: number): Feature<Polygon>;
|
|
28
|
+
/**
|
|
29
|
+
* Create a simple line from center to edge of sector (for debugging/visualization)
|
|
30
|
+
*
|
|
31
|
+
* @param center - Center point [longitude, latitude]
|
|
32
|
+
* @param azimuth - Direction in degrees
|
|
33
|
+
* @param radius - Distance in meters
|
|
34
|
+
* @returns GeoJSON Point at the edge of the sector
|
|
35
|
+
*/
|
|
36
|
+
export declare function getArcEdgePoint(center: [number, number], azimuth: number, radius: number): [number, number];
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Arc Geometry Utilities
|
|
3
|
+
*
|
|
4
|
+
* Calculate arc polygons for cell sectors using Turf.js
|
|
5
|
+
*/
|
|
6
|
+
import * as turf from '@turf/turf';
|
|
7
|
+
/**
|
|
8
|
+
* Create an arc polygon representing a cell sector
|
|
9
|
+
*
|
|
10
|
+
* @param center - Center point [longitude, latitude]
|
|
11
|
+
* @param azimuth - Direction in degrees (0 = North, clockwise)
|
|
12
|
+
* @param beamwidth - Coverage angle in degrees (e.g., 65°)
|
|
13
|
+
* @param radius - Sector radius in meters
|
|
14
|
+
* @param steps - Number of points in the arc (more = smoother, default 64)
|
|
15
|
+
* @returns GeoJSON Polygon feature representing the sector arc
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // Create a 65° sector pointing north with 500m radius
|
|
19
|
+
* const arc = createArcPolygon(
|
|
20
|
+
* [-122.4194, 37.7749], // San Francisco
|
|
21
|
+
* 0, // North
|
|
22
|
+
* 65, // 65° beamwidth
|
|
23
|
+
* 500, // 500 meters
|
|
24
|
+
* 64 // 64 points
|
|
25
|
+
* );
|
|
26
|
+
*/
|
|
27
|
+
export function createArcPolygon(center, azimuth, beamwidth, radius, steps = 64) {
|
|
28
|
+
// Convert radius from meters to kilometers for Turf
|
|
29
|
+
const radiusKm = radius / 1000;
|
|
30
|
+
// Calculate start and end bearings for the arc
|
|
31
|
+
// Azimuth is the center direction, beamwidth is the total angle
|
|
32
|
+
const halfBeam = beamwidth / 2;
|
|
33
|
+
const startBearing = azimuth - halfBeam;
|
|
34
|
+
const endBearing = azimuth + halfBeam;
|
|
35
|
+
// Create the sector using Turf.js
|
|
36
|
+
// sector(center, radius, bearing1, bearing2, options)
|
|
37
|
+
const sector = turf.sector(center, radiusKm, startBearing, endBearing, {
|
|
38
|
+
steps: steps,
|
|
39
|
+
units: 'kilometers'
|
|
40
|
+
});
|
|
41
|
+
return sector;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Create a simple line from center to edge of sector (for debugging/visualization)
|
|
45
|
+
*
|
|
46
|
+
* @param center - Center point [longitude, latitude]
|
|
47
|
+
* @param azimuth - Direction in degrees
|
|
48
|
+
* @param radius - Distance in meters
|
|
49
|
+
* @returns GeoJSON Point at the edge of the sector
|
|
50
|
+
*/
|
|
51
|
+
export function getArcEdgePoint(center, azimuth, radius) {
|
|
52
|
+
const radiusKm = radius / 1000;
|
|
53
|
+
const point = turf.destination(center, radiusKm, azimuth, { units: 'kilometers' });
|
|
54
|
+
return point.geometry.coordinates;
|
|
55
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cell GeoJSON Conversion
|
|
3
|
+
*
|
|
4
|
+
* Convert cell data to GeoJSON FeatureCollection with styling properties
|
|
5
|
+
*/
|
|
6
|
+
import type { FeatureCollection, Polygon } from 'geojson';
|
|
7
|
+
import type { Cell } from '../types';
|
|
8
|
+
/**
|
|
9
|
+
* Convert cells to GeoJSON FeatureCollection with arc geometries and styling properties
|
|
10
|
+
*
|
|
11
|
+
* @param cells - Array of cells to convert
|
|
12
|
+
* @param currentZoom - Current map zoom level for radius calculation
|
|
13
|
+
* @param baseRadius - Base radius in meters before multipliers
|
|
14
|
+
* @param groupColorMap - Optional custom colors for cell groups
|
|
15
|
+
* @returns GeoJSON FeatureCollection with arc polygons
|
|
16
|
+
*/
|
|
17
|
+
export declare function cellsToGeoJSON(cells: Cell[], currentZoom: number, baseRadius?: number, groupColorMap?: Map<string, string>): FeatureCollection<Polygon>;
|
|
18
|
+
/**
|
|
19
|
+
* Helper function to generate group key from cell based on grouping config
|
|
20
|
+
* This will be used when implementing dynamic grouping
|
|
21
|
+
*/
|
|
22
|
+
export declare function getCellGroupKey(cell: Cell, level1Field: string, level2Field?: string): string;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cell GeoJSON Conversion
|
|
3
|
+
*
|
|
4
|
+
* Convert cell data to GeoJSON FeatureCollection with styling properties
|
|
5
|
+
*/
|
|
6
|
+
import { TECHNOLOGY_BAND_COLORS } from '../constants/colors';
|
|
7
|
+
import { DEFAULT_STATUS_STYLES } from '../constants/statusStyles';
|
|
8
|
+
import { calculateRadius } from './zoomScaling';
|
|
9
|
+
import { createArcPolygon } from './arcGeometry';
|
|
10
|
+
/**
|
|
11
|
+
* Convert cells to GeoJSON FeatureCollection with arc geometries and styling properties
|
|
12
|
+
*
|
|
13
|
+
* @param cells - Array of cells to convert
|
|
14
|
+
* @param currentZoom - Current map zoom level for radius calculation
|
|
15
|
+
* @param baseRadius - Base radius in meters before multipliers
|
|
16
|
+
* @param groupColorMap - Optional custom colors for cell groups
|
|
17
|
+
* @returns GeoJSON FeatureCollection with arc polygons
|
|
18
|
+
*/
|
|
19
|
+
export function cellsToGeoJSON(cells, currentZoom, baseRadius = 500, groupColorMap) {
|
|
20
|
+
const features = cells.map((cell) => {
|
|
21
|
+
// Calculate tech-band key for styling
|
|
22
|
+
const techBandKey = `${cell.tech}_${cell.frq}`;
|
|
23
|
+
// Get default tech-band color
|
|
24
|
+
const defaultColor = TECHNOLOGY_BAND_COLORS[techBandKey] || '#cccccc';
|
|
25
|
+
// Get custom group color if available
|
|
26
|
+
// Group key depends on grouping config, for now use tech-band
|
|
27
|
+
const groupKey = techBandKey;
|
|
28
|
+
const groupColor = groupColorMap?.get(groupKey);
|
|
29
|
+
// Get status style
|
|
30
|
+
const statusStyle = DEFAULT_STATUS_STYLES[cell.status] || DEFAULT_STATUS_STYLES['On_Air'];
|
|
31
|
+
// Calculate final radius based on zoom and tech-band
|
|
32
|
+
const radius = calculateRadius(baseRadius, techBandKey, currentZoom);
|
|
33
|
+
// Create arc polygon geometry
|
|
34
|
+
const center = [cell.longitude, cell.latitude];
|
|
35
|
+
const arc = createArcPolygon(center, cell.azimuth, cell.beamwidth, radius);
|
|
36
|
+
// Build feature with styling properties
|
|
37
|
+
return {
|
|
38
|
+
type: 'Feature',
|
|
39
|
+
geometry: arc.geometry,
|
|
40
|
+
properties: {
|
|
41
|
+
// Cell identification
|
|
42
|
+
id: cell.id,
|
|
43
|
+
cellID: cell.cellID,
|
|
44
|
+
cellName: cell.cellName,
|
|
45
|
+
siteId: cell.siteId,
|
|
46
|
+
// Cell attributes
|
|
47
|
+
tech: cell.tech,
|
|
48
|
+
band: cell.frq,
|
|
49
|
+
status: cell.status,
|
|
50
|
+
type: cell.type,
|
|
51
|
+
azimuth: cell.azimuth,
|
|
52
|
+
beamwidth: cell.beamwidth,
|
|
53
|
+
// Styling properties for Mapbox
|
|
54
|
+
techBandKey,
|
|
55
|
+
techBandColor: defaultColor, // Default color from constants
|
|
56
|
+
groupColor: groupColor, // Custom color (if set)
|
|
57
|
+
// Line (border) styling from status
|
|
58
|
+
lineColor: statusStyle.lineColor,
|
|
59
|
+
lineWidth: statusStyle.lineWidth,
|
|
60
|
+
lineOpacity: statusStyle.opacity,
|
|
61
|
+
dashArray: statusStyle.dashArray,
|
|
62
|
+
// Additional metadata for tooltips
|
|
63
|
+
onAirDate: cell.onAirDate,
|
|
64
|
+
comment: cell.comment,
|
|
65
|
+
planner: cell.planner
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
return {
|
|
70
|
+
type: 'FeatureCollection',
|
|
71
|
+
features
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Helper function to generate group key from cell based on grouping config
|
|
76
|
+
* This will be used when implementing dynamic grouping
|
|
77
|
+
*/
|
|
78
|
+
export function getCellGroupKey(cell, level1Field, level2Field) {
|
|
79
|
+
// For now, default to tech-band
|
|
80
|
+
return `${cell.tech}_${cell.frq}`;
|
|
81
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cell Tree Builder
|
|
3
|
+
*
|
|
4
|
+
* Build hierarchical tree structure for cell filtering
|
|
5
|
+
* Structure: Tech → Band → Status → Individual Cells (configurable)
|
|
6
|
+
*/
|
|
7
|
+
import type { Cell, CellTreeConfig } from '../types';
|
|
8
|
+
import type { TreeNode } from '../../../../core/TreeView/tree.model';
|
|
9
|
+
/**
|
|
10
|
+
* Build hierarchical tree from flat cell array with dynamic grouping
|
|
11
|
+
*
|
|
12
|
+
* @param cells - Array of cells to build tree from
|
|
13
|
+
* @param config - Grouping configuration (level1, level2)
|
|
14
|
+
* @param colorMap - Optional map of leaf group IDs to custom colors
|
|
15
|
+
* @returns Root tree node
|
|
16
|
+
*/
|
|
17
|
+
export declare function buildCellTree(cells: Cell[], config: CellTreeConfig, colorMap?: Map<string, string>): TreeNode;
|
|
18
|
+
/**
|
|
19
|
+
* Get filtered cells based on checked tree paths
|
|
20
|
+
*
|
|
21
|
+
* @param checkedPaths - Set of checked node IDs from TreeView
|
|
22
|
+
* @param allCells - All available cells
|
|
23
|
+
* @returns Filtered array of cells
|
|
24
|
+
*/
|
|
25
|
+
export declare function getFilteredCells(checkedPaths: Set<string>, allCells: Cell[]): Cell[];
|