vue中使用高德地圖自定義開發

Maya本尊發表於2019-07-23

前言

用一個在地圖上挖寶的小例子,來總結下自己使用高德地圖的心得。

高德地圖文件

起步-載入高德地圖

// 進入
cd utils

// 建立AMap.js檔案
vim AMap.js
複製程式碼

AMap.js

export default function MapLoader() {
  return new Promise((resolve, reject) => {
    if (window.AMap) {
      resolve(window.AMap);
    } else {
      var script = document.createElement("script");
      script.type = "text/javascript";
      script.async = true;
      script.src =
        "https://webapi.amap.com/maps?v=1.4.15&key=你們自己申請的key&plugin=AMap.Geocoder&callback=initAMap";
      script.onerror = reject;
      document.head.appendChild(script);
    }
    window.initAMap = () => {
      resolve(window.AMap);
    };
  });
}

複製程式碼

使用,在那個頁面需要用高德地圖,就在那個頁面呼叫

<script>
import AMap from "@/utils/AMap";

export default {
  name: "home",
  data() {
    return {
      map: null
    };
  },
  created() {
    window.title = "地圖";
  },
  mounted() {
    this.initAMap();
  },
  methods: {
    async initAMap() {
      try {
        const res = await AMap();
        this.map = new res.Map("container", {
          resizeEnable: true, //是否監控地圖容器尺寸變化
          zoom: 11, //初始化地圖層級
          center: [116.397428, 39.90923] //初始化地圖中心點
        });
      } catch (err) {
        console.error(err);
      }
    }
  }
};
</script>
複製程式碼

獲取傳入的寶箱位置


// 別忘記在data中新增lng和lat
created() {
    this.lng = this.$route.query.lng;
    this.lat = this.$route.query.lat;
},

複製程式碼

考慮後面方便呼叫高德api,修改下程式碼

<script>
import AMap from "@/utils/AMap";

export default {
  name: "home",
  data() {
    return {
      map: null,
      // 寶箱位置
      lng: null,
      lat: null,
      
      // 新增
      resMap: null
    };
  },
  created() {
    this.lng = this.$route.query.lng;
    this.lat = this.$route.query.lat;
  },
  mounted() {
    this.initAMap();
  },
  methods: {
    async initAMap() {
      try {
        // 修改
        this.resMap = await AMap();
        
        this.map = new this.resMap.Map("container", {
          resizeEnable: true, //是否監控地圖容器尺寸變化
          zooms: [3, 19], //設定地圖級別範圍
          zoom: 14, //初始化地圖層級
          zoomEnable: true, // 是否縮放
          scrollWheel: true, // 是否支援滾輪縮放
          dragEnable: true, // 是否支援滑鼠拖拽平移
          jogEnable: true, // 是否支援緩動效果
          buildingAnimation: true, // 模組消失是否有動畫效果
          center:  [this.lng, this.lat] //初始化地圖中心點
        });
      } catch (err) {
        console.error(err);
      }
    }
  }
};
</script>
複製程式碼

新增點標記

新建一個函式

// 建立點標記
addMarker() {
  this.marker = new this.resMap.Marker({
    icon: "https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png",
    position:  [this.lng, this.lat],
    offset: new this.resMap.Pixel(-13, -30)
  });

  this.map.add(this.marker);
  this.map.setFitView();
},
複製程式碼

initAMap 函式中呼叫

async initAMap() {
      try {
        ...
        this.addMarker()
      } catch (err) {
        console.error(err);
      }
    }
複製程式碼

新增向量圓形

新建一個函式

// 構建向量圓形
addCircle() {
  return new this.resMap.Circle({
    center: new this.resMap.LngLat(`${this.lng}`, `${this.lat}`), // 圓心位置
    radius: 500, //半徑,米
    strokeColor: "#F33", //線顏色
    strokeOpacity: 1, //線透明度
    strokeWeight: 3, //線粗細度
    fillColor: "#ee2200", //填充顏色
    fillOpacity: 0.35 //填充透明度
  });
},
複製程式碼

