diff --git a/config/proxy.ts b/config/proxy.ts index a290994be3b66d7b7b0328e9865829b595ec6ec6..bf406bfe30a27670aaa02eb17ba25eb1de2436dd 100644 --- a/config/proxy.ts +++ b/config/proxy.ts @@ -13,4 +13,18 @@ export default { logLevel: 'debug', secure: false, }, + // 网格和区域API代理 + '/region': { + target: 'https://10.1.174.34:13600/kelan', + changeOrigin: true, + pathRewrite: { '^/region': '' }, + logLevel: 'debug', + secure: false, + }, + '/grid-range': { + target: 'https://10.1.174.34:13600', + changeOrigin: true, + logLevel: 'debug', + secure: false, + }, } as Record; diff --git a/src/services/RegionAPI.ts b/src/services/RegionAPI.ts new file mode 100644 index 0000000000000000000000000000000000000000..111684b72d35c333b9dfad1e49c51b375f6a0018 --- /dev/null +++ b/src/services/RegionAPI.ts @@ -0,0 +1,55 @@ +import { request } from '@umijs/max'; + +/** + * 区域和网格API服务 + */ +export default { + /** + * 获取区域详情 + * @param regionCode 区域编码 + * @returns 返回区域详情数据 + */ + getRegionDetailByCode(regionCode: string) { + return request(`/grid-range/unit/${regionCode}`, { + method: 'GET', + }); + }, + + /** + * 获取区域大数据分析 + * @param params 查询参数 + * @returns 返回区域分析数据 + */ + getBigDataAnalysis(params: { + regionCode: string; + gridType?: string; + startTime?: string; + endTime?: string; + dataCode?: string; + hasChildren?: number; + }) { + return request('/region/api/es/v1.0/bigdata_search_analysis', { + method: 'POST', + data: params, + }); + }, + + /** + * 获取点位搜索数据 + * @param params 搜索参数 + * @returns 返回点位数据 + */ + getPointSearchData(params: { + regionCode: string; + dataCode?: string; + gridtype?: string; + startTime?: string; + endTime?: string; + coordinates: string; + }) { + return request('/region/api/es/v1.0/search', { + method: 'POST', + data: params, + }); + } +}; \ No newline at end of file diff --git a/src/services/index.ts b/src/services/index.ts index fbb3a077ae4c95cacb649d07ddf9389138d1ce7f..0689b64648594a77379394c14ddf9b41dcd34a61 100644 --- a/src/services/index.ts +++ b/src/services/index.ts @@ -9,6 +9,8 @@ import * as Information from './Information' import * as CommQuery from './CommQuery' import * as DataBase from './DataBase' import * as AuthApi from './Auth' +import RegionAPI from './RegionAPI' + export default { HomeApi, Physicalsign, @@ -20,5 +22,6 @@ export default { CityRiskApi, Information, CommQuery, - DataBase + DataBase, + RegionAPI }; diff --git a/src/utils/loadArea.js b/src/utils/loadArea.js new file mode 100644 index 0000000000000000000000000000000000000000..0ad347f24be71baa99b9a3836c684076422a9094 --- /dev/null +++ b/src/utils/loadArea.js @@ -0,0 +1,269 @@ +import regionResult from './regionTreeResult.json' + +export class CooglLoadArea { + constructor(viewer, token) { + this.viewer = viewer + this.imageGraphicList = [] + this.polygonGraphicList = [] + this.pickHandler = null + this.regionResult = regionResult.data + this.token = token ?? CooGL.CooServer.defaultAccessToken + this.mapInit() + } + + async mapInit() { + if (this.pickHandler) { + this.pickHandler() + this.pickHandler = null + } + + //清除画布 + this.clear() + + await this.addArea({ + regionCode: '5101', + gridType: '01', + dataCode: '20101', + hasChildren: 1, + }) + } + + /** + * 添加区域 + * @param {string} regionCode - 区域编码 + * @param {string} gridtype - 网格类型 + * 01:城市部件 + * 02:事件 + * 03:资源 + * 04:单元网格 + * 05:责任网格 + * 06:任意网格 + * 07:资源网格 + * 08:感知设备 + * @param {string} startTime - 开始时间 格式:yyyy-MM-DD HH:mm:ss 可选 + * @param {string} endTime - 结束时间 格式:yyyy-MM-DD HH:mm:ss 可选 + */ + + async addArea(params, clearData = false) { + if (clearData) { + this.clear() + } + + const list = this.findRegionByCode(params.regionCode, true) + const resList = await Promise.all([ + this.getRigionDetailByCode(params.regionCode), + ...list.map(({ id }) => this.getRigionDetailByCode(id)), + ]) + let positions = resList[0].features[0].geometry.coordinates.flat(Infinity) + // 将扁平化的坐标数组重新组装成对象数组 + const positionObjects = [] + for (let i = 0; i < positions.length; i += 2) { + positionObjects.push({ + x: positions[i], + y: positions[i + 1], + z: 0, + }) + } + positions = positionObjects + // 添加多边形图层 + this.addPolygon(resList[0]) + this.moveViewToPolygon(positions) + const sons = resList.slice(1) + for (const res of sons) { + this.addPolygon(res) + } + + fetch('/region/coogl/api/es/v1.0/bigdata_search_analysis', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + token: this.token, + }, + body: JSON.stringify(params), + }) + .then(res => res.json()) + .then(res => { + const obj = res.data + delete obj[params.regionCode] + console.warn('Sons:', sons) + console.warn('API Result:', obj) + }) + .catch(err => { + console.error('Error fetching area data:', err) + }) + } + + // 获取指定regionCode的区域的经纬度以及中心点和下级区域的所有经纬度 + async getRigionDetailByCode(regionCode) { + if (!regionCode) return Promise.reject('regionCode is required') + try { + const response = await fetch(`/grid-range/unit/${regionCode}.txt`) + if (!response.ok) { + throw new Error(`Failed to fetch region data: ${response.status}`) + } + const data = await response.text() + const geo = JSON.parse(data) + return geo + } catch (error) { + console.error(`Error fetching region ${regionCode}:`, error) + // 提供一个fallback数据结构以防API失败 + return { + type: "FeatureCollection", + features: [{ + type: "Feature", + properties: { + _name: `区域${regionCode}`, + _center: "104.06,30.67" // 成都中心点 + }, + geometry: { + type: "Polygon", + coordinates: [[[104.01, 30.62], [104.11, 30.62], [104.11, 30.72], [104.01, 30.72], [104.01, 30.62]]] + } + }] + } + } + } + + addImage(num, code, position) { + return this.viewer.addLayer( + CooGL.Layer.fromImageTextLabel({ + id: code, + description: { + code, + }, + image: 'point.png', + position: position || { x: 104.06, y: 30.67, z: 35 }, + textContent: num, + font: '24px simsum', + style: CooGL.LabelStyle.FILL_AND_OUTLINE, + outlineWidth: 2, + outlineColor: 'rgb(128,236,35)', + }), + ) + } + + addPolygon(polygonData) { + try { + this.viewer + .addLayer( + CooGL.Layer.fromGeoJsonGraphicResource({ + resource: polygonData, + customPolygonLabelOptions: function (positions, properties) { + const center = properties._center.split(',') + const textPosition = { x: center[0], y: center[1], z: 0 } + return { + positions, + material: '#0B304B', + textPosition, + outline: true, + outlineColor: '#36A6F5', + outlineWidth: 5, + fillColor: '#fff', + font: '32px simsum', + textContent: properties._name, + } + }, + }), + ) + .then(res => { + this.polygonGraphicList.push(res) + }) + .catch(err => { + console.error('Error adding polygon:', err) + }) + } catch (error) { + console.error('Error in addPolygon:', error) + } + } + + //计算多边形的包围盒,并将视角移动到包围盒的中心 + moveViewToPolygon(positions) { + try { + const bs = CooGL.BoundingSphere.fromPoints( + CooGL.Vector3.degreesArray2cartesian(positions), + ) + if (!bs) return + + const height = bs.radius * 2.5 + const center = CooGL.Vector3.cartesian2degrees(bs.center) + if (!center) return + + const destination = { + x: center.x, + y: center.y, + z: height, + } + + this.viewer.camera.flyTo({ + destination, + orientation: { + heading: 0, + pitch: -1.5707963267948966, + roll: 0, + }, + duration: 1, + }) + } catch (error) { + console.error('Error in moveViewToPolygon:', error) + } + } + + findRegionByCode(code, findSon = false) { + if (!code) return [] + const dfs = (tree, result = []) => { + if (!tree) return result + for (const item of tree) { + if (findSon) { + if (item.id === code) { + return item.children || [] + } + } else { + if (item.id === code) { + result.push(item) + } + } + if (item.children && item.children.length) { + dfs(item.children, result) + } + } + return result + } + return dfs(this.regionResult) + } + + flyToArea([x, y], code) { + this.clear() + this.addArea({ + regionCode: code, + gridType: '01', + dataCode: '20101', + hasChildren: 1, + }) + } + + clear() { + try { + // 清除图标 + this.imageGraphicList.forEach(item => { + this.viewer.removeLayer(item) + }) + this.imageGraphicList = [] + + // 清除多边形 + this.polygonGraphicList.forEach(item => { + this.viewer.removeLayer(item) + }) + this.polygonGraphicList = [] + } catch (error) { + console.error('Error in clear:', error) + } + } + + destory() { + this.clear() + if (this.pickHandler) { + this.pickHandler() + this.pickHandler = null + } + } +} \ No newline at end of file diff --git a/src/utils/regionTreeResult.json b/src/utils/regionTreeResult.json new file mode 100644 index 0000000000000000000000000000000000000000..8b167f2fae11f45199f8e76134c48ad5bd0aee41 --- /dev/null +++ b/src/utils/regionTreeResult.json @@ -0,0 +1,111 @@ +{ + "code": 200, + "data": [ + { + "id": "5101", + "name": "成都市", + "children": [ + { + "id": "510104", + "name": "锦江区", + "children": [] + }, + { + "id": "510105", + "name": "青羊区", + "children": [] + }, + { + "id": "510106", + "name": "金牛区", + "children": [] + }, + { + "id": "510107", + "name": "武侯区", + "children": [] + }, + { + "id": "510108", + "name": "成华区", + "children": [] + }, + { + "id": "510112", + "name": "龙泉驿区", + "children": [] + }, + { + "id": "510113", + "name": "青白江区", + "children": [] + }, + { + "id": "510114", + "name": "新都区", + "children": [] + }, + { + "id": "510115", + "name": "温江区", + "children": [] + }, + { + "id": "510116", + "name": "双流区", + "children": [] + }, + { + "id": "510117", + "name": "郫都区", + "children": [] + }, + { + "id": "510121", + "name": "金堂县", + "children": [] + }, + { + "id": "510129", + "name": "大邑县", + "children": [] + }, + { + "id": "510131", + "name": "蒲江县", + "children": [] + }, + { + "id": "510132", + "name": "新津区", + "children": [] + }, + { + "id": "510181", + "name": "都江堰市", + "children": [] + }, + { + "id": "510182", + "name": "彭州市", + "children": [] + }, + { + "id": "510183", + "name": "邛崃市", + "children": [] + }, + { + "id": "510184", + "name": "崇州市", + "children": [] + }, + { + "id": "510185", + "name": "简阳市", + "children": [] + } + ] + } + ] +} \ No newline at end of file