From 2e606513f576e98df6d497c6a765a5e699b3beac Mon Sep 17 00:00:00 2001 From: gcw_IJ7DAiVL Date: Tue, 18 Nov 2025 16:01:57 +0800 Subject: [PATCH] =?UTF-8?q?add=20=E9=81=93=E8=B7=AF=E5=88=86=E6=9E=90?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E8=8E=B7=E5=8F=96=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- public/config.ini | 4 +- public/config/config.js | 4 + public/index.html | 1 + src/main.js | 3 + src/utils/map.js | 162 ++ src/views/home/home.vue | 1350 ++++++----------- ...home202510115.vue => home_offlineData.vue} | 335 ++-- vue.config.js | 10 + 9 files changed, 855 insertions(+), 1016 deletions(-) create mode 100644 public/config/config.js create mode 100644 src/utils/map.js rename src/views/home/{home202510115.vue => home_offlineData.vue} (89%) diff --git a/package.json b/package.json index d32a75f..2fe97f6 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@babel/preset-env": "^7.28.3", - "axios": "0.21.0", + "axios": "^1.13.2", "echarts": "^5.4.3", "element-ui": "2.9.2", "file-saver": "^2.0.5", diff --git a/public/config.ini b/public/config.ini index b55b302..1630e69 100644 --- a/public/config.ini +++ b/public/config.ini @@ -1,6 +1,6 @@ [http] -port=8083 -address=127.0.0.1 +port=8381 +address=192.168.3.35 [title] msg=道路堪选分析 \ No newline at end of file diff --git a/public/config/config.js b/public/config/config.js new file mode 100644 index 0000000..6cab059 --- /dev/null +++ b/public/config/config.js @@ -0,0 +1,4 @@ +window.config = { + // baseUrl: 'http://192.168.3.35:8381', + baseUrl: '/api' +} \ No newline at end of file diff --git a/public/index.html b/public/index.html index 0aed2da..fca558a 100644 --- a/public/index.html +++ b/public/index.html @@ -11,6 +11,7 @@ rel="stylesheet" type="text/css" /> + diff --git a/src/main.js b/src/main.js index 9780c88..0871257 100644 --- a/src/main.js +++ b/src/main.js @@ -10,6 +10,9 @@ import 'vxe-pc-ui/es/style.css' import VxeUITable from 'vxe-table' import 'vxe-table/es/style.css' +import axios from 'axios' + +Vue.prototype.$http = axios Vue.config.productionTip = false diff --git a/src/utils/map.js b/src/utils/map.js new file mode 100644 index 0000000..ba6379c --- /dev/null +++ b/src/utils/map.js @@ -0,0 +1,162 @@ +/** + * 极简 WKT -> GeoJSON + * 支持 POINT / LINESTRING / POLYGON + * @param {String} wkt + * @return {Object} GeoJSON + */ +function wktToGeoJSON (wkt) { + const trim = str => str.trim() + const split = (str, d) => str.split(d).map(trim) + + // 1. 提取类型 + 坐标字符串 + const [head, coords] = split(wkt, '(') + const type = trim(head).toUpperCase() + const coordStr = coords.replace(/\)$/, '') + + // 2. 通用“数字对”解析 + const parseRing = ring => + split(ring, ',').map(p => { + const [x, y] = split(p, ' ').map(Number) + return [x, y] // GeoJSON 里经度在前 + }) + + // 3. 按类型组装 + switch (type) { + case 'POINT': { + const [x, y] = split(coordStr, ' ').map(Number) + return { type: 'Point', coordinates: [x, y] } + } + case 'LINESTRING': + return { type: 'LineString', coordinates: parseRing(coordStr) } + case 'POLYGON': { + // 可能带孔,先按“), (”切 + const rings = coordStr.split(/\s*\),\s*\(/).map(parseRing) + return { type: 'Polygon', coordinates: rings } + } + default: + throw new Error('暂不支持该 WKT 类型:' + type) + } +} + +/* 拿当前视野四至(容错版) */ +function getBounds(map) { + let rect = map.camera.computeViewRectangle() + + if (!rect) { + // 高空/2D 模式下 computeViewRectangle 会失效,用四个角点兜底 + const canvas = map.scene.canvas + const ellipsoid = Cesium.Ellipsoid.WGS84 + const cv = (x, y) => map.camera.pickEllipsoid( + new Cesium.Cartesian2(x, y), ellipsoid + ) + + const ptNW = cv(0, 0) + const ptSE = cv(canvas.clientWidth, canvas.clientHeight) + + // 如果仍 pick 不到,就缩小范围再试(再不行就返回一个默认矩形) + if (!ptNW || !ptSE) { + rect = map.camera.computeViewRectangle( + ellipsoid, + Cesium.Math.toRadians(0.1) // 0.1° 容差 + ) + if (!rect) { + // 终极保底:以相机位置为中心 ±0.1° + const c = map.camera.positionCartographic + const d = 0.1 + return { + west : Cesium.Math.toDegrees(c.longitude) - d, + east : Cesium.Math.toDegrees(c.longitude) + d, + south: Cesium.Math.toDegrees(c.latitude) - d, + north: Cesium.Math.toDegrees(c.latitude) + d + } + } + } else { + // pick 成功 + const nw = Cesium.Cartographic.fromCartesian(ptNW) + const se = Cesium.Cartographic.fromCartesian(ptSE) + return { + west : Cesium.Math.toDegrees(nw.longitude), + north: Cesium.Math.toDegrees(nw.latitude), + east : Cesium.Math.toDegrees(se.longitude), + south: Cesium.Math.toDegrees(se.latitude) + } + } + } + + // 正常能算到 + return { + west : Cesium.Math.toDegrees(rect.west), + south: Cesium.Math.toDegrees(rect.south), + east : Cesium.Math.toDegrees(rect.east), + north: Cesium.Math.toDegrees(rect.north) + } +} + + +/* 计算当前地图层级(zoom) */ +function getZoom(map) { + const height = map.camera.positionCartographic.height + // 经验公式:Cesium 高度 -> WebMercator zoom + return Math.floor(29.5 - Math.log(height) / Math.LN2) +} + +/* 画布像素边界 */ +function getViewportPxBounds(map) { + const cvs = map.scene.canvas + return { left: 0, top: 0, right: cvs.clientWidth, bottom: cvs.clientHeight } +} + +/* 像素 -> 经纬度四至 */ +function pxToLatLngBounds(px, map) { + const pick = (x, y) => { + const cart = map.camera.pickEllipsoid( + new Cesium.Cartesian2(x, y), + Cesium.Ellipsoid.WGS84 + ) + if (!cart) return null + const c = Cesium.Cartographic.fromCartesian(cart) + return { lng: Cesium.Math.toDegrees(c.longitude), lat: Cesium.Math.toDegrees(c.latitude) } + } + const nw = pick(px.left, px.top) + const se = pick(px.right, px.bottom) + // 兜底:高空 pick 不到就用相机矩形 + if (!nw || !se) { + const rect = map.camera.computeViewRectangle() || {} + return { + west : Cesium.Math.toDegrees(rect.west || 0), + south: Cesium.Math.toDegrees(rect.south || 0), + east : Cesium.Math.toDegrees(rect.east || 0), + north: Cesium.Math.toDegrees(rect.north || 0) + } + } + return { west: nw.lng, north: nw.lat, east: se.lng, south: se.lat } +} + + +var GRID_SIZE_DEG = 0.05 // 0.05° ≈ 5 km 一格 +var CACHE_MIN = 30 * 60 * 1000 // 30 min +/* 经纬度 → 格子 key */ +function lonLatToGridKey (lon, lat) { + const x = Math.floor(lon / GRID_SIZE_DEG) + const y = Math.floor(lat / GRID_SIZE_DEG) + return `${x}_${y}` +} + +/* 取格子中心点(方便防抖) */ +function gridKeyToCenter (key) { + const [x, y] = key.split('_').map(Number) + return { + lon: (x + 0.5) * GRID_SIZE_DEG, + lat: (y + 0.5) * GRID_SIZE_DEG + } +} + +export { + wktToGeoJSON, + getBounds, + getZoom, + getViewportPxBounds, + pxToLatLngBounds, + lonLatToGridKey, + gridKeyToCenter, +} \ No newline at end of file diff --git a/src/views/home/home.vue b/src/views/home/home.vue index b876d95..0736c45 100644 --- a/src/views/home/home.vue +++ b/src/views/home/home.vue @@ -18,19 +18,10 @@
清除
-
确定
+
确定
路线隐蔽规划
点隐蔽规划
-
导出
json编辑
@@ -41,7 +32,7 @@
参数
@@ -176,13 +167,11 @@ }},最大车辆载重{{ inputform.load || 0 }}吨
- - - - - - - + + + + + @@ -303,18 +292,6 @@ {{ row.载重吨 }} - - - - - -