ZhangXianQiang
2024-03-05 26ab0d5c9dba0b1bb8605f49195a8ebfd0e822e9
src/views/daoAnOffice/center-map.vue
@@ -1,162 +1,141 @@
<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">
      <BorderBox13>
<!--        <div class="quanguo" @click="getData('china')" >-->
<!--          中国-->
<!--        </div>-->
      <div ref="map" class="map-style"></div>
    </div>
        <chartgd @changeDt="handlechan"  v-if="dtFig ==0"></chartgd>
        <chart2 v-else></chart2>
<!--      <v-chart-->
<!--          class="chart"-->
<!--          :option="option"-->
<!--          ref="centerMapRef"-->
<!--          @click="mapClick"-->
<!--          v-if="JSON.stringify(option) != '{}'"-->
<!--        />-->
      </BorderBox13>
    <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;
@@ -169,7 +148,7 @@
    .quanguo {
      position: absolute;
      right: 20px;
        top: -46px;
      top: -46px;
      width: 80px;
      height: 28px;
      border: 1px solid #00eded;
@@ -185,4 +164,83 @@
    }
  }
}
.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>