| | |
| | | <script setup lang="ts"> |
| | | import { ref, reactive, nextTick } from "vue"; |
| | | import { currentGET, GETNOBASE } from "@/api"; |
| | | import { registerMap, getMap } from "echarts/core"; |
| | | import { optionHandle, regionCodes } from "./center.map"; |
| | | import BorderBox13 from "@/components/datav/border-box-13"; |
| | | import type { MapdataType } from "./center.map"; |
| | | import chart2 from "./chart2.vue" |
| | | import chartgd from "./chartgd.vue" |
| | | const option = ref({}); |
| | | const code = ref("china"); //china 代表中国 其他地市是行政编码 |
| | | |
| | | withDefaults( |
| | | defineProps<{ |
| | | // 结束数值 |
| | | title: number | string; |
| | | }>(), |
| | | { |
| | | title: "地图", |
| | | } |
| | | ); |
| | | |
| | | const dataSetHandle = async (regionCode: string, list: object[]) => { |
| | | const geojson: any = await getGeojson(regionCode); |
| | | let cityCenter: any = {}; |
| | | let mapData: MapdataType[] = []; |
| | | //获取当前地图每块行政区中心点 |
| | | geojson.features.forEach((element: any) => { |
| | | cityCenter[element.properties.name] = |
| | | element.properties.centroid || element.properties.center; |
| | | }); |
| | | //当前中心点如果有此条数据中心点则赋值x,y当然这个x,y也可以后端返回进行大点,前端省去多行代码 |
| | | list.forEach((item: any) => { |
| | | if (cityCenter[item.name]) { |
| | | mapData.push({ |
| | | name: item.name, |
| | | value: cityCenter[item.name].concat(item.value), |
| | | }); |
| | | } |
| | | }); |
| | | await nextTick(); |
| | | console.log(mapData) |
| | | option.value = optionHandle(regionCode, list, mapData); |
| | | }; |
| | | |
| | | const getData = async (regionCode: string) => { |
| | | currentGET("centerMap", { regionCode: regionCode }).then((res) => { |
| | | console.log("设备分布", res); |
| | | if (res.success) { |
| | | dataSetHandle(res.data.regionCode, res.data.dataList); |
| | | } |
| | | }); |
| | | }; |
| | | const getGeojson = (regionCode: string) => { |
| | | return new Promise<boolean>(async (resolve) => { |
| | | let mapjson = getMap(regionCode); |
| | | if (mapjson) { |
| | | mapjson = mapjson.geoJSON; |
| | | resolve(mapjson); |
| | | } else { |
| | | mapjson = await GETNOBASE(`./map-geojson/${regionCode}.json`).then( |
| | | (data) => data |
| | | ); |
| | | code.value = regionCode; |
| | | registerMap(regionCode, { |
| | | geoJSON: mapjson as any, |
| | | specialAreas: {}, |
| | | }); |
| | | resolve(mapjson); |
| | | } |
| | | }); |
| | | }; |
| | | getData(code.value); |
| | | |
| | | const mapClick = (params: any) => { |
| | | console.log(params); |
| | | let xzqData = regionCodes[params.name]; |
| | | if (xzqData) { |
| | | getData(xzqData.adcode); |
| | | } else { |
| | | window["$message"].warning("暂无下级地市"); |
| | | } |
| | | }; |
| | | const dtFig =ref(0) |
| | | const handlechan =()=>{ |
| | | console.log(dtFig.value) |
| | | dtFig.value = 1 |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="centermap"> |
| | | <div class="maptitle" style="display:none;"> |
| | | <div class="zuo"></div> |
| | | <span class="titletext">{{ title }}</span> |
| | | <div class="you"></div> |
| | | <div class="maptitle"> |
| | | <img src="@/assets/img/icon/map_title.png" alt=""> |
| | | </div> |
| | | <div class="mapwrap" style="display:none;"> |
| | | <!-- <chartgd @changeDt="handlechan" v-if="dtFig ==0"></chartgd>--> |
| | | <chart2 ></chart2> |
| | | <div class="mapwrap"> |
| | | <div ref="map" class="map-style"></div> |
| | | </div> |
| | | |
| | | <div class="map-info-container"> |
| | | <div class="info-title-container"> |
| | | <div class="img-bg"> |
| | | <img src="@/assets/img/icon/map_info_title.png" alt=""> |
| | | </div> |
| | | <div class="info-title"> |
| | | <div class="icon"> |
| | | <img src="@/assets/img/icon/arrow_right.png" alt=""> |
| | | </div> |
| | | <span class="title">都江堰市</span> |
| | | </div> |
| | | </div> |
| | | <div class="info-content-container"> |
| | | <div class="info-item"> |
| | | <div class="info-lable">事故易发多发路段:</div> |
| | | <div class="info-text">78</div> |
| | | </div> |
| | | <div class="info-item"> |
| | | <div class="info-lable">重点旅游通道:</div> |
| | | <div class="info-text">12</div> |
| | | </div> |
| | | <div class="info-item"> |
| | | <div class="info-lable">都江堰景区:</div> |
| | | <div class="info-text">5</div> |
| | | </div> |
| | | <div class="info-item"> |
| | | <div class="info-lable">警力配备:</div> |
| | | <div class="info-text">265</div> |
| | | </div> |
| | | <div class="info-item"> |
| | | <div class="info-lable">打围施工:</div> |
| | | <div class="info-text">12</div> |
| | | </div> |
| | | <div class="info-item"> |
| | | <div class="info-lable">交通事故易发点:</div> |
| | | <div class="info-text">31</div> |
| | | </div> |
| | | <div class="info-item"> |
| | | <div class="info-lable">重点运输企业:</div> |
| | | <div class="info-text">19</div> |
| | | </div> |
| | | <div class="info-item"> |
| | | <div class="info-lable">公交线路:</div> |
| | | <div class="info-text">89</div> |
| | | </div> |
| | | <div class="info-item"> |
| | | <div class="info-lable">安全隐患:</div> |
| | | <div class="info-text">3</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | |
| | | <script setup> |
| | | import * as echarts from 'echarts'; |
| | | import 'echarts-gl'; |
| | | import { ref, onMounted, nextTick } from "vue"; |
| | | |
| | | import mapData from '@/assets/map/dujiangyan.json'; |
| | | |
| | | |
| | | echarts.registerMap('dujiangyan', mapData); |
| | | |
| | | const map = ref(null); |
| | | let mapChart = null; |
| | | |
| | | const mapConfig = { |
| | | geo3D: { |
| | | map: "dujiangyan", //注册地图的名字 |
| | | roam: true, //开启鼠标缩放和平移漫游。默认不开启 |
| | | bottom: 80, |
| | | left: 10, |
| | | itemStyle: { |
| | | color: "#4189f2", // 背景 |
| | | opacity: 0.7, //透明度 |
| | | borderWidth: 1.5, // 边框宽度 |
| | | borderColor: "#fff", // 边框颜色 |
| | | fontSize: 16, // |
| | | }, |
| | | // 标签 |
| | | label: { |
| | | show: true, |
| | | color: "#fff", //地图初始化区域字体颜色 |
| | | fontSize: 18, |
| | | formatter: function (params) { |
| | | return params.name |
| | | }, |
| | | }, |
| | | // 控制器 |
| | | viewControl: { |
| | | beta: 80, |
| | | alpha: 55, |
| | | distance: 210, |
| | | maxBeta: 180 |
| | | }, |
| | | // 灯光 |
| | | light: { |
| | | main: { |
| | | shadow: true, |
| | | intensity: 1 |
| | | } |
| | | }, |
| | | // 鼠标移入时样式 |
| | | emphasis: { |
| | | itemStyle: { |
| | | color: "#F63545" |
| | | } |
| | | } |
| | | } |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | nextTick(() => { |
| | | setTimeout(() => { |
| | | mapChart = echarts.init(map.value); |
| | | mapChart.setOption(mapConfig, true); |
| | | }, 1000); |
| | | }) |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .centermap { |
| | | margin-bottom: 30px; |
| | | |
| | | .maptitle { |
| | | height: 60px; |
| | | display: flex; |
| | | justify-content: center; |
| | | padding-top: 10px; |
| | | box-sizing: border-box; |
| | | |
| | | .titletext { |
| | | font-size: 28px; |
| | | font-weight: 900; |
| | | letter-spacing: 6px; |
| | | background: linear-gradient( |
| | | 92deg, |
| | | #0072ff 0%, |
| | | #00eaff 48.8525390625%, |
| | | #01aaff 100% |
| | | ); |
| | | -webkit-background-clip: text; |
| | | -webkit-text-fill-color: transparent; |
| | | margin: 0 10px; |
| | | } |
| | | |
| | | .zuo, |
| | | .you { |
| | | background-size: 100% 100%; |
| | | width: 29px; |
| | | height: 20px; |
| | | margin-top: 8px; |
| | | } |
| | | |
| | | .zuo { |
| | | background: url("@/assets/img/xiezuo.png") no-repeat; |
| | | } |
| | | |
| | | .you { |
| | | background: url("@/assets/img/xieyou.png") no-repeat; |
| | | } |
| | | } |
| | | position: relative; |
| | | |
| | | .mapwrap { |
| | | //height: 580px; |
| | |
| | | .quanguo { |
| | | position: absolute; |
| | | right: 20px; |
| | | top: -46px; |
| | | top: -46px; |
| | | width: 80px; |
| | | height: 28px; |
| | | border: 1px solid #00eded; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | .map-style { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | .maptitle { |
| | | width: 308px; |
| | | position: absolute; |
| | | left: 0; |
| | | top: 0; |
| | | } |
| | | |
| | | .map-info-container { |
| | | width: 225px; |
| | | position: absolute; |
| | | right: 0; |
| | | bottom: 200px; |
| | | background: rgba(17, 34, 58, 0.6); |
| | | border: 1px solid #29466A; |
| | | |
| | | .info-title-container { |
| | | width: 100%; |
| | | position: relative; |
| | | |
| | | .img-bg { |
| | | width: 100%; |
| | | } |
| | | |
| | | .info-title { |
| | | |
| | | width: 100%; |
| | | position: absolute; |
| | | top: 5px; |
| | | left: 0; |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | .icon { |
| | | width: 15px; |
| | | margin: 0 5px 0 12px; |
| | | } |
| | | |
| | | .title { |
| | | font-weight: 400; |
| | | font-size: 20px; |
| | | color: #FFFFFF; |
| | | text-shadow: 0px 2px 10px rgba(0, 0, 0, 0.5); |
| | | font-style: italic; |
| | | background: linear-gradient(180deg, #FFFFFF 0%, #70B2F4 100%); |
| | | -webkit-background-clip: text; |
| | | // -webkit-text-fill-color: transparent; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .info-content-container { |
| | | padding: 18px 20px; |
| | | margin-top: -40px; |
| | | font-size: 14px; |
| | | |
| | | .info-item { |
| | | width: 100%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | color: #4481DD; |
| | | line-height: 28px; |
| | | .info-text { |
| | | color: #fff; |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | .info-lable { |
| | | font-family: 'PingFang SC' !important; |
| | | } |
| | | </style> |