raintee-maputils 1.0.3 → 1.0.5

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/index.js CHANGED
@@ -1,11 +1,11 @@
1
- import CustomOptionsControl from './src/CustomOptionsControl';
2
- import CustomToggleControl from './src/CustomToggleControl';
3
- import RainteeConstants from './src/RainteeConstants';
4
- import RainteeGISUtil from './src/RainteeGISUtil';
5
- import RainteeSourceMapTool from './src/RainteeSourceMapTool';
6
- import RasterLayerController from './src/RasterLayerController';
7
- import TerrainToggleControl from './src/TerrainToggleControl';
8
- import useDrawCache from './src/useDrawCache';
1
+ import * as CustomOptionsControl from './src/CustomOptionsControl.js';
2
+ import * as CustomToggleControl from './src/CustomToggleControl.js';
3
+ import * as RainteeConstants from './src/RainteeConstants.js';
4
+ import * as RainteeGISUtil from './src/RainteeGISUtil.js';
5
+ import * as RainteeSourceMapTool from './src/RainteeSourceMapTool.js';
6
+ import * as RasterLayerController from './src/RasterLayerController.js';
7
+ import * as TerrainToggleControl from './src/TerrainToggleControl.js';
8
+ import * as useDrawCache from './src/useDrawCache.js';
9
9
 
10
10
  export default {
11
11
  RainteeConstants,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "raintee-maputils",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Raintee的GIS开发工具包",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -8,8 +8,8 @@
8
8
  "raintee-maputils": "index.js"
9
9
  },
10
10
  "files": [
11
- "index.js",
12
- "lib"
11
+ "in dex.js",
12
+ "src"
13
13
  ],
