| | |
| | | <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 { 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"); |
| | |
| | | // 1. 设置初始时间 |
| | | const date = new Date(2025, 3, 11, 12, 0, 0, 0); |
| | | const julianDate = SmartEarth.Cesium.JulianDate.fromDate(date); |
| | | // earthCtrl.viewer.clock.currentTime = julianDate; |
| | | |
| | | // 2. 配置时钟选项,禁止自动推进时间 |
| | | earthCtrl.viewer.clockViewModel.shouldAnimate = false; // 禁用动画 |
| | | // 2. 配置时钟选项 |
| | | earthCtrl.viewer.clockViewModel.shouldAnimate = false; |
| | | earthCtrl.viewer.clockViewModel.clockRange = |
| | | SmartEarth.Cesium.ClockRange.CLAMPED; // 限制时间范围 |
| | | earthCtrl.viewer.clockViewModel.multiplier = 0; // 设置时间推进速度为0 |
| | | |
| | | // 3. 设置当前时间并锁定 |
| | | SmartEarth.Cesium.ClockRange.CLAMPED; |
| | | earthCtrl.viewer.clockViewModel.multiplier = 0; |
| | | earthCtrl.viewer.clock.currentTime = julianDate; |
| | | |
| | | //显示fps |
| | | // 显示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", |
| | |
| | | style: "default", |
| | | format: "image/jpeg", |
| | | maximumLevel: 18, |
| | | layer: "", |
| | | tileMatrixSetID: "", |
| | | }); |
| | | // 关闭地形深度检测 |
| | | // viewer.scene.globe.depthTestAgainstTerrain = false; |
| | | } |
| | | |
| | | /////////////////////////新建方案区域选择///////////////////////// |
| | | const MULTIPOLYGON_COORDS = ref([]); |
| | | let previousEntities = []; // 用于存储之前创建的实体 |
| | | const flyToHeight = ref(null); |
| | |
| | | EventBus.on("select-geom", ({ geom, flyHeight, shouldShowFill }) => { |
| | | flyToHeight.value = flyHeight; |
| | | ShowFill.value = shouldShowFill; |
| | | console.log(ShowFill.value, "ShowFill.valueShowFill.value"); |
| | | const coordsStr = geom |
| | | .replace("MULTIPOLYGON(((", "") // 去掉开头 |
| | | .replace(")))", ""); // 去掉结尾 |
| | |
| | | hierarchy: Cesium.Cartesian3.fromDegreesArray( |
| | | geoJson.geometry.coordinates[0][0].flat() |
| | | ), |
| | | material: ShowFill |
| | | material: ShowFill |
| | | ? Cesium.Color.RED.withAlpha(0.3) // 半透明红色填充 |
| | | : new Cesium.ColorMaterialProperty(Cesium.Color.TRANSPARENT), // 如果不需要填充,则使用透明材质 |
| | | outline: true, |
| | |
| | | clampToGround: true, // 贴地显示 |
| | | }, |
| | | }); |
| | | |
| | | |
| | | previousEntities.push(polygonEntity); |
| | | |
| | | // 飞向中心点 |
| | |
| | | clearPreviousEntities(); |
| | | flyToHomeView(); |
| | | }); |
| | | /////////////////////////新建方案区域选择///////////////////////// |
| | | |
| | | function addCityPolygon() { |
| | | const url = `/json/110000.geo.json`; |
| | |
| | | 50000000 |
| | | ); |
| | | polygonEntity.forEach((entity) => { |
| | | // console.log("entity", entity) |
| | | |
| | | entity.polygon.material = new Cesium.ColorMaterialProperty( |
| | | Cesium.Color.LIGHTSTEELBLUE.withAlpha(0) |
| | | // new Cesium.Color.fromCssColorString("#0f2636b3") |
| | |
| | | viewer.scene.camera.flyTo(view); |
| | | } |
| | | |
| | | let htmlEntityList = []; |
| | | function initDistrictCount() { |
| | | getDistrictCount().then((res) => { |
| | | res.data.forEach((item) => { |
| | | const { districtName, count, lat, lon } = item; |
| | | item.name = `${item.districtName}\n${item.count}`; |
| | | item.longitude = item.lon; |
| | | item.latitude = item.lat; |
| | | item.showBillboard = false; |
| | | item.showLabel = true; |
| | | item.label = { |
| | | text: item.name, |
| | | backgroundColor: SmartEarth.Cesium.Color.SKYBLUE.withAlpha(0.8), |
| | | font: "14pt Source Han Sans CN", |
| | | fillColor: SmartEarth.Cesium.Color.WHITE, |
| | | showBackground: true, |
| | | }; |
| | | // createPoint(item) |
| | | const html = earthCtrl.view.createScreenDialog({ |
| | | html: ` |
| | | <div class="district-count"> |
| | | <div class="name">${districtName}</div> |
| | | <div class="value">${count}</div> |
| | | </div> |
| | | `, |
| | | lon: item.lon, |
| | | lat: item.lat, |
| | | height: 0, |
| | | }); |
| | | html.maxVisibleDistance = 69000; |
| | | html.minVisibleDistance = 20000; |
| | | html.element.addEventListener("click", () => { |
| | | viewer.camera.flyTo({ |
| | | destination: Cesium.Cartesian3.fromDegrees( |
| | | item.longitude, |
| | | item.latitude, |
| | | 12000 |
| | | ), |
| | | orientation: { |
| | | pitch: Cesium.Math.toRadians(-90), |
| | | heading: Cesium.Math.toRadians(0), |
| | | roll: 0, |
| | | }, |
| | | duration: 2, |
| | | }); |
| | | }); |
| | | ///////////////////////// 区域标记点管理系统 ///////////////////////// |
| | | // 存储所有创建的HTML实体(地图上的标记点) |
| | | const htmlEntityList = []; |
| | | const wmsLayers = []; // 存储创建的WMS图层 |
| | | |
| | | htmlEntityList.push(html); |
| | | // 路由对应的 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 initDistrictCountByCity() { |
| | | getDistrictCountByCity().then((res) => { |
| | | res.data.forEach((item) => { |
| | | const { districtName, count, lat, lon } = item; |
| | | item.name = `${item.districtName}\n${item.count}`; |
| | | item.longitude = item.lon; |
| | | item.latitude = item.lat; |
| | | item.showBillboard = false; |
| | | item.showLabel = true; |
| | | item.label = { |
| | | text: item.name, |
| | | backgroundColor: SmartEarth.Cesium.Color.SKYBLUE.withAlpha(0.8), |
| | | font: "14pt Source Han Sans CN", |
| | | fillColor: SmartEarth.Cesium.Color.WHITE, |
| | | showBackground: true, |
| | | }; |
| | | // createPoint(item) |
| | | const html = earthCtrl.view.createScreenDialog({ |
| | | html: ` |
| | | <div class="district-count"> |
| | | <div class="name">${districtName}</div> |
| | | <div class="value">${count}</div> |
| | | </div> |
| | | `, |
| | | lon: item.lon, |
| | | lat: item.lat, |
| | | height: 0, |
| | | }); |
| | | html.maxVisibleDistance = 50000000; |
| | | html.minVisibleDistance = 70000; |
| | | html.element.addEventListener("click", () => { |
| | | viewer.camera.flyTo({ |
| | | destination: Cesium.Cartesian3.fromDegrees( |
| | | item.longitude, |
| | | item.latitude, |
| | | 45000 |
| | | ), |
| | | orientation: { |
| | | pitch: Cesium.Math.toRadians(-90), |
| | | heading: Cesium.Math.toRadians(0), |
| | | roll: 0, |
| | | }, |
| | | duration: 2, |
| | | }); |
| | | }); |
| | | |
| | | htmlEntityList.push(html); |
| | | }); |
| | | // 设置一级区域点击处理 |
| | | 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) => { |
| | | if (val != "/") { |
| | | // clusterLayer.dataSource.show = false |
| | | htmlEntityList.forEach((item) => { |
| | | item.show = false; |
| | | }); |
| | | removeCameraChange(); |
| | | } else { |
| | | const isValidPath = validPaths.includes(val); |
| | | |
| | | // 更新 WMS 图层配置 |
| | | updateWmsLayerByRoute(val); |
| | | |
| | | // 控制HTML实体显示 |
| | | htmlEntityList.forEach((item) => { |
| | | item.show = isValidPath |
| | | ? isVisibleDistance(item.minVisibleDistance, item.maxVisibleDistance) |
| | | : false; |
| | | }); |
| | | |
| | | // 控制相机变化监听 |
| | | if (isValidPath) { |
| | | handleCameraChange(); |
| | | // clusterLayer.dataSource.show = true |
| | | htmlEntityList.forEach((item) => { |
| | | item.show = isVisibleDistance( |
| | | item.minVisibleDistance, |
| | | item.maxVisibleDistance |
| | | ); |
| | | }); |
| | | |
| | | // 如果满足可视范围,尝试重新加载 WMS 图层 |
| | | const cameraHeight = viewer.camera.positionCartographic.height; |
| | | // loadWmsImg(cameraHeight); |
| | | } else { |
| | | removeCameraChange(); |
| | | removeAllWmsLayers(); |
| | | } |
| | | } |
| | | ); |
| | | function handleCameraChange() { |
| | | viewer.camera.changed.addEventListener(toggleHtmlLayerByVisibleDistance); |
| | | |
| | | // 自动加载 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; |
| | | } |
| | | } |
| | | } |
| | | function removeCameraChange() { |
| | | viewer.camera.changed.removeEventListener(toggleHtmlLayerByVisibleDistance); |
| | | |
| | | let clickHandler = null; |
| | | |
| | | // 移除所有WMS图层 |
| | | function removeAllWmsLayers() { |
| | | wmsLayers.forEach((layer) => { |
| | | layer.removeFromMap(); |
| | | }); |
| | | wmsLayers.length = 0; // 清空数组 |
| | | } |
| | | |
| | | let cameraChangeTimer = null; |
| | | |
| | | function toggleHtmlLayerByVisibleDistance() { |
| | |
| | | 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(); |
| | | initDistrictCount(); |
| | | initDistrictCountByCity(); |
| | | // 页面加载时初始化 |
| | | initAllDistrictCounts(); |
| | | handleCameraChange(); |
| | | // 设置 billboard 点击事件 |
| | | }); |
| | |
| | | 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> |