Commit b76cf85feddb6e1740f49361a7ef378bcec4eda2

Authored by fengwotao
1 parent 98daac85

feat(src/packages): 优化3d地图代码和注释

@@ -111,7 +111,7 @@ export const getVideoUrl = (id: string) => @@ -111,7 +111,7 @@ export const getVideoUrl = (id: string) =>
111 }) 111 })
112 112
113 //获取行政区域 113 //获取行政区域
114 -export const getGeoJsonMap = (code: number, level: string) => 114 +export const getGeoJsonMap = (code: number | string, level: string) =>
115 defHttp.get({ 115 defHttp.get({
116 url: `${Api.GEOJSONURL}${code}/${level}` 116 url: `${Api.GEOJSONURL}${code}/${level}`
117 }) 117 })
@@ -14,6 +14,26 @@ export const enum areaEnum { @@ -14,6 +14,26 @@ export const enum areaEnum {
14 TOWN = 'TOWN' //镇 14 TOWN = 'TOWN' //镇
15 } 15 }
16 16
  17 +//父级地区编码和级别接口
  18 +export interface HistoryParentType {
  19 + adcode: string | number
  20 + level: string
  21 +}
  22 +
  23 +//数据源接口
  24 +export interface dataPointI {
  25 + name: string
  26 + value: number[]
  27 + adcode: number
  28 + height: number
  29 + itemStyle: {
  30 + color: string
  31 + opacity: number
  32 + borderWidth: number
  33 + borderColor: string
  34 + }
  35 +}
  36 +
17 export const includes = [] 37 export const includes = []
18 38
19 export const option = { 39 export const option = {
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 <!-- 原生方式,没有使用vue-echarts --> 2 <!-- 原生方式,没有使用vue-echarts -->
3 <n-space vertical> 3 <n-space vertical>
4 <n-spin :show="show"> 4 <n-spin :show="show">
5 - <div :style="`width:${w}px;height:${h}px;`" ref="map3DRef"></div> 5 + <div id="map3DId" :style="`width:${w}px;height:${h}px;`"></div>
6 </n-spin> 6 </n-spin>
7 </n-space> 7 </n-space>
8 </template> 8 </template>
@@ -12,7 +12,7 @@ import { onMounted, ref, nextTick, PropType, toRefs, watch, reactive } from 'vue @@ -12,7 +12,7 @@ import { onMounted, ref, nextTick, PropType, toRefs, watch, reactive } from 'vue
12 import * as echarts from 'echarts' 12 import * as echarts from 'echarts'
13 import { registerMap } from 'echarts/core' 13 import { registerMap } from 'echarts/core'
14 import 'echarts-gl' 14 import 'echarts-gl'
15 -import config, { areaEnum } from './config' 15 +import config, { areaEnum, dataPointI, HistoryParentType } from './config'
16 import { getGeoJsonMap } from '@/api/external/common' 16 import { getGeoJsonMap } from '@/api/external/common'
17 import dataMaps from './data.json' 17 import dataMaps from './data.json'
18 18
@@ -29,8 +29,6 @@ const iconStr = ref( @@ -29,8 +29,6 @@ const iconStr = ref(
29 29
30 const { w, h } = toRefs(props.chartConfig.attr) 30 const { w, h } = toRefs(props.chartConfig.attr)
31 31
32 -const map3DRef = ref()  
33 -  
34 const show = ref(true) 32 const show = ref(true)
35 33
36 const chartInstance = ref() 34 const chartInstance = ref()
@@ -47,7 +45,7 @@ const toolBoxOption = ref({ @@ -47,7 +45,7 @@ const toolBoxOption = ref({
47 iconStyle: { 45 iconStyle: {
48 color: '' 46 color: ''
49 }, 47 },
50 - onclick: () => watchAdcode() 48 + onclick: () => mapClickBack()
51 } 49 }
52 } 50 }
53 }) 51 })
@@ -60,44 +58,53 @@ watch( @@ -60,44 +58,53 @@ watch(
60 toolBoxOption.value.feature.myFullButton.iconStyle.color = iconColor 58 toolBoxOption.value.feature.myFullButton.iconStyle.color = iconColor
61 toolBoxOption.value.right = iconDistanceRight 59 toolBoxOption.value.right = iconDistanceRight
62 toolBoxOption.value.top = iconDistanceTop 60 toolBoxOption.value.top = iconDistanceTop
63 - },  
64 - {  
65 - deep: true  
66 } 61 }
67 ) 62 )
68 63
  64 +//追加右上角返回图标配置
