내 연락처 정보
우편메소피아@프로톤메일.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
이 기사에서는 openlayers WebGL을 사용하여 레이어를 자르고 이중 레이어 접합을 표시하는 방법을 소개합니다.
레이어 사전 렌더링 및 사후 렌더링 이벤트 사용
웹지엘 가위방법의 사용
가위 방법은 그리기 영역을 경계 상자 영역으로 제한하는 데 사용되는 클리핑 영역을 지정합니다.
gl.가위(x, y, 너비, 높이);
매개변수:
x는 상자 모양 자르기 영역의 왼쪽 하단 모서리에 대한 가로 좌표를 지정하며 기본값은 0입니다.
y는 상자 모양 자르기 영역의 왼쪽 하단 모서리의 세로 좌표를 지정하며 기본값은 0입니다.
width는 상자 자르기 영역의 너비를 결정하는 데 사용되는 음수가 아닌 숫자이며 기본값은 캔버스 너비입니다.
height, 상자 모양 자르기 영역의 높이를 지정하는 데 사용되는 음수가 아닌 숫자입니다. 기본값은 캔버스의 높이입니다.
<template>
<div id="map" class="map"></div>
<div class="toolbar">
<el-slider v-model="rateH" :min="1" :max="100" :step="1" @input="handleInput"></el-slider>
<el-slider v-model="rateV" :min="1" :max="100" :step="1" @input="handleInput"></el-slider>
</div>
</template>
<script setup lang="ts">
import { Map, View } from 'ol';
import { WebGLTile as WebGLTileLayer } from 'ol/layer';
import { fromLonLat, get } from 'ol/proj';
import { XYZ } from 'ol/source';
import { getRenderPixel } from 'ol/render.js';
const projection = get('EPSG:3857');
const key = '替换为天地图key';
const layerTypeMap = {
vector: ['vec', 'cva'], // [矢量底图, 矢量注记]
image: ['img', 'cia'], // [影像底图, 影像注记]
terrain: ['ter', 'cta'] // [地形晕渲, 地形注记]
};
let map = null;
const rateH = ref(50);
const rateV = ref(50);
const imageLayer = new WebGLTileLayer({
source: new XYZ({
url: `https://t{0-7}.tianditu.gov.cn/DataServer?T=${layerTypeMap['image'][0]}_w&tk=${key}&x={x}&y={y}&l={z}`,
projection
})
});
const terrainLayer = new WebGLTileLayer({
source: new XYZ({
url: `https://t{0-7}.tianditu.gov.cn/DataServer?T=${layerTypeMap['terrain'][0]}_w&tk=${key}&x={x}&y={y}&l={z}`,
projection
})
});
onMounted(() => {
initMap('image');
});
const initMap = (layerType = 'image') => {
// c: 经纬度 w: 墨卡托
const matrixSet = 'w';
map = new Map({
target: 'map',
layers: [
// 底图
terrainLayer,
imageLayer,
// 注记
new WebGLTileLayer({
source: new XYZ({
url: `https://t{0-7}.tianditu.gov.cn/DataServer?T=${layerTypeMap[layerType][1]}_${matrixSet}&tk=${key}&x={x}&y={y}&l={z}`,
projection
})
})
],
view: new View({
center: fromLonLat([116.406393, 39.909006]),
projection: projection,
zoom: 5,
maxZoom: 17,
minZoom: 1
})
});
imageLayer.on('prerender', function (event) {
const gl = event.context;
gl.enable(gl.SCISSOR_TEST);
//获取地图[宽,高]像素(数组)
const mapSize = map.getSize();
// getRenderPixel从地图视口的CSS像素获取事件的画布上下文的像素。
// 获取canvas坐标的左下和右上点坐标
const bottomLeft = getRenderPixel(event, [0, mapSize[1]]);
const topRight = getRenderPixel(event, [mapSize[0], 0]);
const width = Math.round((topRight[0] - bottomLeft[0]) * (rateH.value / 100));
const height = Math.round((topRight[1] - bottomLeft[1] )* (rateV.value / 100));;
gl.scissor(bottomLeft[0], bottomLeft[1], width, height);
});
imageLayer.on('postrender', function (event) {
const gl = event.context;
gl.disable(gl.SCISSOR_TEST);
});
};
const handleInput = val => {
map.render();
};
</script>
<style scoped lang="scss">
.map {
width: 100%;
height: 100%;
}
.toolbar {
position: absolute;
top: 20px;
left: 100px;
width: 500px;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
.el-slider {
margin-right: 50px;
}
div {
width: 100px;
height: 30px;
display: flex;
justify-content: center;
align-items: center;
}
}
</style>
스플라이싱된 레이어를 왼쪽 상단에 넣으려면 이 문장만 수정하면 됩니다.
gl.scissor(bottomLeft[0],topRight[1]-height , width, height);