Map.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <script setup>
  2. import L from "leaflet";
  3. import "leaflet.markercluster";
  4. import "leaflet/dist/leaflet.css";
  5. import "leaflet.markercluster/dist/MarkerCluster.css";
  6. import "leaflet.markercluster/dist/MarkerCluster.Default.css";
  7. import { ref, reactive, onMounted, getCurrentInstance } from "vue";
  8. import axios from "axios";
  9. import { useMainStore } from "@/stores/store";
  10. const store = useMainStore();
  11. const mapContainer = ref(null);
  12. const location_id = ref("");
  13. const { proxy } = getCurrentInstance();
  14. onMounted(() => {
  15. let mapData = reactive({
  16. data: [],
  17. });
  18. (async function getData() {
  19. try {
  20. const response = await axios.get("https://cmm.ai:8088/api/get_school");
  21. mapData.data = response.data.schools;
  22. console.log("data", mapData.data);
  23. console.log("response.data", response.data);
  24. mapData.data.forEach((item) => {
  25. let customIcon = L.icon({
  26. iconUrl: store.getImageUrl("map-icon/icon_house06.png"),
  27. iconSize: [30, 50],
  28. });
  29. let marker = L.marker(new L.LatLng(item.Lat, item.Lng), {
  30. icon: customIcon,
  31. }).bindPopup(`<p>${item.location_name}</p>`);
  32. // let marker = L.marker(new L.LatLng(item.Lat, item.Lng)).bindPopup(
  33. // `<p>${item.location_name}</p>`
  34. // );
  35. marker.on("mouseover", function () {
  36. this.openPopup();
  37. });
  38. marker.on("mouseout", function () {
  39. this.closePopup();
  40. });
  41. marker.on("click", function () {
  42. location_id.value = item.location_id;
  43. proxy.$emit("locationId", location_id.value);
  44. });
  45. markers.addLayer(marker);
  46. });
  47. } catch (error) {
  48. console.error(error);
  49. }
  50. })();
  51. // 創建地圖
  52. const map = L.map(mapContainer.value, {
  53. center: [23.611, 120.768],
  54. zoom: 8,
  55. });
  56. // 加入圖層
  57. L.tileLayer(
  58. "https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}"
  59. ).addTo(map);
  60. // 取得使用者的當前位置座標
  61. map.locate({ setView: true, maxZoom: 16 });
  62. console.log(
  63. "使用者的當前位置座標",
  64. map.locate({ setView: true, maxZoom: 16 })
  65. );
  66. let customIcon = L.icon({
  67. iconUrl: store.getImageUrl("map-icon/icon_house05.png"),
  68. iconSize: [30, 50],
  69. });
  70. // 當取得位置成功時,將地圖中心設定為使用者位置
  71. function onLocationFound(e) {
  72. L.marker(e.latlng, { icon: customIcon })
  73. .addTo(map)
  74. .bindPopup("您的位置")
  75. .openPopup();
  76. }
  77. // 當取得位置失敗時,顯示錯誤提示
  78. function onLocationError(e) {
  79. alert("無法取得位置或拒絕提供位置訪問權限。");
  80. }
  81. map.on("locationfound", onLocationFound);
  82. map.on("locationerror", onLocationError);
  83. // const popup = L.popup();
  84. const markers = L.markerClusterGroup();
  85. // 限制在台灣範圍
  86. const taiwanBounds = L.latLngBounds(
  87. L.latLng(20.68, 119.16),
  88. L.latLng(25.56, 122.48)
  89. );
  90. map.setMaxBounds(taiwanBounds);
  91. map.setMaxZoom(16); // 最大縮放級別
  92. map.setMinZoom(8); // 最小縮放級別
  93. map.addLayer(markers);
  94. });
  95. </script>
  96. <template>
  97. <div id="map" class="mapContainer" ref="mapContainer"></div>
  98. </template>
  99. <style>
  100. #map {
  101. width: 100%;
  102. height: 100%;
  103. }
  104. </style>