Skip to content

View 对象:地图视图控制中心

View 是 OpenLayers 中控制地图显示状态的核心组件,负责管理地图的中心点、缩放级别、旋转角度和坐标系等关键参数。

核心属性

属性名类型默认值描述
centerArray[0, 0]地图中心坐标(地图投影坐标系)
constrainRotationbooleantrue是否约束旋转角度为 0、90、180、270 度(默认为 false)
zoomnumberundefined仅在 resolution 未定义时使用。用于计算视图初始分辨率的缩放级别
projectionstring'EPSG:3857'地图坐标系(如'EPSG:4326')
minZoomnumber0最小缩放级别
maxZoomnumber28最大缩放级别
resolutionnumberundefined分辨率(替代 zoom 使用)
resolutionsArrayundefined分辨率数组(用于自定义缩放级别)
rotationnumber0旋转角度(弧度)
extentArrayundefined地图视图的边界限制([minx, miny, maxx, maxy])
constrainOnlyCenterbooleanfalse是否仅限制中心点在 extent 内(默认为限制整个视图)
constrainResolutionbooleanfalse是否将缩放操作约束为固定分辨率(整数级别)
smoothExtentConstraintbooleantrue是否平滑过渡到约束范围
enableRotationbooleantrue是否允许旋转
maxResolutionnumberundefined最大分辨率
minResolutionnumberundefined最小分辨率
zoomFactornumber2缩放因子(每次缩放的比例)
multiWorldbooleanfalse是否允许地图在世界范围外平移(WGS84 投影下通常设为 true)
js
// 中国区域推荐配置
const view = new View({
  projection: "EPSG:4326", // 使用经纬度坐标
  center: [116.4, 39.9], // 北京市中心
  zoom: 10,
  minZoom: 3, // 限制最小缩放
  maxZoom: 18, // 限制最大缩放
  constrainResolution: true, // 整数缩放级别
  multiWorld: true, // 允许超出经度-180~180范围
});

projection

  • 定义地图坐标系,EPSG:3857为 Web 墨卡托投影(默认),EPSG:4326为 WGS84 经纬度坐标系(常用)。
  • 所有图层必须使用相同投影
js
new View({
  projection: "EPSG:4326", // 使用经纬度坐标系
});
  • 经纬度 -> 墨卡托投影坐标
js
import { fromLonLat } from "ol/proj";

new View({
  center: fromLonLat([116.4, 39.9]), // 将经纬度转换为EPSG:3857坐标
});
  • 墨卡托投影坐标 -> 经纬度
js
import { toLonLat } from "ol/proj";
const lonLat = toLonLat([1296000, 4820000]); // 将墨卡托投影坐标转换为经纬度
console.log(lonLat); // 输出经纬度坐标[11.642166082188997, 39.68311704790915]
  • transform 将坐标从源投影转换到目标投影。这会返回一个新的坐标(并且不会修改原始坐标)
js
import { transform } from "ol/proj";

// 经纬度坐标转换为墨卡托投影坐标
var mercator = transform([116.4074, 39.9042], "EPSG:4326", "EPSG:3857");
console.log(mercator); // 输出:[12958412.492568914, 4852030.634814578]

// 墨卡托投影坐标转换为经纬度坐标
var lonlat = transform(
  [12958412.492568914, 4852030.634814578],
  "EPSG:3857",
  "EPSG:4326"
);
console.log(lonlat); // 输出:[116.4074, 39.9042]

center

设置地图中心点坐标,一般使用经纬度坐标

js
new View({
  center: [116.4074, 39.9042], // 北京市中心坐标
  projection: "EPSG:4326", // 使用经纬度坐标系
});

zoom

设置地图缩放级别,如果设置了 resolution,则 zoom 会被忽略

js
new View({
  zoom: 10.5, // 设置缩放级别,可以为小数
});

minZoom & maxZoom

限制缩放级别范围,只影响用户交互和 API 缩放,不影响直接设置 resolution

js
new View({
  minZoom: 3,
  maxZoom: 18,
  zoom: 10,
});

rotation

视图的初始旋转角度,以弧度表示(正旋转为顺时针方向,0 表示北方)

js
new View({
  rotation: Math.PI / 4, // 旋转45度
});

extent

设置地图边界,此范围之外的内容无法在地图上显示,值为[minx, miny, maxx, maxy]

js
// 限制视图在北京市范围内
new View({
  extent: [115.4, 39.4, 117.5, 41.0],
});

resolution

直接设置分辨率,一般直接设置zoom即可,除非需要精确控制显示比例时使用

js
// 在EPSG:3857中,zoom0的分辨率约为156543.03392804097
new View({
  resolution: 78271.51696402048, // 相当于zoom1
});

核心方法

