Commit b76cf85feddb6e1740f49361a7ef378bcec4eda2

Authored by fengwotao
1 parent 98daac85

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

... ... @@ -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 115 defHttp.get({
116 116 url: `${Api.GEOJSONURL}${code}/${level}`
117 117 })
... ...
... ... @@ -14,6 +14,26 @@ export const enum areaEnum {
14 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 37 export const includes = []
18 38
19 39 export const option = {
... ...
... ... @@ -2,7 +2,7 @@
2 2 <!-- 原生方式,没有使用vue-echarts -->
3 3 <n-space vertical>
4 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 6 </n-spin>
7 7 </n-space>
8 8 </template>
... ... @@ -12,7 +12,7 @@ import { onMounted, ref, nextTick, PropType, toRefs, watch, reactive } from 'vue
12 12 import * as echarts from 'echarts'
13 13 import { registerMap } from 'echarts/core'
14 14 import 'echarts-gl'
15   -import config, { areaEnum } from './config'
  15 +import config, { areaEnum, dataPointI, HistoryParentType } from './config'
16 16 import { getGeoJsonMap } from '@/api/external/common'
17 17 import dataMaps from './data.json'
18 18
... ... @@ -29,8 +29,6 @@ const iconStr = ref(
29 29
30 30 const { w, h } = toRefs(props.chartConfig.attr)
31 31
32   -const map3DRef = ref()
33   -
34 32 const show = ref(true)
35 33
36 34 const chartInstance = ref()
... ... @@ -47,7 +45,7 @@ const toolBoxOption = ref({
47 45 iconStyle: {
48 46 color: ''
49 47 },
50   - onclick: () => watchAdcode()
  48 + onclick: () => mapClickBack()
51 49 }
52 50 }
53 51 })
... ... @@ -60,44 +58,53 @@ watch(
60 58 toolBoxOption.value.feature.myFullButton.iconStyle.color = iconColor
61 59 toolBoxOption.value.right = iconDistanceRight
62 60 toolBoxOption.value.top = iconDistanceTop
63   - },
64   - {
65   - deep: true
66 61 }
67 62 )
68 63
  64 +//追加右上角返回图标配置
69 65 props.chartConfig.option = {
70 66 ...props.chartConfig.option,
71 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 108 const regionMapParentArea = {
102 109 [areaEnum.PROVINCE]: areaEnum.COUNTRY, //省份的上一级 中国
103 110 [areaEnum.CITY]: areaEnum.PROVINCE, //城市的上一级 省份
... ... @@ -105,62 +112,63 @@ const regionMapParentArea = {
105 112 [areaEnum.TOWN]: areaEnum.COUNTY //镇的上一级 县或者区
106 113 }
107 114
108   -//地图点击
109   -const handleMap3DClick = async (params: any) => {
  115 +//三维地图点击
  116 +const handleMap3DClick = async (params: Recordable) => {
110 117 if (props.chartConfig.option.drillingIn) {
111 118 const { name } = params
112   - saveGeojson.value?.features.forEach((item: any) => {
  119 + saveGeojson.value?.features.forEach((item: Recordable) => {
113 120 if (item.properties.name === name) {
114 121 const level = item.properties.level.toUpperCase()
115 122 const adcode = item.properties.adcode
  123 + //如果是区则终止,目前没有加区下面的geojson数据
116 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 127 props.chartConfig.option.mapRegion.adcode = adcode
119 128 saveLevelStr.level = level
120 129 handleDataPoint(adcode)
121 130 saveHistoryParent.value.push({
122 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 151 const saveHistoryParent = ref<HistoryParentType[]>([])
146 152
147 153 //动态注册地图
148   -const getGeojson = (regionId: any) => {
  154 +const registerGeojson = (regionId: number | string) => {
149 155 try {
150 156 return new Promise<boolean>(resolve => {
151   - const { levelStr } = props.chartConfig.option.mapRegion.saveSelect //右侧配置项获取的行政级别
  157 + const { levelStr } = props.chartConfig.option.mapRegion.saveSelect //右侧配置项获取的行政级别
152 158 getGeoJsonMap(
153 159 regionId === 'china' ? chinaDefaultRegionId.value : regionId,
154 160 !saveLevelStr.level ? levelStr : saveLevelStr.level
155 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 174 } catch (error) {
... ... @@ -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 186 const getParentAdcode = (adcode: number) => {
177 187 let adcodeNum = 100000
178   - saveGeojson.value?.features.forEach((item: any) => {
  188 + saveGeojson.value?.features?.forEach((item: Recordable) => {
179 189 if (item.properties.adcode === adcode) {
180 190 adcodeNum = item.properties.parent.adcode
181 191 }
... ... @@ -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 233 try {
  234 + if (!instance) return
212 235 instance.clear()
213 236 instance.setOption(option)
214 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 244 if (newData === 'china') {
  245 + //全国则显示所有标点
226 246 props.chartConfig.option.dataset = dataMaps
227 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 254 watch(
234 255 () => `${props.chartConfig.option.mapRegion.adcode}`,
235   - async (newData: any) => {
  256 + async (newData: string | number) => {
236 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 260 handleSetOption(chartInstance.value, props.chartConfig.option)
246 261 handleDataPoint(newData)
247 262 } catch (error) {
248   - console.log('展示区域发生变化出错', error)
  263 + console.log('监听地图展示区域发生变化', error)
249 264 }
250 265 },
251 266 {
... ... @@ -260,7 +275,7 @@ watch(
260 275 try {
261 276 handleSetOption(chartInstance.value, newData)
262 277 } catch (error) {
263   - console.log(error)
  278 + console.log('监听地图右侧配置项变化', error)
264 279 }
265 280 },
266 281 {
... ... @@ -273,14 +288,14 @@ watch(
273 288 () => props.chartConfig.option.dataset,
274 289 newData => {
275 290 try {
276   - props.chartConfig.option.series.forEach((item: any) => {
  291 + props.chartConfig.option.series.forEach((item: Recordable) => {
277 292 if (item.type === 'map3D') {
278 293 item.data = newData
279 294 }
280 295 })
281 296 handleSetOption(chartInstance.value, props.chartConfig.option)
282 297 } catch (error) {
283   - console.log(error)
  298 + console.log('监听地图dataset配置项变化', error)
284 299 }
285 300 },
286 301 {
... ...