69 props.chartConfig.option = { 65 props.chartConfig.option = {
70 ...props.chartConfig.option, 66 ...props.chartConfig.option,
71 ...{ toolbox: toolBoxOption.value } 67 ...{ toolbox: toolBoxOption.value }
72 } 68 }
73 69
74 //地图点击返回 70 //地图点击返回
75 -const watchAdcode = async () => {  
76 - if (props.chartConfig.option.drillingIn) {  
77 - //如果是从右边配置里设置的,比如点击四川省,然后点击返回  
78 - const savePopParent = saveHistoryParent.value.pop()  
79 - let saveAdcode: any = savePopParent?.adcode  
80 - saveLevelStr.level = savePopParent?.level as string  
81 - if (!savePopParent) {  
82 - saveAdcode = getParentAdcode(props.chartConfig.option.mapRegion.adcode)  
83 - saveLevelStr.level = (regionMapParentArea as any)[props.chartConfig.option.mapRegion.saveSelect.levelStr]  
84 - }  
85 - if (saveAdcode === 0) {  
86 - saveAdcode = 'china'  
87 - saveLevelStr.level = 'COUNTRY' 71 +const mapClickBack = async () => {
  72 + try {
  73 + if (props.chartConfig.option.drillingIn) {
  74 + //如果是从右边配置里设置的,比如点击四川省,然后点击返回
  75 + const savePopParent = saveHistoryParent.value.pop()
  76 + let saveAdcode = savePopParent?.adcode as string | number
  77 + saveLevelStr.level = savePopParent?.level
  78 + if (!savePopParent) {
  79 + saveAdcode = getParentAdcode(props.chartConfig.option.mapRegion.adcode)
  80 + saveLevelStr.level = (regionMapParentArea as Recordable)[props.chartConfig.option.mapRegion.saveSelect.levelStr]
  81 + }
  82 + if (saveAdcode === 0) {
  83 + saveAdcode = 'china'
  84 + saveLevelStr.level = 'COUNTRY'
  85 + }
  86 + await registerGeojson(saveAdcode)
  87 + const adcode = saveAdcode === 100000 ? 'china' : saveAdcode
  88 + setMap3DPartOption(adcode)
  89 + handleSetOption(chartInstance.value, props.chartConfig.option)
  90 + handleDataPoint(adcode)
88 } 91 }
89 - await getGeojson(saveAdcode)  
90 - const adcode = saveAdcode === 100000 ? 'china' : saveAdcode  
91 - props.chartConfig.option.geo3D.map = adcode  
92 - props.chartConfig.option.series.forEach((item: any) => {  
93 - if (item.type === 'map3D') item.map = adcode  
94 - item.data = props.chartConfig.option.dataset  
95 - })  
96 - handleSetOption(chartInstance.value, props.chartConfig.option)  
97 - handleDataPoint(adcode) 92 + } catch (error) {
  93 + console.error('地图点击返回出错', error)
98 } 94 }
99 } 95 }
100 96
  97 +//设置map3D部分属性
  98 +const setMap3DPartOption = (adcode: number | string) => {
  99 + props.chartConfig.option.geo3D.map = adcode
  100 + props.chartConfig.option.series.forEach((item: Recordable) => {
  101 + if (item.type === 'map3D') {
  102 + item.map = adcode
  103 + item.data = props.chartConfig.option.dataset
  104 + }
  105 + })
  106 +}
  107 +
