riku
2024-05-13 d277d770292df0a1266c07f4773d62edd70e6515
新增场景标注
已修改11个文件
已添加13个文件
680 ■■■■■ 文件已修改
index.html 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/sceneInfoApi.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/mipmap/scene_1.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/mipmap/scene_15.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/mipmap/scene_16.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/mipmap/scene_17.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/mipmap/scene_18.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/mipmap/scene_4.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/mipmap/scene_5.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/mipmap/scene_6.png 补丁 | 查看 | 原始文档 | blame | 历史
src/components.d.ts 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/map/MapLocation.vue 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/map/MapScene.vue 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/search/OptionLocation.vue 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/constant/scene-types.js 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/model/FactorDatas.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/map/animation.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/map/calculate.js 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/map/index_old.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/map/marks.js 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/map/util.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/HomePage.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/realtimemode/RealtimeMode.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
index.html
@@ -10,7 +10,7 @@
    <div id="app"></div>
    <script
      type="text/javascript"
      src="https://webapi.amap.com/maps?v=1.4.5&key=c55f27799afbfa69dc5a3fad90cafe51&plugin=Map3D,ElasticMarker,AMap.ControlBar"
      src="https://webapi.amap.com/maps?v=1.4.5&key=c55f27799afbfa69dc5a3fad90cafe51&plugin=Map3D,ElasticMarker,AMap.ControlBar,AMap.Geocoder"
    ></script>
    <script src="/src/lib/jquery-3.5.1.min.js"></script>
    <script type="module" src="/src/main.js"></script>
