Files
td_official/src/views/progress/progressPaper/test.vue
2025-06-25 18:48:23 +08:00

157 lines
5.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div ref="mapContainer" class="map-container"></div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ';
import TileGrid from 'ol/tilegrid/TileGrid';
import { fromLonLat, transform, transformExtent } from 'ol/proj';
import { fromUrl } from 'geotiff';
import gcoord from 'gcoord';
import ImageLayer from 'ol/layer/Image';
import Static from 'ol/source/ImageStatic';
import { Feature } from 'ol';
import { Polygon } from 'ol/geom';
import { Stroke, Style } from 'ol/style';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
const mapContainer = ref<HTMLDivElement | null>(null);
// 您提供的经纬度范围EPSG:4326
const extent4326 = [107.13149481208748, 23.80411597354268, 107.13487254421389, 23.80801427852998];
// 计算中心点(经纬度)
const centerLon = (extent4326[0] + extent4326[2]) / 2;
const centerLat = (extent4326[1] + extent4326[3]) / 2;
// 转换 extent 到 EPSG:3857
const extent3857 = transformExtent(extent4326, 'EPSG:4326', 'EPSG:3857');
// 生成 resolutions256像素瓦片
const resolutions = Array.from({ length: 20 }, (_, z) => 156543.03392804097 / Math.pow(2, z));
onMounted(async () => {
// const tiff = await fromUrl('/image/clean_rgba_cleaned.tif');
// const image = await tiff.getImage();
// const width = image.getWidth();
// const height = image.getHeight();
// const bbox = image.getBoundingBox(); // [minX, minY, maxX, maxY]
// console.log('bbox', bbox);
// const rasters = await image.readRasters({ interleave: true });
// // 创建 Canvas
// const canvas = document.createElement('canvas');
// canvas.width = width;
// canvas.height = height;
// const ctx = canvas.getContext('2d')!;
// const imageData: any = ctx.createImageData(width, height);
// // 设置 RGBA 数据
// imageData.data.set(rasters); // ✅ 完整设置,不用手动循环
// ctx.putImageData(imageData, 0, 0);
// // 将 canvas 转成 Data URL 用作图层 source
// const imageUrl = canvas.toDataURL();
// // 转换为 WGS84 经纬度
// const minLonLat = transform([bbox[0], bbox[1]], 'EPSG:32648', 'EPSG:4326');
// const maxLonLat = transform([bbox[2], bbox[3]], 'EPSG:32648', 'EPSG:4326');
// console.log('minLonLat', minLonLat);
// console.log('maxLonLat', maxLonLat);
// // 转为 GCJ02高德地图坐标系
// const gcjMin = gcoord.transform(minLonLat as [number, number, number], gcoord.WGS84, gcoord.GCJ02);
// const gcjMax = gcoord.transform(maxLonLat as [number, number, number], gcoord.WGS84, gcoord.GCJ02);
// // 再转 EPSG:3857 供 OpenLayers 使用
// const minXY = fromLonLat(gcjMin);
// const maxXY = fromLonLat(gcjMax);
let imageExtent = [11926280.148303444, 2729254.667731837, 11926657.474014785, 2729714.281185133];
console.log('imageExtent', imageExtent);
console.log('extent3857', extent3857);
if (!mapContainer.value) return;
const tileGrid = new TileGrid({
extent: imageExtent,
origin: [-20037508.342789244, 20037508.342789244], // Web Mercator 左上角
resolutions,
tileSize: 256
});
// 高德卫星图图层 (EPSG:3857)
const gaodeLayer = new TileLayer({
source: new XYZ({
url: 'https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
maxZoom: 19,
wrapX: true
}),
opacity: 1
});
// 自定义瓦片图层EPSG:3857
const customLayer = new TileLayer({
source: new XYZ({
url: 'http://192.168.110.2:8000/api/projects/3/tasks/c2e3227f-343f-48b1-88c0-1432d6eab33f/orthophoto/tiles/{z}/{x}/{y}'
// extent: imageExtent
})
});
const layer = customLayer; // eg: TileLayer<XYZ>
const source = layer.getSource();
const projection = source?.getProjection();
console.log('图层坐标系:', projection?.getCode());
const borderLayer = createExtentBorderLayer(imageExtent);
const testLayer = createExtentBorderLayer([
...fromLonLat([107.13149481208748, 23.80411597354268]),
...fromLonLat([107.13487254421389, 23.80801427852998])
]);
// 创建地图
const map = new Map({
target: mapContainer.value,
layers: [gaodeLayer, customLayer, borderLayer, testLayer],
view: new View({
projection: 'EPSG:3857',
center: fromLonLat([centerLon, centerLat]),
zoom: 16,
minZoom: 10
// extent: extent3857 // 限制视图范围
})
});
});
const createExtentBorderLayer = (extent: number[]) => {
// 构造矩形坐标,闭合成环,顺序可以是顺时针或逆时针
const coords = [
[
[extent[0], extent[1]],
[extent[0], extent[3]],
[extent[2], extent[3]],
[extent[2], extent[1]],
[extent[0], extent[1]]
]
];
const polygonFeature = new Feature(new Polygon(coords));
polygonFeature.setStyle(
new Style({
stroke: new Stroke({
color: 'red', // 你想要的边框颜色
width: 3 // 线宽
}),
fill: null // 不填充,纯边框
})
);
return new VectorLayer({
source: new VectorSource({
features: [polygonFeature]
})
});
};
</script>
<style scoped>
.map-container {
width: 100%;
height: 100vh;
}
</style>