Skip to content

Controls

控件是屏幕上具有固定位置的可见小部件,带有一个 DOM 元素。它们可以涉及用户输入(如按钮),也可以仅用于信息显示;其位置通过 CSS 确定。默认情况下,这些控件被放置在具有 CSS 类名 ol-overlaycontainer-stopevent 的容器中,但也可以使用任何外部 DOM 元素。

这是控件的基类。通过创建带有监听器的元素和一个实例,您可以用它来实现简单的自定义控件:

jsx
const myControl = new Control({ element: myElement });

然后将其添加到地图中即可。

将控件作为控件而不是简单的独立 DOM 元素的主要优势在于,它会为您处理事件传播的阻止。此外,控件还会作为 Collection 中的对象,因此您可以使用其方法。

您还可以扩展该基类来创建自己的控件类。有关如何执行此操作的示例,请参阅 examples/custom-controls。

不包含任何 Controls 的地图

jsx
import { defaults as defaultControls } from 'ol/control.js'

const map = new Map({
  ...
	controls: defaultControls({
		attribution: false,
		zoom: false,
		rotate: false
	}),
})

openlayers 内置的 Controls

Zoom

一个带有两个按钮的控件,一个用于放大(zoom in),另一个用于缩小(zoom out)。此控件是地图的默认控件之一。要对该控件进行样式设置,可以使用 CSS 选择器 .ol-zoom-in.ol-zoom-out。 按照下面的代码可以禁用此控件:

jsx
const map = new Map({
  ...
	controls: defaultControls({
		zoom: false,
	}),
})

Rotate

一个用于将旋转重置为 0 的按钮控件,只会在地图 view 的 rotate 值不为 0 时出现。此控件也是地图的默认控件之一。要对该控件进行样式设置,可以使用 CSS 选择器 .ol-rotate。当旋转角度为 0 时,会为按钮添加一个 .ol-hidden CSS 选择器。 按照下面的代码可以禁用此控件:

jsx
const map = new Map({
  ...
	controls: defaultControls({
		rotate: false,
	}),
})

FullScreen

提供一个按钮,点击后将地图填充到全屏显示。默认情况下,全屏显示的元素是包含地图视图的元素,除非通过提供 source 选项进行覆盖。在这种情况下,将使用该参数指定的 DOM 元素进行全屏显示。

进入全屏模式时,会显示一个关闭按钮以退出全屏模式。使用全屏 API 来切换地图的全屏模式。

jsx
import { defaults as defaultControls, FullScreen } from 'ol/control.js'

const map = new Map({
	...
	controls: defaultControls().extend([new FullScreen()]),
})

ZoomSlider

一个用于缩放地图的滑杆

jsx
import { defaults as defaultControls, ZoomSlider } from 'ol/control.js'

const map = new Map({
	...
	controls: defaultControls().extend([new ZoomSlider()]),
})

ScaleLine

一个显示粗略 y 轴距离的控件,基于视口中心位置计算得出。对于共形投影(例如 EPSG:3857,这是 OpenLayers 的默认视图投影),比例尺在所有方向上都有效。如果无法在视图投影中计算视口中心像素的 y 轴距离,则不会显示比例尺。

默认情况下,比例尺会显示在地图的左下角,但可以通过 CSS 选择器 .ol-scale-line 进行调整。如果将 bar 设置为 true,则会渲染比例条而不是比例线。对于比例线的笛卡尔测量,需要将投影的 getPointResolution 方法设置为直接返回输入值,例如:projection.setGetPointResolution(r => r);

jsx
import { defaults as defaultControls, ScaleLine} from 'ol/control.js'

const map = new Map({
	...
	controls: defaultControls().extend([new ScaleLine()]),
})

自定义 Controls

我们写一个 openlayers 的自定义 Controls,实现以下功能: 1、实时显示地图当前的中心点的经纬度坐标; 2、每次鼠标点击地图,能够显示点击位置的经纬度; 3、实时显示地图的 zoom;

ViewInfo.js

jsx
import Control from "ol/control/Control";

export class ViewInfo extends Control {
  constructor() {
    const element = document.createElement("div");
    element.className = "ol-control map-info-control";

    element.innerHTML = `
			<div>中心点坐标: <span id="center-coords"></span></div>
			<div>点击位置坐标: <span id="click-coords"></span></div>
			<div>缩放级别: <span id="zoom-level"></span></div>
		`;

    super({
      element: element,
    });
  }

  update() {
    const centerCoordsElement = this.element.querySelector("#center-coords");
    const clickCoordsElement = this.element.querySelector("#click-coords");
    const zoomLevelElement = this.element.querySelector("#zoom-level");

    const map = this.getMap();
    // 实时更新中心点和缩放级别
    const view = map.getView();
    view.on("change:center", () => {
      const center = view.getCenter();
      if (center) {
        const [lon, lat] = center;
        centerCoordsElement.innerText = `${lon.toFixed(6)}, ${lat.toFixed(6)}`;
      }
    });

    view.on("change:resolution", () => {
      const zoom = view.getZoom();
      zoomLevelElement.innerText = zoom.toFixed(2);
    });

    // 更新点击位置
    map.on("click", event => {
      const coords = event.coordinate;
      const [lon, lat] = coords;
      clickCoordsElement.innerText = `${lon.toFixed(6)}, ${lat.toFixed(6)}`;
    });
  }
}

main.js

jsx
import "ol/ol.css";
import Map from "ol/Map.js";
import OSM from "ol/source/OSM.js";
import TileLayer from "ol/layer/Tile.js";
import View from "ol/View.js";
import { defaults as defaultControls } from "ol/control.js";
import { ViewInfo } from "./ViewInfo";

const viewInfo = new ViewInfo();

const map = new Map({
  target: "map",
  layers: [
    new TileLayer({
      source: new OSM(),
    }),
  ],
  view: new View({
    center: [0, 0],
    zoom: 3,
  }),
  controls: defaultControls({ zoom: false }).extend([viewInfo]),
});

viewInfo.update();

style.css

css
.ol-control.map-info-control {
  background: rgba(255, 255, 255, 0.8);
  padding: 10px;
  border-radius: 4px;
  font-size: 14px;
  color: #333;
}
.ol-control.map-info-control div {
  margin-bottom: 5px;
}