src/api/index.js
@@ -1,13 +1,13 @@
import axios from 'axios';
import { ElMessage } from 'element-plus';
const debug = false;
const debug = true;
let ip1 = 'http://114.215.109.124:8805/';
// let ip1 = 'http://47.100.191.150:9029/';
if (debug) {
  ip1 = 'http://192.168.0.138:8082/';
  ip1 = 'http://192.168.0.138:8084/';
}
const $http = axios.create({
src/api/sceneInfoApi.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
import { $http } from './index';
/**
 *
 */
export default {
  searchScene(area) {
    return $http.post(`scene/find`, area).then((res) => res.data);
  }
  // searchByCoordinate({lng, lat, radius}) {
  //   return $http.post(`scene/find/radius`, mission).then((res) => res.data);
  // },
};
src/assets/mipmap/scene_1.png
src/assets/mipmap/scene_15.png
src/assets/mipmap/scene_16.png
src/assets/mipmap/scene_17.png
src/assets/mipmap/scene_18.png
src/assets/mipmap/scene_4.png
src/assets/mipmap/scene_5.png
src/assets/mipmap/scene_6.png
src/components.d.ts
@@ -11,8 +11,7 @@
    BaseMap: typeof import('./components/map/BaseMap.vue')['default']
    CardButton: typeof import('./components/CardButton.vue')['default']
    CardDialog: typeof import('./components/CardDialog.vue')['default']
    cop: typeof import('./components/monitor/WeatherData.vue')['default']
    copy: typeof import('./components/monitor/WeatherData.vue')['default']
    copy: typeof import('./components/search/OptionType copy.vue')['default']
    CoreHeader: typeof import('./components/core/CoreHeader.vue')['default']
    CoreMenu: typeof import('./components/core/CoreMenu.vue')['default']
    DataSummary: typeof import('./components/monitor/DataSummary.vue')['default']
@@ -30,8 +29,10 @@
    ElForm: typeof import('element-plus/es')['ElForm']
    ElFormItem: typeof import('element-plus/es')['ElFormItem']
    ElIcon: typeof import('element-plus/es')['ElIcon']
    ElInput: typeof import('element-plus/es')['ElInput']
    ElOption: typeof import('element-plus/es')['ElOption']
    ElPagination: typeof import('element-plus/es')['ElPagination']
    ElPopover: typeof import('element-plus/es')['ElPopover']
    ElRadio: typeof import('element-plus/es')['ElRadio']
    ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
    ElRow: typeof import('element-plus/es')['ElRow']
@@ -47,11 +48,14 @@
    FactorTrend: typeof import('./components/monitor/FactorTrend.vue')['default']
    GaugeChart: typeof import('./components/chart/GaugeChart.vue')['default']
    HistoricalTrajectory: typeof import('./components/animation/HistoricalTrajectory.vue')['default']
    MapLocation: typeof import('./components/map/MapLocation.vue')['default']
    MapScene: typeof import('./components/map/MapScene.vue')['default']
    MapToolbox: typeof import('./components/map/MapToolbox.vue')['default']
    MIssionCreate: typeof import('./components/mission/MIssionCreate.vue')['default']
    MissionImport: typeof import('./components/mission/MissionImport.vue')['default']
    MissionManage: typeof import('./components/mission/MissionManage.vue')['default']
    OptionDevice: typeof import('./components/search/OptionDevice.vue')['default']
    OptionLocation: typeof import('./components/search/OptionLocation.vue')['default']
    OptionMission: typeof import('./components/search/OptionMission.vue')['default']
    OptionTime: typeof import('./components/search/OptionTime.vue')['default']
    OptionType: typeof import('./components/search/OptionType.vue')['default']
@@ -64,7 +68,6 @@
    TrajectoryState: typeof import('./components/animation/TrajectoryState.vue')['default']
    VehicleData: typeof import('./components/monitor/VehicleData.vue')['default']
    WeatherData: typeof import('./components/monitor/WeatherData.vue')['default']
    'WeatherData cop': typeof import('./components/monitor/WeatherData.vue')['default']
    WeatherDataCopy: typeof import('./components/monitor/WeatherData-copy.vue')['default']
  }
  export interface ComponentCustomProperties {
src/components/map/MapLocation.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,190 @@
<template>
  <el-button
    type="primary"
    icon="Memo"
    class="el-button-custom p-events-auto"
    @click="dialogVisible = !dialogVisible"
  >
    åœ°ç†ç¼–码
  </el-button>
  <el-dialog v-model="dialogVisible" :show-close="false" align-center>
    <template #header="{ close, titleId, titleClass }">
      <BaseCard direction="top-left" borderless="t">
        <template #content>
          <el-row justify="space-between" align="middle">
            <el-row align="middle">
              <font-awesome-icon icon="fa fa-list" class="m-r-4" />
              <span :id="titleId" :class="titleClass">地理编码</span>
            </el-row>
            <font-awesome-icon
              icon="fa fa-times"
              class="cursor-p m-r-4"
              @click="close"
            />
          </el-row>
        </template>
      </BaseCard>
    </template>
    <BaseCard size="medium">
      <template #content>
        <el-row class="mission-table">
          <el-col :span="20">
            <el-input
              v-model="address"
              :autosize="{ minRows: 2, maxRows: 4 }"
              type="textarea"
              placeholder="Please input"
            />
            <el-scrollbar height="calc(40vh - var(--bevel-length-2))">
              <div v-for="item in location" :key="item.lng">
                <span>{{ item.lng }}</span>
                <span>,</span>
                <span>{{ item.lat }}</span>
                <!-- <span> | </span> -->
                <!-- <span>{{ item.gpsLng }}</span>
                <span>,</span>
                <span>{{ item.gpsLat }}</span> -->
                <span> | </span>
                <span>{{ item.formattedAddress }}</span>
                <!-- <span>{{ item.adcode }}</span> -->
              </div>
            </el-scrollbar>
          </el-col>
          <el-col :span="4" class="flex-col">
            <div>
              <el-button
                type="primary"
                class="el-button-custom"
                @click="search"
              >
                æŸ¥è¯¢åæ ‡
              </el-button>
            </div>
            <div>
              <el-button
                type="primary"
                class="el-button-custom"
                @click="convert"
              >
                GPS转高德坐标
              </el-button>
            </div>
          </el-col>
        </el-row>
      </template>
    </BaseCard>
  </el-dialog>
</template>
<script>
import calculate from '../../utils/map/calculate';
// eslint-disable-next-line no-undef
const geocoder = new AMap.Geocoder({
  // city æŒ‡å®šè¿›è¡Œç¼–码查询的城市,支持传入城市名、adcode å’Œ citycode
  city: '上海',
  district: '长宁区'
});
export default {
  props: {},
  data() {
    return {
      dialogVisible: false,
      address: '',
      location: []
    };
  },
  computed: {},
  methods: {
    search() {
      if (this.address == '') return;
      const addressList = this.address.split('\n');
      const res = [];
      geocoder.getLocation(addressList, (status, result) => {
        if (status === 'complete' && result.info === 'OK') {
          // const gdList = result.geocodes.map((v) => {
          //   return [v.location.getLng(), v.location.getLat()];
          // });
          // calculate.convertFromGPS(gdList, (gd) => {
          // });
          for (let y = 0; y < result.geocodes.length; y++) {
            const g = result.geocodes[y];
            if (!g) continue;
            const lng = g.location.getLng();
            const lat = g.location.getLat();
            const { formattedAddress, adcode, level } = g;
            if (adcode == '310105') {
              // const [gpsLng, gpsLat] = gd[i];
              const findRes = res.find((v) => {
                return v.formattedAddress == formattedAddress;
              });
              if (!findRes) {
                for (let i = 0; i < addressList.length; i++) {
                  const a = addressList[i];
                  if (formattedAddress.match(a)) {
                    res.push({
                      lng,
                      lat,
                      // gpsLng,
                      // gpsLat,
                      formattedAddress,
                      adcode,
                      level
                    });
                    break;
                  }
                }
              }
            }
          }
          this.location = res;
        }
      });
    },
    convert() {
      if (this.address == '') return;
      const gpsList = this.address.split('\n').map((v) => {
        return v.split(',');
      });
      calculate.convertFromGPS(
        gpsList,
        (gd) => {
          this.location = gd.map((v) => {
            return {
              lng: v[0],
              lat: v[1]
            };
          });
        },
        'baidu'
      );
    }
  }
};
</script>
<style>
.el-dialog {
  --el-dialog-bg-color: transparent !important;
  --el-dialog-title-font-size: var(--el-font-size-medium);
  --el-dialog-content-font-size: 14px;
  --el-dialog-padding-primary: 0px !important;
}
.el-dialog__title {
  color: var(--font-color);
}
</style>
<style scoped>
.flex-col {
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: flex-end;
}
.mission-table {
  height: 60vh;
}
</style>
src/components/map/MapScene.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,122 @@
<template>
  <el-popover placement="bottom" trigger="click">
    <template #reference>
      <el-button
        type="primary"
        icon="Memo"
        class="el-button-custom p-events-auto"
      >
        åœºæ™¯æ ‡æ³¨
      </el-button>
    </template>
    <OptionLocation v-model="districtCode"></OptionLocation>
    <div class="vertical-class">
      <el-checkbox
        :indeterminate="isIndeterminate"
        v-model="checkAll"
        @change="handelCheckAllChange"
        >全选</el-checkbox
      >
    </div>
    <el-checkbox-group
      v-model="selectType"
      size="default"
      @change="handleChange"
    >
      <div class="vertical-class">
        <el-checkbox
          v-for="item in options"
          :key="item.label"
          :value="item.value"
          >{{ item.label }}</el-checkbox
        >
      </div>
    </el-checkbox-group>
  </el-popover>
</template>
<script>
import { sceneTypes, sceneIcon } from '@/constant/scene-types';
import sceneInfoApi from '@/api/sceneInfoApi';
import marks from '@/utils/map/marks';
import MapUtil from '@/utils/map/util';
const lableMarkMap = new Map();
export default {
  data() {
    return {
      districtCode: '',
      isIndeterminate: false,
      checkAll: false,
      selectType: [],
      options: sceneTypes(),
      sceneMap: new Map()
    };
  },
  methods: {
    fetchScene(sceneType) {
      return sceneInfoApi
        .searchScene({
          districtCode: this.districtCode,
          sceneTypeId: sceneType
        })
        .then((res) => {
          return res.data;
        });
    },
    handelCheckAllChange(val) {
      this.selectType = val ? this.options.map((v) => v.value) : [];
      this.isIndeterminate = false;
      this.handleChange(this.selectType);
    },
    handleChange(types) {
      // for (const iterator of lableMarkMap) {
      //   MapUtil.removeViews(iterator[1]);
      // }
      let checkedCount = types.length;
      this.checkAll = checkedCount === this.options.length;
      this.isIndeterminate =
        checkedCount > 0 && checkedCount < this.options.length;
      // æ ¹æ®é€‰é¡¹ï¼Œå°†æœªæ‰“开的图层开启
      types.forEach((t) => {
        if (!lableMarkMap.has(t)) {
          this.fetchScene(t).then((res) => {
            const layer = marks.createLabelMarks(sceneIcon(t), res);
            lableMarkMap.set(t, { show: true, layer });
          });
        } else {
          const m = lableMarkMap.get(t);
          if (!m.show) {
            MapUtil.addViews(m.layer);
            m.show = true;
          }
        }
      });
      // æ ¹æ®é€‰é¡¹ï¼Œå°†å¼€å¯ä¸­çš„æœªé€‰ä¸­å›¾å±‚关闭
      for (const [key, value] of lableMarkMap) {
        if (!types.includes(key)) {
          if (value.show) {
            MapUtil.removeViews(value.layer);
            value.show = false;
          }
        }
      }
      // MapUtil.setFitView();
    }
  }
};
</script>
<style scoped>
.el-button {
  margin: initial !important;
}
.vertical-class {
  display: flex;
  flex-direction: column;
}
</style>
src/components/search/OptionLocation.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,47 @@
<template>
  <!-- <el-form-item label="区县"> -->
  <el-select
    :model-value="modelValue"
    @update:model-value="handleChange"
    placeholder="区县"
    size="small"
    class="w-80"
  >
    <el-option
      v-for="(s, i) in typeList"
      :key="i"
      :label="s.label"
      :value="s.value"
    />
  </el-select>
  <!-- </el-form-item> -->
</template>
<script>
export default {
  props: {
    modelValue: String
  },
  emits: ['update:modelValue'],
  data() {
    return {
      typeList: [
        {
          label: '长宁区',
          value: '310105'
        }
      ]
    };
  },
  methods: {
    handleChange(value) {
      // todo æ ¹æ®è®¾å¤‡ç±»åž‹åˆ‡æ¢åœ°å›¾è½½å…·çš„图标、
      this.$emit('update:modelValue', value);
    }
  },
  mounted() {
    this.handleChange(this.typeList[0].value);
  }
};
</script>
<style scoped></style>
src/constant/scene-types.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,110 @@
import scene_1 from '@/assets/mipmap/scene_1.png';
import scene_4 from '@/assets/mipmap/scene_4.png';
import scene_5 from '@/assets/mipmap/scene_5.png';
import scene_6 from '@/assets/mipmap/scene_6.png';
import scene_15 from '@/assets/mipmap/scene_15.png';
import scene_16 from '@/assets/mipmap/scene_16.png';
import scene_17 from '@/assets/mipmap/scene_17.png';
import scene_18 from '@/assets/mipmap/scene_18.png';
function sceneTypes() {
  return [
    {
      label: '工地',
      value: '1'
    },
    // {
    //   label: '码头',
    //   value: '2',
    // },
    // {
    //   label: '搅拌站',
    //   value: '3',
    // },
    {
      label: '工业企业',
      value: '4'
    },
    {
      label: '餐饮',
      value: '5'
    },
    {
      label: '汽修',
      value: '6'
    },
    // {
    //   label: '降尘点',
    //   value: '7',
    // },
    // {
    //   label: '空气质量监测点',
    //   value: '8',
    // },
    // {
    //   label: '道路扬尘监测点',
    //   value: '9',
    // },
    // {
    //   label: '道路',
    //   value: '10',
    // },
    // {
    //   label: '河流断面',
    //   value: '11',
    // },
    // {
    //   label: '工业园区',
    //   value: '12',
    // },
    // {
    //   label: '无固定场景',
    //   value: '13',
    // },
    // {
    //   label: '堆场',
    //   value: '14',
    // },
    {
      label: '实验室',
      value: '15'
    },
    {
      label: '精品小区',
      value: '16'
    },
    {
      label: '加油站',
      value: '17'
    },
    {
      label: '商业体',
      value: '18'
    }
  ];
}
function sceneIcon(type) {
  switch (type) {
    case '1':
      return scene_1;
    case '4':
      return scene_4;
    case '5':
      return scene_5;
    case '6':
      return scene_6;
    case '15':
      return scene_15;
    case '16':
      return scene_16;
    case '17':
      return scene_17;
    case '18':
      return scene_18;
    default:
      return scene_1;
  }
}
export { sceneTypes, sceneIcon };
src/model/FactorDatas.js
@@ -1,5 +1,5 @@
import { Factor } from "./Factor";
import calculate from "@/utils/map/calculate";
import { Factor } from './Factor';
import calculate from '@/utils/map/calculate';
/**
 *
@@ -61,8 +61,6 @@
        f.pushData(v, drawMode == undefined ? 0 : drawMode);
      });
    });
    this.convertGPS(this.lnglats_GPS, callback);
  },
@@ -162,7 +160,7 @@
  // èŽ·å–æ•°æ®é•¿åº¦
  length: function () {
    return this.lnglats_GD.length;
  },
  }
};
export { FactorDatas };
src/utils/map/animation.js
@@ -245,11 +245,11 @@
    // this.OnEachFrameCallback = undefined;
    // this.OnEachTaskEndCallback = undefined;
    this.frameAnimation.stop();
    this._clearMap();
  },
  setOnStopCallback: function (callback) {
    this.frameAnimation.setOnStopCallback(
      function () {
        this._clearMap();
        callback();
      }.bind(this)
    );
@@ -419,6 +419,6 @@
};
const realTimeMapAnimation = new MapAnimation();
realTimeMapAnimation.clear = false;
// realTimeMapAnimation.clear = false;
export { realTimeMapAnimation, MapAnimation };
src/utils/map/calculate.js
@@ -30,19 +30,82 @@
  return path;
}
//定义一些常量
const PI = 3.1415926535897932384626;
const a = 6378245.0; //长半轴
const ee = 0.00669342162296594323; //扁率/*** GCJ02 è½¬æ¢ä¸º WGS84* @param lng* @param lat* @returns {*[]}*/
/**
 * åˆ¤æ–­æ˜¯å¦åœ¨å›½å†…,不在国内则不做偏移
 * @param lng
 * @param lat
 * @returns {boolean}
 */
function out_of_china(lng, lat) {
  // çº¬åº¦3.86~53.55,经度73.66~135.05
  return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
}
function transformlat(lng, lat) {
  // lat = +lat lng = +lng
  let ret =
    -100.0 +
    2.0 * lng +
    3.0 * lat +
    0.2 * lat * lat +
    0.1 * lng * lat +
    0.2 * Math.sqrt(Math.abs(lng));
  ret +=
    ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) *
      2.0) /
    3.0;
  ret +=
    ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) /
    3.0;
  ret +=
    ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) *
      2.0) /
    3.0;
  return ret;
}
function transformlng(lng, lat) {
  // lat = +latlng = +lng
  let ret =
    300.0 +
    lng +
    2.0 * lat +
    0.1 * lng * lng +
    0.1 * lng * lat +
    0.1 * Math.sqrt(Math.abs(lng));
  ret +=
    ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) *
      2.0) /
    3.0;
  ret +=
    ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) /
    3.0;
  ret +=
    ((150.0 * Math.sin((lng / 12.0) * PI) +
      300.0 * Math.sin((lng / 30.0) * PI)) *
      2.0) /
    3.0;
  return ret;
}
/**
 * å°†gps经纬度转换为高德地图经纬度
 * @param {*} lnglats
 * @param {*} callback
 */
