<template>
|
<div id="gis-view" ref="mapRef"></div>
|
<!-- 切换底图影像 -->
|
<div
|
@click="handleShow"
|
class="diqiu"
|
:class="{ 'shift-right': simStore.isShowEarth }"
|
>
|
<img src="@/assets/img/screen/dq.png" alt="" />
|
</div>
|
<div
|
v-show="picShow"
|
class="earthBox"
|
:class="{ 'shift-right': simStore.isShowEarth }"
|
>
|
<div
|
v-for="(item, index) in views"
|
:key="index"
|
:class="['item-container', { active: currentIndex === index }]"
|
@click="switchView(index)"
|
>
|
<div class="icon-wrapper">
|
<img :src="getImageUrl(item.icon)" :alt="item.label" />
|
<span class="label">{{ item.label }}</span>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script setup>
|
import { onMounted, onUnmounted, ref, watch } from "vue";
|
import {
|
createPoint,
|
initHandler,
|
initView,
|
addTileset,
|
addTerrain,
|
} from "@/utils/map.js";
|
import { loadAreaPolygon } from "@/utils/area.js";
|
import { loadAreaPolygonAll } from "@/utils/area_all.js";
|
import { isVisibleDistance } from "@/utils/customEntity";
|
import { getDistrictCount, getDistrictCountByCity } from "@/api/index";
|
import { useRoute } from "vue-router";
|
import { EventBus } from "@/eventBus"; // 引入事件总线
|
import { useSimStore } from "@/store/simulation";
|
const simStore = useSimStore();
|
/////////////////////////地图影像选择/////////////////////////
|
const views = [
|
{ label: "地图", value: "map", icon: "地图.png" },
|
{ label: "影像", value: "image", icon: "影像.png" },
|
{ label: "地形", value: "terrain", icon: "地形.png" },
|
];
|
|
const getImageUrl = (iconName) => {
|
return `/images/earth/${iconName}`;
|
};
|
|
const picShow = ref(false);
|
|
const handleShow = () => {
|
picShow.value = !picShow.value;
|
};
|
|
const currentIndex = ref(-1);
|
|
let currentLayer = null;
|
|
const switchView = async (index) => {
|
currentIndex.value = index;
|
|
// 如果已经有图层存在,先从地图中移除
|
if (currentLayer) {
|
currentLayer.removeFromMap();
|
currentLayer = null; // 清空引用
|
}
|
|
if (views[index].value === "map") {
|
// 百度地图
|
currentLayer = await earthCtrl.factory.createImageryLayer({
|
sourceType: "baidu",
|
url: "https://ss1.bdstatic.com/8bo_dTSlR1gBo1vgoIiO_jowehsv/tile/?qt=vtile&x={x}&y={y}&z={z}&styles=pl&udt=20180810&scaler=1&showtext=1",
|
});
|
} else if (views[index].value === "image") {
|
currentLayer = await earthCtrl.factory.createImageryLayer({
|
sourceType: "mapworld",
|
url: "https://t0.tianditu.gov.cn/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=3ec79cf7a9dcc6bb18411a5414b148cb",
|
layers: "tdtBasicLayer",
|
style: "default",
|
format: "image/jpeg",
|
maximumLevel: 18,
|
layer: "",
|
tileMatrixSetID: "",
|
});
|
//标注层
|
currentLayer = await earthCtrl.factory.createImageryLayer({
|
sourceType: "mapworld",
|
subdomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"],
|
url: "https://{s}.tianditu.gov.cn/cia_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cia&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&tk=c53eb074c3fcba5ac86103d4d711bbe8",
|
});
|
} else if (views[index].value === "terrain") {
|
// 地形图层
|
currentLayer = await earthCtrl.factory.createTerrainLayer({
|
sourceType: "arcgis",
|
url: "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer",
|
});
|
}
|
};
|
/////////////////////////地图影像选择/////////////////////////
|
|
const route = useRoute();
|
let handler = null;
|
/////////////////////////初始化地图/////////////////////////
|
function initMap() {
|
window.Cesium = SmartEarth.Cesium;
|
window.earthCtrl = new SmartEarth.EarthCtrl("gis-view");
|
window.viewer = earthCtrl.viewer;
|
|
// 1. 设置初始时间
|
const date = new Date(2025, 3, 11, 12, 0, 0, 0);
|
const julianDate = SmartEarth.Cesium.JulianDate.fromDate(date);
|
|
// 2. 配置时钟选项
|
earthCtrl.viewer.clockViewModel.shouldAnimate = false;
|
earthCtrl.viewer.clockViewModel.clockRange =
|
SmartEarth.Cesium.ClockRange.CLAMPED;
|
earthCtrl.viewer.clockViewModel.multiplier = 0;
|
earthCtrl.viewer.clock.currentTime = julianDate;
|
|
// 显示fps
|
earthCtrl.showFPS = true;
|
|
// 先添加底图
|
earthCtrl.factory.createImageryLayer({
|
sourceType: "mapworld",
|
url: "http://t0.tianditu.com/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=7eb11c0c503429878691ac917238f87f",
|
layers: "tdtBasicLayer",
|
style: "default",
|
format: "image/jpeg",
|
maximumLevel: 18,
|
});
|
}
|
|
/////////////////////////新建方案区域选择/////////////////////////
|
const MULTIPOLYGON_COORDS = ref([]);
|
let previousEntities = []; // 用于存储之前创建的实体
|
const flyToHeight = ref(null);
|
const ShowFill = ref(true);
|
|
// 监听新建方案选择的区域范围
|
EventBus.on("select-geom", ({ geom, flyHeight, shouldShowFill }) => {
|
flyToHeight.value = flyHeight;
|
ShowFill.value = shouldShowFill;
|
const coordsStr = geom
|
.replace("MULTIPOLYGON(((", "") // 去掉开头
|
.replace(")))", ""); // 去掉结尾
|
|
// 分割成 ["lon lat", "lon lat", ...]
|
const coordPairs = coordsStr.split(",");
|
|
// 转换为 [[[lon, lat], [lon, lat], ...]] 格式
|
MULTIPOLYGON_COORDS.value = [
|
coordPairs.map((pair) => {
|
const [lon, lat] = pair.trim().split(" ").map(Number);
|
return [lon, lat];
|
}),
|
];
|
|
// 检查是否是空多边形,如果是空,则去掉面片颜色,并飞回初始位置
|
if (geom === "MULTIPOLYGON EMPTY") {
|
clearPreviousEntities();
|
flyToHomeView();
|
return; // 不执行后续操作
|
}
|
|
// 清除之前的所有实体
|
clearPreviousEntities();
|
// 选中区域标色
|
addCustomPolygon(ShowFill.value);
|
});
|
|
// 清除之前的所有实体
|
function clearPreviousEntities() {
|
previousEntities.forEach((entity) => {
|
viewer.entities.remove(entity);
|
});
|
previousEntities = [];
|
}
|
|
// 计算选中区域中心点
|
function calculateCenter(coordinates) {
|
const lons = coordinates.flat().map((coord) => coord[0]);
|
const lats = coordinates.flat().map((coord) => coord[1]);
|
return {
|
lon: (Math.min(...lons) + Math.max(...lons)) / 2,
|
lat: (Math.min(...lats) + Math.max(...lats)) / 2,
|
};
|
}
|
|
function convertToGeoJson(coords) {
|
return {
|
type: "Feature",
|
id: 0,
|
bbox: calculateCenter(MULTIPOLYGON_COORDS.value), // 可选
|
properties: {
|
center: calculateCenter(MULTIPOLYGON_COORDS.value), // 第一个点作为 center
|
centroid: MULTIPOLYGON_COORDS.value[0][0], // 可选
|
level: "district",
|
code: 123456,
|
districtCount: 0,
|
},
|
geometry: {
|
type: "MultiPolygon",
|
coordinates: [coords], // 包装成 MultiPolygon
|
},
|
};
|
}
|
|
function addCustomPolygon(ShowFill = true) {
|
// 将 MULTIPOLYGON_COORDS.value 转换为 GeoJSON 格式
|
const geoJson = convertToGeoJson(MULTIPOLYGON_COORDS.value);
|
const center = geoJson.properties.center;
|
|
// 创建多边形实体,并根据 ShowFill 参数决定是否显示填充颜色
|
const polygonEntity = viewer.entities.add({
|
polygon: {
|
hierarchy: Cesium.Cartesian3.fromDegreesArray(
|
geoJson.geometry.coordinates[0][0].flat()
|
),
|
material: ShowFill
|
? Cesium.Color.RED.withAlpha(0.3) // 半透明红色填充
|
: new Cesium.ColorMaterialProperty(Cesium.Color.TRANSPARENT), // 如果不需要填充,则使用透明材质
|
outline: true,
|
outlineColor: Cesium.Color.RED, // 红色边框
|
outlineWidth: 5,
|
clampToGround: true, // 贴地显示
|
},
|
});
|
|
previousEntities.push(polygonEntity);
|
|
// 飞向中心点
|
viewer.camera.flyTo({
|
destination: Cesium.Cartesian3.fromDegrees(
|
center.lon,
|
center.lat,
|
flyToHeight.value
|
), // 提高到指定高度
|
orientation: {
|
heading: Cesium.Math.toRadians(0), // 正北方向
|
pitch: Cesium.Math.toRadians(-90), // 向下倾斜90度(垂直俯视)
|
roll: 0.0,
|
},
|
});
|
}
|
|
EventBus.on("close-selectArea", () => {
|
clearPreviousEntities();
|
flyToHomeView();
|
});
|
/////////////////////////新建方案区域选择/////////////////////////
|
|
function addCityPolygon() {
|
const url = `/json/110000.geo.json`;
|
let wallLayer = earthCtrl.factory.createTrailWallLayer({
|
url: "/json/110000.geojson",
|
color: "LIGHTSTEELBLUE", //颜色
|
height: 2000, //高度
|
speed: 3,
|
});
|
const dataSourcePromise = Cesium.GeoJsonDataSource.load(url, {
|
clampToGround: true,
|
});
|
return dataSourcePromise.then(function (dataSource) {
|
viewer.dataSources.add(dataSource);
|
// 所有的数据
|
const polygonEntity = dataSource.entities.values;
|
const distanceDisplayCondition = new Cesium.DistanceDisplayCondition(
|
1000,
|
50000000
|
);
|
polygonEntity.forEach((entity) => {
|
entity.polygon.material = new Cesium.ColorMaterialProperty(
|
Cesium.Color.LIGHTSTEELBLUE.withAlpha(0)
|
// new Cesium.Color.fromCssColorString("#0f2636b3")
|
// Cesium.Color.fromRandom({
|
// alpha: 0.5,
|
// minimumAlpha: 0.2,
|
// maximumAlpha: 0.9,
|
// })
|
);
|
|
entity.polygon.distanceDisplayCondition = distanceDisplayCondition;
|
|
const properties = entity.properties;
|
const center = properties.centroid.getValue();
|
const fullname = properties.fullname.getValue();
|
const districtCount = properties.districtCount.getValue() || 0;
|
|
const position = Cesium.Cartesian3.fromDegrees(center[0], center[1]);
|
const positions = entity.polygon.hierarchy._value.positions;
|
|
entity.position = position;
|
// 判断是否为东城区或西城区
|
let labelText = fullname || "默认标签";
|
if (fullname === "东城区" || fullname === "西城区") {
|
// 将文本拆分为竖列
|
labelText = fullname.split("").join("\n");
|
}
|
entity.label = {
|
// 文本。支持显式换行符“ \ n”
|
text: labelText,
|
// 字体样式,以CSS语法指定字体
|
font: "22pt Source Han Sans CN",
|
// 字体颜色
|
|
fillColor: Cesium.Color.fromCssColorString("#FD9B00"),
|
// 背景颜色
|
backgroundColor: Cesium.Color.BLACK.withAlpha(0.8),
|
// 是否显示背景颜色
|
showBackground: false,
|
// 字体边框
|
outline: true,
|
// 字体边框颜色
|
outlineColor: Cesium.Color.WHITE,
|
// 字体边框尺寸
|
outlineWidth: 0,
|
// 应用于图像的统一比例。比例大于会1.0放大标签,而比例小于会1.0缩小标签。
|
scale: 1.0,
|
scaleByDistance: new Cesium.NearFarScalar(1.5e2, 1.0, 1.5e7, 0.5),
|
// 设置样式:FILL:填写标签的文本,但不要勾勒轮廓;OUTLINE:概述标签的文本,但不要填写;FILL_AND_OUTLINE:填写并概述标签文本。
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
// 相对于坐标的水平位置
|
verticalOrigin: Cesium.VerticalOrigin.CENTER,
|
// 相对于坐标的水平位置
|
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
// 该属性指定标签在屏幕空间中距此标签原点的像素偏移量
|
pixelOffset: new Cesium.Cartesian2(0, 0),
|
// pixelOffset: new Cesium.Cartesian2(0, 0),
|
// 显示在距相机的距离处的属性,多少区间内是可以显示的
|
distanceDisplayCondition: distanceDisplayCondition,
|
// : new Cesium.DistanceDisplayCondition(0, 50000),
|
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
// 是否显示
|
show: true,
|
};
|
entity.polyline = {
|
positions: positions,
|
width: 5,
|
material: new Cesium.ColorMaterialProperty(
|
Cesium.Color.SKYBLUE.withAlpha(0.9)
|
// Cesium.Color.fromRandom({
|
// alpha: 0.5,
|
// minimumAlpha: 0.2,
|
// maximumAlpha: 0.9,
|
// })
|
),
|
clampToGround: true,
|
distanceDisplayCondition: distanceDisplayCondition,
|
};
|
|
viewer.entities.add(entity);
|
});
|
|
// 获取 GeoJSON 中的第一个 Polygon feature
|
});
|
}
|
|
function flyToHomeView() {
|
const view = {
|
destination: {
|
x: -2355432.569004413,
|
y: 4687573.191838412,
|
z: 4098726.315265574,
|
},
|
orientation: {
|
pitch: -0.9541030830183503,
|
roll: 0.00031421159527500464,
|
heading: 6.140424766644804,
|
},
|
};
|
viewer.scene.camera.flyTo(view);
|
}
|
|
///////////////////////// 区域标记点管理系统 /////////////////////////
|
// 存储所有创建的HTML实体(地图上的标记点)
|
const htmlEntityList = [];
|
const wmsLayers = []; // 存储创建的WMS图层
|
|
// 路由对应的 WMS 图层配置
|
const WMS_LAYER_MAP = {
|
"/zhjc": {
|
url: "http://192.168.56.106:8191/iserver/services/map-ywsj_view_jc_zkr_device_all_kb/wms130/ywsj_device_kb",
|
},
|
"/yhgl": {
|
url: "http://192.168.56.106:8191/iserver/services/map-ywsj_view_dz_zkr_point_kb/wms130/ywsj_yhd_kb",
|
},
|
};
|
|
// 统一管理所有区域标记的样式配置
|
const ENTITY_CONFIG = {
|
label: {
|
backgroundColor: SmartEarth.Cesium.Color.SKYBLUE.withAlpha(0.8),
|
font: "14pt Source Han Sans CN",
|
fillColor: SmartEarth.Cesium.Color.WHITE,
|
showBackground: true,
|
},
|
showBillboard: false,
|
showLabel: true,
|
};
|
|
// 区域级别配置
|
const LEVEL_CONFIG = {
|
// 二级区域
|
secondary: {
|
maxVisibleDistance: 69000,
|
minVisibleDistance: 20000,
|
flyToHeight: 12000,
|
wmsOptions: {
|
sourceType: "wms",
|
url: "", // 动态设置
|
layers: "0.1",
|
parameters: {
|
format: "image/png",
|
transparent: true,
|
version: "1.1.1",
|
srs: "EPSG:4326",
|
query_layers: "0.2",
|
info_format: "application/json",
|
},
|
},
|
},
|
// 一级区域
|
primary: {
|
maxVisibleDistance: 50000000,
|
minVisibleDistance: 70000,
|
flyToHeight: 45000,
|
},
|
};
|
|
// 更新 WMS 配置函数(根据当前路由)
|
function updateWmsLayerByRoute(currentPath) {
|
const config = WMS_LAYER_MAP[currentPath];
|
if (!config) return;
|
|
LEVEL_CONFIG.secondary.wmsOptions.url = config.url;
|
}
|
|
// 初始化区域统计
|
function initDistrictCount(level = "secondary") {
|
const getPoint =
|
level === "secondary" ? getDistrictCount : getDistrictCountByCity;
|
const config = LEVEL_CONFIG[level];
|
|
getPoint()
|
.then((res) => {
|
res.data.forEach((item) => {
|
processDistrictItem(item, config, level); // 添加level参数
|
});
|
})
|
.catch((error) => {
|
console.error(`初始化${level}级区域统计失败:`, error);
|
});
|
}
|
|
// 处理单个区域项
|
function processDistrictItem(item, config, level = "secondary") {
|
// 添加默认值
|
normalizeItemData(item);
|
const html = createDistrictHtmlMarker(item, config);
|
|
if (level === "secondary") {
|
secondaryHandler(html, item, config);
|
} else {
|
primaryHandler(html, item, config);
|
}
|
|
htmlEntityList.push(html);
|
}
|
|
// 设置二级区域点击处理(包含WMS图层)
|
function secondaryHandler(html, item, config) {
|
html.element.addEventListener("click", async () => {
|
try {
|
// 先飞向目标位置
|
await flyToDistrict(item.longitude, item.latitude, config.flyToHeight);
|
|
// 移除旧图层
|
removeAllWmsLayers();
|
// 延时1秒后添加新图层
|
setTimeout(() => {
|
// 如果满足可视范围,尝试重新加载 WMS 图层
|
const cameraHeight = viewer.camera.positionCartographic.height;
|
// loadWmsImg(cameraHeight);
|
}, 1000); // 1000毫秒 = 1秒
|
|
// 设置WMS要素查询
|
setupWmsFeatureQuery();
|
|
// 添加新的点击事件
|
} catch (error) {
|
console.error("区域点击处理失败:", error);
|
}
|
});
|
}
|
|
// 设置一级区域点击处理
|
function primaryHandler(html, item, config) {
|
html.element.addEventListener("click", () => {
|
flyToDistrict(item.longitude, item.latitude, config.flyToHeight);
|
console.log(item.districtCode, "itemitemitemitem");
|
});
|
}
|
|
// 统一数据格式和添加默认配置
|
function normalizeItemData(item) {
|
item.name = `${item.districtName}\n${item.count}`;
|
item.longitude = item.lon;
|
item.latitude = item.lat;
|
Object.assign(item, ENTITY_CONFIG);
|
}
|
|
// 创建HTML标记
|
function createDistrictHtmlMarker(item, config) {
|
const html = earthCtrl.view.createScreenDialog({
|
html: `
|
<div class="district-count">
|
<div class="name">${item.districtName}</div>
|
<div class="value">${item.count}</div>
|
</div>
|
`,
|
lon: item.lon,
|
lat: item.lat,
|
height: 0,
|
});
|
|
html.maxVisibleDistance = config.maxVisibleDistance;
|
html.minVisibleDistance = config.minVisibleDistance;
|
|
return html;
|
}
|
|
// 飞向指定区域
|
function flyToDistrict(longitude, latitude, height) {
|
viewer.camera.flyTo({
|
destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, height),
|
orientation: {
|
pitch: Cesium.Math.toRadians(-90),
|
heading: Cesium.Math.toRadians(0),
|
roll: 0,
|
},
|
duration: 2,
|
});
|
}
|
|
// 路由监听
|
const validPaths = ["/", "/yhgl", "/zhjc"];
|
watch(
|
() => route.fullPath,
|
(val) => {
|
const isValidPath = validPaths.includes(val);
|
|
// 更新 WMS 图层配置
|
updateWmsLayerByRoute(val);
|
|
// 控制HTML实体显示
|
htmlEntityList.forEach((item) => {
|
item.show = isValidPath
|
? isVisibleDistance(item.minVisibleDistance, item.maxVisibleDistance)
|
: false;
|
});
|
|
// 控制相机变化监听
|
if (isValidPath) {
|
handleCameraChange();
|
|
// 如果满足可视范围,尝试重新加载 WMS 图层
|
const cameraHeight = viewer.camera.positionCartographic.height;
|
// loadWmsImg(cameraHeight);
|
} else {
|
removeCameraChange();
|
removeAllWmsLayers();
|
}
|
}
|
);
|
|
// 自动加载 WMS 图层
|
async function loadWmsImg(cameraHeight) {
|
const config = LEVEL_CONFIG.secondary;
|
|
// 判断是否处于二级可视范围内
|
if (cameraHeight <= config.minVisibleDistance) {
|
// 如果当前没有WMS图层,则自动加载第一个二级点的WMS图层
|
if (wmsLayers.length === 0 && htmlEntityList.length > 0) {
|
const firstItem = htmlEntityList[0]; // 可以选任意一个二级点
|
removeAllWmsLayers(); // 清除可能存在的残留图层
|
|
earthCtrl.factory
|
.createImageryLayer(config.wmsOptions)
|
.then((wmsLayer) => {
|
wmsLayers.push(wmsLayer);
|
});
|
} else {
|
// 已有图层但URL变了,需要更新
|
const currentUrl = wmsLayers[0]?.imageryProvider?.url;
|
if (currentUrl !== config.wmsOptions.url) {
|
removeAllWmsLayers();
|
earthCtrl.factory
|
.createImageryLayer(config.wmsOptions)
|
.then((wmsLayer) => {
|
wmsLayers.push(wmsLayer);
|
});
|
}
|
}
|
} else if (cameraHeight > config.maxVisibleDistance && wmsLayers.length > 0) {
|
// 如果超出可视范围且已有WMS图层,则清除
|
removeAllWmsLayers();
|
// 可以在这里移除事件监听器
|
if (clickHandler) {
|
clickHandler.destroy();
|
clickHandler = null;
|
}
|
}
|
}
|
|
let clickHandler = null;
|
|
// 移除所有WMS图层
|
function removeAllWmsLayers() {
|
wmsLayers.forEach((layer) => {
|
layer.removeFromMap();
|
});
|
wmsLayers.length = 0; // 清空数组
|
}
|
|
let cameraChangeTimer = null;
|
|
function toggleHtmlLayerByVisibleDistance() {
|
if (cameraChangeTimer) {
|
clearTimeout(cameraChangeTimer);
|
cameraChangeTimer = null;
|
return;
|
}
|
|
cameraChangeTimer = setTimeout(() => {
|
const cameraHeight = viewer.camera.positionCartographic.height;
|
|
// 更新HTML实体显示状态
|
htmlEntityList.forEach((item) => {
|
item.show = isVisibleDistance(
|
item.minVisibleDistance,
|
item.maxVisibleDistance
|
);
|
});
|
|
// 检查是否需要自动加载或清除WMS图层
|
// loadWmsImg(cameraHeight);
|
}, 100);
|
}
|
|
function handleCameraChange() {
|
viewer.camera.changed.addEventListener(toggleHtmlLayerByVisibleDistance);
|
}
|
|
function removeCameraChange() {
|
viewer.camera.changed.removeEventListener(toggleHtmlLayerByVisibleDistance);
|
}
|
|
// 初始化函数
|
function initAllDistrictCounts() {
|
initDistrictCount("secondary"); // 二级区域
|
initDistrictCount("primary"); // 一级区域
|
}
|
|
// 设置WMS要素查询
|
function setupWmsFeatureQuery() {
|
// // 先移除已有的事件监听(不能要,要了之后隐患点就不会请求了)
|
// earthCtrl.viewer.screenSpaceEventHandler.removeInputAction(
|
// Cesium.ScreenSpaceEventType.LEFT_CLICK
|
// );
|
|
// 添加新的点击事件
|
earthCtrl.viewer.screenSpaceEventHandler.setInputAction(
|
handleMapClick,
|
Cesium.ScreenSpaceEventType.LEFT_CLICK
|
);
|
}
|
|
// 处理地图点击查询
|
function handleMapClick(click) {
|
console.log("点击屏幕位置:", click.position);
|
|
// 1. 获取点击位置的地理坐标
|
const ray = viewer.camera.getPickRay(click.position);
|
if (!ray) {
|
console.log("无法获取拾取射线");
|
return;
|
}
|
|
const cartesian = viewer.scene.globe.pick(ray, viewer.scene);
|
if (!cartesian) {
|
console.log("无法获取地理坐标");
|
return;
|
}
|
|
// console.log("cartesian:", cartesian);
|
|
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
|
const longitude = Cesium.Math.toDegrees(cartographic.longitude);
|
const latitude = Cesium.Math.toDegrees(cartographic.latitude);
|
console.log("点击位置坐标:", longitude, latitude);
|
|
queryWmsFeatures(longitude, latitude, click.position);
|
}
|
|
// 查询WMS要素
|
function queryWmsFeatures(longitude, latitude, clickPosition) {
|
const wmsUrl = LEVEL_CONFIG.secondary.wmsOptions.url;
|
const params = new URLSearchParams({
|
SERVICE: "WMS",
|
VERSION: "1.1.1",
|
REQUEST: "GetFeatureInfo",
|
LAYERS: "0.1", // 查询信息所在的图层
|
QUERY_LAYERS: "0.2",
|
INFO_FORMAT: "text/xml",
|
FEATURE_COUNT: "10", // 返回最多10个要素
|
X: Math.floor(clickPosition.x),
|
Y: Math.floor(clickPosition.y),
|
SRS: "EPSG:4326",
|
WIDTH: viewer.canvas.width,
|
HEIGHT: viewer.canvas.height,
|
BBOX: [longitude - 1, latitude - 1, longitude + 1, latitude + 1].join(","),
|
});
|
|
const featureInfoUrl = wmsUrl + "?" + params.toString();
|
// console.log("请求URL:", featureInfoUrl);
|
|
// 3. 发送GetFeatureInfo请求
|
fetch(featureInfoUrl)
|
.then((res) => res.text()) // 先获取文本
|
.then((text) => {
|
// console.log(text);
|
});
|
}
|
onMounted(() => {
|
initMap();
|
addCityPolygon();
|
initHandler();
|
// initView()
|
loadAreaPolygon("/json/nsl_area.geojson");
|
loadAreaPolygonAll("/json/geometry.json", true);
|
flyToHomeView();
|
// 页面加载时初始化
|
initAllDistrictCounts();
|
handleCameraChange();
|
// 设置 billboard 点击事件
|
});
|
onUnmounted(() => {
|
removeCameraChange();
|
EventBus.off("select-geom");
|
EventBus.off("close-selectArea");
|
});
|
</script>
|
|
<style lang="less" scoped>
|
#gis-view {
|
width: 100vw;
|
height: 100vh;
|
position: absolute;
|
}
|
|
// // 修改指南针位置
|
/deep/ .compass {
|
right: 128px !important;
|
top: 112px;
|
}
|
|
.diqiu {
|
position: absolute;
|
bottom: 8%;
|
right: 4%;
|
z-index: 9999;
|
}
|
|
.earthBox {
|
z-index: 9999;
|
width: 12%;
|
height: 7%;
|
background-color: rgba(0, 9, 9, 0.3);
|
position: absolute;
|
right: 8%;
|
bottom: 6%;
|
display: flex;
|
justify-content: space-evenly;
|
padding: 10px 6px;
|
}
|
|
.icon-wrapper {
|
position: relative;
|
margin: 0;
|
padding: 0;
|
box-sizing: border-box;
|
border: 1px solid transparent; /* 默认透明边框占位 */
|
|
img {
|
height: 100%;
|
width: auto; /* 确保图片按比例缩放 */
|
margin: 0;
|
padding: 0;
|
display: block; /* 移除图片下方可能存在的空白间隙 */
|
}
|
|
.label {
|
position: absolute;
|
bottom: 0;
|
right: 0;
|
left: 0;
|
background-color: rgba(0, 0, 0, 0.5);
|
text-align: center;
|
color: white;
|
}
|
}
|
|
.item-container {
|
position: relative;
|
display: inline-block;
|
cursor: pointer;
|
}
|
|
.item-container.active .icon-wrapper {
|
border: 1px solid #218967; /* 蓝色边框 */
|
}
|
|
.item-container.active .label {
|
background-color: rgba(33, 137, 103, 0.8);
|
}
|
|
.diqiu.shift-right {
|
right: 10%;
|
}
|
.earthBox.shift-right {
|
right: 13%;
|
}
|
</style>
|