controls
本文回答:
map.addControl的各种控件 —— 导航 / 比例尺 / 全屏 / 鼠标位置 / 鹰眼 / 按钮组。
一、支持的控件
| 控件 | 说明 |
|---|---|
NavigationControl |
缩放 + 指南针 |
ScaleControl |
比例尺 |
FullscreenControl |
全屏切换 |
MousePositionControl |
鼠标坐标 + 可选 zoom |
MiniMapControl |
小地图 / 鹰眼 |
ButtonGroupControl |
自定义按钮组 |
二、基本用法
map.addControl(new vjmap.NavigationControl(), "top-right");
map.addControl(new vjmap.ScaleControl(), "bottom-left");
map.addControl(new vjmap.FullscreenControl(), "bottom-right");
map.addControl(new vjmap.MousePositionControl({ showZoom: true, showLatLng: true }), "top-left");
位置 = top-left | top-right | bottom-left | bottom-right。
三、移除
map.removeControl(nav);
四、比例尺
map.addControl(new vjmap.ScaleControl({
maxWidth: 100,
unit: "metric" // "imperial" / "nautical"
}));
vjmap 已改写 ScaleControl:只要地图投影不是 LnglatProjection(即普通 CAD 图),比例尺按 CAD 坐标距离 计算(1 个 CAD 单位按 1 m 显示 m / km 标签);图纸单位不是米时标签数值需自行换算,或改用自定义比例尺(见 overlay/legend-north-scale)。
五、鼠标位置
new vjmap.MousePositionControl({
showZoom: true, // 显示 zoom
showLatLng: true // 显示 lng, lat;CAD 图一般用 showLatLng: false
});
六、鹰眼(MiniMap)
map.addControl(new vjmap.MiniMapControl({
containerStyle: {
background: "#31346a85",
transform: "scale(0.6)",
transformOrigin: "100% 0%" // 对应 top-right
// 'top-right' => '100% 0%'
// 'top-left' => '0% 0%'
// 'bottom-right' => '100% 100%'
// 'bottom-left' => '0% 100%'
}
}), "top-right");
七、按钮组 ButtonGroupControl
构造函数签名是 constructor(options?: Record<string, any>)——传 options 对象,自定义按钮放在 buttons(或 addControls)数组里。直接把按钮数组传给构造函数不会渲染任何按钮(数组没有 .buttons 属性):
map.addControl(new vjmap.ButtonGroupControl({
buttons: [
{
id: "home",
icon: "url('data:image/svg+xml;base64,...')", // 非 <svg 开头的值原样当 CSS background-image,须带 url()
title: "回到主页",
onActivate: () => map.fitMapBounds()
},
{
id: "3d",
icon: "...",
title: "切换 3D",
onActivate: () => map.setPitch(map.getPitch() === 0 ? 60 : 0)
}
]
}), "top-left");
按钮项字段(见 vjmap.min.js addButtons):
| 字段 | 说明 |
|---|---|
id |
按钮 id;options.controls[id] === false 可单独隐藏该按钮 |
icon |
图标。<svg ... 开头的字符串自动转成 background-image data-uri(缺 width= 时补 width="24" height="24");其他值原样作为 CSS background-image |
text |
按钮文字(innerHTML) |
title |
悬停提示,缺省取 id |
style / className / container |
自定义样式、类名、挂载容器 |
isCheckbox + checked |
渲染为复选框,change 事件触发回调 |
onActivate(ctx, e) |
点击回调(每次点击都调,没有"再点取消"的切换);ctx 是控件实例,e 是 DOM 事件。不是 onClick |
onDeactivate |
可传但永不触发(源码中调用处已被注释掉);开关逻辑请在 onActivate 里自己维护状态,或用 isCheckbox |
按钮没有 onActivate 时,点击会向地图派发 buttonGroupControl_event 事件,载荷 { event: "onActivate", id, context }(isCheckbox 项另带 e),可用 map.on("buttonGroupControl_event", ...) 统一兜底。
坑位(removeControl 残留):
ButtonGroupControl.onRemove只删按钮元素(ui.removeButtons()),不移除控件容器本身——map.removeControl(bg)后空的.vjmapgis-ctrldiv 残留在地图上。需手动清理:map.removeControl(bg); bg.ControlContainer?.parentNode?.removeChild(bg.ControlContainer);
八、本地化
locale 是 Map 构造选项(不是 vjmap.setLocale 函数——包里没有该方法),在 new vjmap.Map 时传入:
const map = new vjmap.Map({
container: "map",
style,
center, zoom: 2,
locale: {
"FullscreenControl.Enter": "进入全屏",
"FullscreenControl.Exit": "退出全屏",
"NavigationControl.ZoomIn": "放大",
"NavigationControl.ZoomOut": "缩小",
"NavigationControl.ResetBearing": "方位角复位",
"ScaleControl.Meters": "m",
"ScaleControl.Kilometers": "km"
}
});
源:map2d/vjmap-playground/src/04control_控件/controlAddRemove.js;MapOptions.locale 见 vjmap.d.ts。
九、Geolocate / Attribution
map.addControl(new vjmap.GeolocateControl({ trackUserLocation: true }), "bottom-right");
map.addControl(new vjmap.AttributionControl({ compact: true }));
十、自定义控件
class MyControl {
onAdd(map) {
this.map = map;
this.container = document.createElement("div");
this.container.className = "vjmapgis-ctrl vjmapgis-ctrl-group";
this.container.innerHTML = `<button>🔍</button>`;
this.container.onclick = () => map.fitMapBounds();
return this.container;
}
onRemove() {
this.container.parentNode.removeChild(this.container);
this.map = undefined;
}
}
map.addControl(new MyControl(), "top-right");
自定义控件建议沿用
vjmapgis-ctrl/vjmapgis-ctrl-group这两个 CSS 类名,这样可以直接继承 vjmap 内置控件的外观(圆角、阴影、hover 样式),开发者工具里也能看到 vjmap 内置控件同样带这些类名。
十一、常见坑
- 控件样式丢失:必须引入 vjmap 的样式文件(
vjmap.min.css)。 - MiniMap 选错 transformOrigin:4 个位置对应不同 origin,否则缩放后位移。
- NavigationControl 的指南针需要 pitch > 0 才能显示 pitch 可视化;需
visualizePitch: true。 - 多控件挤在 top-left → 换位置或用 ButtonGroupControl 集中。