吉安感知网项目-前端
shuishen
3 days ago 6e88705bd5b443a259b24c17c8a299765d059d96
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// @/utils/geoParseUtil.js
import _ from 'lodash'; // 若需要用到 lodash,需引入(当前解析逻辑暂未用到,可先注释)
 
/**
 * 单独的 WKT 解析函数(处理 POLYGON 和 LineString 类型)
 * @param {string} wktStr - WKT 格式的地理数据字符串
 * @param {number} altitude - 高度值
 * @returns {Array} 转换后的坐标数组,格式:[{lng, lat, height}, ...]
 */
export const parseWktToPositions = (wktStr, altitude) => {
  try {
    // 步骤1:移除 WKT 开头的类型标识(如 POLYGON(...) → (...))
    const content = wktStr.replace(/^(POLYGON|LineString)\(/i, '').replace(/\)$/, '');
    // 步骤2:处理 POLYGON 的双层括号(如 ((x1 y1, x2 y2)) → x1 y1, x2 y2)
    const coordStr = content.replace(/^\(\s*(.*?)\s*\)$/, '$1').trim();
    if (!coordStr) return [];
 
    // 步骤3:按逗号分割坐标对(如 "x1 y1, x2 y2" → ["x1 y1", "x2 y2"])
    const coordPairs = coordStr.split(',').map(pair => pair.trim());
    if (coordPairs.length < 2) {
      console.warn('WKT 坐标点数量不足');
      return [];
    }
 
    // 步骤4:转换为 {lng, lat, height} 格式(WKT 中坐标是 "lng lat" 顺序)
    return coordPairs.map(pair => {
      const [lng, lat] = pair.split(/\s+/).map(Number); // 按空格分割经纬度
      return {
        lng: lng,
        lat: lat,
        height: Number(altitude) || 0,
      };
    });
  } catch (error) {
    console.error('解析 WKT 格式失败:', error);
    return [];
  }
};
 
/**
 * 统一的地理数据解析函数(兼容 GeoJSON 和 WKT 格式)
 * @param {string} geoDataStr - 地理数据字符串(GeoJSON 或 WKT 格式)
 * @param {number} altitude - 高度值
 * @returns {Array} 转换后的坐标数组,格式:[{lng, lat, height}, ...]
 */
export const parseGeoDataToPositions = (geoDataStr, altitude) => {
  try {
    // 1. 先判断是否为 WKT 格式(以 POLYGON/LineString 开头,不含 { })
    if (
      (geoDataStr.startsWith('POLYGON') || geoDataStr.startsWith('LineString')) &&
      !geoDataStr.includes('{')
    ) {
      return parseWktToPositions(geoDataStr, altitude);
    } 
    // 2. 新增:判断是否为纯坐标数组字符串(以 [ 开头,以 ] 结尾)
    else if (geoDataStr.startsWith('[') && geoDataStr.endsWith(']')) {
      const coordinates = JSON.parse(geoDataStr); // 直接解析为数组
      // 验证是否为二维数组([[lng, lat], ...])
      if (Array.isArray(coordinates) && coordinates.every(item => Array.isArray(item) && item.length >= 2)) {
        return coordinates.map(([lng, lat]) => ({
          lng: Number(lng),
          lat: Number(lat),
          height: Number(altitude) || 0,
        }));
      } else {
        console.warn('纯数组格式错误,需为 [[lng, lat], ...] 结构');
        return [];
      }
    }
    // 3. 最后按 GeoJSON 格式解析
    else {
      const geoData = JSON.parse(geoDataStr);
      let coordinates = [];
 
      if (geoData.type === 'Polygon') {
        coordinates = geoData.coordinates[0] || [];
      } else if (geoData.type === 'LineString') {
        coordinates = geoData.coordinates || [];
      } else {
        console.warn(`不支持的 GeoJSON 类型:${geoData.type}`);
        return [];
      }
 
      return coordinates.map(([lng, lat]) => ({
        lng: Number(lng),
        lat: Number(lat),
        height: Number(altitude) || 0,
      }));
    }
  } catch (error) {
    console.error('解析 geo_data 失败:', error);
    return [];
  }
};