方法名描述
getCenter()获取当前视图中心坐标
setCenter(center)设置视图中心
getZoom()获取当前缩放级别(整数或小数)
setZoom(zoom)设置缩放级别(立即生效)
getRotation()获取当前旋转角度(弧度)
setRotation(rotation)设置旋转角度(弧度)
getProjection()获取当前投影对象
getResolution()获取当前分辨率
setResolution(resolution)设置分辨率(立即生效)
getResolutions()获取分辨率数组(如果设置)
getMinZoom()获取最小缩放级别
setMinZoom(zoom)设置最小缩放级别
getMaxZoom()获取最大缩放级别
setMaxZoom(zoom)设置最大缩放级别
getMinResolution()获取最小分辨率
getMaxResolution()获取最大分辨率
animate(animation)执行动画效果(移动、缩放、旋转等)
cancelAnimations()取消任何正在进行的动画
fit(geometry, options)调整视图以适配指定几何体或范围
calculateExtent(size)计算当前视图的范围(需传入地图容器尺寸[width, height])

视图控制方法

js
// 获取当前视图状态
const center = view.getCenter();
const zoom = view.getZoom();
const rotation = view.getRotation();

// 设置视图状态(立即生效)
view.setCenter([13500000, 4500000]);
view.setZoom(8);
view.setRotation(Math.PI / 6);

animate() - 动画效果

执行平滑的视图过渡,单个动画配置对象或数组

动画配置属性

属性名类型描述
centerArray目标中心
zoomnumber目标缩放
resolutionnumber目标分辨率
rotationnumber目标旋转
durationnumber动画时长(毫秒)
easingfunction缓动函数 参考 常用 api
js
// 平滑移动到新位置
view.animate({
  center: [116.4, 39.9],
  zoom: 14,
  duration: 2000,
  easing: ol.easing.easeIn,
});

// 链式动画:先缩放后移动
view.animate([
  { zoom: 10, duration: 1500 },
  { center: [121.4, 31.2], duration: 1000 },
]);

fit() - 适配显示

fit(geometryOrExtent, options)自动调整视图以完整显示指定区域

  • geometryOrExtent:适配视图的几何形状或范围,矢量图形

  • options:适配选项对象,包含以下属性:

选项名类型默认值描述
sizeArray地图容器尺寸用于计算适配的容器尺寸([width, height])
paddingArray[0,0,0,0]内边距([top, right, bottom, left])
minResolutionnumber0适配的最小分辨率
maxZoomnumberundefined适配的最大缩放级别
durationnumberundefined动画时长(毫秒)
easingfunctionundefined缓动函数
callbackfunctionundefined动画完成后的回调函数
定位跳转
vue
<template>
  <div ref="mapContainer" id="map"></div>
  <div style="position: absolute; top: 10px; left: 100px; z-index: 1000">
    <button @click="goto">定位到polygon区域</button>
  </div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import Map from "ol/Map.js";
import XYZ from "ol/source/XYZ.js";
import TileLayer from "ol/layer/Tile.js";
import View from "ol/View.js";
import "ol/ol.css";
import Polygon from "ol/geom/Polygon.js";
import Style from "ol/style/Style";
import Fill from "ol/style/Fill";
import Stroke from "ol/style/Stroke";
import Vector from "ol/source/Vector.js";
import VectorLayer from "ol/layer/Vector.js";
import Feature from "ol/Feature.js";

const mapContainer = ref(null);
let map = null;
let view = null;
let polygon = null;
onMounted(() => {
  initMap();
});
const initMap = () => {
  view = new View({
    center: [116.4, 39.9], // 北京市中心经纬度
    zoom: 10.5,
    projection: "EPSG:4326", // 默认使用球面墨卡托投影(EPSG:3857),需要设置为WGS 84(EPSG:4326)经纬度
    // extent: [115.4, 39.4, 117.5, 41.0],
  });
  map = new Map({
    target: mapContainer.value,
    layers: [
      new TileLayer({
        // 设置高德地图为数据源底图
        source: new XYZ({
          // 矢量图(含路网、含注记)
          url: "http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7 ",
        }),
      }),
    ],
    view,
  });

  polygon = new Polygon([
    [
      [117.4, 39.9],
      [117.5, 39.9],
      [117.5, 40.0],
      [117.4, 40.0],
      [117.4, 39.9],
    ],
  ]);
  // 将polygon渲染到地图上,设置颜色为红色
  const feature = new Feature({
    geometry: polygon,
  });
  const source = new Vector({
    features: [feature],
  });
  const layer = new VectorLayer({
    source,
    style: new Style({
      fill: new Fill({
        color: "rgba(255, 0, 0, 0.5)", // 半透明红色填充
      }),
      stroke: new Stroke({
        color: "red", // 红色边框
        width: 2,
      }),
    }),
  });
  map.addLayer(layer);
};
const goto = () => {
  // 定位到polygon区域
  view.fit(polygon, {
    padding: [50, 50, 50, 50], // 四周留白
    duration: 3000,
    maxZoom: 15,
  });
};
</script>
<style scoped>
#map {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}
</style>

calculateExtent()

通过传入地图容器的尺寸,计算当前视图的范围。返回值为 [minX, minY, maxX, maxY]

js
// 计算当前视图范围
const mapSize = map.getSize();
const currentExtent = view.calculateExtent(mapSize);
console.log(currentExtent); // 输出范围 [minX, minY, maxX, maxY]