From cf4ed06dea0076e518319de24c5120bb3fe0dae9 Mon Sep 17 00:00:00 2001 From: guonan <guonan201020@163.com> Date: 星期五, 06 六月 2025 14:41:25 +0800 Subject: [PATCH] 提交 --- src/views/GisView.vue | 475 ++++++++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 340 insertions(+), 135 deletions(-) diff --git a/src/views/GisView.vue b/src/views/GisView.vue index 5640040..9ea1a4f 100644 --- a/src/views/GisView.vue +++ b/src/views/GisView.vue @@ -44,7 +44,7 @@ import { EventBus } from "@/eventBus"; // 寮曞叆浜嬩欢鎬荤嚎 import { useSimStore } from "@/store/simulation"; const simStore = useSimStore(); - +/////////////////////////鍦板浘褰卞儚閫夋嫨///////////////////////// const views = [ { label: "鍦板浘", value: "map", icon: "鍦板浘.png" }, { label: "褰卞儚", value: "image", icon: "褰卞儚.png" }, @@ -105,8 +105,11 @@ }); } }; +/////////////////////////鍦板浘褰卞儚閫夋嫨///////////////////////// + const route = useRoute(); let handler = null; +/////////////////////////鍒濆鍖栧湴鍥�///////////////////////// function initMap() { window.Cesium = SmartEarth.Cesium; window.earthCtrl = new SmartEarth.EarthCtrl("gis-view"); @@ -114,24 +117,19 @@ // 1. 璁剧疆鍒濆鏃堕棿 const date = new Date(2025, 3, 11, 12, 0, 0, 0); - // const date = new Date(2024, 6, 13, 5, 5, 50); 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 - // 寮�鍚ぇ姘旀暎灏勬晥鏋� - earthCtrl.atmosphere.enable(); - // 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", @@ -139,13 +137,10 @@ style: "default", format: "image/jpeg", maximumLevel: 18, - layer: "", - tileMatrixSetID: "", }); - // 鍏抽棴鍦板舰娣卞害妫�娴� - // viewer.scene.globe.depthTestAgainstTerrain = false; } +/////////////////////////鏂板缓鏂规鍖哄煙閫夋嫨///////////////////////// const MULTIPOLYGON_COORDS = ref([]); let previousEntities = []; // 鐢ㄤ簬瀛樺偍涔嬪墠鍒涘缓鐨勫疄浣� const flyToHeight = ref(null); @@ -262,6 +257,7 @@ clearPreviousEntities(); flyToHomeView(); }); +/////////////////////////鏂板缓鏂规鍖哄煙閫夋嫨///////////////////////// function addCityPolygon() { const url = `/json/110000.geo.json`; @@ -283,8 +279,6 @@ 50000000 ); polygonEntity.forEach((entity) => { - // console.log("entity", entity) - entity.polygon.material = new Cesium.ColorMaterialProperty( Cesium.Color.LIGHTSTEELBLUE.withAlpha(0) // new Cesium.Color.fromCssColorString("#0f2636b3") @@ -388,136 +382,257 @@ 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 = []; // 瀛樺偍鍒涘缓鐨刉MS鍥惧眰 - 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 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 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); +} + +// 璁剧疆浜岀骇鍖哄煙鐐瑰嚮澶勭悊锛堝寘鍚玏MS鍥惧眰锛� +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); + } }); } -const validPaths = ["/", "/yhgl"]; +// 璁剧疆涓�绾у尯鍩熺偣鍑诲鐞� +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 (!validPaths.includes(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鍥惧眰锛屽垯鑷姩鍔犺浇绗竴涓簩绾х偣鐨刉MS鍥惧眰 + if (wmsLayers.length === 0 && htmlEntityList.length > 0) { + const firstItem = htmlEntityList[0]; // 鍙互閫変换鎰忎竴涓簩绾х偣 + removeAllWmsLayers(); // 娓呴櫎鍙兘瀛樺湪鐨勬畫鐣欏浘灞� + + earthCtrl.factory + .createImageryLayer(config.wmsOptions) + .then((wmsLayer) => { + wmsLayers.push(wmsLayer); + }); + } else { + // 宸叉湁鍥惧眰浣哢RL鍙樹簡锛岄渶瑕佹洿鏂� + 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) { + // 濡傛灉瓒呭嚭鍙鑼冨洿涓斿凡鏈塛MS鍥惧眰锛屽垯娓呴櫎 + removeAllWmsLayers(); + // 鍙互鍦ㄨ繖閲岀Щ闄や簨浠剁洃鍚櫒 + if (clickHandler) { + clickHandler.destroy(); + clickHandler = null; + } + } } -function removeCameraChange() { - viewer.camera.changed.removeEventListener(toggleHtmlLayerByVisibleDistance); + +let clickHandler = null; + +// 绉婚櫎鎵�鏈塛MS鍥惧眰 +function removeAllWmsLayers() { + wmsLayers.forEach((layer) => { + layer.removeFromMap(); + }); + wmsLayers.length = 0; // 娓呯┖鏁扮粍 } + let cameraChangeTimer = null; function toggleHtmlLayerByVisibleDistance() { @@ -526,27 +641,117 @@ 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() { + // // 鍏堢Щ闄ゅ凡鏈夌殑浜嬩欢鐩戝惉锛堜笉鑳借锛岃浜嗕箣鍚庨殣鎮g偣灏变笉浼氳姹備簡锛� + // 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. 鍙戦�丟etFeatureInfo璇锋眰 + fetch(featureInfoUrl) + .then((res) => res.text()) // 鍏堣幏鍙栨枃鏈� + .then((text) => { + // console.log(text); + }); +} onMounted(() => { initMap(); - // 鍦ㄤ綘鐨勫垵濮嬪寲浠g爜涓皟鐢ㄨ繖涓嚱鏁� addCityPolygon(); initHandler(); // initView() loadAreaPolygon("/json/nsl_area.geojson"); loadAreaPolygonAll("/json/geometry.json", true); flyToHomeView(); - initDistrictCount(); - initDistrictCountByCity(); + // 椤甸潰鍔犺浇鏃跺垵濮嬪寲 + initAllDistrictCounts(); handleCameraChange(); // 璁剧疆 billboard 鐐瑰嚮浜嬩欢 }); -- Gitblit v1.9.3