前言:本篇文章面向于刚接触openlayers,看过/写过一点,懂了,但没完全懂的看客。
一、openlayers是什么,有什么相似的库
openlayers是一个显示地图和地理空间数据并与之交互的库。简单的讲就是画出地图,并在地图上绘制图形、文案,或计算相关数据等。
相似的库: 百度地图、高德地图、cesium;其中openlayers、百度、高德是2D地图;cesium是3D
二、几个基础变量的理解
首先用一个例子来引入,假如现在我要实现在地图上标点。代码大致如下:
// <div id="map" style="width: 100%, height: 400px"></div>
import 'ol/ol.css';
import { Map, View, Feature, Overlay } from 'ol';
import { Circle as CircleStyle, Fill, Stroke, Style, Icon, Text } from 'ol/style';
import { LineString, Polygon, Point } from 'ol/geom';
import * as sources from 'ol/source.js';
import { OSM, XYZ, TileArcGISRest, Vector as VectorSource, WMTS } from 'ol/source';
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer';
let pointPos = [121, 29] //经纬度坐标
let map = new Map({
target: 'map',
layers: new TileLayer({
source: new sources.BingMaps({
key: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', //自己获取的token
culture: 'zh-cn'
})
})
}); //新建一个地图map,地图上的所有东西都放在map里面
let point = new Feature({
geometry: new Point(pointPos)
});//构造点
let pointLayer = new VectorLayer({
source: new VectorSource({//设置图层
features: [point]
}),
style: new Style({//设置features的样式
image: new CircleStyle({//具体设置点的样式
radius: 4,
fill: new Fill({
color: 'black'
})
})
})
});
map.addLayer(pointLayer); //将图层添加到地图上
可以看到,简单的标个点还要经历很多步骤。首先,取一个dom对象新建map,设置瓦片图层(用于显示基本地图);其次,设置一个矢量图层(用于绘制图形);接着,在矢量图层上新建Feature(要绘制的图形)并设置样式;最后,把矢量图层添加到map上。
接下来,我会用自己的理解,一一解释这些关键词的意义和作用(具体变量、键值、字段参考官方文档OpenLayers v6.9.0 API - Index)
1、map
以id为关键字段取一个dom元素作为map的容器,注意给宽高。
2、TileLayer(瓦片图层)
地图可以有许多图层。但是一般都至少有一个基本的瓦片图层,用于显示基本地图。你可以选择不同类别的瓦片图层来满足不同需求。
3、VectorLayer(矢量图层)
该图层可以自由添加,一般用于显示绘制的图形,可以设置各种图形后通过addLayer添加,removeLayer删除。并且后续只要操作该图层就可以修改样式,不会影响到其它图层。
4、Feature
为矢量图层中的一个属性,用于展示某个图层中的某个图形,该属性可以单独setStyle。并且可以单独操作某个图层的Feature【通过drawLayer.getSource().addFeature(feature)添加,其中,drawLayer为图层名;feature为该属性名】。
feature的其中一个作用:有这样一个场景,现在有多个矢量图层,图层1画点线面、图层2画不规则图形、图层3显示正射影像。所以通过Feature属性分别对不同图层进行操作,而不是每次都addLayer,造成图层混乱。
三、根据经纬度绘制点线面
OpenLayers中如何通过坐标绘制点线面 - SuperMap技术问答社区
通过基本步骤一步步将已经拿到的经纬度添加到地图中,详情参考上述网址
// 构造点
var pointsList = [
[2823.940, -4690.000],
[3448.940, -4690.301],
[3816.561, -3810.125],
[3917.383, -3609.158],
[3976.983, -3490.291],
[4020.004, -4377.027],
[4076.265, -4382.939],
[4215.049, -4382.333],
[4428.156, -4382.285]
];
// 在所有离散gps信号点添加到地图上
for (i = 0; i < pointsList.length; i++) {
var point = new ol.Feature({
geometry: new ol.geom.Point(pointsList[i])
});//构点
var pointLayer = new ol.layer.Vector({
source: new ol.source.Vector({
features: [point]
}),
style: new ol.style.Style({
image: new ol.style.Circle({
radius: 4,
fill: new ol.style.Fill({
color: 'black'
})
})
})
});
map.addLayer(pointLayer);
}
// 构造线
// 将由离散gps信号点生成的线路添加到地图上
var roadLine = new ol.geom.LineString(pointsList);
var roadLineSource = new ol.source.Vector({
features: [new ol.Feature(roadLine)]
});
var roadLineLayer = new ol.layer.Vector({
source: roadLineSource,
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'red',
width: 3
})
})
});
map.addLayer(roadLineLayer);
// 构造面
var polygon = new ol.geom.Polygon([[[0, 0], [-10, 30], [-30, 0], [0, 0]]]);
var polygonSource = new ol.source.Vector({
features: [new ol.Feature(polygon)],
wrapX: false
});
vectorLayer = new ol.layer.Vector({
source: polygonSource,
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'red',
width: 3
}),
fill: new ol.style.Fill({
color: 'rgba(0, 0, 255, 0.1)'
})
})
});
map.addLayer(vectorLayer);
四、手动在地图上绘制点线面
可加细节Measure
五、测量与计算
openlayers有自带,但是我用了turf插件(Turf.js中文网),这个插件在图形测量与计算方面会更强大一些。
使用起来非常简单,除了简单的长度,区域面积外,还能满足其他奇奇怪怪的需求。(PS:我遇到个需求,计算折线的中点,愣是没想明白怎么搞,用这个插件,2分钟搞定)
六、图层切换
2个图层的切换刚开始我用add和remove,但是图层一旦多了起来,这样的操作显然不具备可行性。后面我控制图层的显隐来实现图层切换。核心代码如下:
map = new Map({
target: 'map',
layers: [BingMaps, drawLayer, rasterProject, designLayer], //这里有4个图层(包括瓦片图层BingMaps)
view: viewer,
controls: defaultControls({
zoom: false
})
});
if(xxxx) { //达到某个条件后,给rasterProject设置图层和显隐
let source = new XYZ({ //图层是XYZ类,可以自己选择其他图层
url: `xxxxxxxxxx` //自己的url
});
rasterProject.setSource(source);
rasterProject.setVisible(true);
}
欢迎指正错误