例子:有天地图、百度地图、Arcgis,mapbox,geoserver自建瓦片服务、自定义d3图层
var addExample = createModuleExample('vue', { deps: ['css!bootstrapCss'] })
var BaseMap = {
mounted() {
var container = this.$refs.main;
container.className = "h-100 w-100";
var view = this.view = new ol.View({
projection: "EPSG:4326",
center: [121, 31],
zoom: 5
})
var map = this.map = window.map = new ol.Map({
target: container,
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: view,
controls: ol.control.defaults().extend(new ol.control.ScaleLine({
units: 'metric',
bar: true,
steps: 4,
text: false,
minWidth: 140,
}))
})
}
}
addExample({
title: "自定义d3图层",
template: `<div><div ref="main" class="h-100 w-100"></div></div>`,
data() { return {}; },
computed: {},
mounted() {
var container = this.$refs.main;
var { Layer, Tile: TileLayer } = ol.layer;
var { toLonLat, fromLonLat } = ol.proj;
var { Stamen } = ol.source;
var { getCenter, getWidth } = ol.extent;
var SourceState = {
UNDEFINED: 'undefined',
LOADING: 'loading',
READY: 'ready',
ERROR: 'error',
}
class CanvasLayer extends Layer {
constructor(options) {
super(options);
this.features = [];
if (options.features) {
this.features = options.features;
}
this.sourcestate = SourceState.UNDEFINED;
if (options.url) {
this.sourcestate = SourceState.LOADING;
fetch(options.url).then(r => r.json()).then(data => {
this.sourcestate = SourceState.READY;
this.features = data;
//this.svg.datum(this.features);
})
}
this.svg = d3
.select(document.createElement('div'))
.append('svg')
.style('position', 'absolute');
//this.svg.append('path').attr('stroke-width',1).attr('stroke','red').attr('fill','blue').attr('class', 'boundary pathlayer');
}
getSourceState() {
return this.sourcestate;
}
render(frameState) {
const width = frameState.size[0];
const height = frameState.size[1];
const projection = frameState.viewState.projection;
const d3Projection = d3.geoMercator().scale(1).translate([0, 0]);
let d3Path = d3.geoPath().projection(d3Projection);
const pixelBounds = d3Path.bounds(this.features);
const pixelBoundsWidth = pixelBounds[1][0] - pixelBounds[0][0];
const pixelBoundsHeight = pixelBounds[1][1] - pixelBounds[0][1];
const geoBounds = d3.geoBounds(this.features);
const geoBoundsLeftBottom = fromLonLat(geoBounds[0], projection);
const geoBoundsRightTop = fromLonLat(geoBounds[1], projection);
let geoBoundsWidth = geoBoundsRightTop[0] - geoBoundsLeftBottom[0];
if (geoBoundsWidth < 0) {
geoBoundsWidth += getWidth(projection.getExtent());
}
const geoBoundsHeight = geoBoundsRightTop[1] - geoBoundsLeftBottom[1];
const widthResolution = geoBoundsWidth / pixelBoundsWidth;
const heightResolution = geoBoundsHeight / pixelBoundsHeight;
const r = Math.max(widthResolution, heightResolution);
const scale = r / frameState.viewState.resolution;
const center = toLonLat(getCenter(frameState.extent), projection);
d3Projection
.scale(scale)
.center(center)
.translate([width / 2, height / 2]);
// d3Projection.fitExtent(projection.getExtent(),this.features)
d3Path = d3Path.projection(d3Projection);
// d3Path(this.features);
this.svg.attr('width', width);
this.svg.attr('height', height);
var g = this.svg.selectAll('g').data(this.features.features).join(enter => {
var g = enter.append('g').attr('data-name', d => d.properties.name);
g.append('path');
return g;
});
g.select('path').each(function (feature) {
// console.log(feature.properties.name)
if (feature.properties.name == "南海诸岛") {
return;
}
d3.select(this).attr('d', d3Path).attr('fill', 'blue').attr('stroke', 'red').attr('stroke-width', 1);
})
return this.svg.node();
}
}
var map = new ol.Map({
target: container,
layers: [new ol.layer.Tile({
source: new ol.source.OSM()
}),
new CanvasLayer({
url: 'https://cdn.jsdelivr.net/npm/china-geojson@1.0.0/src/geojson/china.json'
})
],
view: new ol.View({
projection: "EPSG:4326",
// constrainRotation:90,
// enableRotation:true,
center: [121, 31],
zoom: 5
})
})
}
})
addExample({
title: "OSM",
template: `<div><div ref="main" class="h-100"></div></div>`,
data() { return {}; },
computed: {},
mounted() {
var container = this.$refs.main;
var gui = this.$gui;
var guiObj = {
sourceType: "osm"
};
// gui.add(guiObj,"sourceType",['osm','']).name('地图数据源类型')
var layer = new ol.layer.Tile({
图层对应数据源,此为加载OpenStreetMap在线瓦片服务数据
source: new ol.source.OSM()
});
var view = new ol.View({
center: [0, 0],
zoom: 1
});
var map = new ol.Map({
target: container,
layers: [layer],
view: view
})
}
});
addExample({
title: "mage ArcGIS MapServer",
template: `<div><div ref="main" class="h-100"></div></div>`,
data() { return {}; },
computed: {},
mounted() {
var container = this.$refs.main;
var url = 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/' +
'Specialty/ESRI_StateCityHighway_USA/MapServer';
var layers = [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
new ol.layer.Image({
source: new ol.source.ImageArcGISRest({
ratio: 1,
params: {},
url: url
})
})
];
//实例化Map对象加载地图
var map = new ol.Map({
//地图容器div的ID
target: container,
//地图容器中加载的图层
layers: layers,
//地图视图设置
view: new ol.View({
//地图初始中心点
center: [-121.1, 47.5],
//地图初始显示级别
zoom: 2
})
});
}
})
addExample({
title: "arcgis 矢量",
template: `<div class="position-relative">
<div class="position-absolute" style="z-index:1000">
<select name="changeLayer" ref="arcgisType">
<option value="MapServer" selected="selected">MapServer在线瓦片数据</option>
<option value="arcgisOnline">arcgisOnline在线瓦片数据</option>
<option value="RestFeatureService">ArcGIS REST Feature Service</option>
</select>
</div>
<div ref="main" class="h-100"></div></div>`,
data() { return {}; },
computed: {},
mounted() {
var container = this.$refs.main;
var arcGISLayers;
//实例化Map对象加载地图
var map = new ol.Map({
//地图容器div的ID
target: container,
//地图容器中加载的图层
layers: [],
//地图视图设置
view: new ol.View({
//地图初始中心点
center: [-121.1, 47.5],
//地图初始显示级别
zoom: 2
})
});
//功能项控制处理,加载选中项对应的地图
var select = this.$refs.arcgisType;//数据类型对象
select.addEventListener('change', onChange); //添加地图类型选项的事件监听
loadArcGISMap(select.value); //默认加载选中类型的地图
//数据类型切换处理函数
function onChange() {
map.removeLayer(arcGISLayers); //移除图层
loadArcGISMap(select.value); //加载当前类型的地图数据
}
function loadArcGISMap(type) {
//移除当前已有图层
var cLayers = map.getLayers();
if (cLayers != null) {
for (var i = 0; i < cLayers.length; i++) {
map.removeLayer(cLayers[i]);
}
}
//加载ArcGIS MapServer地图
if (type == "MapServer") {
var arcGISSource = new ol.source.TileArcGISRest({
url: 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/' +
'Specialty/ESRI_StateCityHighway_USA/MapServer'
});
arcGISLayers = new ol.layer.Tile({
source: arcGISSource,
extent: [-13884991, 2870341, -7455066, 6338219]
});
map.addLayer(arcGISLayers); //添加瓦片地图图层
setMapView([-10997148, 4569099], 5);
}
//加载arcgisOnline地图
else if (type == "arcgisOnline") {
arcGISLayers = new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/' +
'World_Topo_Map/MapServer/tile/{z}/{y}/{x}'
})
})
map.addLayer(arcGISLayers); //添加地图图层
setMapView(ol.proj.fromLonLat([-121.1, 47.5]), 7);
}
//加载ArcGIS REST矢量要素服务地图
else if (type == "RestFeatureService") {
var serviceUrl = 'http://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/' +
'services/PDX_Pedestrian_Districts/FeatureServer/';
var layer = '0';
var esrijsonFormat = new ol.format.EsriJSON();//ESRI的JSON数据格式解析类
//实例化矢量数据源对象(AJAX请求REST服务)
var arcGISSource = new ol.source.Vector({
loader: function (extent, resolution, projection) {
var url = serviceUrl + layer + '/query/?f=json&' +
'returnGeometry=true&spatialRel=esriSpatialRelIntersects&geometry=' +
encodeURIComponent('{"xmin":' + extent[0] + ',"ymin":' +
extent[1] + ',"xmax":' + extent[2] + ',"ymax":' + extent[3] +
',"spatialReference":{"wkid":102100}}') +
'&geometryType=esriGeometryEnvelope&inSR=102100&outFields=*' +
'&outSR=102100';
$.ajax({
url: url, dataType: 'jsonp', success: function (response) {
if (response.error) {
alert(response.error.message + '\n' +
response.error.details.join('\n'));
} else {
// 从请求结果中读取要素
var features = esrijsonFormat.readFeatures(response, {
featureProjection: projection
});
if (features.length > 0) {
arcGISSource.addFeatures(features);//要素设置数据源
}
}
}
});
},
strategy: ol.loadingstrategy.tile(ol.tilegrid.createXYZ({
tileSize: 512
}))
});
arcGISLayers = new ol.layer.Vector({
source: arcGISSource
});
map.addLayer(arcGISLayers); //添加地图图层
setMapView(ol.proj.fromLonLat([-121.1, 47.5]), 5);
}
}
/**
* 重新设置地图视图
* @param {ol.Coordinate} center 中心点
* @param {number} zoom 缩放级数
*/
function setMapView(center, zoom) {
var view = map.getView(); //获取地图视图
view.setCenter(center); //平移地图
view.setZoom(zoom); //地图缩放
}
}
});
addExample({
title: "百度",
template: `<div><div ref="main" class="h-100"></div></div>`,
data() { return {}; },
computed: {},
mounted() {
var container = this.$refs.main;
//坐标参考系
var projection = ol.proj.get("EPSG:3857");
//分辨率
var resolutions = [];
for (var i = 0; i < 19; i++) {
resolutions[i] = Math.pow(2, 18 - i);
}
var tilegrid = new ol.tilegrid.TileGrid({
origin: [0, 0],
resolutions: resolutions
});
//拼接百度地图出图地址
var baidu_source = new ol.source.TileImage({
//设置坐标参考系
projection: projection,
//设置分辨率
tileGrid: tilegrid,
//出图基地址
tileUrlFunction: function (tileCoord, pixelRatio, proj) {
if (!tileCoord) {
return "";
}
var z = tileCoord[0];
var x = tileCoord[1];
var y = tileCoord[2];
if (x < 0) {
x = "M" + (-x);
}
if (y < 0) {
y = "M" + (-y);
}
return "http://online3.map.bdimg.com/onlinelabel/?qt=tile&x=" + x + "&y=" + y + "&z=" + z + "&styles=pl&udt=20151021&scaler=1&p=1";
}
});
//百度地图
var baidu_layer = new ol.layer.Tile({
source: baidu_source
});
//地图容器
var map = new ol.Map({
target: container,
layers: [baidu_layer],
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
}
});
//创建图层(xyz方式)
function crtLayerXYZ(type, proj, opacity) {
var projection = ol.proj.get('EPSG:4326');
var layer = new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'http://t' + Math.round(Math.random() * 7) + '.tianditu.com/DataServer?T=' + type + '&x={x}&y={y}&l={z}&tk=d7e367d1d59017bf35a9101765b2dd7c',
//url:`http://t${Math.round(Math.random() * 7)}.tianditu.gov.cn/${type}/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=${type.substring(0,3)}&STYLE=default&TILEMATRIXSET=${type.slice(-1)}&FORMAT=tiles&TILEMATRIX={z}&TILEROW={x}&TILECOL={y}&tk=密钥`,
projection: projection,
// tileSize:256,
// maxZoom:18,
// wrapX:true,
// maxResolution:ol.extent.getWidth(projection.getExtent())/256
}),
opacity: opacity
});
layer.id = type;
return layer;
}
//创建图层(WMTS方式)
function crtLayerWMTS(type, proj, opacity) {
var projection = ol.proj.get(proj);
var projectionExtent = projection.getExtent();
var size = ol.extent.getWidth(projectionExtent) / 256;
var resolutions = new Array(19);
var matrixIds = new Array(19);
for (var z = 1; z < 19; ++z) {
// generate resolutions and matrixIds arrays for this WMTS
resolutions[z] = size / Math.pow(2, z);
matrixIds[z] = z;
}
var layer = new ol.layer.Tile({
opacity: opacity,
source: new ol.source.WMTS({
attributions: 'Tiles © <a href="http://www.tianditu.com/service/info.html?sid=5292&type=info">天地图</a>',
url: 'http://t' + Math.round(Math.random() * 7) + '.tianditu.com/' + type + '/wmts?tk=自己的',
layer: type.substr(0, 3),
matrixSet: type.substring(4),
format: 'tiles',
projection: projection,
tileGrid: new ol.tilegrid.WMTS({
origin: ol.extent.getTopLeft(projectionExtent),
resolutions: resolutions,
matrixIds: matrixIds
}),
style: 'default',
wrapX: true
})
});
layer.id = type;
return layer;
}
addExample({
title: "天地图",
template: `<div><div ref="main" class="h-100"></div></div>`,
data() { return {}; },
computed: {},
mounted() {
var container = this.$refs.main;
//实例化map对象加载地图
var map = new ol.Map({
//地图容器div的id
target: container,
//地图容器中加载的图层
layers: [
//加载瓦片图层数据
new ol.layer.Tile({
title: "天地图矢量图层",
source: new ol.source.XYZ({
url: "http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=自己的",
wrapX: false
})
}),
new ol.layer.Tile({
title: "天地图矢量图层注记",
source: new ol.source.XYZ({
url: "http://t0.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=自己的",
wrapX: false
})
})
],
//地图视图设置
view: new ol.View({
//地图初始中心点
center: [0, 0],
//地图初始显示级别
zoom: 3,
//参考系设置
projection: "EPSG:4326"
})
});
}
})
addExample({
title: "geoserver wms",
template: `<div><div ref="main" class="h-100"></div></div>`,
data() { return {}; },
computed: {},
mounted() {
var container = this.$refs.main;
//http://localhost:8089/geoserver/topp/wms
var wmsLayer = new ol.layer.Tile({
source: new ol.source.TileWMS({
// extent: [-13884991, 2870341, -7455066, 6338219],
url: 'http://localhost:8089/geoserver/wms',
params: { 'LAYERS': 'topp:states', 'TILED': true },
serverType: 'geoserver',
// Countries have transparency, so do not fade tiles:
transition: 0
})
})
var view = new ol.View({
projection: "EPSG:3857",//默认投影为球形墨卡托(EPSG:3857)。ol.proj.get('EPSG:4326')
center: [0, 0],
zoom: 2
});
var map = new ol.Map({
target: container,
layers: [wmsLayer],
view: view
})
}
})
addExample({
title: "arc wmts",
template: `<div><div ref="main" class="h-100"></div></div>`,
data() { return {}; },
computed: {},
mounted() {
var container = this.$refs.main;
var guiObj = {
sourceType: "osm"
};
var projection = ol.proj.get('EPSG:3857');
var projectionExtent = projection.getExtent();
var size = ol.extent.getWidth(projectionExtent) / 256;
var resolutions = new Array(14);
var matrixIds = new Array(14);
for (var z = 0; z < 14; ++z) {
// generate resolutions and matrixIds arrays for this WMTS
resolutions[z] = size / Math.pow(2, z);
matrixIds[z] = z;
}
// gui.add(guiObj,"sourceType",['osm','']).name('地图数据源类型')
var layer = new ol.layer.Tile({
图层对应数据源,此为加载OpenStreetMap在线瓦片服务数据
source: new ol.source.OSM()
});
var wmtsLayer = new ol.layer.Tile({
opacity: 0.7,
source: new ol.source.WMTS({
attributions: 'Tiles © <a href="https://services.arcgisonline.com/arcgis/rest/' +
'services/Demographics/USA_Population_Density/MapServer/">ArcGIS</a>',
url: 'https://services.arcgisonline.com/arcgis/rest/' +
'services/World_Topo_Map/MapService/WMTS/',
layer: '0',
matrixSet: 'EPSG:3857',
format: 'image/png',
projection: projection,
tileGrid: new ol.tilegrid.WMTS({
origin: ol.extent.getTopLeft(projectionExtent),
resolutions: resolutions,
matrixIds: matrixIds
}),
style: 'default',
wrapX: true
})
})
var view = new ol.View({
center: [0, 0],
zoom: 1
});
var map = new ol.Map({
target: container,
layers: [wmtsLayer],
view: view
})
}
})
addExample("mapbox", function () {
mapboxgl.accessToken =“”
mapboxgl.setRTLTextPlugin(
'https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-rtl-text/v0.2.3/mapbox-gl-rtl-text.js'
);
class MapboxLayer extends ol.layer.Layer {
constructor(options={}) {
super(options)
let container=document.createElement('div')
var map = this.mapbox = new mapboxgl.Map({
container: container,
style: 'mapbox://styles/mapbox/streets-v11',
center: [121.58200395278817, 30.970218383322546],
zoom: 3,
// pitch: 45,
// bearing: -17.6,
antialias: true,
});
var that = this;
map.on('load', function () {
})
}
render(frameState) {
let mbMap = this.mapbox
const canvas = mbMap.getCanvas();
const viewState = frameState.viewState;
const visible = mbLayer.getVisible();
canvas.style.display = visible ? 'block' : 'none';
const opacity = mbLayer.getOpacity();
canvas.style.opacity = opacity;
// adjust view parameters in mapbox
const 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;
}
}
return {
template: `<div><div ref="main" class="w-100 h-100"></div></div>`,
data() { return {}; },
computed: {},
methods: {},
mounted() {
var container = this.$refs.main;
var view = this.view = new ol.View({
projection: "EPSG:4326",
center: [121, 31],
zoom: 5
})
var map = this.map = window.map = new ol.Map({
target: container,
layers: [new MapboxLayer()],
view: view,
controls: ol.control.defaults().extend(new ol.control.ScaleLine({
units: 'metric',
bar: true,
steps: 4,
text: false,
minWidth: 140,
}))
})
}
}
})
addExample({
title: "自定义",
extends: BaseMap,
template: `<div><div ref="main"></div></div>`,
data() { return {}; },
computed: {},
mounted() {
var container = this.$refs.main;
var points = turf.randomPoint(100, {
bbox: this.map.getView().getProjection().getExtent()
});
var vectorLayer = new ol.layer.Vector({
style: new ol.style.Style({
image: new ol.style.Circle({
radius: 20,
fill: new ol.style.Fill({ color: 'red' })
})
}),
source: new ol.source.Vector({
features: new ol.format.GeoJSON().readFeatures(points)
})
})
this.map.addLayer(vectorLayer)
}
})