官网demo地址:
https://openlayers.org/en/latest/examples/data-tiles.html
这篇示例讲解的是自定义加载DataTile源格式的数据。
先来看一下什么是DataTile,这个源是一个数组,与我们之前XYZ切片源有所不同。DataTile主要适用于需要动态生成、处理或渲染瓦片数据的复杂场景。
先新建一个canvas,设置一下画布参数。
//256x256 像素是瓦片图层的常见尺寸
const size = 256;
const canvas = document.createElement("canvas");
canvas.width = size;
canvas.height = size;
const context = canvas.getContext("2d");
//设置描边颜色为白色。
context.strokeStyle = "white";
//设置文本对齐方式为居中
context.textAlign = "center";
//设置字体为 24 像素的无衬线字体。
context.font = "24px sans-serif";
//用于控制文本行高
const lineHeight = 30;
loader
是一个自定义数据加载函数,用于在需要时生成或获取瓦片数据。它的设计目的是为了处理动态生成的或特定格式的数据,比如在运行时计算或从非标准源获取的数据。
new TileLayer({
source: new DataTile({
loader: function (z, x, y) {
const half = size / 2;
//清除画布内容
context.clearRect(0, 0, size, size);
context.fillStyle = "rgba(100, 100, 100, 0.5)";
//填充整个画布
context.fillRect(0, 0, size, size);
context.fillStyle = "red";
//绘制文字
context.fillText(`z: ${z}`, half, half - lineHeight);
context.fillText(`x: ${x}`, half, half);
context.fillText(`y: ${y}`, half, half + lineHeight);
context.strokeRect(0, 0, size, size);
//获取画布内容的像素数据
const data = context.getImageData(0, 0, size, size).data;
// 转换为Uint8Array以提高浏览器兼容性
return new Uint8Array(data.buffer);
},
//禁用不透明度过渡,以避免在tile加载期间重叠标签
transition: 0,
}),
}),
事实上,很多源都提供loader参数方便我们把获取的数据或地图路径经过二次处理之后再加载到地图上。而具体返回什么样的数据格式取决于源本身所接受的数据格式。
完整代码:
<template>
<div class="box">
<h1>Data Tiles自定义绘制DataTile源数据</h1>
<div id="map"></div>
</div>
</template>
<script>
import DataTile from "ol/source/DataTile.js";
import Map from "ol/Map.js";
import TileLayer from "ol/layer/WebGLTile.js";
import View from "ol/View.js";
export default {
name: "",
components: {},
data() {
return {
map: null,
};
},
computed: {},
created() {},
mounted() {
//256x256 像素是瓦片图层的常见尺寸
const size = 256;
const canvas = document.createElement("canvas");
canvas.width = size;
canvas.height = size;
const context = canvas.getContext("2d");
//设置描边颜色为白色。
context.strokeStyle = "white";
//设置文本对齐方式为居中
context.textAlign = "center";
//设置字体为 24 像素的无衬线字体。
context.font = "24px sans-serif";
//用于控制文本行高
const lineHeight = 30;
const map = new Map({
target: "map",
layers: [
new TileLayer({
source: new DataTile({
loader: function (z, x, y) {
const half = size / 2;
//清除画布内容
context.clearRect(0, 0, size, size);
context.fillStyle = "rgba(100, 100, 100, 0.5)";
//填充整个画布
context.fillRect(0, 0, size, size);
context.fillStyle = "red";
//绘制文字
context.fillText(`z: ${z}`, half, half - lineHeight);
context.fillText(`x: ${x}`, half, half);
context.fillText(`y: ${y}`, half, half + lineHeight);
context.strokeRect(0, 0, size, size);
//获取画布内容的像素数据
const data = context.getImageData(0, 0, size, size).data;
// 转换为Uint8Array以提高浏览器兼容性
return new Uint8Array(data.buffer);
},
//禁用不透明度过渡,以避免在tile加载期间重叠标签
transition: 0,
}),
}),
],
view: new View({
center: [0, 0],
zoom: 0,
}),
});
},
methods: {},
};
</script>
<style lang="scss" scoped>
#map {
width: 100%;
height: 500px;
}
.box {
height: 100%;
}
#info {
width: 100%;
height: 24rem;
overflow: scroll;
display: flex;
align-items: baseline;
border: 1px solid black;
justify-content: flex-start;
}
</style>