gdmap-utils 1.2.2 → 1.2.4
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 +214 -1
- package/dist/index.js.map +1 -1
- package/docs/README.md +5 -0
- package/docs/classes/MapUtils.md +153 -0
- package/docs/functions/createMapUtils.md +18 -0
- package/docs/functions/initMapSource.md +14 -0
- package/docs/globals.md +11 -0
- package/examples/1_init.html +1 -1
- package/examples/2_mapInit.html +1 -1
- package/examples/3_MarkerLayer.html +1 -1
- package/examples/4_LabelMarkerLayer.html +1 -1
- package/examples/5_markerCluster.html +528 -0
- package/package.json +8 -2
- package/scripts/cleanDocs.js +220 -0
- package/scripts/mergeDocs.js +129 -0
- package/src/LayerManager.ts +21 -5
- package/src/MapUtils.ts +194 -19
- package/src/gdMap/gdHelper.ts +28 -0
- package/src/index.ts +2 -0
- package/src/layers/baseMarkerLayer/LabelMarkerLayer.ts +2 -0
- package/src/layers/baseMarkerLayer/MarkerLayer.ts +2 -0
- package/src/layers/baseMarkerLayer/index.ts +18 -3
- package/src/layers/clusterMarkerLayer/MarkerClusterLayer.ts +41 -18
- package/src/layers/clusterMarkerLayer/index.ts +204 -0
- package/src/layers/index.ts +4 -0
- package/src/types/clusterMarkerLayer.d.ts +89 -0
- package/src/types/index.d.ts +3 -1
- package/typedoc.json +22 -0
- package/webpack.config.js +3 -4
- package/src/gdMap/gdHelper.js +0 -194
- package/src/gdMapUtils.js +0 -377
- package/src/index.html +0 -14
- package/src/layers/clusterMarkerLayer/MarkerClusterLayer.js +0 -155
- /package/src/types/{BaseMarkerLayer.d.ts → baseMarkerLayer.d.ts} +0 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
// 要处理的文档目录
|
|
5
|
+
const docsDir = path.join(__dirname, '../docs');
|
|
6
|
+
// 源代码目录
|
|
7
|
+
const srcDir = path.join(__dirname, '../src');
|
|
8
|
+
|
|
9
|
+
// 从TypeScript源文件中提取方法参数类型
|
|
10
|
+
function extractMethodParamTypes() {
|
|
11
|
+
const paramTypes = {};
|
|
12
|
+
|
|
13
|
+
// 递归遍历源代码文件
|
|
14
|
+
function traverseDir(dir) {
|
|
15
|
+
const files = fs.readdirSync(dir);
|
|
16
|
+
|
|
17
|
+
files.forEach(file => {
|
|
18
|
+
const filePath = path.join(dir, file);
|
|
19
|
+
const stats = fs.statSync(filePath);
|
|
20
|
+
|
|
21
|
+
if (stats.isDirectory()) {
|
|
22
|
+
traverseDir(filePath);
|
|
23
|
+
} else if (path.extname(file) === '.ts') {
|
|
24
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
25
|
+
|
|
26
|
+
// 按行读取文件内容
|
|
27
|
+
const lines = content.split('\n');
|
|
28
|
+
let currentMethod = null;
|
|
29
|
+
let currentParams = [];
|
|
30
|
+
let inMethod = false;
|
|
31
|
+
|
|
32
|
+
lines.forEach(line => {
|
|
33
|
+
// 检查是否是方法定义的开始
|
|
34
|
+
const methodStartMatch = line.match(/(?:public|private|protected)?\s*(\w+)\s*<[^>]*>?\s*\(([^)]*)\)\s*(?::\s*([^\{]+))?\s*(?:\{|=>)/);
|
|
35
|
+
|
|
36
|
+
if (methodStartMatch) {
|
|
37
|
+
// 如果之前有正在处理的方法,保存它
|
|
38
|
+
if (currentMethod && currentParams.length > 0) {
|
|
39
|
+
paramTypes[currentMethod] = currentParams;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 开始处理新方法
|
|
43
|
+
currentMethod = methodStartMatch[1];
|
|
44
|
+
currentParams = [];
|
|
45
|
+
inMethod = true;
|
|
46
|
+
|
|
47
|
+
// 提取当前行的参数
|
|
48
|
+
const paramsStr = methodStartMatch[2];
|
|
49
|
+
if (paramsStr && paramsStr.trim() !== '') {
|
|
50
|
+
const params = paramsStr.split(',').map(param => {
|
|
51
|
+
const paramMatch = param.trim().match(/(\w+)\s*:\s*([^=]+)/);
|
|
52
|
+
if (paramMatch) {
|
|
53
|
+
return {
|
|
54
|
+
name: paramMatch[1],
|
|
55
|
+
type: paramMatch[2].trim()
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
}).filter(Boolean);
|
|
60
|
+
|
|
61
|
+
currentParams = currentParams.concat(params);
|
|
62
|
+
}
|
|
63
|
+
} else if (inMethod) {
|
|
64
|
+
// 检查是否是方法定义的结束
|
|
65
|
+
if (line.trim() === '{' || line.trim() === '};') {
|
|
66
|
+
// 保存当前方法
|
|
67
|
+
if (currentMethod && currentParams.length > 0) {
|
|
68
|
+
paramTypes[currentMethod] = currentParams;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
currentMethod = null;
|
|
72
|
+
currentParams = [];
|
|
73
|
+
inMethod = false;
|
|
74
|
+
} else {
|
|
75
|
+
// 提取跨多行的参数
|
|
76
|
+
const paramMatch = line.trim().match(/(\w+)\s*:\s*([^=]+)/);
|
|
77
|
+
if (paramMatch) {
|
|
78
|
+
currentParams.push({
|
|
79
|
+
name: paramMatch[1],
|
|
80
|
+
type: paramMatch[2].trim()
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// 保存最后一个方法
|
|
88
|
+
if (currentMethod && currentParams.length > 0) {
|
|
89
|
+
paramTypes[currentMethod] = currentParams;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
traverseDir(srcDir);
|
|
96
|
+
|
|
97
|
+
// 添加硬编码的参数类型映射,为那些难以通过正则表达式提取的方法提供类型信息
|
|
98
|
+
const hardcodedParamTypes = {
|
|
99
|
+
'removeLayer': [{ name: 'layer', type: 'BaseMarkerLayerIns | ClusterMarkerLayerIns' }],
|
|
100
|
+
'setFitView': [{ name: 'opts', type: 'Parameters<mapIns[\'setFitView\']>' }],
|
|
101
|
+
'seZoomAndCenter': [{ name: 'opts', type: '{ zoom: number; center: AMap.LngLat | [number, number]; immediately?: boolean; duration?: number }' }]
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
// 合并硬编码的参数类型映射
|
|
105
|
+
Object.assign(paramTypes, hardcodedParamTypes);
|
|
106
|
+
|
|
107
|
+
return paramTypes;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// 递归处理所有.md文件
|
|
111
|
+
function processMarkdownFiles(dir) {
|
|
112
|
+
const files = fs.readdirSync(dir);
|
|
113
|
+
const paramTypes = extractMethodParamTypes();
|
|
114
|
+
|
|
115
|
+
files.forEach(file => {
|
|
116
|
+
const filePath = path.join(dir, file);
|
|
117
|
+
const stats = fs.statSync(filePath);
|
|
118
|
+
|
|
119
|
+
if (stats.isDirectory()) {
|
|
120
|
+
processMarkdownFiles(filePath);
|
|
121
|
+
} else if (path.extname(file) === '.md') {
|
|
122
|
+
processMarkdownFile(filePath, paramTypes);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// 在分类标题后添加描述文字
|
|
128
|
+
function addCategoryDescription(content) {
|
|
129
|
+
// 定义分类描述映射
|
|
130
|
+
const categoryDescriptions = {
|
|
131
|
+
'高德地图工具': '本分类封装了高德地图(AMap)的核心功能,包括标记点、图标、折线、信息窗口等常用地图元素的创建和管理。这些静态方法提供了便捷的API,帮助开发者快速构建地图应用。'
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
// 遍历所有分类,添加描述文字
|
|
135
|
+
Object.keys(categoryDescriptions).forEach(category => {
|
|
136
|
+
const regex = new RegExp(`##\\s*${category}\\s*\\n`, 'g');
|
|
137
|
+
content = content.replace(regex, `## ${category}\n\n${categoryDescriptions[category]}\n\n`);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
return content;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// 处理单个Markdown文件,移除Params和Return部分,并添加参数类型
|
|
144
|
+
function processMarkdownFile(filePath, paramTypes) {
|
|
145
|
+
let content = fs.readFileSync(filePath, 'utf8');
|
|
146
|
+
|
|
147
|
+
// 在分类标题后添加描述文字
|
|
148
|
+
content = addCategoryDescription(content);
|
|
149
|
+
|
|
150
|
+
// 移除Params部分
|
|
151
|
+
content = content.replace(/#### Parameters[\s\S]*?(?=#### Returns|\*\*\*|$)/g, '');
|
|
152
|
+
|
|
153
|
+
// 移除Returns部分
|
|
154
|
+
content = content.replace(/#### Returns[\s\S]*?(?=####|\*\*\*|$)/g, '');
|
|
155
|
+
|
|
156
|
+
// 移除Memberof部分
|
|
157
|
+
content = content.replace(/#### Memberof[\s\S]*?(?=####|\*\*\*|$)/g, '');
|
|
158
|
+
|
|
159
|
+
// 移除Type Parameters部分(包含#### Type Parameters标题和后续的所有参数行)
|
|
160
|
+
content = content.replace(/#### Type Parameters[\s\S]*?(?=\*\*\*|$)/g, '');
|
|
161
|
+
|
|
162
|
+
// 移除单独的Type Parameter行(如##### U, ##### T等)
|
|
163
|
+
content = content.replace(/#####\s+\w+[\s\S]*?(?=#####|\*\*\*|$)/g, '');
|
|
164
|
+
|
|
165
|
+
// 移除单独的Type Parameter描述行(如`U` *extends* `object`)
|
|
166
|
+
content = content.replace(/`\w+`\s*\*extends\*\s*`[^`]+`[^\n]*\n/g, '');
|
|
167
|
+
|
|
168
|
+
// 为方法参数添加类型信息
|
|
169
|
+
content = content.replace(/(###\s+(\w+)\(\)[\s\S]*?>\s*\*\*\w+\*\*\s*)\(([^)]*)\)(:\s*`[^`]+`)/g, (match, prefix, methodName, paramsStr, returnType) => {
|
|
170
|
+
if (paramTypes[methodName]) {
|
|
171
|
+
const params = paramTypes[methodName];
|
|
172
|
+
let newParamsStr = '';
|
|
173
|
+
|
|
174
|
+
params.forEach((param, index) => {
|
|
175
|
+
if (index > 0) {
|
|
176
|
+
newParamsStr += ', ';
|
|
177
|
+
}
|
|
178
|
+
newParamsStr += `${param.name}: ${param.type}`;
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
return `${prefix}(${newParamsStr})${returnType}`;
|
|
182
|
+
}
|
|
183
|
+
return match;
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// 处理带有反引号的参数
|
|
187
|
+
content = content.replace(/###\s+(\w+)\(\)[\s\S]*?>(\s*\*\*\w+\*\*\s*)\(`([^`]+)`\)(:\s*`[^`]+`)/g, (match, methodName, prefix, paramName, returnType) => {
|
|
188
|
+
if (paramTypes[methodName]) {
|
|
189
|
+
const params = paramTypes[methodName];
|
|
190
|
+
let newParamsStr = '';
|
|
191
|
+
|
|
192
|
+
params.forEach((param, index) => {
|
|
193
|
+
if (index > 0) {
|
|
194
|
+
newParamsStr += ', ';
|
|
195
|
+
}
|
|
196
|
+
newParamsStr += `${param.name}: ${param.type}`;
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
return match.replace(/\(`[^`]+`\)/, `(${newParamsStr})`);
|
|
200
|
+
}
|
|
201
|
+
return match;
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// 移除多余的换行
|
|
205
|
+
content = content.replace(/\n{3,}/g, '\n\n');
|
|
206
|
+
|
|
207
|
+
// 移除分隔线前的多余换行
|
|
208
|
+
content = content.replace(/\n+\*\*\*/g, '\n***');
|
|
209
|
+
|
|
210
|
+
// 移除多余的分隔线
|
|
211
|
+
content = content.replace(/\*\*\*\n\*\*\*/g, '***');
|
|
212
|
+
|
|
213
|
+
// 保存处理后的内容
|
|
214
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
215
|
+
console.log(`Processed: ${filePath}`);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// 执行处理
|
|
219
|
+
processMarkdownFiles(docsDir);
|
|
220
|
+
console.log('All markdown files processed successfully!');
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const docsDir = path.join(__dirname, '../docs');
|
|
5
|
+
const srcDir = path.join(__dirname, '../src');
|
|
6
|
+
const outputFile = path.join(docsDir, 'COMPLETE_API.md');
|
|
7
|
+
|
|
8
|
+
// 读取README.md作为文档头部
|
|
9
|
+
const readmePath = path.join(docsDir, 'README.md');
|
|
10
|
+
let readmeContent = '';
|
|
11
|
+
if (fs.existsSync(readmePath)) {
|
|
12
|
+
readmeContent = fs.readFileSync(readmePath, 'utf8');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// 要处理的源文件
|
|
16
|
+
const sourceFiles = [
|
|
17
|
+
{
|
|
18
|
+
path: path.join(srcDir, 'layers', 'baseMarkerLayer', 'index.ts'),
|
|
19
|
+
name: 'BaseMarkerLayer'
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
path: path.join(srcDir, 'layers', 'clusterMarkerLayer', 'index.ts'),
|
|
23
|
+
name: 'ClusterMarkerLayer'
|
|
24
|
+
}
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
// 从TypeScript源文件中提取文档注释
|
|
28
|
+
function extractDocumentationFromSource(filePath, className) {
|
|
29
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
30
|
+
let documentation = '';
|
|
31
|
+
|
|
32
|
+
// 提取类文档注释
|
|
33
|
+
const classCommentMatch = content.match(/\/\*\*[\s\S]*?\*\/\s*class\s+\w+/);
|
|
34
|
+
if (classCommentMatch) {
|
|
35
|
+
documentation += classCommentMatch[0].replace(/class\s+\w+/, '') + '\n\n';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// 提取构造函数
|
|
39
|
+
const constructorMatch = content.match(/constructor\s*\([^)]*\)\s*\{/);
|
|
40
|
+
if (constructorMatch) {
|
|
41
|
+
let constructorStr = constructorMatch[0].replace(/\{/, '');
|
|
42
|
+
// 移除类型注解
|
|
43
|
+
constructorStr = constructorStr.replace(/:\s*[^,]+/g, '');
|
|
44
|
+
documentation += '## Constructors\n\n';
|
|
45
|
+
documentation += '### Constructor\n';
|
|
46
|
+
documentation += `> **new ${className}**${constructorStr}\n\n`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 提取属性(去重)
|
|
50
|
+
const propertiesMatch = content.match(/\w+:\s*[^;]+;/g);
|
|
51
|
+
if (propertiesMatch) {
|
|
52
|
+
const uniqueProps = [...new Set(propertiesMatch.map(prop => prop.match(/\w+/)[0]))];
|
|
53
|
+
documentation += '## Properties\n\n';
|
|
54
|
+
uniqueProps.forEach(propName => {
|
|
55
|
+
documentation += `### ${propName}\n`;
|
|
56
|
+
documentation += `> **${propName}**\n\n`;
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 提取方法
|
|
61
|
+
const methodMatch = content.match(/\w+\s*\([^)]*\)\s*[:{]/g);
|
|
62
|
+
if (methodMatch) {
|
|
63
|
+
documentation += '## Methods\n\n';
|
|
64
|
+
methodMatch.forEach(method => {
|
|
65
|
+
const methodName = method.match(/\w+/)[0];
|
|
66
|
+
if (methodName !== 'constructor') {
|
|
67
|
+
let methodStr = method.replace(/:\s*$/, '');
|
|
68
|
+
// 移除类型注解
|
|
69
|
+
methodStr = methodStr.replace(/:\s*[^,]+/g, '');
|
|
70
|
+
documentation += `### ${methodName}\n`;
|
|
71
|
+
documentation += `> **${methodName}**${methodStr.replace(methodName, '')}\n\n`;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return documentation;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// 合并所有文档
|
|
80
|
+
function mergeDocs() {
|
|
81
|
+
console.log('开始合并文档...');
|
|
82
|
+
|
|
83
|
+
// 构建文档内容
|
|
84
|
+
let mergedContent = '';
|
|
85
|
+
|
|
86
|
+
// 添加README内容
|
|
87
|
+
if (readmeContent) {
|
|
88
|
+
mergedContent += readmeContent + '\n\n';
|
|
89
|
+
mergedContent += '---\n\n';
|
|
90
|
+
mergedContent += '# API 文档\n\n';
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// 添加目录
|
|
94
|
+
mergedContent += '## 目录\n\n';
|
|
95
|
+
sourceFiles.forEach(file => {
|
|
96
|
+
mergedContent += `- [${file.name}](#${file.name.toLowerCase()})\n`;
|
|
97
|
+
});
|
|
98
|
+
mergedContent += '\n---\n\n';
|
|
99
|
+
|
|
100
|
+
// 添加各个文档内容
|
|
101
|
+
sourceFiles.forEach(file => {
|
|
102
|
+
const documentation = extractDocumentationFromSource(file.path, file.name);
|
|
103
|
+
|
|
104
|
+
mergedContent += `## ${file.name}\n\n`;
|
|
105
|
+
mergedContent += `<a id="${file.name.toLowerCase()}"></a>\n\n`;
|
|
106
|
+
mergedContent += documentation + '\n\n';
|
|
107
|
+
mergedContent += '---\n\n';
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// 移除末尾多余的分隔符
|
|
111
|
+
mergedContent = mergedContent.replace(/\n*\*\*\n*$/, '');
|
|
112
|
+
|
|
113
|
+
// 添加生成信息
|
|
114
|
+
mergedContent += '\n\n---\n\n';
|
|
115
|
+
mergedContent += `*最后更新时间: ${new Date().toLocaleString('zh-CN')}*`;
|
|
116
|
+
|
|
117
|
+
// 写入合并后的文档
|
|
118
|
+
fs.writeFileSync(outputFile, mergedContent, 'utf8');
|
|
119
|
+
console.log(`文档合并完成: ${outputFile}`);
|
|
120
|
+
console.log(`总字数: ${mergedContent.length}`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// 执行合并
|
|
124
|
+
try {
|
|
125
|
+
mergeDocs();
|
|
126
|
+
} catch (error) {
|
|
127
|
+
console.error('文档合并失败:', error);
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
package/src/LayerManager.ts
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type {
|
|
2
|
+
BaseMarkerLayerClass,
|
|
3
|
+
ClusterMarkerLayerClass,
|
|
4
|
+
} from '@/layers/index.ts';
|
|
5
|
+
import { MapUtils } from '@/MapUtils';
|
|
3
6
|
|
|
4
|
-
type LayerIns =
|
|
7
|
+
type LayerIns =
|
|
8
|
+
| InstanceType<BaseMarkerLayerClass>
|
|
9
|
+
| InstanceType<ClusterMarkerLayerClass>;
|
|
5
10
|
export class LayerManager {
|
|
6
11
|
layers: Map<string, LayerIns> = new Map(); //组合模式
|
|
7
12
|
|
|
8
13
|
addLayer(layer: LayerIns) {
|
|
9
14
|
if (this.hasLayer(layer)) {
|
|
10
|
-
|
|
15
|
+
const errorMsg = `Layer with name "${layer.layerName}" already exists`;
|
|
16
|
+
return MapUtils.error(errorMsg);
|
|
11
17
|
}
|
|
12
18
|
this.layers.set(layer.layerName, layer);
|
|
13
19
|
}
|
|
@@ -20,6 +26,9 @@ export class LayerManager {
|
|
|
20
26
|
let layer = this.layers.get(LayerName);
|
|
21
27
|
if (layer) {
|
|
22
28
|
layer.show();
|
|
29
|
+
} else {
|
|
30
|
+
const errorMsg = `Layer with name "${LayerName}" not found`;
|
|
31
|
+
return MapUtils.error(errorMsg);
|
|
23
32
|
}
|
|
24
33
|
}
|
|
25
34
|
|
|
@@ -27,6 +36,9 @@ export class LayerManager {
|
|
|
27
36
|
let layer = this.layers.get(LayerName);
|
|
28
37
|
if (layer) {
|
|
29
38
|
layer.hide();
|
|
39
|
+
} else {
|
|
40
|
+
const errorMsg = `Layer with name "${LayerName}" not found`;
|
|
41
|
+
return MapUtils.error(errorMsg);
|
|
30
42
|
}
|
|
31
43
|
}
|
|
32
44
|
|
|
@@ -39,7 +51,11 @@ export class LayerManager {
|
|
|
39
51
|
}
|
|
40
52
|
|
|
41
53
|
reload() {
|
|
42
|
-
this.layers.forEach(val =>
|
|
54
|
+
this.layers.forEach(val => {
|
|
55
|
+
if (typeof (val as any).reload === 'function') {
|
|
56
|
+
(val as any).reload();
|
|
57
|
+
}
|
|
58
|
+
});
|
|
43
59
|
}
|
|
44
60
|
|
|
45
61
|
hasLayer(layer: LayerIns): boolean {
|
package/src/MapUtils.ts
CHANGED
|
@@ -5,9 +5,16 @@ import type {
|
|
|
5
5
|
MapUtilsOpts,
|
|
6
6
|
mapIns,
|
|
7
7
|
MarkerLayerBaseType,
|
|
8
|
+
MarkerClusterLayerType,
|
|
8
9
|
LayerOpts,
|
|
10
|
+
ClusterMarkerLayerOpts,
|
|
9
11
|
} from './types/index.d';
|
|
10
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
BaseMarkerLayerIns,
|
|
14
|
+
BaseMarkerLayer,
|
|
15
|
+
ClusterMarkerLayerIns,
|
|
16
|
+
ClusterMarkerLayer,
|
|
17
|
+
} from './layers/index';
|
|
11
18
|
import type { SetOptional, Simplify } from 'type-fest';
|
|
12
19
|
import LayerManager from './LayerManager';
|
|
13
20
|
|
|
@@ -23,18 +30,42 @@ export class MapUtils {
|
|
|
23
30
|
|
|
24
31
|
LayerManager: LayerManager = new LayerManager();
|
|
25
32
|
|
|
33
|
+
/**
|
|
34
|
+
*@category 高德地图工具
|
|
35
|
+
*/
|
|
26
36
|
static createAMapMarker = MapMixin.createAMapMarker;
|
|
27
|
-
|
|
37
|
+
/**
|
|
38
|
+
*@category 高德地图工具
|
|
39
|
+
*/
|
|
28
40
|
static createIcon = MapMixin.createIcon;
|
|
29
|
-
|
|
41
|
+
/**
|
|
42
|
+
*@category 高德地图工具
|
|
43
|
+
*/
|
|
30
44
|
static Size = MapMixin.Size;
|
|
31
|
-
|
|
45
|
+
/**
|
|
46
|
+
*@category 高德地图工具
|
|
47
|
+
*/
|
|
32
48
|
static Pixel = MapMixin.Pixel;
|
|
33
|
-
|
|
49
|
+
/**
|
|
50
|
+
*@category 高德地图工具
|
|
51
|
+
*/
|
|
34
52
|
static LngLat = MapMixin.LngLat;
|
|
35
|
-
|
|
53
|
+
/**
|
|
54
|
+
*@category 高德地图工具
|
|
55
|
+
*/
|
|
36
56
|
static createAMapInfoWindow = MapMixin.createAMapInfoWindow;
|
|
57
|
+
/**
|
|
58
|
+
*@category 高德地图工具
|
|
59
|
+
*/
|
|
60
|
+
static createAMapPolyline = MapMixin.createAMapPolyline;
|
|
61
|
+
/**
|
|
62
|
+
*@category 高德地图工具
|
|
63
|
+
*/
|
|
64
|
+
static loadPlugins = MapMixin.loadPlugins;
|
|
37
65
|
|
|
66
|
+
/**
|
|
67
|
+
* @ignore
|
|
68
|
+
*/
|
|
38
69
|
constructor(
|
|
39
70
|
opts: MapUtilsOpts[keyof MapUtilsOpts],
|
|
40
71
|
AMap: Simplify<typeof gdAMap>
|
|
@@ -58,26 +89,36 @@ export class MapUtils {
|
|
|
58
89
|
this.map = this.initMap(mountSelector, rest); //地图初始化
|
|
59
90
|
}
|
|
60
91
|
}
|
|
61
|
-
|
|
62
|
-
this.bindMapClickEvent();
|
|
63
92
|
}
|
|
64
93
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
94
|
+
/**
|
|
95
|
+
* @param {AMap.EventType} type 地图事件类型
|
|
96
|
+
* @param {(e: any) => void} fn 回调函数
|
|
97
|
+
* @param {*} [context] 事件上下文,缺省为当前实例
|
|
98
|
+
* @param {boolean} [once] 事件是否执行一次
|
|
99
|
+
* @memberof MapUtils
|
|
100
|
+
*/
|
|
101
|
+
bindMapClickEvent(
|
|
102
|
+
type: AMap.EventType,
|
|
103
|
+
fn: (e: any) => void,
|
|
104
|
+
context?: any,
|
|
105
|
+
once?: boolean
|
|
106
|
+
) {
|
|
107
|
+
this.map.on(type, fn, context, once);
|
|
74
108
|
}
|
|
75
109
|
|
|
110
|
+
/**
|
|
111
|
+
* @ignore
|
|
112
|
+
*/
|
|
76
113
|
initMap(id: string, opts: MapOptions): mapIns {
|
|
77
114
|
//参数要作检验吗
|
|
78
115
|
return new window.AMap.Map(id, opts);
|
|
79
116
|
}
|
|
80
117
|
|
|
118
|
+
/**
|
|
119
|
+
* @ignore
|
|
120
|
+
* @return {*}
|
|
121
|
+
*/
|
|
81
122
|
createBaseMarkerLayer<
|
|
82
123
|
U extends {},
|
|
83
124
|
T extends MarkerLayerBaseType = 'markerLayer',
|
|
@@ -88,7 +129,26 @@ export class MapUtils {
|
|
|
88
129
|
return layer;
|
|
89
130
|
}
|
|
90
131
|
|
|
91
|
-
|
|
132
|
+
/**
|
|
133
|
+
* 高德地图中 `MarkerCluster, MassMarks`用于渲染海量点,它们调用方式也比较接近,将其聚合为一个统一的图层管理
|
|
134
|
+
* 目前, 聚合图层只包装`MarkerCluster`
|
|
135
|
+
* @param {ClusterMarkerLayerOpts<U, T>} opts - 图层配置选项
|
|
136
|
+
*/
|
|
137
|
+
createClusterMarkerLayer<
|
|
138
|
+
U extends {},
|
|
139
|
+
T extends MarkerClusterLayerType = 'markerClusterLayer',
|
|
140
|
+
>(opts: ClusterMarkerLayerOpts<U, T>) {
|
|
141
|
+
const layer = new ClusterMarkerLayer<U, T>(opts, this);
|
|
142
|
+
// @ts-ignore
|
|
143
|
+
this.LayerManager.addLayer(layer);
|
|
144
|
+
return layer;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* `removeLayer`接收图层实例将其从mapUtils的关联中移除
|
|
149
|
+
* @param {(BaseMarkerLayerIns | ClusterMarkerLayerIns)} layer
|
|
150
|
+
*/
|
|
151
|
+
removeLayer(layer: BaseMarkerLayerIns | ClusterMarkerLayerIns) {
|
|
92
152
|
const isLayerExist = this.LayerManager.hasLayer(layer);
|
|
93
153
|
|
|
94
154
|
if (isLayerExist) {
|
|
@@ -109,10 +169,26 @@ export class MapUtils {
|
|
|
109
169
|
this.map.setFitView(...opts);
|
|
110
170
|
}
|
|
111
171
|
|
|
172
|
+
/**
|
|
173
|
+
* 地图弹窗关闭
|
|
174
|
+
* @memberof MapUtils
|
|
175
|
+
*/
|
|
112
176
|
clearInfoWindow() {
|
|
113
177
|
this.map.clearInfoWindow();
|
|
114
178
|
}
|
|
115
179
|
|
|
180
|
+
/**
|
|
181
|
+
* 地图跳转参数
|
|
182
|
+
* @typedef {Object} GotoOpts
|
|
183
|
+
* @property {number} zoom - 目标缩放级别
|
|
184
|
+
* @property {AMap.LngLat|[number,number]} center - 目标中心点(高德坐标实例或 [lng,lat] 数组)
|
|
185
|
+
* @property {boolean} [immediately=false] - 是否立即跳转,默认平滑过渡
|
|
186
|
+
* @property {number} [duration] - 过渡动画时长(毫秒)
|
|
187
|
+
*/
|
|
188
|
+
/**
|
|
189
|
+
* 将地图视图切换到指定状态
|
|
190
|
+
* @param {GotoOpts} opts 跳转配置
|
|
191
|
+
*/
|
|
116
192
|
seZoomAndCenter(opts: {
|
|
117
193
|
zoom: number;
|
|
118
194
|
center: AMap.LngLat | [number, number];
|
|
@@ -127,6 +203,47 @@ export class MapUtils {
|
|
|
127
203
|
this.map.setZoomAndCenter(zoom, center, immediately, duration);
|
|
128
204
|
}
|
|
129
205
|
|
|
206
|
+
/**
|
|
207
|
+
* 图层`layerName`显示, `layerName`为创建图层所传递的参数,用于标识图层名称。
|
|
208
|
+
* @param {string} layerName - 图层名称
|
|
209
|
+
*/
|
|
210
|
+
showLayer(layerName: string): void {
|
|
211
|
+
this.LayerManager.show(layerName);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* 图层`layerName`隐藏, `layerName`为创建图层所传递的参数,用于标识图层名称。
|
|
216
|
+
* @param {string} layerName - 图层名称
|
|
217
|
+
*/
|
|
218
|
+
hideLayer(layerName: string): void {
|
|
219
|
+
this.LayerManager.hide(layerName);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* 地图显示所有图层
|
|
224
|
+
*/
|
|
225
|
+
showAllLayers(): void {
|
|
226
|
+
this.LayerManager.showAll();
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* 地图隐藏所有图层
|
|
231
|
+
*/
|
|
232
|
+
hideAllLayers(): void {
|
|
233
|
+
this.LayerManager.hideAll();
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* 地图重新渲染所有图层
|
|
238
|
+
*/
|
|
239
|
+
reloadLayers(): void {
|
|
240
|
+
this.LayerManager.reload();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* @ignore
|
|
245
|
+
* @param msg
|
|
246
|
+
*/
|
|
130
247
|
static error(msg: string) {
|
|
131
248
|
console.error(`[MapUtils Error]:${msg}`);
|
|
132
249
|
}
|
|
@@ -134,6 +251,45 @@ export class MapUtils {
|
|
|
134
251
|
|
|
135
252
|
export type { mapUtilsIns, MapUtilsConstructor };
|
|
136
253
|
|
|
254
|
+
/**
|
|
255
|
+
*
|
|
256
|
+
* `createMapUtils`功能如下:
|
|
257
|
+
* 1. 支持将高德地图实例包装成工具函数 (为其扩展功能),
|
|
258
|
+
* 2. 地图创建并为其扩展功能,
|
|
259
|
+
* 3. 高德地图依赖加载 ( 高德AMap函数加载 )
|
|
260
|
+
* @param {MapUtilsOpts[keyof MapUtilsOpts]} opts
|
|
261
|
+
* - 工具函数配置选项,支持两种模式:
|
|
262
|
+
* 1. 使用现有地图实例(MapUtilsUseExistingOpts)
|
|
263
|
+
* 2. 创建新地图实例(MapUtilsCreateOpts)
|
|
264
|
+
*
|
|
265
|
+
* [MapOptions文档地址](https://lbs.amap.com/api/javascript-api-v2/documentation#map)
|
|
266
|
+
* ```
|
|
267
|
+
* interface MapUtilsCreateOpts extends MapOptions {
|
|
268
|
+
mountSelector: string; //选择器
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
interface MapUtilsUseExistingOpts extends MapOptions {
|
|
272
|
+
mapIns: mapIns; //高德地图实例
|
|
273
|
+
}
|
|
274
|
+
* ```
|
|
275
|
+
* @param {loaderOpts} [loaderOPts]
|
|
276
|
+
* - 高德地图环境加载所传递的配置对象
|
|
277
|
+
* ```
|
|
278
|
+
* type loaderOpts = {
|
|
279
|
+
key: string;
|
|
280
|
+
version: string;
|
|
281
|
+
plugins?: string[] | undefined;
|
|
282
|
+
AMapUI?: {
|
|
283
|
+
version?: string | undefined;
|
|
284
|
+
plugins?: string[] | undefined;
|
|
285
|
+
} | undefined;
|
|
286
|
+
Loca?: {
|
|
287
|
+
version?: string | undefined;
|
|
288
|
+
} | undefined;
|
|
289
|
+
}
|
|
290
|
+
* ```
|
|
291
|
+
* @return {*}
|
|
292
|
+
*/
|
|
137
293
|
export async function createMapUtils(
|
|
138
294
|
opts: MapUtilsOpts[keyof MapUtilsOpts],
|
|
139
295
|
loaderOPts?: loaderOpts
|
|
@@ -148,7 +304,26 @@ export async function createMapUtils(
|
|
|
148
304
|
return new MapUtils(opts, AMap);
|
|
149
305
|
}
|
|
150
306
|
|
|
151
|
-
|
|
307
|
+
/**
|
|
308
|
+
*
|
|
309
|
+
* @param {loaderOpts} Opts
|
|
310
|
+
* - 高德地图环境加载所传递的配置对象
|
|
311
|
+
* ```
|
|
312
|
+
* type loaderOpts = {
|
|
313
|
+
key: string;
|
|
314
|
+
version: string;
|
|
315
|
+
plugins?: string[] | undefined;
|
|
316
|
+
AMapUI?: {
|
|
317
|
+
version?: string | undefined;
|
|
318
|
+
plugins?: string[] | undefined;
|
|
319
|
+
} | undefined;
|
|
320
|
+
Loca?: {
|
|
321
|
+
version?: string | undefined;
|
|
322
|
+
} | undefined;
|
|
323
|
+
}
|
|
324
|
+
* ```
|
|
325
|
+
* @return {*}
|
|
326
|
+
*/
|
|
152
327
|
export async function initMapSource(Opts: loaderOpts) {
|
|
153
328
|
return await MapSourceImport.loadScript(Opts);
|
|
154
329
|
}
|