开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第46天,点击查看活动详情
openlayers.js
基础知识
投影坐标的概念
地理坐标系:用三维建模构建的一个椭球体,同时将这个椭圆球体进行栅格化并标注位置, 我们平常所用的经纬度就是地理学坐标单位。投影坐标系:用二维模型描述一个球体,实质 上也是对椭圆球体进行栅格处理,但是他会把球体上的坐标展开到一张地图上,对于 3D 来 说 2D 更容易分析和携带。
EPSG:4326 和 3857 区别
在 web 页面上显示的时候以 3857 这个投影来显示,存储数据的时候使用 4326 来存储 。 EPSG 是一个代号,在国际上每一个坐标系统都会分配一个 EPSG 代码。
EPSG:4326(WGS84):世界大地测量系统 1984:WGS84(World Geodetic System of 1984) 是世界上最流行的地理坐标系统,代号为 EPSG:4326,用来描述地球上的各个位 置坐标;GPS 就是基于 WGS84 的,WGS84 又是基于 GeoJSON 作为坐标系统的单位,也就是 经纬度,所以我们说的经度纬度得到的数据都是基于 EPSG:4326 这个系统的。缺点是不 适合展示数据,适合存储数据,数据格式是经纬度:[130, 20] 。
EPSG:3857(Pseudo-Mercator):伪墨卡托投影,也被称为球体墨卡托投影,代号为 EPSG:3857;该投影不能显示北纬南维 85.06 度以上的地区,但是能把球体(3D)投影成一张 正方形地图(2D),2D 地图是非常适合用来展示分析的,但是不适合用来存储数据,数据 格式是:[12914838.35,4814529.9] 。
核心组件
Map 类:地图容器,最核心的部件,用于装载图层与各种控件。 Layer 类:地图图层类, 地图数据通过 Layer 图层进行渲染,数据源可以分为:
- Image:单一图像数据。
- Tile:瓦片数据,可以联想下站在金字塔顶一层一层往下看,越来越详细。
- Vector:矢量数据
View 类:地图视图类,用于提供人机交互的控件,如缩放移动旋转等等操作。
加载地图两种方式
有两种方式能加载地图:
- 直接在 map 类的 layers 图层中加载。
import { Map, View } from 'ol';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ';
const publicKey = 'xxxxx'; // 自行去注册获取:https://www.tianditu.gov.cn/
const url = `http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=${publicKey}`;
const url2 = `http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=${publicKey}`;
const map = new Map({
target: 'map',
layers: [
new TileLayer({
title: '天地矢量图层',
source: new XYZ({
url: url, // 地图瓦片层
attributions: '天地图的属性描述',
wrapX: false, // 地图是否是无边际的
}),
}),
new TileLayer({
title: '天地矢量标记图层',
source: new XYZ({
url: url2, // 地图标记层
}),
}),
],
view: new View({
center: [0, 0], // 初始地图显示的位置,经纬度
zoom: 2, // 初始缩放级别
minZoom: 1, // 最小缩放级别
maxZoom: 20, // 最大缩放级别
// rotation: Math.PI / 6, // 旋转地图
}),
});
- 使用 addLayer 往 map 容器中调价 layers 图层
const map = new Map({
target: 'map',
layers: [], // 初始图层为空
view: new View({
center: [0, 0],
zoom: 2,
minZoom: 1,
maxZoom: 20,
// rotation: Math.PI / 6, // 旋转地图
}),
});
let layers1 = new TileLayer({
title: '天地矢量图层',
source: new XYZ({
url: url,
attributions: '天地图的属性描述',
wrapX: false, // 地图是否是无边际的
}),
});
let layers2 = new TileLayer({
title: '天地矢量标记图层',
source: new XYZ({
url: url2,
}),
});
map.addLayer(layers1); // 通过addLayer添加
map.addLayer(layers2); // 通过addLayer添加