raintee-maputils 1.0.50 → 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 +221 -186
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6505,7 +6505,7 @@ class RulerControl {
|
|
|
6505
6505
|
this.removeDragEvents = null;
|
|
6506
6506
|
if (!this.options.invisible) {
|
|
6507
6507
|
this.button = controlButton({
|
|
6508
|
-
title: 'Ruler',
|
|
6508
|
+
title: this.options.title || 'Ruler',
|
|
6509
6509
|
icon: icons.ruler(),
|
|
6510
6510
|
onClick: () => this.onControlButtonClick(),
|
|
6511
6511
|
});
|
|
@@ -7340,6 +7340,7 @@ class CustomSearchSelectControl {
|
|
|
7340
7340
|
onCancel: () => { },
|
|
7341
7341
|
placeholder: '搜索...',
|
|
7342
7342
|
title: '选择',
|
|
7343
|
+
cancelButtonText: '取消',
|
|
7343
7344
|
showSearch: true,
|
|
7344
7345
|
compactMode: true, // 新增:紧凑模式
|
|
7345
7346
|
maxHeight: '100vh', // 新增:最大高度
|
|
@@ -7642,7 +7643,7 @@ class CustomSearchSelectControl {
|
|
|
7642
7643
|
`;
|
|
7643
7644
|
|
|
7644
7645
|
const cancelBtn = document.createElement('button');
|
|
7645
|
-
cancelBtn.textContent =
|
|
7646
|
+
cancelBtn.textContent = this.options.cancelButtonText;
|
|
7646
7647
|
cancelBtn.className = 'vector-layer-cancel';
|
|
7647
7648
|
cancelBtn.style.cssText = `
|
|
7648
7649
|
padding: ${this._isMobile ? '6px 12px' : '6px 16px'};
|
|
@@ -21431,7 +21432,10 @@ class CustomToggleControl {
|
|
|
21431
21432
|
class RasterLayerControl {
|
|
21432
21433
|
constructor() {
|
|
21433
21434
|
this._panel = null;
|
|
21435
|
+
this._dialog = null;
|
|
21436
|
+
this._layerListContainer = null;
|
|
21434
21437
|
this._isOpen = false;
|
|
21438
|
+
this._tempLayers = [];
|
|
21435
21439
|
}
|
|
21436
21440
|
|
|
21437
21441
|
onAdd(map) {
|
|
@@ -21444,21 +21448,22 @@ class RasterLayerControl {
|
|
|
21444
21448
|
this._button.type = 'button';
|
|
21445
21449
|
this._button.innerHTML = '底图:初始化中';
|
|
21446
21450
|
this._button.style.cssText = `
|
|
21447
|
-
|
|
21448
|
-
|
|
21449
|
-
|
|
21450
|
-
|
|
21451
|
-
|
|
21452
|
-
|
|
21453
|
-
|
|
21454
|
-
|
|
21455
|
-
|
|
21456
|
-
|
|
21457
|
-
|
|
21458
|
-
|
|
21459
|
-
|
|
21460
|
-
|
|
21461
|
-
|
|
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
|
+
|
|
21462
21467
|
this._button.addEventListener('mouseenter', () => {
|
|
21463
21468
|
this._button.style.background = '#e9ecef';
|
|
21464
21469
|
});
|
|
@@ -21466,26 +21471,17 @@ class RasterLayerControl {
|
|
|
21466
21471
|
this._button.style.background = '#f8f9fa';
|
|
21467
21472
|
});
|
|
21468
21473
|
|
|
21469
|
-
this._container.appendChild(this._button);
|
|
21470
|
-
|
|
21471
21474
|
this._button.addEventListener('click', () => {
|
|
21472
21475
|
this._togglePanel();
|
|
21473
21476
|
});
|
|
21474
21477
|
|
|
21475
|
-
this.
|
|
21476
|
-
this._updateRasterLayers();
|
|
21477
|
-
|
|
21478
|
-
});
|
|
21479
|
-
|
|
21480
|
-
this._map.on('styledata', () => {
|
|
21481
|
-
this._updateRasterLayers();
|
|
21482
|
-
});
|
|
21478
|
+
this._container.appendChild(this._button);
|
|
21483
21479
|
|
|
21484
|
-
this._map.on('
|
|
21485
|
-
|
|
21486
|
-
|
|
21480
|
+
this._map.on('idle', () => this._updateButtonText());
|
|
21481
|
+
this._map.on('styledata', () => this._updateButtonText());
|
|
21482
|
+
this._map.on('sourcedata', () => this._updateButtonText());
|
|
21487
21483
|
|
|
21488
|
-
this.
|
|
21484
|
+
this._updateButtonText();
|
|
21489
21485
|
|
|
21490
21486
|
return this._container;
|
|
21491
21487
|
}
|
|
@@ -21497,20 +21493,26 @@ class RasterLayerControl {
|
|
|
21497
21493
|
if (this._container && this._container.parentNode) {
|
|
21498
21494
|
this._container.parentNode.removeChild(this._container);
|
|
21499
21495
|
}
|
|
21496
|
+
this._map = undefined;
|
|
21500
21497
|
}
|
|
21501
21498
|
|
|
21502
21499
|
_togglePanel() {
|
|
21503
|
-
|
|
21504
|
-
this._closePanel();
|
|
21505
|
-
} else {
|
|
21506
|
-
this._openPanel();
|
|
21507
|
-
}
|
|
21500
|
+
this._isOpen ? this._closePanel() : this._openPanel();
|
|
21508
21501
|
}
|
|
21509
21502
|
|
|
21510
21503
|
_openPanel() {
|
|
21511
21504
|
this._createPanelIfNeeded();
|
|
21512
|
-
|
|
21513
|
-
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';
|
|
21514
21516
|
this._isOpen = true;
|
|
21515
21517
|
}
|
|
21516
21518
|
|
|
@@ -21522,171 +21524,204 @@ class RasterLayerControl {
|
|
|
21522
21524
|
}
|
|
21523
21525
|
|
|
21524
21526
|
_createPanelIfNeeded() {
|
|
21525
|
-
if (
|
|
21526
|
-
|
|
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
|
-
this._dialog.appendChild(title);
|
|
21570
|
-
|
|
21571
|
-
// 图层列表容器(原 _layerListContainer)
|
|
21572
|
-
this._layerListContainer = document.createElement('div');
|
|
21573
|
-
this._layerListContainer.style.cssText = `
|
|
21574
|
-
width: 100%;
|
|
21575
|
-
max-height: 60vh;
|
|
21576
|
-
display: flex;
|
|
21577
|
-
flex-direction: column;
|
|
21578
|
-
gap: 4px;
|
|
21579
|
-
overflow-y: auto;
|
|
21580
|
-
overflow-x: hidden;
|
|
21581
|
-
`;
|
|
21582
|
-
this._dialog.appendChild(this._layerListContainer);
|
|
21583
|
-
|
|
21584
|
-
// // 关闭按钮(可选增强)
|
|
21585
|
-
// const closeButton = document.createElement('button');
|
|
21586
|
-
// closeButton.textContent = '✅ 关闭';
|
|
21587
|
-
// closeButton.style.cssText = `
|
|
21588
|
-
// margin-left: auto;
|
|
21589
|
-
// margin-right: auto;
|
|
21590
|
-
// margin-top: 15px;
|
|
21591
|
-
// padding: 6px 12px;
|
|
21592
|
-
// background: #6c757d;
|
|
21593
|
-
// color: white;
|
|
21594
|
-
// border: none;
|
|
21595
|
-
// border-radius: 4px;
|
|
21596
|
-
// cursor: pointer;
|
|
21597
|
-
// `;
|
|
21598
|
-
// closeButton.addEventListener('click', () => {
|
|
21599
|
-
// this._closePanel();
|
|
21600
|
-
// });
|
|
21601
|
-
// this._dialog.appendChild(closeButton);
|
|
21602
|
-
|
|
21603
|
-
this._panel.appendChild(this._dialog);
|
|
21604
|
-
document.body.appendChild(this._panel);
|
|
21605
|
-
|
|
21606
|
-
// 点击背景遮罩关闭弹窗(增强用户体验,可选)
|
|
21607
|
-
this._panel.addEventListener('click', (e) => {
|
|
21608
|
-
// 只有点击背景遮罩部分才关闭,点击对话框内容不关闭
|
|
21609
|
-
if (e.target === this._panel) {
|
|
21610
|
-
this._closePanel();
|
|
21611
|
-
}
|
|
21612
|
-
});
|
|
21613
|
-
}
|
|
21614
|
-
}
|
|
21615
|
-
|
|
21616
|
-
_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
|
+
`;
|
|
21617
21571
|
|
|
21618
|
-
|
|
21619
|
-
|
|
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);
|
|
21620
21594
|
|
|
21621
|
-
|
|
21622
|
-
|
|
21595
|
+
// 点击遮罩关闭
|
|
21596
|
+
this._panel.addEventListener('click', (e) => {
|
|
21597
|
+
if (e.target === this._panel) this._closePanel();
|
|
21598
|
+
});
|
|
21599
|
+
}
|
|
21623
21600
|
|
|
21624
|
-
|
|
21625
|
-
|
|
21626
|
-
|
|
21627
|
-
if (visibility === 'visible') {
|
|
21628
|
-
firstVisibleLayerId = layer.id;
|
|
21629
|
-
break;
|
|
21630
|
-
}
|
|
21631
|
-
}
|
|
21601
|
+
_renderLayerList() {
|
|
21602
|
+
if (!this._layerListContainer) return;
|
|
21603
|
+
this._layerListContainer.innerHTML = '';
|
|
21632
21604
|
|
|
21633
|
-
if (
|
|
21634
|
-
|
|
21635
|
-
|
|
21636
|
-
buttonText = '底图:无';
|
|
21605
|
+
if (!this._tempLayers.length) {
|
|
21606
|
+
this._layerListContainer.textContent = '无可选栅格图层';
|
|
21607
|
+
return;
|
|
21637
21608
|
}
|
|
21638
21609
|
|
|
21639
|
-
this.
|
|
21640
|
-
|
|
21641
|
-
// 清空旧的图层列表
|
|
21642
|
-
if (this._layerListContainer) { this._layerListContainer.innerHTML = ''; }
|
|
21643
|
-
rasterLayers.forEach(layer => {
|
|
21644
|
-
const layerId = layer.id;
|
|
21610
|
+
this._tempLayers.forEach((layer, index) => {
|
|
21645
21611
|
const row = document.createElement('div');
|
|
21646
21612
|
row.style.cssText = `
|
|
21647
|
-
|
|
21648
|
-
|
|
21649
|
-
|
|
21650
|
-
|
|
21651
|
-
|
|
21652
|
-
|
|
21653
|
-
|
|
21613
|
+
display: flex;
|
|
21614
|
+
align-items: center;
|
|
21615
|
+
gap: 6px;
|
|
21616
|
+
padding: 6px 8px;
|
|
21617
|
+
background: #f8f9fa;
|
|
21618
|
+
border-radius: 4px;
|
|
21619
|
+
`;
|
|
21654
21620
|
|
|
21655
|
-
|
|
21656
|
-
|
|
21657
|
-
|
|
21658
|
-
|
|
21659
|
-
|
|
21660
|
-
|
|
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
|
+
};
|
|
21661
21638
|
|
|
21662
|
-
// 更新按钮文字
|
|
21663
|
-
if (this._button) {
|
|
21664
|
-
this._button.innerHTML = `底图:${layerId}`;
|
|
21665
|
-
}
|
|
21666
|
-
this._togglePanel();
|
|
21667
|
-
});
|
|
21668
21639
|
|
|
21669
|
-
// 鼠标 hover 效果
|
|
21670
|
-
row.addEventListener('mouseenter', () => {
|
|
21671
|
-
row.style.background = '#e9ecef';
|
|
21672
|
-
});
|
|
21673
|
-
row.addEventListener('mouseleave', () => {
|
|
21674
|
-
row.style.background = '#f8f9fa';
|
|
21675
|
-
});
|
|
21676
21640
|
|
|
21677
|
-
// 显示图层 ID(可加样式或 icon)
|
|
21678
21641
|
const label = document.createElement('span');
|
|
21679
|
-
label.textContent =
|
|
21680
|
-
label.style.
|
|
21681
|
-
|
|
21682
|
-
|
|
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
|
+
`;
|
|
21683
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);
|
|
21684
21673
|
row.appendChild(label);
|
|
21685
|
-
|
|
21674
|
+
row.appendChild(upBtn);
|
|
21675
|
+
row.appendChild(downBtn);
|
|
21676
|
+
this._layerListContainer.appendChild(row);
|
|
21686
21677
|
});
|
|
21687
|
-
|
|
21688
|
-
|
|
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
|
+
}
|
|
21689
21720
|
}
|
|
21721
|
+
|
|
21722
|
+
this._button.innerHTML = firstVisible
|
|
21723
|
+
? `底图:${firstVisible}`
|
|
21724
|
+
: rasterLayers.length ? '底图:无' : '底图:无栅格图层';
|
|
21690
21725
|
}
|
|
21691
21726
|
}
|
|
21692
21727
|
|