101 const regionMapParentArea = { 108 const regionMapParentArea = {
102 [areaEnum.PROVINCE]: areaEnum.COUNTRY, //省份的上一级 中国 109 [areaEnum.PROVINCE]: areaEnum.COUNTRY, //省份的上一级 中国
103 [areaEnum.CITY]: areaEnum.PROVINCE, //城市的上一级 省份 110 [areaEnum.CITY]: areaEnum.PROVINCE, //城市的上一级 省份
@@ -105,62 +112,63 @@ const regionMapParentArea = { @@ -105,62 +112,63 @@ const regionMapParentArea = {
105 [areaEnum.TOWN]: areaEnum.COUNTY //镇的上一级 县或者区 112 [areaEnum.TOWN]: areaEnum.COUNTY //镇的上一级 县或者区
106 } 113 }
107 114
108 -//地图点击  
109 -const handleMap3DClick = async (params: any) => { 115 +//三维地图点击
  116 +const handleMap3DClick = async (params: Recordable) => {
110 if (props.chartConfig.option.drillingIn) { 117 if (props.chartConfig.option.drillingIn) {
111 const { name } = params 118 const { name } = params
112 - saveGeojson.value?.features.forEach((item: any) => { 119 + saveGeojson.value?.features.forEach((item: Recordable) => {
113 if (item.properties.name === name) { 120 if (item.properties.name === name) {
114 const level = item.properties.level.toUpperCase() 121 const level = item.properties.level.toUpperCase()
115 const adcode = item.properties.adcode 122 const adcode = item.properties.adcode
  123 + //如果是区则终止,目前没有加区下面的geojson数据
116 if (level === 'DISTRICT') return 124 if (level === 'DISTRICT') return
117 - if(String(adcode).startsWith('15') && level===areaEnum.CITY) return 125 + //特殊处理15开头的geojson数据
  126 + if (String(adcode).startsWith('15') && level === areaEnum.CITY) return
118 props.chartConfig.option.mapRegion.adcode = adcode 127 props.chartConfig.option.mapRegion.adcode = adcode
119 saveLevelStr.level = level 128 saveLevelStr.level = level
120 handleDataPoint(adcode) 129 handleDataPoint(adcode)
121 saveHistoryParent.value.push({ 130 saveHistoryParent.value.push({
122 adcode: item.properties.parent.adcode, 131 adcode: item.properties.parent.adcode,
123 - level: (regionMapParentArea as any)[level] 132 + level: (regionMapParentArea as Recordable)[level]
124 }) 133 })
125 } 134 }
126 }) 135 })
127 } 136 }
128 } 137 }
129 138
130 -const saveGeojson: any = ref({}) // 保存geojson 139 +// 保存geojson
  140 +const saveGeojson: Recordable = ref({})
131 141
132 -const chinaDefaultRegionId = ref(100000) //如果是china则adcode为100000 142 +//如果是china则adcode为100000
  143 +const chinaDefaultRegionId = ref(100000)
133 144
134 -const saveLevelStr = reactive({  
135 - // 地区级别  
136 - level: '' 145 +// 保存地区级别
  146 +const saveLevelStr = reactive<{ level: string | undefined }>({
  147 + level: ''
137 }) 148 })
138 149
139 -//父级地区编码和级别接口  
140 -interface HistoryParentType {  
141 - adcode: number  
142 - level: string  
143 -}  
144 - 150 +// 保存上一级的adcode和行政级别
145 const saveHistoryParent = ref<HistoryParentType[]>([]) 151 const saveHistoryParent = ref<HistoryParentType[]>([])
146 152
147 //动态注册地图 153 //动态注册地图
148 -const getGeojson = (regionId: any) => { 154 +const registerGeojson = (regionId: number | string) => {
149 try { 155 try {
150 return new Promise<boolean>(resolve => { 156 return new Promise<boolean>(resolve => {
151 - const { levelStr } = props.chartConfig.option.mapRegion.saveSelect //右侧配置项获取的行政级别 157 + const { levelStr } = props.chartConfig.option.mapRegion.saveSelect //右侧配置项获取的行政级别
152 getGeoJsonMap( 158 getGeoJsonMap(
153 regionId === 'china' ? chinaDefaultRegionId.value : regionId, 159 regionId === 'china' ? chinaDefaultRegionId.value : regionId,
154 !saveLevelStr.level ? levelStr : saveLevelStr.level 160 !saveLevelStr.level ? levelStr : saveLevelStr.level
155 ).then(res => { 161 ).then(res => {
156 - const { geoJson, name, code, level } = res.data  
157 - const geoJsonFile = JSON.parse(geoJson)  
158 - if (!geoJsonFile) return  
159 - saveGeojson.value = geoJsonFile  
160 - const nameChina = name === '中国' ? 'china' : name  
161 - registerMap(level === areaEnum.COUNTRY ? nameChina : code, { geoJSON: geoJsonFile as any, specialAreas: {} })  
162 - show.value = false  
163 - resolve(true) 162 + if (res.data) {
  163 + const { geoJson, name, code, level } = res.data
  164 + if (!geoJson) return
  165 + const geoJsonFile = JSON.parse(geoJson)
  166 + saveGeojson.value = geoJsonFile
  167 + const nameChina = name === '中国' ? 'china' : name
  168 + registerMap(level === areaEnum.COUNTRY ? nameChina : code, { geoJSON: geoJsonFile, specialAreas: {} })
  169 + resolve(true)
  170 + show.value = false
  171 + }
164 }) 172 })
165 }) 173 })
166 } catch (error) { 174 } catch (error) {
@@ -171,11 +179,13 @@ const getGeojson = (regionId: any) => { @@ -171,11 +179,13 @@ const getGeojson = (regionId: any) => {
171 } 179 }
172 } 180 }
173 181
  182 +//注册出错则注册空的,不然在选择正确的adcode,则视图无法更新
  183 +registerMap(props.chartConfig.option.mapRegion.adcode, { geoJSON: {} as any, specialAreas: {} })
174 184
175 -//传adcode 获取上级 185 +//获取上级adcode
176 const getParentAdcode = (adcode: number) => { 186 const getParentAdcode = (adcode: number) => {
177 let adcodeNum = 100000 187 let adcodeNum = 100000
178 - saveGeojson.value?.features.forEach((item: any) => { 188 + saveGeojson.value?.features?.forEach((item: Recordable) => {
179 if (item.properties.adcode === adcode) { 189 if (item.properties.adcode === adcode) {
180 adcodeNum = item.properties.parent.adcode 190 adcodeNum = item.properties.parent.adcode
181 } 191 }
@@ -193,59 +203,64 @@ watch( @@ -193,59 +203,64 @@ watch(
193 } 203 }
194 ) 204 )
195 205
196 -const initMap = async () => {  
197 - chartInstance.value = echarts.init(map3DRef.value)  
198 - await nextTick()  
199 - await getGeojson(props.chartConfig.option.mapRegion.adcode)  
200 - await nextTick().then(() => {  
201 - handleSetOption(chartInstance.value, props.chartConfig.option)  
202 - })  
203 - chartInstance.value.on('click', (e: any) => {  
204 - handleMap3DClick(e)  
205 - }) 206 +//初始化3D地图
  207 +const initMap3D = async () => {
  208 + try {
  209 + const dom = document.getElementById('map3DId') as HTMLElement
  210 + chartInstance.value = echarts.init(dom)
  211 + await nextTick()
  212 + await registerGeojson(props.chartConfig.option.mapRegion.adcode)
  213 + await nextTick().then(() => {
  214 + handleSetOption(chartInstance.value, props.chartConfig.option)
  215 + })
  216 + //三维地图点击
  217 + chartInstance.value.on('click', (e: Recordable) => {
  218 + handleMap3DClick(e)
  219 + })
  220 + } catch (error) {
  221 + console.error('[initMap3D]初始化3d地图出错', error)
  222 + }
206 } 223 }
207 224
  225 +onMounted(() => {
  226 + setTimeout(() => {
  227 + initMap3D()
  228 + }, 500)
  229 +})
  230 +
208 // 手动触发渲染 231 // 手动触发渲染
209 -const handleSetOption = (instance: any, option: any) => {  
210 - if (!instance) return 232 +const handleSetOption = (instance: any, option: Recordable) => {
211 try { 233 try {
  234 + if (!instance) return
212 instance.clear() 235 instance.clear()
213 instance.setOption(option) 236 instance.setOption(option)
214 } catch (error) { 237 } catch (error) {
215 - console.error('触发渲染出错', error) 238 + console.error('手动触发渲染出错', error)
216 } 239 }
217 } 240 }
218 241
219 -onMounted(() => {  
220 - initMap()  
221 -})  
222 -  
223 //处理数据标点 242 //处理数据标点
224 -const handleDataPoint = (newData: any) => { 243 +const handleDataPoint = (newData: string | number) => {
225 if (newData === 'china') { 244 if (newData === 'china') {
  245 + //全国则显示所有标点
226 props.chartConfig.option.dataset = dataMaps 246 props.chartConfig.option.dataset = dataMaps
227 } else { 247 } else {
228 - props.chartConfig.option.dataset = dataMaps.filter((item: any) => item.adcode === newData) 248 + //显示对应区域标点
  249 + props.chartConfig.option.dataset = dataMaps.filter((item: dataPointI) => item.adcode === newData)
229 } 250 }
230 } 251 }
231 252
232 //监听地图展示区域发生变化 253 //监听地图展示区域发生变化
233 watch( 254 watch(
234 () => `${props.chartConfig.option.mapRegion.adcode}`, 255 () => `${props.chartConfig.option.mapRegion.adcode}`,
235 - async (newData: any) => { 256 + async (newData: string | number) => {
236 try { 257 try {
237 - await getGeojson(newData)  
238 - props.chartConfig.option.geo3D.map = newData  
239 - props.chartConfig.option.series.forEach((item: any) => {  
240 - if (item.type === 'map3D') {  
241 - item.map = newData  
242 - item.data = props.chartConfig.option.dataset  
243 - }  
244 - }) 258 + await registerGeojson(newData)
  259 + setMap3DPartOption(newData)
245 handleSetOption(chartInstance.value, props.chartConfig.option) 260 handleSetOption(chartInstance.value, props.chartConfig.option)
246 handleDataPoint(newData) 261 handleDataPoint(newData)
247 } catch (error) { 262 } catch (error) {
248 - console.log('展示区域发生变化出错', error) 263 + console.log('监听地图展示区域发生变化', error)
249 } 264 }
250 }, 265 },
251 { 266 {
@@ -260,7 +275,7 @@ watch( @@ -260,7 +275,7 @@ watch(
260 try { 275 try {
261 handleSetOption(chartInstance.value, newData) 276 handleSetOption(chartInstance.value, newData)
262 } catch (error) { 277 } catch (error) {
263 - console.log(error) 278 + console.log('监听地图右侧配置项变化', error)
264 } 279 }
265 }, 280 },
266 { 281 {
@@ -273,14 +288,14 @@ watch( @@ -273,14 +288,14 @@ watch(
273 () => props.chartConfig.option.dataset, 288 () => props.chartConfig.option.dataset,
274 newData => { 289 newData => {
275 try { 290 try {
276 - props.chartConfig.option.series.forEach((item: any) => { 291 + props.chartConfig.option.series.forEach((item: Recordable) => {
277 if (item.type === 'map3D') { 292 if (item.type === 'map3D') {
278 item.data = newData 293 item.data = newData
279 } 294 }
280 }) 295 })
281 handleSetOption(chartInstance.value, props.chartConfig.option) 296 handleSetOption(chartInstance.value, props.chartConfig.option)
282 } catch (error) { 297 } catch (error) {
283 - console.log(error) 298 + console.log('监听地图dataset配置项变化', error)
284 } 299 }
285 }, 300 },
286 { 301 {