@smartnet360/svelte-components 0.0.95 → 0.0.96
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-v3/features/cells/components/CellSettingsPanel.svelte +20 -0
- package/dist/map-v3/features/cells/layers/CellsLayer.svelte +52 -39
- package/dist/map-v3/features/cells/logic/geometry.js +23 -0
- package/dist/map-v3/features/cells/stores/cell.display.svelte.d.ts +1 -0
- package/dist/map-v3/features/cells/stores/cell.display.svelte.js +3 -0
- package/dist/map-v3/features/cells/types.d.ts +1 -1
- package/package.json +1 -1
|
@@ -111,9 +111,29 @@
|
|
|
111
111
|
<option value="logarithmic">Logarithmic (smooth)</option>
|
|
112
112
|
<option value="percentage">Proportional (40%)</option>
|
|
113
113
|
<option value="tiered">Tiered (4 levels)</option>
|
|
114
|
+
<option value="hybrid">Hybrid (stepped proportional)</option>
|
|
114
115
|
</select>
|
|
115
116
|
</div>
|
|
116
117
|
</div>
|
|
118
|
+
|
|
119
|
+
<!-- Auto Size Base Multiplier -->
|
|
120
|
+
<div class="row align-items-center g-2 mb-3 ps-3">
|
|
121
|
+
<div class="col-4 text-secondary small">Base Size</div>
|
|
122
|
+
<div class="col-3 text-end">
|
|
123
|
+
<span class="badge bg-white text-muted border">{displayStore.autoSizeBase.toFixed(1)}x</span>
|
|
124
|
+
</div>
|
|
125
|
+
<div class="col-5">
|
|
126
|
+
<input
|
|
127
|
+
id="cell-autosize-base-slider"
|
|
128
|
+
type="range"
|
|
129
|
+
class="form-range w-100"
|
|
130
|
+
min="0.3"
|
|
131
|
+
max="2.0"
|
|
132
|
+
step="0.1"
|
|
133
|
+
bind:value={displayStore.autoSizeBase}
|
|
134
|
+
/>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
117
137
|
{/if}
|
|
118
138
|
|
|
119
139
|
<div class="border-top my-3"></div>
|
|
@@ -100,10 +100,14 @@
|
|
|
100
100
|
// Initial setup
|
|
101
101
|
addLayers();
|
|
102
102
|
|
|
103
|
-
// Events for updating
|
|
103
|
+
// Events for updating - conditional based on auto-size
|
|
104
104
|
map.on('style.load', addLayers);
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
|
|
106
|
+
// Only listen to zoom/move events if NOT using auto-size
|
|
107
|
+
if (!displayStore.useAutoSize) {
|
|
108
|
+
map.on('moveend', updateLayer);
|
|
109
|
+
map.on('zoomend', updateLayer);
|
|
110
|
+
}
|
|
107
111
|
|
|
108
112
|
// Cleanup
|
|
109
113
|
return () => {
|
|
@@ -129,6 +133,7 @@
|
|
|
129
133
|
const _layerGrouping = displayStore.layerGrouping;
|
|
130
134
|
const _useAutoSize = displayStore.useAutoSize;
|
|
131
135
|
const _autoSizeMode = displayStore.autoSizeMode;
|
|
136
|
+
const _autoSizeBase = displayStore.autoSizeBase;
|
|
132
137
|
|
|
133
138
|
updateLayer();
|
|
134
139
|
});
|
|
@@ -144,17 +149,17 @@
|
|
|
144
149
|
}
|
|
145
150
|
|
|
146
151
|
function renderCells(map: mapboxgl.Map) {
|
|
147
|
-
const bounds = map.getBounds();
|
|
148
|
-
if (!bounds) return;
|
|
149
|
-
|
|
150
152
|
const zoom = map.getZoom();
|
|
151
153
|
const centerLat = map.getCenter().lat;
|
|
152
154
|
|
|
153
155
|
console.log(`[CellsLayer] Rendering.. Zoom: ${zoom.toFixed(2)}, Cells: ${dataStore.filteredCells.length}`);
|
|
154
156
|
|
|
155
|
-
// 1. Calculate base radius
|
|
157
|
+
// 1. Calculate base radius (only used in manual mode)
|
|
156
158
|
const baseRadiusMeters = calculateRadiusInMeters(centerLat, zoom, displayStore.targetPixelSize);
|
|
157
|
-
|
|
159
|
+
|
|
160
|
+
if (!displayStore.useAutoSize) {
|
|
161
|
+
console.log(`[CellsLayer] Base radius: ${baseRadiusMeters.toFixed(2)}m for target ${displayStore.targetPixelSize}px`);
|
|
162
|
+
}
|
|
158
163
|
|
|
159
164
|
// 2. Group cells (Level 1=Tech, Level 2=Band for now hardcoded)
|
|
160
165
|
// In real app, this comes from a store
|
|
@@ -173,43 +178,51 @@
|
|
|
173
178
|
if (!style.visible) continue;
|
|
174
179
|
|
|
175
180
|
for (const cell of cells) {
|
|
176
|
-
// 4. BBox Filter
|
|
177
|
-
if (
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
// 6. Calculate radius with z-index scaling
|
|
183
|
-
const MAX_Z = 35;
|
|
184
|
-
let radiusMeters: number;
|
|
185
|
-
|
|
186
|
-
if (displayStore.useAutoSize) {
|
|
187
|
-
// Auto-size mode: get target radius for this site
|
|
188
|
-
const siteDistance = dataStore.siteDistanceStore.getDistance(cell.siteId, 500);
|
|
189
|
-
const autoRadius = calculateAutoRadius(siteDistance, displayStore.autoSizeMode);
|
|
190
|
-
|
|
191
|
-
// Scale based on z-index for stacking visibility
|
|
192
|
-
// Lower z-index (background) = larger, higher z-index (foreground) = smaller
|
|
193
|
-
const scaleFactor = 1 + Math.max(0, MAX_Z - zIndex) * 0.08; // 8% per layer
|
|
194
|
-
radiusMeters = autoRadius * scaleFactor;
|
|
195
|
-
} else {
|
|
196
|
-
// Manual mode: base from pixel size, then scale by z-index
|
|
197
|
-
const scaleFactor = 1 + Math.max(0, MAX_Z - zIndex) * 0.08;
|
|
198
|
-
radiusMeters = baseRadiusMeters * scaleFactor;
|
|
181
|
+
// 4. BBox Filter - SKIP if auto-size is enabled
|
|
182
|
+
if (!displayStore.useAutoSize) {
|
|
183
|
+
const bounds = map.getBounds();
|
|
184
|
+
if (!bounds || !bounds.contains([cell.longitude, cell.latitude])) {
|
|
185
|
+
continue;
|
|
199
186
|
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// 5. Z-Index Lookup
|
|
190
|
+
const zIndexKey = `${cell.tech}_${cell.frq}` as TechnologyBandKey;
|
|
191
|
+
const zIndex = displayStore.currentZIndex[zIndexKey] ?? 10;
|
|
192
|
+
|
|
193
|
+
// 6. Calculate radius with z-index scaling
|
|
194
|
+
const MAX_Z = 35;
|
|
195
|
+
let radiusMeters: number;
|
|
196
|
+
|
|
197
|
+
if (displayStore.useAutoSize) {
|
|
198
|
+
// Auto-size mode: get target radius for this site
|
|
199
|
+
const siteDistance = dataStore.siteDistanceStore.getDistance(cell.siteId, 500);
|
|
200
|
+
const autoRadius = calculateAutoRadius(siteDistance, displayStore.autoSizeMode);
|
|
201
|
+
|
|
202
|
+
// Apply base size multiplier
|
|
203
|
+
const baseAdjusted = autoRadius * displayStore.autoSizeBase;
|
|
204
|
+
|
|
205
|
+
// Scale based on z-index for stacking visibility
|
|
206
|
+
// Lower z-index (background) = larger, higher z-index (foreground) = smaller
|
|
207
|
+
const scaleFactor = 1 + Math.max(0, MAX_Z - zIndex) * 0.08; // 8% per layer
|
|
208
|
+
radiusMeters = baseAdjusted * scaleFactor;
|
|
209
|
+
} else {
|
|
210
|
+
// Manual mode: base from pixel size, then scale by z-index
|
|
211
|
+
const scaleFactor = 1 + Math.max(0, MAX_Z - zIndex) * 0.08;
|
|
212
|
+
radiusMeters = baseRadiusMeters * scaleFactor;
|
|
213
|
+
}
|
|
200
214
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
215
|
+
// 7. Apply beamwidth boost from displayStore preset
|
|
216
|
+
const beamwidthBoost = displayStore.currentBeamwidthBoost[zIndexKey] || 0;
|
|
217
|
+
const adjustedBeamwidth = cell.beamwidth + beamwidthBoost;
|
|
204
218
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
219
|
+
// 8. Generate Arc
|
|
220
|
+
const feature = generateCellArc(cell, radiusMeters, zIndex, style.color, adjustedBeamwidth);
|
|
221
|
+
features.push(feature);
|
|
209
222
|
}
|
|
210
223
|
}
|
|
211
224
|
|
|
212
|
-
console.log(`[CellsLayer] Generated ${features.length} features in view`);
|
|
225
|
+
console.log(`[CellsLayer] Generated ${features.length} features ${displayStore.useAutoSize ? '(all cells)' : 'in view'}`);
|
|
213
226
|
|
|
214
227
|
// 8. Update Source
|
|
215
228
|
const source = map.getSource(sourceId) as mapboxgl.GeoJSONSource;
|
|
@@ -38,6 +38,29 @@ export function calculateAutoRadius(nearestSiteDistance, mode = 'logarithmic') {
|
|
|
38
38
|
return 120;
|
|
39
39
|
return 180;
|
|
40
40
|
}
|
|
41
|
+
case 'hybrid': {
|
|
42
|
+
// Stepped proportional - tiers with proportional scaling within each tier
|
|
43
|
+
if (nearestSiteDistance < 300) {
|
|
44
|
+
// Tier 1: 0-300m → 30-50m radius
|
|
45
|
+
const ratio = nearestSiteDistance / 300;
|
|
46
|
+
return 30 + (ratio * 20);
|
|
47
|
+
}
|
|
48
|
+
else if (nearestSiteDistance < 600) {
|
|
49
|
+
// Tier 2: 300-600m → 50-80m radius
|
|
50
|
+
const ratio = (nearestSiteDistance - 300) / 300;
|
|
51
|
+
return 50 + (ratio * 30);
|
|
52
|
+
}
|
|
53
|
+
else if (nearestSiteDistance < 1200) {
|
|
54
|
+
// Tier 3: 600-1200m → 80-120m radius
|
|
55
|
+
const ratio = (nearestSiteDistance - 600) / 600;
|
|
56
|
+
return 80 + (ratio * 40);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// Tier 4: 1200m+ → 120-180m radius
|
|
60
|
+
const ratio = Math.min((nearestSiteDistance - 1200) / 1200, 1);
|
|
61
|
+
return 120 + (ratio * 60);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
41
64
|
default:
|
|
42
65
|
return 80;
|
|
43
66
|
}
|
|
@@ -11,6 +11,7 @@ export class CellDisplayStore {
|
|
|
11
11
|
// Auto-size settings
|
|
12
12
|
useAutoSize = $state(false);
|
|
13
13
|
autoSizeMode = $state('logarithmic');
|
|
14
|
+
autoSizeBase = $state(1.0);
|
|
14
15
|
// Grouping
|
|
15
16
|
level1 = $state('tech');
|
|
16
17
|
level2 = $state('fband');
|
|
@@ -40,6 +41,7 @@ export class CellDisplayStore {
|
|
|
40
41
|
this.layerGrouping = parsed.layerGrouping ?? 'frequency';
|
|
41
42
|
this.useAutoSize = parsed.useAutoSize ?? false;
|
|
42
43
|
this.autoSizeMode = parsed.autoSizeMode ?? 'logarithmic';
|
|
44
|
+
this.autoSizeBase = parsed.autoSizeBase ?? 1.0;
|
|
43
45
|
this.level1 = parsed.level1 ?? 'tech';
|
|
44
46
|
this.level2 = parsed.level2 ?? 'fband';
|
|
45
47
|
this.labelPixelDistance = parsed.labelPixelDistance ?? 60;
|
|
@@ -64,6 +66,7 @@ export class CellDisplayStore {
|
|
|
64
66
|
layerGrouping: this.layerGrouping,
|
|
65
67
|
useAutoSize: this.useAutoSize,
|
|
66
68
|
autoSizeMode: this.autoSizeMode,
|
|
69
|
+
autoSizeBase: this.autoSizeBase,
|
|
67
70
|
level1: this.level1,
|
|
68
71
|
level2: this.level2,
|
|
69
72
|
labelPixelDistance: this.labelPixelDistance,
|
|
@@ -63,7 +63,7 @@ export type CellGroupingField = 'tech' | 'fband' | 'frq' | 'status' | 'siteId' |
|
|
|
63
63
|
/**
|
|
64
64
|
* Auto-size calculation modes
|
|
65
65
|
*/
|
|
66
|
-
export type AutoSizeMode = 'logarithmic' | 'percentage' | 'tiered';
|
|
66
|
+
export type AutoSizeMode = 'logarithmic' | 'percentage' | 'tiered' | 'hybrid';
|
|
67
67
|
/**
|
|
68
68
|
* Site distance data for auto-sizing
|
|
69
69
|
*/
|