修改 addMarker 函式

// 建立點標記
addMarker() {
  ...
   
  // 記的在data裡新增circle
  this.circle = this.addCircle();

  this.map.add([this.marker, this.circle]);
  this.map.setFitView();
},
複製程式碼

新增一個圖示

新建一個函式

// 建立一個icon
addIcon() {
  return new this.resMap.Icon({
    // 圖示尺寸
    size: new this.resMap.Size(40, 40),
    // 圖示的取圖地址
    image: require("@/assets/images/Treasure Box.png"),
    // 圖示所用圖片大小
    imageSize: new this.resMap.Size(40, 40)
    // 圖示取圖偏移量
    // imageOffset: new this.resMap.Pixel(0, 13)
  });
},
複製程式碼

修改 addMarker 函式

 // 建立點標記
addMarker() {
  this.marker = new this.resMap.Marker({
    icon: this.addIcon(),
    position: [this.lng, this.lat],
    offset: new this.resMap.Pixel(-20, -20)
  });

  this.circle = this.addCircle();

  this.map.add([this.marker, this.circle]);
  this.map.setFitView();
},
複製程式碼

獲取當前位置

新建一個函式

// 獲取當前位置資訊
getCityInfo() {
  this.map.plugin("AMap.Geolocation", () => {
    var geolocation = new this.resMap.Geolocation({
      // 是否使用高精度定位,預設:true
      enableHighAccuracy: true,
      // 設定定位超時時間,預設:無窮大
      timeout: 10000,
      // 定位按鈕的停靠位置的偏移量,預設:Pixel(10, 20)
      buttonOffset: new this.resMap.Pixel(10, 20),
      //  定位成功後調整地圖視野範圍使定位位置及精度範圍視野內可見,預設:false
      zoomToAccuracy: true,
      //  定位按鈕的排放位置,  RB表示右下
      buttonPosition: "RB"
    });

    geolocation.getCurrentPosition();
    this.resMap.event.addListener(geolocation, "complete", this.onComplete);
    this.resMap.event.addListener(geolocation, "error", this.onError);
  });
},

// 獲取定位結果
onComplete(res) {
  console.log(res)
},

// 定位出錯
onError(err) {
  console.error(err, "--定位出錯--");
}

複製程式碼

計算寶箱和當前的距離

新建一個函式

// 計算兩點之間的距離
calculatingDistance(position) {
  const p1 = [this.lng, this.lat];
  // data中新增myPosition
  this.myPosition = [position.lng, position.lat];
  return this.resMap.GeometryUtil.distance(p1, this.myPosition);
},
複製程式碼

修改 onComplete 函式

onComplete(res) {
  // data中新增distance
  this.distance = this.calculatingDistance(res.position);
},

複製程式碼

新增是否能挖寶邏輯

當前位置處於寶箱500米範圍內可以挖寶,同時顯示 ‘我’ 標記

computed: {
    // 是否在500米範圍內
    is500() {
      return this.distance === undefined ||
        this.distance === null ||
        this.distance > 500
        ? false
        : true;
    }
},
watch: {
    is500(newValue) {
      if (newValue) {
        const marker = new this.resMap.Marker({
          icon: "https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png",
          position: this.myPosition,
          offset: new this.resMap.Pixel(-13, -30),
          title: "我"
        });
        this.map.add(marker);
        this.map.setFitView();
    
        // 設定滑鼠劃過點標記顯示的文字提示
        marker.setTitle("我");
    
        // 設定label標籤
        // label預設藍框白底左上角顯示,樣式className為:amap-marker-label
        marker.setLabel({
          offset: new this.resMap.Pixel(0, 0), //設定文字標註偏移量
          content: "<div class='info'>我</div>", //設定文字標註內容
          direction: "bottom" //設定文字標註方位
        });
      }
    }
},
複製程式碼

最後

水平有限,有錯漏之處各位大佬輕噴!

參考

在vue專案中非同步使用高德地圖AMap

相關文章