View
就是这样的,作为地图的窗口,做一些改变,就能看到变化,便于初学者学习。同时,View
是OpenLayers地图组成部分中非常重要的一个概念,涉及到地图移动,放大,缩小,旋转等,这些功能是任何一个GIS引擎必不可少的。为此,我们把它作为最先介绍和学习的组成部分。
1.view之视图导航
在深入学习之前,还是先来个开胃菜,见识一下View所承载的功能。下面将演示地图导航功能,关于导航相关功能,在前面操作地图的时候,已经有了充分的理解和认识。为什么我们还要再讨论它呢?因为这次的导航功能,需要自己来实现,而且只使用ol.View提供的方法就可以做到。
我们先创建地图,实现左移,右移,上移,下移,移动到重庆,放大,缩小
这几个功能
我们还是以vue3中的代码为案例
<script setup lang="ts">import "ol/ol.css";import { ref, onMounted } from "vue";import * as ol from "ol";import { Projection, addProjection } from "ol/proj";import { XYZ } from "ol/source";import Tile from "ol/layer/Tile";const mapRef = ref();const olmap = ref();onMounted(() => {// 4490处理const projection = new Projection({code: "EPSG:4490",units: "degrees",axisOrientation: "neu"});projection.setExtent([-180, -90, 180, 90]);projection.setWorldExtent([-180, -90, 180, 90]);addProjection(projection);const GJ_TDT_HOST = () =>`http://t${Math.round(Math.random() * 7)}.tianditu.com/DataServer?T=`;const GJ_TDT_TOKEN = "13a4fee837babd2b8c569ebff100fe9f";olmap.value = new ol.Map({layers: [new Tile({source: new XYZ({projection: "EPSG:4490",url: `${GJ_TDT_HOST()}vec_c&x={x}&y={y}&l={z}&tk=${GJ_TDT_TOKEN}`})}),new Tile({source: new XYZ({projection: "EPSG:4490",url: `${GJ_TDT_HOST()}cva_c&x={x}&y={y}&l={z}&tk=${GJ_TDT_TOKEN}`})})],view: new ol.View({projection: "EPSG:4490",center: [107.530635013, 29.5446061089],zoom: 8,minZoom: 6}),target: mapRef.value});});
</script>
<template><div id="map" ref="mapRef"><div id="navigate"><el-button @click="moveToLeft()">左移</el-button><el-button @click="moveToRight()">右移</el-button><el-button @click="moveToUp()">上移</el-button><el-button onClick="moveToDown();">下移</el-button><el-button @click="moveToChengDu()">移到成都</el-button><el-button @click="zoomIn()">放大</el-button><el-button @click="zoomOut()">缩小</el-button></div></div>
</template><style scoped>#map {position: absolute;left: 0;width: 100%;height: 100%;border: 1px solid #ccc;}
</style>
1.1实现左移方法
const moveToLeft = () => {const view = olmap.value.getView();const mapCenter = view.getCenter();// 让地图中心的x值增加,即可使得地图向左移动,增加的值根据效果可自由设定mapCenter[0] += 1;view.setCenter(mapCenter);olmap.value.render();};
1.2实现右移方法
const moveToLeft = () => {const view = olmap.value.getView();const mapCenter = view.getCenter();// 让地图中心的x值增加,即可使得地图向左移动,增加的值根据效果可自由设定mapCenter[0] += 1;view.setCenter(mapCenter);olmap.value.render();};
1.3 实现上移方法
const moveToUp = () => {const view = olmap.value.getView();const mapCenter = view.getCenter();mapCenter[1] -= 1;view.setCenter(mapCenter);olmap.value.render();
};
1.4实现下移方法
const moveToDown = () => {const view = olmap.value.getView();const mapCenter = view.getCenter();mapCenter[1] += 1;view.setCenter(mapCenter);olmap.value.render();
};
1.5 定位到重庆
const moveToCq = () => {const view = olmap.value.getView();view.setCenter([107.530635013, 29.5446061089]);
};
1.6 放大
const zoomIn = () => {const view = olmap.value.getView();view.setZoom(view.getZoom() + 1);
};
1.7 缩小
const zoomOut = () => {const view = olmap.value.getView();view.setZoom(view.getZoom() - 1);
};
2.坐标
关于原点,方向,单位
等等的相关定义和描述,组成了我们常说的坐标系。
2.1 坐标系及投影
在GIS中我们需要地理坐标系。但它并不像笛卡尔坐标系那样简单,学过地理知识就知道,地球并不是一个完全规则的球体。在不同的地区,为了在数学上表示它,就出现了多种不同的参考椭球体,比如克拉索夫斯基(Krasovsky)椭球体,WGS1984椭球体,更多的椭球体参见参考椭球体。在参考椭球体的基础上,就发展出了不同的地理坐标系,比如我国常用的WGS84,北京54,西安80坐标系,欧洲,北美也有不同的坐标系。北京54使用的是克拉索夫斯基(Krasovsky)椭球体,WGS84使用的是WGS1984椭球体。由此可见,多个坐标系是源于地理的复杂性
。
由于存在着多种坐标系,即使同样的坐标,在不同的坐标系中,也表示的是不同的位置,这就是大家经常遇到的偏移问题的根源,要解决这类问题,就需要纠偏,把一个坐标系的坐标转换成另一个坐标系的坐标
。由于WGS84是全球通用的坐标系,涉及到多个坐标系与它之间的转换
有了坐标系后,我们就能精确的表示地球上的每一个位置,但为什么还需要投影呢?投影是为了把不可展的椭球面描绘到平面上,它使用几何透视方法或数学分析的方法,将地球上的点和线投影到可展的曲面(平面、园柱面或圆锥面)上,再将此可展曲面展成平面
,建立该平面上的点、线和地球椭球面上的点、线的对应关系。正是因为有投影,大家才能在网页上看到二维平面的地球地图。
2.2 ol中使用的坐标系
目前OpenLayers 3支持两种投影,一个是EPSG:4326
,等同于WGS84坐标系,参见详情。另一个是EPSG:3857
,等同于900913,由Mercator投影而来,经常用于web地图,参见详情。一个是全球通用的,一个是web地图专用的,自然OpenLayers支持它们。在使用过程中,需要注意OpenLayers默认使用的是EPSG:3857。这也是为什么前面的代码里需要进行坐标转换的原因。 既然支持EPSG:4326,为什么还要转换?当然是可以不用转换的,但前提是你得指定使用具体那种投影,就像下面这样。
import { Projection, addProjection } from "ol/proj";const projection = new Projection({code: "EPSG:4490",units: "degrees",axisOrientation: "neu"});projection.setExtent([-180, -90, 180, 90]);projection.setWorldExtent([-180, -90, 180, 90]);addProjection(projection);
3.ol.View的应用
1.限制地图的范围
在实际使用中,往往只关心某一个区域的地图,而无需显示整个地球的地图
,这样可以聚焦于业务,同时可以减少前端和后台的地图数据。无疑,这样的功能是非常有用的。下面我们就将看到,地图只能在经度29度到31度,纬度在102到104度之间显示.
view: new ol.View({projection: "EPSG:4490",center: [107.530635013, 29.5446061089],extent: [102, 29, 104, 31],zoom: 8,minZoom: 6}),
就只是添加了 extent: [102, 29, 104, 31],这行代码就实现了功能。extent参数类型为[minX, minY, maxX, maxY]
的ol.Extent,很容易记住
2.自适配区域
在实际应用中,会有一些地图查找和标注的业务,比如查看重庆渝北区。而这时,地图所在区域可能是北京,我们需要能够让地图直接定位到渝北区,并且最大化完全地显示这块区。
const fitToyubei = () => {olmap.value.getView().fit([106.631187, 29.718143, 107.631187, 30.718143]);
};
只用了一行代码,ol.View的fit函数很强大,希望能认真仔细的查看API文档,它的第三个参数还可以设置更多的选项,以适应更多的需要。