14
14
  "scripts": {
15
15
  "test": "echo \"Error: no test specified\" && exit 1",
@@ -0,0 +1,168 @@
1
+ export default class CustomOptionsControl {
2
+ constructor(args) {
3
+ const { options, onConfirm } = args;
4
+
5
+ this._container = null;
6
+ this._map = null;
7
+
8
+ this._options = options || [];
9
+ this._onConfirm = onConfirm || (() => { });
10
+
11
+ if (!this._options || !Array.isArray(this._options)) {
12
+ console.error('请传入有效的 options 参数(数组)');
13
+ }
14
+ }
15
+
16
+ onAdd(map) {
17
+ this._map = map;
18
+
19
+ // 创建控件外层容器
20
+ this._container = document.createElement('div');
21
+ this._container.className = 'mapboxgl-ctrl mapboxgl-ctrl-group custom-options-control';
22
+
23
+ // 创建主按钮(初始只显示“三维模型”文字,点击展开)
24
+ const mainButton = document.createElement('button');
25
+ mainButton.style.cssText = `
26
+ width: 100%;
27
+ height: 100%;
28
+ padding: 0.25rem 0.5rem;
29
+ margin: 0;
30
+ border: 1px solid #ccc;
31
+ background: white;
32
+ border-radius: 4px;
33
+ cursor: pointer;
34
+ font-size: 14px;
35
+ text-align: left;
36
+ `;
37
+ mainButton.textContent = '三维模型';
38
+ mainButton.addEventListener('click', () => this._toggleExpanded());
39
+
40
+ this._container.appendChild(mainButton);
41
+
42
+ // 创建隐藏的选项面板(默认不显示)
43
+ this._panel = document.createElement('div');
44
+ this._panel.style.display = 'none';
45
+ this._panel.style.padding = '10px';
46
+ this._container.appendChild(this._panel);
47
+
48
+ // 创建选项列表和按钮组
49
+ this._renderOptionsPanel();
50
+
51
+ return this._container;
52
+ }
53
+
54
+ _toggleExpanded() {
55
+ const isExpanded = this._panel.style.display !== 'none';
56
+ this._setExpanded(!isExpanded);
57
+ }
58
+
59
+ _setExpanded(isExpanded) {
60
+ this._panel.style.display = isExpanded ? 'block' : 'none';
61
+ }
62
+
63
+ _renderOptionsPanel() {
64
+ // 清空面板内容
65
+ this._panel.innerHTML = '';
66
+
67
+ // 创建复选框选项列表
68
+ this._options.forEach((opt) => {
69
+ const optionDiv = document.createElement('div');
70
+ optionDiv.style.marginBottom = '6px';
71
+
72
+ const label = document.createElement('label');
73
+ label.style.display = 'flex';
74
+ label.style.alignItems = 'center';
75
+ label.style.cursor = 'pointer';
76
+
77
+ const checkbox = document.createElement('input');
78
+ checkbox.type = 'checkbox';
79
+ checkbox.value = opt.value;
80
+ checkbox.style.marginRight = '8px';
81
+
82
+ // 绑定选中状态
83
+ checkbox.checked = this._getSelectedOption(opt.value);
84
+ checkbox.addEventListener('change', () => this._toggleOption(opt.value));
85
+
86
+ const span = document.createElement('span');
87
+ span.textContent = opt.label;
88
+
89
+ label.appendChild(checkbox);
90
+ label.appendChild(span);
91
+ optionDiv.appendChild(label);
92
+ this._panel.appendChild(optionDiv);
93
+ });
94
+
95
+ // 创建按钮组:取消 / 确定
96
+ const buttonGroup = document.createElement('div');
97
+ buttonGroup.style.marginTop = '12px';
98
+ buttonGroup.style.display = 'flex';
99
+ buttonGroup.style.gap = '8px';
100
+ buttonGroup.style.justifyContent = 'flex-end';
101
+
102
+ const cancelButton = document.createElement('button');
103
+ cancelButton.textContent = '取消';
104
+ cancelButton.style.cssText = `
105
+ padding: 6px 12px;
106
+ background: #ccc;
107
+ border: none;
108
+ border-radius: 4px;
109
+ cursor: pointer;
110
+ width: auto;
111
+ `;
112
+ cancelButton.addEventListener('click', () => this._handleCancel());
113
+
114
+ const confirmButton = document.createElement('button');
115
+ confirmButton.textContent = '确定';
116
+ confirmButton.style.cssText = `
117
+ padding: 6px 12px;
118
+ background: #007cba;
119
+ color: white;
120
+ border: none;
121
+ border-radius: 4px;
122
+ cursor: pointer;
123
+ width: auto;
124
+ `;
125
+ confirmButton.addEventListener('click', () => this._handleConfirm());
126
+
127
+ buttonGroup.appendChild(cancelButton);
128
+ buttonGroup.appendChild(confirmButton);
129
+ this._panel.appendChild(buttonGroup);
130
+ }
131
+
132
+ _getSelectedOption(value) {
133
+ return this._selectedOptions?.includes(value) || false;
134
+ }
135
+
136
+ _toggleOption(value) {
137
+ if (!this._selectedOptions) this._selectedOptions = [];
138
+
139
+ const idx = this._selectedOptions.indexOf(value);
140
+ if (idx > -1) {
141
+ this._selectedOptions.splice(idx, 1);
142
+ } else {
143
+ this._selectedOptions.push(value);
144
+ }
145
+
146
+ // 可选:重新渲染复选框状态(如果需要动态更新 UI,但目前 onchange 已处理)
147
+ }
148
+
149
+ _handleConfirm() {
150
+ this._setExpanded(false);
151
+
152
+ this._onConfirm({
153
+ selectedOptions: this._selectedOptions || [],
154
+ unselectedOptions: this._options.filter((item) => !this._selectedOptions?.includes(item.value)),
155
+ allOptions: this._options,
156
+ });
157
+ }
158
+
159
+ _handleCancel() {
160
+ this._setExpanded(false);
161
+ }
162
+
163
+ onRemove() {
164
+ if (this._container && this._container.parentNode) {
165
+ this._container.parentNode.removeChild(this._container);
166
+ }
167
+ }
168
+ }
@@ -0,0 +1,125 @@
1
+ // 自定义控件类:ToggleControl
2
+ export default class ToggleControl {
3
+ /**
4
+ * 构造函数
5
+ * @param {Object} options
6
+ * @param {string} options.name - 控件名称(用于识别,可选展示)
7
+ * @param {string} options.field - 控制的字段名,对应 map.SourceMap[field]
8
+ * @param {boolean} options.defaultValue - 默认值(当 field 未定义时使用)
9
+ * @param {string} options.svgIcon - SVG 图标字符串,例如 '<svg>...</svg>'
10
+ * @param {Function} [options.onToggle] - 可选的回调函数,状态切换后调用,参数为最新的布尔值
11
+ */
12
+ constructor({ name, field, defaultValue = false, svgIcon, onToggle }) {
13
+ this.name = name;
14
+ this.field = field;
15
+ this.defaultValue = defaultValue;
16
+ this.svgIcon = svgIcon;
17
+ this.onToggle = onToggle; // ✅ 新增:回调函数
18
+
19
+ // 控件容器
20
+ this._container = null;
21
+ this._button = null;
22
+ this.isActive = false; // 当前是否为激活状态(高亮/true)
23
+ }
24
+
25
+ // Mapbox 要求的 onAdd 方法
26
+ onAdd(map) {
27
+ this.map = map;
28
+
29
+ // 创建外层容器 div
30
+ this._container = document.createElement('div');
31
+ this._container.className = 'mapboxgl-ctrl mapboxgl-ctrl-group';
32
+
33
+ // 创建 button 元素
34
+ this._button = document.createElement('button');
35
+ this._button.type = 'button';
36
+ this._button.innerHTML = this.svgIcon;
37
+
38
+ // 设置按钮样式
39
+ this._button.style.cursor = 'pointer';
40
+ this._button.style.border = 'none';
41
+ this._button.style.background = 'none';
42
+ this._button.style.padding = '0';
43
+ this._button.style.display = 'flex';
44
+ this._button.style.alignItems = 'center';
45
+ this._button.style.justifyContent = 'center';
46
+
47
+ // 初始化状态
48
+ this.updateStatus();
49
+
50
+ // 绑定点击事件
51
+ this._button.addEventListener('click', () => {
52
+ this.toggle();
53
+ });
54
+
55
+ this._container.appendChild(this._button);
56
+
57
+ return this._container;
58
+ }
59
+
60
+ // Mapbox 要求的 onRemove 方法
61
+ onRemove() {
62
+ if (this._container && this._container.parentNode) {
63
+ this._container.parentNode.removeChild(this._container);
64
+ }
65
+ this.map = null;
66
+ this._container = null;
67
+ this._button = null;
68
+ }
69
+
70
+ // 更新控件状态(根据当前 field 值)
71
+ updateStatus() {
72
+ // 从 map.SourceMap 中获取当前 field 的值,如果不存在则使用 defaultValue
73
+ let currentValue = this.defaultValue;
74
+
75
+ if (
76
+ this.map &&
77
+ this.map.SourceMap &&
78
+ typeof this.map.SourceMap[this.field] === 'boolean'
79
+ ) {
80
+ currentValue = this.map.SourceMap[this.field];
81
+ }
82
+
83
+ this.isActive = currentValue; // true 表示激活,false 表示未激活
84
+
85
+ // 更新按钮样式
86
+ if (this.isActive) {
87
+ this._button.style.opacity = '1';
88
+ this._button.style.filter = 'none';
89
+ } else {
90
+ this._button.style.opacity = '0.4';
91
+ this._button.style.filter = 'grayscale(100%)';
92
+ }
93
+ }
94
+
95
+ // 切换状态
96
+ toggle() {
97
+ // 获取当前值
98
+ let currentValue = this.defaultValue;
99
+
100
+ if (
101
+ this.map &&
102
+ this.map.SourceMap &&
103
+ typeof this.map.SourceMap[this.field] === 'boolean'
104
+ ) {
105
+ currentValue = this.map.SourceMap[this.field];
106
+ }
107
+
108
+ // 切换值
109
+ const newValue = !currentValue;
110
+
111
+ // 更新到 map.SourceMap 中
112
+ if (this.map && this.map.SourceMap) {
113
+ this.map.SourceMap[this.field] = newValue;
114
+ }
115
+
116
+ // 更新内部状态
117
+ this.isActive = newValue;
118
+
119
+ // 更新 UI 样式
120
+ this.updateStatus();
121
+
122
+ // ✅ 调用回调函数(如果传入了 onToggle),并传入最新的值
123
+ this.onToggle?.(newValue); // 安全调用,仅当函数存在时才执行
124
+ }
125
+ }