Openlayers加载在线地图,画点、线、面、图片、自定义切图等数据源,大数据下的聚合标注,绘制交互等
参考 https://openlayers.org/en/latest/examples ,官网更详细
1、地图
加载在线地图资源,这里以天地图为例
const baseLayer = new Tile() // 底图
const labelLayer = new Tile() // 标注
map = new ol.Map({
layers: [baseLayer, labelLayer],
target: Element, // 绑定的dom元素
view: new ol.View({
center: center, // 中心点坐标
maxZoom: maxZoom, // 最大缩放等级
minZoom: minZoom, // 最小缩放等级
zoom: zoom // 默认缩放等级
})
})
getTdtSource(lyr) {
const key = '3d7245b3b701467ef55e80a971c91612' // 当出现418、429状态码,可能是apiKey超出每日调用限制了,换一个或自己注册
const url = 'http://t{0-7}.tianditu.com/DataServer?T=' + lyr + '&X={x}&Y={y}&L={z}&tk=' + key
return new XYZ({
url: url
})
}
/**
* 切换地图瓦片材质
* @param {string} type 默认矢量图
* @example ['影像','地形']
*/
changeBaseLayer(type) {
let baseSource, labelSouce
switch (type) {
case '影像':
{
baseSource = this.getTdtSource('img_w')
labelSouce = this.getTdtSource('cia_w')
break
}
case '地形':
{
baseSource = this.getTdtSource('ter_w')
labelSouce = this.getTdtSource('cva_w')
break
}
default: // 矢量图
{
baseSource = this.getTdtSource('vec_w')
labelSouce = this.getTdtSource('cva_w')
break
}
}
baseLayer.setSource(baseSource)
labelLayer.setSource(labelSouce)
}
2、加载切片
const osmSource = new ol.source.OSM()
const projectionExtent = fromEPSG4326(projectionExtent) // 切片范围
const projection = new Projection({
code: 'EPSG:3857',
units: 'pixel',
extent: projectionExtent,
global: true
})
const tileGrid = new TileGrid({
tileSize: 256,
minZoom: 11,
origin: [-2.00377E7, 3.02411E7],
extent: projectionExtent,
resolutions: osmSource.getResolutions()
})
const untiled = new Tile({
source: new TileImage({
wrapX: false,
crossOrigin: 'anonymous',
tileUrlFunction: function(tileCoord) { // 加载切片瓦片地址
if (!tileCoord) {
return ''
}
const z = tileCoord[0]
let x = tileCoord[1]
// const y = Math.pow(2, z-1) + tileCoord[2];
const y = Math.pow(2, z) + tileCoord[2] // openlayers 3.x
// const y = Math.abs(tileCoord[2]);
// wrap the world on the X axis
const n = Math.pow(2, z + 1) // 2 tiles at z=0
x = x % n
if (x * n < 0) {
x = x + n
}
const path = '/' + z + '/' + x + '/' + y + '.png'
return path
}
}),
tileGrid: tileGrid,
projection: projection
})
map.addLayer(untiled)
3、销毁实例
由于OpenLayers中大量用到了闭包,最开始OpenLayers的内存泄露、销毁问题也是蛮严重的,后面差不多每个类中都写了destroy方法,用于释放资源,在单页应用中,在销毁当前组件前应调用下Openlayers用到那些类的destroy方法以释放资源。
/**
* 销毁openlayers,内存回收
* @summary 移除UI控件、交互、图层、要素、覆盖物
*/
destroy() {
const controls = map.getControls().getArray()
const interactions = =map.getInteractions().getArray()
const layers = map.getLayers().getArray()
const overlays = map.getOverlays().getArray()
for (let i = controls.length - 1; i >= 0; i--) {
map.removeControl(controls[i])
}
for (let i = interactions.length - 1; i >= 0; i--) {
map.removeInteraction(interactions[i])
}
for (let i = layers.length - 1; i >= 0; i--) {
const sources = layers[i].getSource()
if (sources && sources.clear) sources.clear()
map.removeLayer(layers[i])
}
for (let i = overlays.length - 1; i >= 0; i--) {
map.removeOverlay(overlays[i])
}
}
4、画各种要素、数据源
4.1、点
const feature = new Feature({
geometry: new Point(coordinates)
})
const pointLayer = new VectorLayer({
source: new VectorSource({
features: [feature]
}),
style: function(feature) {}
})
this.map.addLayer(pointLayer)
4.2、线
const features = []
for (let i = 0; i < data.length; i++) {
const feature = new ol.Feature({
geometry: new ol.geom.LineString(data[i])
})
features.push(feature)
}
const lineLayer = new ol.layer.Vector({
source: new ol.source.Vector({
features: features
}),
style: function(feature) {}
})
map.addLayer(lineLayer)
4.3、面
const extent = [x1, y1, x2, y2]
// 多边形要素
const polygonFeature = new ol.Feature(
new ol.geom.Polygon(
[
[
[x1, y1], // 原点
[x1, y2], // 第二个点
[x2, y2], // 第三个点
// ……
[x1, y1] // 回到原点
]
]
)
)
const source = new ol.source.Vector({
features: [polygonFeature]
})
var polygonLayer = new ol.layer.Vector({
source: source,
style: function() {}
})
map.addLayer(polygonLayer)
4.4、单张图片
const source = new ol.source.ImageStatic({
attributions: img.name, // 图片的名称
url: img.url, // 图片的地址
imageExtent: img.imageExtent // 图片的展示范围,无参考坐标系可以用图片的尺寸
})
const tl = new ol.layer.Image({
source: source
})
map.addLayer(tl)
5、聚合
//此示例创建10000个要素
const count = 10000;
const features = new Array(count);
const e = 4500000;
for(let i = 0; i < count; i++){
const coordinates = [2*e*Math.random()-e, 2*e*Math.random()-e];
features[i] = new ol.Feature(
new ol.geom.Point(coordinates)
);
}
//矢量要素数据源
const source = new ol.source.Vector({
features: features
});
//聚合标注数据源
const clusterSource = new ol.source.Cluster({
distance: 40, //聚合的距离参数,即当标注间距离小于此值时进行聚合,单位是像素
source: source //聚合的数据源,即矢量要素数据源对象
});
//加载聚合标注的矢量图层
const styleCache = {}; //用于保存特定数量的聚合群的要素样式
const clusters = new ol.layer.Vector({
source: clusterSource,
style: function (feature, resolution){
const size = feature.get('features').length; //获取该要素所在聚合群的要素数量
let style = styleCache[size];
if(!style){
style = [
new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
stroke: new ol.style.Stroke({
color: '#fff'
}),
fill: new ol.style.Fill({
color: '#3399CC'
})
}),
text: new ol.style.Text({
text: size.toString(),
fill: new ol.style.Fill({
color: '#fff'
})
})
})
];
styleCache[size] = style;
}
return style;
}
});
map.addLayer(clusters);
6、覆盖物
/**
* 添加覆盖要素
* @param { HTMLElement | String } 元素id | HTML元素
* @param { String } positioning 容器基于鼠标点的定位
* @param { Array } offset 容器的偏移
*/
addOverLayers(name = 'simpleCarBox', positioning, offset = [0, 0]) {
this.overlay = new ol.Overlay({
id: name,
element: document.getElementById(name),
autoPan: true,
positioning,
offset,
autoPanAnimation: {
duration: 250
}
})
this.map.addOverlay(this.overlay)
}
/**
* 更新信息气泡的位置
* @param {Array} coordinate 新的坐标点
*/
setOverLayer(coordinates) {
this.overlay.setPosition(coordinates)
}
7、绘制、交互
const drawSource = new ol.source.Vector()
const drawLayer = new ol.layer.Vector({
source: drawSource,
style: function() {}
})
const draw = new ol.interaction.Draw({
source: drawSource,
type: type
})
const snap = new ol.interaction.Snap({ source: drawSource })
const modify = new ol.interaction.Modify({ source: drawSource })
map.addInteraction(draw)
map.addInteraction(snap)
map.addInteraction(modify)
map.addLayer(drawLayer)
8、导出图片
获取map中的canvas,并导出图片
map.once('postcompose', (event) => {
const canvas = event.context.canvas
const imageData = canvas.toDataURL('image/png')
return imageData
})
还没有评论,快来抢第一吧