Controls
控件是屏幕上具有固定位置的可见小部件,带有一个 DOM 元素。它们可以涉及用户输入(如按钮),也可以仅用于信息显示;其位置通过 CSS 确定。默认情况下,这些控件被放置在具有 CSS 类名 ol-overlaycontainer-stopevent
的容器中,但也可以使用任何外部 DOM 元素。
这是控件的基类。通过创建带有监听器的元素和一个实例,您可以用它来实现简单的自定义控件:
const myControl = new Control({ element: myElement });
然后将其添加到地图中即可。
将控件作为控件而不是简单的独立 DOM 元素的主要优势在于,它会为您处理事件传播的阻止。此外,控件还会作为 Collection
中的对象,因此您可以使用其方法。
您还可以扩展该基类来创建自己的控件类。有关如何执行此操作的示例,请参阅 examples/custom-controls。
不包含任何 Controls 的地图
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
。 按照下面的代码可以禁用此控件:
const map = new Map({
...
controls: defaultControls({
zoom: false,
}),
})
Rotate
一个用于将旋转重置为 0 的按钮控件,只会在地图 view 的 rotate 值不为 0 时出现。此控件也是地图的默认控件之一。要对该控件进行样式设置,可以使用 CSS 选择器 .ol-rotate
。当旋转角度为 0 时,会为按钮添加一个 .ol-hidden
CSS 选择器。 按照下面的代码可以禁用此控件:
const map = new Map({
...
controls: defaultControls({
rotate: false,
}),
})
FullScreen
提供一个按钮,点击后将地图填充到全屏显示。默认情况下,全屏显示的元素是包含地图视图的元素,除非通过提供 source
选项进行覆盖。在这种情况下,将使用该参数指定的 DOM 元素进行全屏显示。
进入全屏模式时,会显示一个关闭按钮以退出全屏模式。使用全屏 API 来切换地图的全屏模式。
import { defaults as defaultControls, FullScreen } from 'ol/control.js'
const map = new Map({
...
controls: defaultControls().extend([new FullScreen()]),
})
ZoomSlider
一个用于缩放地图的滑杆
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);
。
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
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
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
.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;
}