-
前言 如果你正在使用mapbox和openlayers就会知道他们各自的好处,openlayers架构优美,扩展方便,更加适合gis分析,mapbox则更加偏向于展示,但是毕竟他们是两个不同的地图api,鱼和熊掌不可兼得,现在我们来介绍下他们之间如何结合使用。
-
首先需要引入mapboxgl,并且在dom中同时实例化ol和mapboxgl的map对象,关闭mapboxgl的交互,使用Layer基类加载mapboxgl的canvas,进行图层的同步控制。
import 'ol/ol.css';
import GeoJSON from 'ol/format/GeoJSON';
import Layer from 'ol/layer/Layer';
import Map from 'ol/Map';
import Source from 'ol/source/Source';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import View from 'ol/View';
import {Stroke, Style} from 'ol/style';
import {fromLonLat, toLonLat} from 'ol/proj';
import mapboxgl from 'mapboxgl'
var center = [-98.8, 37.9];
var key = 'Get your own API key at https://www.maptiler.com/cloud/';
var mbMap = new mapboxgl.Map({
style: 'https://api.maptiler.com/maps/bright/style.json?key=' + key,
attributionControl: false,
boxZoom: false,
center: center,
container: 'map',
doubleClickZoom: false,
dragPan: false,
dragRotate: false,
interactive: false,
keyboard: false,
pitchWithRotate: false,
scrollZoom: false,
touchZoomRotate: false,
});
var mbLayer = new Layer({
render: function (frameState) {
var canvas = mbMap.getCanvas();
var viewState = frameState.viewState;
var visible = mbLayer.getVisible();
canvas.style.display = visible ? 'block' : 'none';
var opacity = mbLayer.getOpacity();
canvas.style.opacity = opacity;
// adjust view parameters in mapbox
var rotation = viewState.rotation;
mbMap.jumpTo({
center: toLonLat(viewState.center),
zoom: viewState.zoom - 1,
bearing: (-rotation * 180) / Math.PI,
animate: false,
});
// cancel the scheduled update & trigger synchronous redraw
// see https://github.com/mapbox/mapbox-gl-js/issues/7893#issue-408992184
// NOTE: THIS MIGHT BREAK IF UPDATING THE MAPBOX VERSION
if (mbMap._frame) {
mbMap._frame.cancel();
mbMap._frame = null;
}
mbMap._render();
return canvas;
},
source: new Source({
attributions: [
'<a href="https://www.maptiler.com/copyright/" target="_blank">© MapTiler</a>',
'<a href="https://www.openstreetmap.org/copyright" target="_blank">© OpenStreetMap contributors</a>' ],
}),
});
var style = new Style({
stroke: new Stroke({
color: '#319FD3',
width: 2,
}),
});
var vectorLayer = new VectorLayer({
source: new VectorSource({
url: 'data/geojson/countries.geojson',
format: new GeoJSON(),
}),
style: style,
});
var map = new Map({
target: 'map',
view: new View({
center: fromLonLat(center),
zoom: 4,
}),
layers: [mbLayer, vectorLayer],
});
3.如果想在antv/l7中使用,原理是一样的,但是需要注意要将’l7-scene’dom结点和’l7-marker-container’append到’ol-viewport’中,保证能将antv的图层渲染出来,和marker对象渲染出来。
let olViewport=document.getElementsByClassName('ol-viewport')[0]
let markerContainer=document.getElementsByClassName('l7-marker-container')[0]
let l7SceneContainer=document.getElementsByClassName('l7-scene')[0]
olViewport.append(markerContainer)
olViewport.append(l7SceneContainer)