Day29-实作(地图) (part1)

进入到尾声,范例的最後一片拼图,马上开始吧!!!

地图的部分使用了leaflet JS和OpenStreetMap,所以在开始前先装一下leaflet,在终端机打上

npm install leaflet

地图元件

完成後,接下来和先前的步骤一样,先在components下建立一个maskMap.vue,把App.vue的地图部分搬过来

<template>
  <div class="mask-map" id="mask-map"></div>
</template>

<script>
export default {
  name: "maskMap",
};
</script>

再来修改App.vue

<template>
  <div id="app">
    <!-- aside-menu 左侧栏 -->
    <asideMenu />

    <!-- 地图区块 -->
    <maskMap />

    <!-- lightBox -->
    <light-box />
  </div>
</template>

<script>
import { mapActions } from "vuex";
import asideMenu from "./components/asideMenu.vue";
import lightBox from "./components/lightBox.vue";
import maskMap from "./components/maskMap.vue";

export default {
  name: "App",
  components: {
    asideMenu,
    lightBox,
    maskMap,
  },
  //...略
};
</script>

回到maskMap.vue将leaflet弄进来

import L from "leaflet";

export default {
  name: "maskMap",
  data() {
    return {
			//别的地方用不到map,所以不用丢到vuex
      map: {},
    };
  },
  mounted() {
		//初始化地图
    this.map = L.map("mask-map", {
      center: [25.03, 121.55],
      zoom: 14,
    });

    L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
      attribution:
        '<a target="_blank" href="https://www.openstreetmap.org/">OpenStreetMap贡献者</a>',
      maxZoom: 18,
    }).addTo(this.map);
  },
};

完成後可以看到完整地图的画面

Untitled

让地图移动到指定的位置

有了地图後就要让他和右边的县市行政区去做反应,选择哪个区域就要到对应的地图区块,只要从vuex拿state.currCity和getters.districtList做比对就可以完成,先在getters加上:

currDistrictInfo(state, getters) {
  // 目前所选行政区
  return getters.districtList.find((d) => d.name === state.currDistrict) || {}
}

也在maskMap.vue加上computed,把getter拿回

computed: {
    currDistrictInfo() {
      return this.$state.getters.currDistrictInfo;
    },
  },

并在此加上watch,当使用者切换行政区地图也会跟着移动

  watch: {
    currDistrictInfo(dist) {
			//this.map.panTo可以指定地图中心点
      this.map.panTo(new L.LatLng(dist.latitude, dist.longitude));
    },
  },

设定药局标记

药局的资料在刚刚已经有从vuex拿到手了,再来就是在maskMap.vue加入computed

filteredStores() {
  return this.$store.getters.filteredStores;
},

还有在watch身上新增filteredStores,列表变动透过addMarker来增加图钉


filteredStores(stores) {
  stores.forEach((element) => this.addMarker(element));
},

再来就是在methods定义刚刚的addMarker

addMarker(item) {
	//标记图案
  const ICON = {
    iconUrl:
      "https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-violet.png",
    shadowUrl:
      "https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png",
    iconSize: [25, 41],
    iconAnchor: [12, 41],
    popupAnchor: [1, -34],
    shadowSize: [41, 41],
  };
	//将标记放到地图上
  const marker = L.marker([item.longitude, item.latitude], ICON)
    .addTo(this.map)
    .bindPopup(`<h2 class="popup-name">${item.name}</h2>`);
},

当多次切换行政区时标记的点并不会清除,反而是累加上去的,所以在methods上要加上clearMarker来清除

clearMarkers() {
  //清除地图所有标记
  this.map.eachLayer((layer) => {
    if (layer instanceof L.Marker) {
      this.map.removeLayer(layer);
    }
  });
},

并改写一下watch中的filteredStores

filteredStores(stores) {
  //先清除原有marker
  this.clearMarkers();
  //根据药局资讯加上对应的marker
  stores.forEach((element) => this.addMarker(element));
},

Untitled

就差一点点了!! 今天来不及弄完,明天再续


<<:  [心得]资料异动行为,需要有意识的风险管理

>>:  [ Day 29 ] 实作一个 React.js 网站 5/5

从零开始学3D游戏开发 Roblox Studio 简介 Part.3

赛程来到了第三天,今天的天气实在太热了,需要多补充一些水分啊 今天是 Roblox Studio 介...

资料取得 - 多重来源

说是多重来源,其实也就是本机和 shioaji 而已,我的想法是这样子的,如果本机有资料的话,就从本...

DAY28 linebot message api-Template 介绍-1

传送样板(Template) 样板有四种,分别是 Confirm、Buttons、Carousel、...

IEEE-754 与浮点数运算

本文目标 IEEE-754 规范对於工程发展的重要性 认识浮点数 使用演算法改善浮点数运算时带来的误...

延伸(1)-ML接入团队的原本开发生态 | ML#Day29

背景提要 团队走DevOps文化,所以频繁地沟通理解,以及任何东西考虑对於系统的定位,已经是我们再熟...