raintee-maputils 1.0.51 → 1.0.52
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/index.js +218 -184
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -21432,7 +21432,10 @@ class CustomToggleControl {
|
|
|
21432
21432
|
class RasterLayerControl {
|
|
21433
21433
|
constructor() {
|
|
21434
21434
|
this._panel = null;
|
|
21435
|
+
this._dialog = null;
|
|
21436
|
+
this._layerListContainer = null;
|
|
21435
21437
|
this._isOpen = false;
|
|
21438
|
+
this._tempLayers = [];
|
|
21436
21439
|
}
|
|
21437
21440
|
|
|
21438
21441
|
onAdd(map) {
|
|
@@ -21445,21 +21448,22 @@ class RasterLayerControl {
|
|
|
21445
21448
|
this._button.type = 'button';
|
|
21446
21449
|
this._button.innerHTML = '底图:初始化中';
|
|
21447
21450
|
this._button.style.cssText = `
|
|
21448
|
-
|
|
21449
|
-
|
|
21450
|
-
|
|
21451
|
-
|
|
21452
|
-
|
|
21453
|
-
|
|
21454
|
-
|
|
21455
|
-
|
|
21456
|
-
|
|
21457
|
-
|
|
21458
|
-
|
|
21459
|
-
|
|
21460
|
-
|
|
21461
|
-
|
|
21462
|
-
|
|
21451
|
+
width: 100%;
|
|
21452
|
+
padding: 6px 10px;
|
|
21453
|
+
margin: 0;
|
|
21454
|
+
font-size: 14px;
|
|
21455
|
+
font-family: Arial, sans-serif;
|
|
21456
|
+
background: #f8f9fa;
|
|
21457
|
+
color: #333;
|
|
21458
|
+
border: 1px solid #dee2e6;
|
|
21459
|
+
border-radius: 4px;
|
|
21460
|
+
cursor: pointer;
|
|
21461
|
+
text-align: left;
|
|
21462
|
+
white-space: nowrap;
|
|
21463
|
+
box-sizing: border-box;
|
|
21464
|
+
line-height: 1.4;
|
|
21465
|
+
`;
|
|
21466
|
+
|
|
21463
21467
|
this._button.addEventListener('mouseenter', () => {
|
|
21464
21468
|
this._button.style.background = '#e9ecef';
|
|
21465
21469
|
});
|
|
@@ -21467,26 +21471,17 @@ class RasterLayerControl {
|
|
|
21467
21471
|
this._button.style.background = '#f8f9fa';
|
|
21468
21472
|
});
|
|
21469
21473
|
|
|
21470
|
-
this._container.appendChild(this._button);
|
|
21471
|
-
|
|
21472
21474
|
this._button.addEventListener('click', () => {
|
|
21473
21475
|
this._togglePanel();
|
|
21474
21476
|
});
|
|
21475
21477
|
|
|
21476
|
-
this.
|
|
21477
|
-
this._updateRasterLayers();
|
|
21478
|
-
|
|
21479
|
-
});
|
|
21480
|
-
|
|
21481
|
-
this._map.on('styledata', () => {
|
|
21482
|
-
this._updateRasterLayers();
|
|
21483
|
-
});
|
|
21478
|
+
this._container.appendChild(this._button);
|
|
21484
21479
|
|
|
21485
|
-
this._map.on('
|
|
21486
|
-
|
|
21487
|
-
|
|
21480
|
+
this._map.on('idle', () => this._updateButtonText());
|
|
21481
|
+
this._map.on('styledata', () => this._updateButtonText());
|
|
21482
|
+
this._map.on('sourcedata', () => this._updateButtonText());
|
|
21488
21483
|
|
|
21489
|
-
this.
|
|
21484
|
+
this._updateButtonText();
|
|
21490
21485
|
|
|
21491
21486
|
return this._container;
|
|
21492
21487
|
}
|
|
@@ -21498,20 +21493,26 @@ class RasterLayerControl {
|
|
|
21498
21493
|
if (this._container && this._container.parentNode) {
|
|
21499
21494
|
this._container.parentNode.removeChild(this._container);
|
|
21500
21495
|
}
|
|
21496
|
+
this._map = undefined;
|
|
21501
21497
|
}
|
|
21502
21498
|
|
|
21503
21499
|
_togglePanel() {
|
|
21504
|
-
|
|
21505
|
-
this._closePanel();
|
|
21506
|
-
} else {
|
|
21507
|
-
this._openPanel();
|
|
21508
|
-
}
|
|
21500
|
+
this._isOpen ? this._closePanel() : this._openPanel();
|
|
21509
21501
|
}
|
|
21510
21502
|
|
|
21511
21503
|
_openPanel() {
|
|
21512
21504
|
this._createPanelIfNeeded();
|
|
21513
|
-
|
|
21514
|
-
this.
|
|
21505
|
+
|
|
21506
|
+
const layers = this._map.getStyle().layers || [];
|
|
21507
|
+
const rasterLayers = layers.filter(l => l.type === 'raster');
|
|
21508
|
+
|
|
21509
|
+
this._tempLayers = rasterLayers.map(l => ({
|
|
21510
|
+
id: l.id,
|
|
21511
|
+
visible: this._map.getLayoutProperty(l.id, 'visibility') !== 'none'
|
|
21512
|
+
}));
|
|
21513
|
+
|
|
21514
|
+
this._renderLayerList();
|
|
21515
|
+
this._panel.style.display = 'flex';
|
|
21515
21516
|
this._isOpen = true;
|
|
21516
21517
|
}
|
|
21517
21518
|
|
|
@@ -21523,171 +21524,204 @@ class RasterLayerControl {
|
|
|
21523
21524
|
}
|
|
21524
21525
|
|
|
21525
21526
|
_createPanelIfNeeded() {
|
|
21526
|
-
if (
|
|
21527
|
-
|
|
21528
|
-
|
|
21529
|
-
|
|
21530
|
-
|
|
21531
|
-
|
|
21532
|
-
|
|
21533
|
-
|
|
21534
|
-
|
|
21535
|
-
|
|
21536
|
-
|
|
21537
|
-
|
|
21538
|
-
|
|
21539
|
-
|
|
21540
|
-
|
|
21541
|
-
|
|
21542
|
-
|
|
21543
|
-
|
|
21544
|
-
|
|
21545
|
-
|
|
21546
|
-
|
|
21547
|
-
|
|
21548
|
-
|
|
21549
|
-
|
|
21550
|
-
|
|
21551
|
-
|
|
21552
|
-
|
|
21553
|
-
|
|
21554
|
-
|
|
21555
|
-
|
|
21556
|
-
|
|
21557
|
-
|
|
21558
|
-
|
|
21559
|
-
|
|
21560
|
-
|
|
21561
|
-
|
|
21562
|
-
|
|
21563
|
-
|
|
21564
|
-
|
|
21565
|
-
|
|
21566
|
-
|
|
21567
|
-
|
|
21568
|
-
|
|
21569
|
-
|
|
21570
|
-
this._dialog.appendChild(title);
|
|
21571
|
-
|
|
21572
|
-
// 图层列表容器(原 _layerListContainer)
|
|
21573
|
-
this._layerListContainer = document.createElement('div');
|
|
21574
|
-
this._layerListContainer.style.cssText = `
|
|
21575
|
-
width: 100%;
|
|
21576
|
-
max-height: 60vh;
|
|
21577
|
-
display: flex;
|
|
21578
|
-
flex-direction: column;
|
|
21579
|
-
gap: 4px;
|
|
21580
|
-
overflow-y: auto;
|
|
21581
|
-
overflow-x: hidden;
|
|
21582
|
-
`;
|
|
21583
|
-
this._dialog.appendChild(this._layerListContainer);
|
|
21584
|
-
|
|
21585
|
-
// // 关闭按钮(可选增强)
|
|
21586
|
-
// const closeButton = document.createElement('button');
|
|
21587
|
-
// closeButton.textContent = '✅ 关闭';
|
|
21588
|
-
// closeButton.style.cssText = `
|
|
21589
|
-
// margin-left: auto;
|
|
21590
|
-
// margin-right: auto;
|
|
21591
|
-
// margin-top: 15px;
|
|
21592
|
-
// padding: 6px 12px;
|
|
21593
|
-
// background: #6c757d;
|
|
21594
|
-
// color: white;
|
|
21595
|
-
// border: none;
|
|
21596
|
-
// border-radius: 4px;
|
|
21597
|
-
// cursor: pointer;
|
|
21598
|
-
// `;
|
|
21599
|
-
// closeButton.addEventListener('click', () => {
|
|
21600
|
-
// this._closePanel();
|
|
21601
|
-
// });
|
|
21602
|
-
// this._dialog.appendChild(closeButton);
|
|
21603
|
-
|
|
21604
|
-
this._panel.appendChild(this._dialog);
|
|
21605
|
-
document.body.appendChild(this._panel);
|
|
21606
|
-
|
|
21607
|
-
// 点击背景遮罩关闭弹窗(增强用户体验,可选)
|
|
21608
|
-
this._panel.addEventListener('click', (e) => {
|
|
21609
|
-
// 只有点击背景遮罩部分才关闭,点击对话框内容不关闭
|
|
21610
|
-
if (e.target === this._panel) {
|
|
21611
|
-
this._closePanel();
|
|
21612
|
-
}
|
|
21613
|
-
});
|
|
21614
|
-
}
|
|
21615
|
-
}
|
|
21616
|
-
|
|
21617
|
-
_updateRasterLayers() {
|
|
21527
|
+
if (this._panel) return;
|
|
21528
|
+
|
|
21529
|
+
// 遮罩
|
|
21530
|
+
this._panel = document.createElement('div');
|
|
21531
|
+
this._panel.style.cssText = `
|
|
21532
|
+
position: fixed;
|
|
21533
|
+
top: 0; left: 0;
|
|
21534
|
+
width: 100vw; height: 100vh;
|
|
21535
|
+
background: rgba(0,0,0,0.45);
|
|
21536
|
+
display: none;
|
|
21537
|
+
align-items: center;
|
|
21538
|
+
justify-content: center;
|
|
21539
|
+
z-index: 10000;
|
|
21540
|
+
`;
|
|
21541
|
+
|
|
21542
|
+
|
|
21543
|
+
// 对话框
|
|
21544
|
+
this._dialog = document.createElement('div');
|
|
21545
|
+
this._dialog.style.cssText = `
|
|
21546
|
+
position: relative;
|
|
21547
|
+
background: #fff;
|
|
21548
|
+
padding: 16px;
|
|
21549
|
+
border-radius: 10px; /* 稍微更柔和 */
|
|
21550
|
+
min-width: 320px;
|
|
21551
|
+
max-width: 520px;
|
|
21552
|
+
max-height: 75vh; /* 🔥 再低一点,留呼吸感 */
|
|
21553
|
+
overflow: hidden; /* 防止整体溢出 */
|
|
21554
|
+
display: flex;
|
|
21555
|
+
flex-direction: column;
|
|
21556
|
+
box-shadow: 0 6px 18px rgba(0,0,0,.22);
|
|
21557
|
+
font-family: Arial, sans-serif;
|
|
21558
|
+
`;
|
|
21559
|
+
|
|
21560
|
+
|
|
21561
|
+
|
|
21562
|
+
|
|
21563
|
+
// 标题
|
|
21564
|
+
const title = document.createElement('div');
|
|
21565
|
+
title.textContent = '🗂 管理栅格底图';
|
|
21566
|
+
title.style.cssText = `
|
|
21567
|
+
font-weight: bold;
|
|
21568
|
+
margin-bottom: 8px;
|
|
21569
|
+
font-size: 15px;
|
|
21570
|
+
`;
|
|
21618
21571
|
|
|
21619
|
-
|
|
21620
|
-
|
|
21572
|
+
// 列表容器
|
|
21573
|
+
this._layerListContainer = document.createElement('div');
|
|
21574
|
+
this._layerListContainer.style.cssText = `
|
|
21575
|
+
width: 100%;
|
|
21576
|
+
max-height: 50vh; /* 🔥 核心:最多占屏幕一半高度 */
|
|
21577
|
+
overflow-y: auto; /* 🔥 超出滚动 */
|
|
21578
|
+
overflow-x: hidden;
|
|
21579
|
+
display: flex;
|
|
21580
|
+
flex-direction: column;
|
|
21581
|
+
gap: 6px;
|
|
21582
|
+
padding: 4px 2px;
|
|
21583
|
+
box-sizing: border-box;
|
|
21584
|
+
border-top: 1px solid #eee;
|
|
21585
|
+
border-bottom: 1px solid #eee;
|
|
21586
|
+
`;
|
|
21587
|
+
|
|
21588
|
+
|
|
21589
|
+
|
|
21590
|
+
this._dialog.appendChild(title);
|
|
21591
|
+
this._dialog.appendChild(this._layerListContainer);
|
|
21592
|
+
this._panel.appendChild(this._dialog);
|
|
21593
|
+
document.body.appendChild(this._panel);
|
|
21621
21594
|
|
|
21622
|
-
|
|
21623
|
-
|
|
21595
|
+
// 点击遮罩关闭
|
|
21596
|
+
this._panel.addEventListener('click', (e) => {
|
|
21597
|
+
if (e.target === this._panel) this._closePanel();
|
|
21598
|
+
});
|
|
21599
|
+
}
|
|
21624
21600
|
|
|
21625
|
-
|
|
21626
|
-
|
|
21627
|
-
|
|
21628
|
-
if (visibility === 'visible') {
|
|
21629
|
-
firstVisibleLayerId = layer.id;
|
|
21630
|
-
break;
|
|
21631
|
-
}
|
|
21632
|
-
}
|
|
21601
|
+
_renderLayerList() {
|
|
21602
|
+
if (!this._layerListContainer) return;
|
|
21603
|
+
this._layerListContainer.innerHTML = '';
|
|
21633
21604
|
|
|
21634
|
-
if (
|
|
21635
|
-
|
|
21636
|
-
|
|
21637
|
-
buttonText = '底图:无';
|
|
21605
|
+
if (!this._tempLayers.length) {
|
|
21606
|
+
this._layerListContainer.textContent = '无可选栅格图层';
|
|
21607
|
+
return;
|
|
21638
21608
|
}
|
|
21639
21609
|
|
|
21640
|
-
this.
|
|
21641
|
-
|
|
21642
|
-
// 清空旧的图层列表
|
|
21643
|
-
if (this._layerListContainer) { this._layerListContainer.innerHTML = ''; }
|
|
21644
|
-
rasterLayers.forEach(layer => {
|
|
21645
|
-
const layerId = layer.id;
|
|
21610
|
+
this._tempLayers.forEach((layer, index) => {
|
|
21646
21611
|
const row = document.createElement('div');
|
|
21647
21612
|
row.style.cssText = `
|
|
21648
|
-
|
|
21649
|
-
|
|
21650
|
-
|
|
21651
|
-
|
|
21652
|
-
|
|
21653
|
-
|
|
21654
|
-
|
|
21613
|
+
display: flex;
|
|
21614
|
+
align-items: center;
|
|
21615
|
+
gap: 6px;
|
|
21616
|
+
padding: 6px 8px;
|
|
21617
|
+
background: #f8f9fa;
|
|
21618
|
+
border-radius: 4px;
|
|
21619
|
+
`;
|
|
21655
21620
|
|
|
21656
|
-
|
|
21657
|
-
|
|
21658
|
-
|
|
21659
|
-
|
|
21660
|
-
|
|
21661
|
-
|
|
21621
|
+
const checkbox = document.createElement('input');
|
|
21622
|
+
checkbox.type = 'checkbox';
|
|
21623
|
+
checkbox.checked = layer.visible;
|
|
21624
|
+
|
|
21625
|
+
checkbox.onchange = () => {
|
|
21626
|
+
layer.visible = checkbox.checked;
|
|
21627
|
+
|
|
21628
|
+
// 🔥 立刻在地图中生效
|
|
21629
|
+
this._map.setLayoutProperty(
|
|
21630
|
+
layer.id,
|
|
21631
|
+
'visibility',
|
|
21632
|
+
layer.visible ? 'visible' : 'none'
|
|
21633
|
+
);
|
|
21634
|
+
|
|
21635
|
+
// 🔄 同步按钮文字
|
|
21636
|
+
this._updateButtonText();
|
|
21637
|
+
};
|
|
21662
21638
|
|
|
21663
|
-
// 更新按钮文字
|
|
21664
|
-
if (this._button) {
|
|
21665
|
-
this._button.innerHTML = `底图:${layerId}`;
|
|
21666
|
-
}
|
|
21667
|
-
this._togglePanel();
|
|
21668
|
-
});
|
|
21669
21639
|
|
|
21670
|
-
// 鼠标 hover 效果
|
|
21671
|
-
row.addEventListener('mouseenter', () => {
|
|
21672
|
-
row.style.background = '#e9ecef';
|
|
21673
|
-
});
|
|
21674
|
-
row.addEventListener('mouseleave', () => {
|
|
21675
|
-
row.style.background = '#f8f9fa';
|
|
21676
|
-
});
|
|
21677
21640
|
|
|
21678
|
-
// 显示图层 ID(可加样式或 icon)
|
|
21679
21641
|
const label = document.createElement('span');
|
|
21680
|
-
label.textContent =
|
|
21681
|
-
label.style.
|
|
21682
|
-
|
|
21683
|
-
|
|
21642
|
+
label.textContent = layer.id;
|
|
21643
|
+
label.style.cssText = `
|
|
21644
|
+
flex: 1;
|
|
21645
|
+
font-size: 13px;
|
|
21646
|
+
color: #333;
|
|
21647
|
+
overflow: hidden;
|
|
21648
|
+
text-overflow: ellipsis;
|
|
21649
|
+
white-space: nowrap;
|
|
21650
|
+
`;
|
|
21684
21651
|
|
|
21652
|
+
const upBtn = document.createElement('button');
|
|
21653
|
+
upBtn.textContent = '↑';
|
|
21654
|
+
upBtn.disabled = index === 0;
|
|
21655
|
+
upBtn.onclick = () => this._moveTempLayer(index, index - 1);
|
|
21656
|
+
|
|
21657
|
+
const downBtn = document.createElement('button');
|
|
21658
|
+
downBtn.textContent = '↓';
|
|
21659
|
+
downBtn.disabled = index === this._tempLayers.length - 1;
|
|
21660
|
+
downBtn.onclick = () => this._moveTempLayer(index, index + 1);
|
|
21661
|
+
|
|
21662
|
+
[upBtn, downBtn].forEach(btn => {
|
|
21663
|
+
btn.style.cssText = `
|
|
21664
|
+
padding: 2px 6px;
|
|
21665
|
+
border: 1px solid #ccc;
|
|
21666
|
+
background: #fff;
|
|
21667
|
+
border-radius: 3px;
|
|
21668
|
+
cursor: pointer;
|
|
21669
|
+
`;
|
|
21670
|
+
});
|
|
21671
|
+
|
|
21672
|
+
row.appendChild(checkbox);
|
|
21685
21673
|
row.appendChild(label);
|
|
21686
|
-
|
|
21674
|
+
row.appendChild(upBtn);
|
|
21675
|
+
row.appendChild(downBtn);
|
|
21676
|
+
this._layerListContainer.appendChild(row);
|
|
21687
21677
|
});
|
|
21688
|
-
|
|
21689
|
-
|
|
21678
|
+
}
|
|
21679
|
+
|
|
21680
|
+
_moveTempLayer(from, to) {
|
|
21681
|
+
const item = this._tempLayers.splice(from, 1)[0];
|
|
21682
|
+
this._tempLayers.splice(to, 0, item);
|
|
21683
|
+
|
|
21684
|
+
// ✅ 按 Mapbox 官方语义:从“最上层”往下重排
|
|
21685
|
+
for (let i = this._tempLayers.length - 1; i >= 0; i--) {
|
|
21686
|
+
const layerId = this._tempLayers[i].id;
|
|
21687
|
+
const beforeId =
|
|
21688
|
+
i === this._tempLayers.length - 1
|
|
21689
|
+
? undefined // 最上面的图层:移到最顶
|
|
21690
|
+
: this._tempLayers[i + 1].id;
|
|
21691
|
+
|
|
21692
|
+
// 关键防御:避免 moveLayer 自己到自己前面
|
|
21693
|
+
if (beforeId && beforeId === layerId) continue;
|
|
21694
|
+
|
|
21695
|
+
this._map.moveLayer(layerId, beforeId);
|
|
21696
|
+
}
|
|
21697
|
+
|
|
21698
|
+
this._renderLayerList();
|
|
21699
|
+
}
|
|
21700
|
+
|
|
21701
|
+
|
|
21702
|
+
_applyChanges() {
|
|
21703
|
+
// 现在不再做任何地图操作,只是关闭面板
|
|
21704
|
+
this._closePanel();
|
|
21705
|
+
}
|
|
21706
|
+
|
|
21707
|
+
|
|
21708
|
+
_updateButtonText() {
|
|
21709
|
+
if (!this._map) return;
|
|
21710
|
+
|
|
21711
|
+
const layers = this._map.getStyle().layers || [];
|
|
21712
|
+
const rasterLayers = layers.filter(l => l.type === 'raster');
|
|
21713
|
+
|
|
21714
|
+
let firstVisible = null;
|
|
21715
|
+
for (const layer of rasterLayers) {
|
|
21716
|
+
if (this._map.getLayoutProperty(layer.id, 'visibility') === 'visible') {
|
|
21717
|
+
firstVisible = layer.id;
|
|
21718
|
+
break;
|
|
21719
|
+
}
|
|
21690
21720
|
}
|
|
21721
|
+
|
|
21722
|
+
this._button.innerHTML = firstVisible
|
|
21723
|
+
? `底图:${firstVisible}`
|
|
21724
|
+
: rasterLayers.length ? '底图:无' : '底图:无栅格图层';
|
|
21691
21725
|
}
|
|
21692
21726
|
}
|
|
21693
21727
|
|