一、安装依赖
"ol": "^7.3.0",
"proj4": "^2.8.0",
二、 初始化一个简单的地图
创建地图的代码如此简单,以致于让一部分初学者误认为在此基础上的深入开发也很简单,这是一个非常错误的理解。此时,最关键的第一步是先弄明白每一句代码的含义,理解他们是如何组织起来的。否则,在后续的学习和使用过程中,犹如瞎子摸象,会找不到问题的关键点而迷失方向。
const proj = 'EPSG:4326' // 投影坐标系
const projection = olProj.get(proj) // 投影类别
projection.setExtent([-180, -90, 180, 90])
// 初始化地图对象
let defaultMap = {
toolbox: true,
proj: proj,
target: 'map',
center: [108.99991, 19.02382],
zoom: 13
}
this.mapObj = new Map({
target: mapOpts.target,
view: new View({
projection: projection, //投影类别
center: mapOpts.center, // 视角的中心
zoom: mapOpts.zoom, // 默认缩放等级
minZoom: 6, // 最小缩放等级
maxZoom: 15 // 最大缩放等级
})
})
二、地图图层-Layer
①添加图层
地图的初始化完成后,它只是一个具备了地图API的容器,在页面上的显示依然是一片空白,这个时候我们就需要为它添加图层,展示我们所需要的地图,这里以天地图图层作为例子。
//设置一些加载地图瓦片所需要用到的配置参数
const projectionExtent = projection.getExtent()
const size = getWidth(projectionExtent) / 256
const resolutions = new Array(18)
const matrixIds = new Array(18)
for (let z = 1; z < 19; ++z) {
resolutions[z] = size / Math.pow(2, z)
matrixIds[z] = z
}
const wmtsUrl_0 = "http://t{0-7}.tianditu.gov.cn/img_c/wmts?tk="; // 影像底图
const wmtsUrl_1 = "http://t{0-7}.tianditu.gov.cn/cia_c/wmts?tk="; // 影像注记
const webKey = '填写从天地图申请到的key值'
// 这里是声明一个影像图图层和对应的地图注记,除开影像图,天地图还提供了矢量图层,这里就不声明了,方式是一样的.
let imgTile = new TileLayer({
id: "img",
source: new WMTS({
url: wmtsUrl_0 + webKey,
layer: "img",
matrixSet: "c",
format: "tiles",
style: "default",
projection: projection,
tileGrid: new WMTSTileGrid({
origin: getTopLeft(projectionExtent),
resolutions: resolutions,
matrixIds: matrixIds,
}),
wrapX: true,
}),
});
let cia_n = new TileLayer({
id: "cia_n",
source: new WMTS({
url: wmtsUrl_1 + webKey,
layer: "cia",
matrixSet: "c",
format: "tiles",
style: "default",
projection: projection,
tileGrid: new WMTSTileGrid({
origin: getTopLeft(projectionExtent),
resolutions: resolutions,
matrixIds: matrixIds,
}),
wrapX: true,
}),
});
// 把图层加到地图组件进去,只需要调用openlayers提供的API,addLayer方法.
this.mapObj.addLayer(imgTile)
this.mapObj.addLayer(cia_n)
②切换图层
图层的切换十分简单,只需要通过Id,获取到图层的本身就可以控制显隐.
//获取图层
getLayer(id) {
let layer
this.mapObj.getLayers().forEach(function (f) {
if (f.getProperties().id == id) {
layer = f
return false
}
})
return layer
},
//显示图层
showLayer(id) {
let layer = this.getLayer(id)
if (layer) {
layer.setVisible(true)
}
},
//隐藏图层
hideLayer(id) {
var layer = this.getLayer(id)
if (layer) layer.setVisible(false)
},
三、地图点位-Point
仅仅只有一张普通的地图太过单调,也没有任何意义,这里简单介绍一下,如何根据经纬度信息往地图上添加一些地图点位。说起点位不得不提到feature对象,feature可以理解成是我们自定义在地图上添加的元素,所以要把点位信息赋予给feature,然后再把feature添加到地图上。
let newFeature = new Feature({
id: data.id, // 自己定义的id
data: data, // 需要让feature携带的数据
geometry: new Point(data.position) // point对象,只需要传入一个经纬度坐标即可
})
以上代码就可以在地图上添加一个蓝色圆点,但是如果我们需要对这个点位做一些个性化的设置,则需要通过改变它的style来完成。
new Style({
text: new Text({
textAlign: "center", //位置
textBaseline: "middle", //基准线
font: "normal 16px 微软雅黑", //文字样式
text: name, //文本内容
fill: new Fill({
//文本填充样式(即文字颜色)
color: "#FFF89A",
}),
stroke: new Stroke({
color: "#12a2ee",
width: 2,
}),
}),
// 改变整个点位的样式,把小圆点用图标代替
image: new Icon({
src: require("@/assets/imgs/u26.png"),
rotateWithView: false,
scale: 0.8
})
四、地图交互-interaction
地图上添加了各种各样的元素之后,我们还想要能够地图根据我们的反馈,给我们展示对应的信息,此时需要添加可以跟地图交互的代码。
①首先为了让用户知道是可以跟地图交互的,当鼠标碰到地图元素的时候,让鼠标变成小手.
this.mapObj.on('pointermove', (e) => {
let pixel = this.mapObj.getEventPixel(e.originalEvent)
let feature = this.mapObj.forEachFeatureAtPixel(pixel, (feature) => {
return feature
})
if (feature) {
if (feature.values_.id == undefined) {
this.mapObj.getTargetElement().style.cursor = 'auto'
} else {
this.mapObj.getTargetElement().style.cursor = 'pointer'
}
}
})
②点击地图点位的时候,我们要获取相关信息,并作出展示,这个时候前面新建Feature时候的data就起作用了
var selectSingleClick = new Select();
map.mapObj.addInteraction(selectSingleClick);
// feature点击事件
selectSingleClick.on("select", (e) => {
let features = e.target.getFeatures().getArray();
if (features.length > 0) {
let feature = features[0];
let featureObj = feature.values_;
if (!featureObj.data) {
return
}
console.log(featureObj.data)
}
// 由于点击图表点位的时候,会出现一个蓝色小圆点,这里需要做移除操作.
setTimeout(() => {
selectSingleClick.getFeatures().clear();
}, 1);
});