唯杰地图 logo唯杰地图
VJMAP
EN

controls

vjmap/references/interaction/controls.md 6.3 KB170 行
原文

本文回答: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-ctrl div 残留在地图上。需手动清理:

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 内置控件同样带这些类名。

十一、常见坑

  1. 控件样式丢失:必须引入 vjmap 的样式文件(vjmap.min.css)。
  2. MiniMap 选错 transformOrigin:4 个位置对应不同 origin,否则缩放后位移。
  3. NavigationControl 的指南针需要 pitch > 0 才能显示 pitch 可视化;需 visualizePitch: true。
  4. 多控件挤在 top-left → 换位置或用 ButtonGroupControl 集中。