function _convertLatlng(index, coor, lnglats, callback) {
function _convertLatlng(index, coor, lnglats, type = 'gps', callback) {
  if (index < coor.length) {
    var path = parse2LngLat(coor[index]);
    // eslint-disable-next-line no-undef
    AMap.convertFrom(path, 'gps', function (status, result) {
    AMap.convertFrom(path, type, function (status, result) {
      if (result.info === 'ok') {
        lnglats.push.apply(lnglats, result.locations);
        _convertLatlng(index + 1, coor, lnglats, callback);
        _convertLatlng(index + 1, coor, lnglats, type, callback);
      }
    });
  } else {
@@ -103,14 +166,36 @@
    return coors_GD;
  },
  convertFromGPS: function (gps, callback) {
  convertFromGPS: function (gps, callback, type = 'gps') {
    var coor = _prepare4convert(gps);
    _convertLatlng(0, coor, [], function (result) {
    _convertLatlng(0, coor, [], type, function (result) {
      var gd = [];
      result.forEach((r) => {
        gd.push([r.lng, r.lat]);
      });
      callback(gd);
    });
  },
  /**
   * é«˜å¾·åœ°å›¾åæ ‡è½¬GPS坐标算法
   */
  gcj02towgs84(lng, lat) {
    // lat = +latlng = +lng
    if (out_of_china(lng, lat)) {
      return [lng, lat];
    } else {
      let dlat = transformlat(lng - 105.0, lat - 35.0);
      let dlng = transformlng(lng - 105.0, lat - 35.0);
      let radlat = (lat / 180.0) * PI;
      let magic = Math.sin(radlat);
      magic = 1 - ee * magic * magic;
      let sqrtmagic = Math.sqrt(magic);
      dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI);
      dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI);
      let mglat = Math.round((lat * 2 - lat - dlat) * 1000000) / 1000000;
      let mglng = Math.round((lng * 2 - lng - dlng) * 1000000) / 1000000;
      return [mglng, mglat];
    }
  }
};
src/utils/map/index_old.js
@@ -53,7 +53,7 @@
    viewMode: '3D', // åœ°å›¾æ¨¡å¼
    resizeEnable: true,
    center: [121.6039283, 31.25295567],
    zooms: [3, 18],
    zooms: [0, 18],
    zoom: 14
  });
src/utils/map/marks.js
@@ -76,5 +76,66 @@
    });
    _massMarks = massMarks;
    map.add(massMarks);
  },
  createLabelMarks(img, dataList) {
    // eslint-disable-next-line no-undef
    const layer = new AMap.LabelsLayer({
      zooms: [3, 20],
      zIndex: 1000,
      // å¼€å¯æ ‡æ³¨é¿è®©ï¼Œé»˜è®¤ä¸ºå¼€å¯ï¼Œv1.4.15 æ–°å¢žå±žæ€§
      collision: true,
      // å¼€å¯æ ‡æ³¨æ·¡å…¥åŠ¨ç”»ï¼Œé»˜è®¤ä¸ºå¼€å¯ï¼Œv1.4.15 æ–°å¢žå±žæ€§
      animation: true
    });
    map.add(layer);
    // var markers = [];
    for (var i = 0; i < dataList.length; i++) {
      const data = dataList[i];
      var curData = {
        name: data.name,
        position: [data.longitude, data.latitude],
        zooms: [10, 20],
        opacity: 1,
        zIndex: 10,
        icon: {
          type: 'image',
          image: img,
          // clipOrigin: [14, 92],
          // clipSize: [50, 68],
          size: [24, 24],
          anchor: 'bottom-center',
          angel: 0,
          retina: true
        },
        text: {
          content: data.name,
          direction: 'top',
          offset: [0, -5],
          style: {
            fontSize: 15,
            fontWeight: 'normal',
            fillColor: '#fff',
            strokeColor: '#333',
            strokeWidth: 2
            // backgroundColor: '#b1009b'
          }
        }
      };
      curData.extData = {
        index: i
      };
      // eslint-disable-next-line no-undef
      var labelMarker = new AMap.LabelMarker(curData);
      // markers.push(labelMarker);
      layer.add(labelMarker);
    }
    return layer;
  }
};
src/utils/map/util.js
@@ -13,5 +13,14 @@
      map.setCenter(lnglat);
      this.lasttime = now;
    }
  },
  addViews(view) {
    map.add(view);
  },
  removeViews(view) {
    map.remove(view);
  },
  setFitView() {
    map.setFitView();
  }
};
src/views/HomePage.vue
@@ -5,6 +5,8 @@
    <el-row class="dropdown-wrap">
      <MapToolbox></MapToolbox>
      <MissionManage></MissionManage>
      <!-- <MapLocation></MapLocation> -->
      <MapScene></MapScene>
    </el-row>
    <CoreMenu></CoreMenu>
    <router-view></router-view>
src/views/realtimemode/RealtimeMode.vue
@@ -162,6 +162,7 @@
  unmounted() {
    this.clearFetchingTask();
    realTimeMapAnimation.stop();
    console.log('clear');
  }
};
</script>