Browse Source

移除第三方地图插件,echart-gl,地图增加mark,限制范围,镂空雅安市,移除天气插件

caner 2 years ago
parent
commit
1021bb409f

+ 1 - 3
package.json

@@ -9,10 +9,8 @@
     "preview": "vite preview"
   },
   "dependencies": {
-    "@vuemap/vue-amap": "^2.0.24",
-    "@vuemap/vue-amap-loca": "^2.0.6",
+    "@amap/amap-jsapi-loader": "^1.0.1",
     "echarts": "^5.4.3",
-    "echarts-gl": "^2.0.9",
     "naive-ui": "^2.36.0",
     "pinia": "^2.1.7",
     "pinia-plugin-persist": "^1.0.0",

BIN
src/assets/img/36.png


File diff suppressed because it is too large
+ 19 - 0
src/assets/img/37.svg


+ 4 - 2
src/assets/native-plugin.ts

@@ -5,7 +5,8 @@ import {
   NProgress,
   NTable,
   NDataTable,
-  NPagination
+  NPagination,
+  NButton
 } from 'naive-ui'
 
 const naive = create({
@@ -15,7 +16,8 @@ const naive = create({
     NProgress,
     NTable,
     NDataTable,
-    NPagination
+    NPagination,
+    NButton
   ]
 })
 

+ 138 - 22
src/components/map.vue

@@ -1,33 +1,149 @@
 <template>
-  <div class="mapContainer">
-    <el-amap
-      :center="center"
-      :zoom="zoom"
-      map-style="amap://styles/grey"
-      @init="_init"
-    />
-  </div>
+  <div
+    id="container"
+    class="mapContainer"
+  />
 </template>
 
 <script setup lang='ts'>
-import { ElAmap } from '@vuemap/vue-amap'
-import { ref } from 'vue'
-withDefaults(defineProps<{
-        zoom?: number
-    }>(), {
-  zoom: 12
+import AMapLoader from '@amap/amap-jsapi-loader'
+import { onMounted, ref } from 'vue'
+import useStore from '@/pages/store/index'
+import { useNotification } from 'naive-ui'
+import img36 from '@/assets/img/36.png'
+
+const store = useStore()
+const notification = useNotification()
+const props = withDefaults(defineProps<{
+  zoom?: number
+}>(), {
+  zoom: 15
 })
+let Maps = null as Any
+let AMaps = null as Any
+window._AMapSecurityConfig = {
+  securityJsCode: '184c86be3bbd9a8a941bcaaf6b09c7cd'
+}
+
+function getAllRings(feature: { geometry: { coordinates: Any[]; }; }) {
+  const coords = feature.geometry.coordinates
+  const rings = []
+  for (let i = 0, len = coords.length; i < len; i++) {
+    rings.push(coords[i][0])
+  }
+  return rings
+}
+
+function getLongestRing(feature: { geometry: { coordinates: Any[]; }; }) {
+  const rings = getAllRings(feature)
+  rings.sort((a, b) => b.length - a.length)
+  return rings[0]
+}
 
-const center = ref([ 103.044313, 30.011438 ])
-let map = null
-function _init(e: any) {
-  const marker = new AMap.Marker({
-    position: center
+function addMark(position:number[], icon:string, size?:{w:number, h:number}) {
+  if (!Maps) return
+  const mark = new AMaps.Marker({
+    position,
+    cursor: 'pointer',
+    icon: new AMaps.Icon({
+      image: icon,
+      imageSize: new AMaps.Size(size?.w || 24, size?.h || 24)
+    }),
+    autoRotation: true,
+    offset: new AMaps.Pixel(-5, -20),
+    angle: 0,
+    anchor: 'center',
+    extData: '1'// 设置自定义属性
   })
-  e.add(marker)
-  map = e
-  console.log('map init: ', e)
+  Maps.add(mark)
 }
+
+onMounted(() => {
+  AMapLoader.load({
+    key: '0c5c83112cafefa77154769b4433c3df',
+    version: '2.0',
+    plugins: [ 'AMap.DistrictSearch', 'AMap.Weather', 'AMap.Bounds' ],
+    AMapUI: {
+      version: '1.1',
+      plugins: [ 'geo/DistrictExplorer' ]
+    }
+  }).then((AMap) => {
+    console.log(123, AMap)
+    const map = new AMap.Map('container', { // 设置地图容器id
+      zoom: props.zoom, // 设置当前显示级别
+      expandZoomRange: true, // 开启显示范围设置
+      zooms: [ 9, 20 ], // 最小显示级别为7,最大显示级别为20
+      center: [ 103.001033, 29.987722 ], // 设置地图中心点位置
+      mapStyle: 'amap://styles/grey'
+    })
+    // 限制位置 getBounds()
+    const bounds = new AMap.Bounds(
+      [ 103.395136, 30.936781 ], // 右上角经纬度 northEast
+      [ 101.93598, 28.845463 ] // 左下角经纬度 southWest
+    )
+    map.setLimitBounds(bounds)
+    // 天气
+    const weather = new AMap.Weather()
+    weather.getLive('雅安市', (err: any, data: Any) => {
+      console.log('天气', err, data)
+      if (err) {
+        notification.warning({
+          content: '天气获取失败',
+          duration: 2000
+        })
+        return
+      }
+      store.setWeather(data)
+    })
+    // 添加mark
+    const mark = new AMap.Marker({
+      title: 'test',
+      position: [ 103.001033, 29.987722 ],
+      cursor: 'pointer',
+      icon: new AMap.Icon({
+        image: img36,
+        imageSize: new AMap.Size(36, 36)
+      }),
+      autoRotation: true,
+      offset: new AMap.Pixel(-5, -20),
+      angle: 0,
+      anchor: 'center',
+      extData: '1'// 设置自定义属性
+    })
+    map.add(mark)
+    // 镂空雅安 511800 adcode
+    AMapUI.loadUI([ 'geo/DistrictExplorer' ], (DistrictExplorer: any) => {
+      const districtExplorer = new DistrictExplorer({ map })
+      districtExplorer.loadMultiAreaNodes([ 100000, 511800 ], (error: any, areaNodes: string | any[]) => {
+        const countryNode = areaNodes[0]
+        const cityNodes = areaNodes.slice(1)
+        const path = []
+        // 首先放置背景区域,这里是大陆的边界
+        path.push(getLongestRing(countryNode.getParentFeature()))
+
+        for (let i = 0, len = cityNodes.length; i < len; i++) {
+          // 逐个放置需要镂空的市级区域
+          path.push(...getAllRings(cityNodes[i].getParentFeature()))
+        }
+        // 绘制带环多边形
+        const polygon = new AMap.Polygon({
+          bubble: true,
+          lineJoin: 'round',
+          strokeColor: '#030E25', // 线颜色
+          strokeOpacity: 1, // 线透明度
+          strokeWeight: 1, // 线宽
+          fillColor: '#030E25', // 填充色
+          fillOpacity: 1, // 填充透明度
+          map,
+          path
+        })
+      })
+    })
+
+    Maps = map
+    AMaps = AMap
+  })
+})
 </script>
 
 <style lang="scss" scoped>

+ 0 - 8
src/pages/main.ts

@@ -3,17 +3,10 @@ import App from './App.vue'
 import { createPinia } from 'pinia'
 import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
 import piniaPersist from 'pinia-plugin-persist'
-import VueAMap, { initAMapApiLoader } from '@vuemap/vue-amap'
-import '@vuemap/vue-amap/dist/style.css'
 import Icon from '@/components/icon.vue'
 import 'virtual:svg-icons-register'
 import naive from '@/assets/native-plugin'
 
-initAMapApiLoader({
-  key: '0c5c83112cafefa77154769b4433c3df',
-  securityJsCode: '184c86be3bbd9a8a941bcaaf6b09c7cd' // 新版key需要配合安全密钥使用
-})
-
 const store = createPinia()
 store.use(piniaPersist)
 
@@ -33,7 +26,6 @@ const router = createRouter({
 // })
 app.use(store)
   .use(router)
-  .use(VueAMap)
   .use(naive)
   .component('Icon', Icon)
 

File diff suppressed because it is too large
+ 13 - 2
src/pages/store/index.ts


+ 83 - 6
src/pages/views/home/index.vue

@@ -1,6 +1,5 @@
 <script setup lang="ts">
-import { markRaw, ref } from 'vue'
-import WeatherService from '@/services/weather.service'
+import { computed, markRaw, ref } from 'vue'
 import homePage from './components/HomePage.vue'
 import cehicleOperation from './components/CehicleOperation.vue'
 import lineAnalysis from './components/LineAnalysis.vue'
@@ -9,8 +8,9 @@ import facilityManagement from './components/FacilityManagement.vue'
 import stationManagement from './components/StationManagement.vue'
 import passengerFlow from './components/PassengerFlow.vue'
 import Map from '@/components/map.vue'
+import useStore from '@/pages/store'
 
-const weatherService = new WeatherService()
+const store = useStore()
 const menus = [
   { name: '主页', component: markRaw(homePage) },
   { name: '线路运营', component: markRaw(cehicleOperation) },
@@ -22,14 +22,28 @@ const menus = [
 ]
 const active = ref(0)
 const currentComponent = ref(menus[active.value].component)
-const weather = ref()
+const weather = computed(() => store.weather)
+const warningMsg = ref({
+  value: '这里是预警提示信息这里是预警提示信息这里是预警提示信息这里是预警提示信息这里是预...',
+  time: ' 2023-01-01 12:00:00',
+  btns: [
+    {
+      name: '忽略',
+      event: '',
+      type: 'default'
+    },
+    {
+      name: '立即处理',
+      event: '',
+      type: 'error'
+    }
+  ]
+})
 
 function changMenu(_id: number) {
   active.value = _id
   currentComponent.value = menus[_id].component
 }
-
-weatherService.getWeather().then((res) => { weather.value = res })
 </script>
 <template>
   <div class="home">
@@ -71,6 +85,27 @@ weatherService.getWeather().then((res) => { weather.value = res })
       </div>
       <div class="home-content-left-img" />
       <div class="home-content-right-img" />
+      <div class="home-content-center-tooltip">
+        <Icon
+          name="37"
+          :size="37"
+        />
+        <div>{{ warningMsg.value }}</div>
+        <div>{{ warningMsg.time }}</div>
+        <div>
+          <template
+            v-for="(item, index) in warningMsg.btns"
+            :key="index"
+          >
+            <n-button
+              round
+              :type="item.type"
+            >
+              {{ item.name }}
+            </n-button>
+          </template>
+        </div>
+      </div>
       <component :is="currentComponent" />
     </div>
     <div class="home-bottom">
@@ -227,6 +262,7 @@ weatherService.getWeather().then((res) => { weather.value = res })
       right: 7px;
       background: url(../../../assets/img/9.svg) no-repeat left top;
       background-size: cover;
+
       &-img {
         background: url(../../../assets/img/34.png) no-repeat right top;
         background-size: cover;
@@ -249,6 +285,37 @@ weatherService.getWeather().then((res) => { weather.value = res })
       z-index: 1;
       margin: 0 auto;
       transform: translate(-50%, 0);
+
+      &-tooltip {
+        position: absolute;
+        top: 90px;
+        min-width: 100px;
+        max-width: 1590px;
+        border: solid 1px red;
+        border-radius: 30px;
+        z-index: 3;
+        left: 50%;
+        transform: translate(-50%, 0);
+        display: flex;
+        align-items: center;
+        padding: 8px 10px;
+        color: #E73D41;
+        font-size: 23px;
+        animation: flicker 0.5s infinite alternate;
+        background: #e73d4048;
+        &>svg {
+          margin-right: 10px;
+          margin-left: 10px;
+        }
+
+        &>div:nth-child(3) {
+          margin: 0 60px;
+        }
+
+        & button:last-child {
+          margin-left: 10px;
+        }
+      }
     }
 
   }
@@ -265,4 +332,14 @@ weatherService.getWeather().then((res) => { weather.value = res })
     text-shadow: 1px 1px 5px rgba(0, 255, 255, 0.6);
   }
 }
+
+@keyframes flicker {
+  0% {
+    opacity: 0.8;
+  }
+
+  100% {
+    opacity: 0.3;
+  }
+}
 </style>

File diff suppressed because it is too large
+ 0 - 10
src/services/weather.service.ts


+ 4 - 2
src/vite-env.d.ts

@@ -11,5 +11,7 @@ declare module '*.vue' {
 }
 
 declare module 'tank-vue3-seamless-scroll'
-declare const AMap: Any
-declare const Loca: Any
+interface Window {
+  _AMapSecurityConfig:{securityJsCode:string}
+}
+declare const AMapUI:Any

Some files were not shown because too many files changed in this diff