一、成为开发者并创建key

进入高德开放平台申请,具体操作可以参考官方提供的说明文档

准备-地图 JS API 2.0 | 高德地图APIhttps://lbs.amap.com/api/javascript-api-v2/prerequisites按照上面的步骤就可以成功申请一个应用,得到 key  和 安全密钥,后面都会用到

二、安装依赖

npm i @amap/amap-jsapi-loader --save

三、设置安全密钥

安全密钥机制旨在提升用户对 key 的安全有效管理,降低明文传输被窃取的风险。 2021年12月02日后创建的 key 必须配备安全密钥一起使用,具体用法参见 JS API 安全密钥使用https://lbs.amap.com/api/jsapi-v2/guide/abc/jscode

在项目的 index.html 中加入如下代码

<!-- 设置高德地图安全密钥 -->
<script type="text/javascript">
  window._AMapSecurityConfig = {
  securityJsCode: '*********', // 你的密钥
}
</script>

 四、引入依赖

在 main.ts 文件中加入如下代码(这里我只写了main.ts中关于高德地图的部分,代码具体的位置可根据自己的项目进行调节)

import AMapLoader from "@amap/amap-jsapi-loader"

AMapLoader.load({
  key: '***********', //设置您的key
  version: "2.0",
  plugins: [
    'AMap.ToolBar', // 工具条,控制地图的缩放、平移等
    'AMap.Geolocation', // 定位,提供了获取用户当前准确位置、所在城市的方法
    'AMap.AutoComplete', // 输入提示,提供了根据关键字获得提示信息的功能
    'AMap.Geocoder', // 地理编码与逆地理编码服务,提供地址与坐标间的相互转换
  ],
  AMapUI: {
    version: "1.1",
    plugins: [],
  },
  Loca: {
    version: "2.0.0"
  },
})

五、封装地图组件

这个组件的功能是通过点击高德地图获取点击地点的地址和经纬度,也可以通过在输入框中输入地址,查询地址的经纬度信息

<template>
  <el-dialog :title="dialog.title" v-model="dialog.visible" width="800px" append-to-body @close="cancel">
    <el-form label-width="60">
      <div class="f-item">
        <el-form-item label="地区">
          <el-input
            v-model="searchKey"
            type="text"
            id="search-box"
            style="width: 446px;z-index: 2000;"
            placeholder="请输入地址"
            @blur="handleSearch"
            @clear="handleClear"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">搜索</el-button>
        </el-form-item>
      </div>
      <div class="f-item">
        <el-form-item label="经度">
          <el-input v-model="lng" class="input-width" :disabled="true"></el-input>
        </el-form-item>
        <el-form-item label="纬度">
          <el-input v-model="lat" class="input-width" :disabled="true"></el-input>
        </el-form-item>
      </div>
    </el-form>
    <div id="map-wrap" :style="{'height': height}"></div>

    <template #footer>
      <div class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup name="mapcomtaint">
import AMapLoader from "@amap/amap-jsapi-loader"
import {
  propTypes
} from '@/utils/propTypes';

const {
  proxy
} = getCurrentInstance();

const props = defineProps({
  height: propTypes.string.def('300px')
});

const searchKey = ref("");
const lng = ref(""); // 经度
const lat = ref(""); // 纬度
const map = ref(""); // 地图
const geocoder = ref(""); //高德
const marker = ref(""); // 标记点

const dialog = reactive({
  visible: false,
  title: ''
});

const ininMap = () => {
  AMapLoader.load({
    key: 'b78fdad2a4732fb46d1c4500be703dda', //设置您的key
    version: "2.0",
    plugins: [
      'AMap.ToolBar', // 工具条,控制地图的缩放、平移等
      'AMap.Geolocation', // 定位,提供了获取用户当前准确位置、所在城市的方法
      'AMap.AutoComplete', // 输入提示,提供了根据关键字获得提示信息的功能
      'AMap.Geocoder', // 地理编码与逆地理编码服务,提供地址与坐标间的相互转换
    ],
    AMapUI: {
      version: "1.1",
      plugins: [],
    },
    Loca: {
      version: "2.0.0"
    },
  }).then((AMap) => {

    console.log(document.getElementById('map-wrap', '--------map-wrap'))
    map.value = new AMap.Map("map-wrap", {
      viewMode: "", //3D 开启3D视图,默认为关闭
      zoom: 10,
      zooms: [2, 22],
      center: [113.88308, 22.55329], //深圳的经纬度
    });
    // 初始化标记点
    // let positionArr = [
    //   [113.357224, 34.977186],
    //   [114.555528, 37.727903],
    //   [112.106257, 36.962733],
    //   [109.830097, 31.859027],
    //   [116.449181, 39.98614],
    // ];
    // for (let item of positionArr) {
    //   let marker = new AMap.Marker({
    //     position: [item[0], item[1]],
    //   });
    //   map.value.add(marker);
    // }
    marker.value = new AMap.Marker();
    map.value.on('click', onMapClick); //地图点击事件
    AMap.plugin(
      ['AMap.ToolBar', 'AMap.Scale', 'AMap.Geolocation', 'AMap.PlaceSearch',
        'AMap.Geocoder', 'AMap.AutoComplete', 'AMap.Pixel'
      ],
      () => {
        // 缩放条
        const toolbar = new AMap.ToolBar();
        // 比例尺
        const scale = new AMap.Scale();
        // 定位
        const geolocation = new AMap.Geolocation({
          enableHighAccuracy: true, //是否使用高精度定位,默认:true
          timeout: 10000, //超过10秒后停止定位,默认:5s
          position: 'RT', //定位按钮的停靠位置
          buttonOffset: new AMap.Pixel(10, 20), //定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
          zoomToAccuracy: true, //定位成功后是否自动调整地图视野到定位点
        });
        geocoder.value = new AMap.Geocoder({
          radius: 1000, //以已知坐标为中心点,radius为半径,返回范围内兴趣点和道路信息
          extensions: "all" //返回地址描述以及附近兴趣点和道路信息,默认“base”
        });
        map.value.addControl(geolocation);
        map.value.addControl(toolbar);
        map.value.addControl(scale);
        // 获取当前设备的经纬度
        // geolocation.getCurrentPosition((status, result) => {
        //   if (status === 'complete') {
        //     console.log(result, '----------result')
        //     // const points = [result.position.lng, result.position.lat]
        //     // map.value.setCenter(points) // 设置中心点
        //   } else {
        //     proxy.$modal.msgError("定位失败");
        //   }
        // });
        // 进行IP城市查询
        geolocation.getCityInfo((status, result) => {
          if(status === 'complete') {
            console.log(status, result, '城市信息')
            map.value.setCenter(result.position); // 设置中心点
            const defaultMarker = new AMap.Marker({
              position: result.position,
            });
            map.value.add(defaultMarker); // 添加标记
          }
        });


        //输入提示
        var auto = new AMap.AutoComplete({
          input: "search-box"
        });
        console.log(auto, '---------auto')
        const placeSearch = new AMap.PlaceSearch({
          city: '全国',
          pageSize: 10, // 单页显示结果条数
          pageIndex: 1, // 页码
          citylimit: false, // 是否强制限制在设置的城市内搜索
          autoFitView: true,
        });
      });
  }).catch(e => {
    // proxy.$modal.msgError("根据经纬度查询地址失败");
  })
}

const onMapClick = (e) => {
  regeoCode([e.lnglat.lng, e.lnglat.lat]);
  lng.value = e.lnglat.lng;
  lat.value = e.lnglat.lat;
}

const regeoCode = (arr) => {
  map.value.add(marker.value);
  marker.value.setPosition(arr);
  geocoder.value.getAddress(arr, function (status, result) {
    console.log(status, result, '----------------------根据经纬度查询地址')
    if (status === 'complete' && result.regeocode) {
      let address = result.regeocode.formattedAddress;
      searchKey.value = address;
    } else {
      proxy.$modal.msgError("根据经纬度查询地址失败");
    }
  });
}

const handleSearch = () => {
  geocoder.value.getLocation(searchKey.value, function (status, result) {
    console.log(status, result, '----------------------根据地址查询经纬度')
    if (status === 'complete' && result.geocodes.length) {
      let lnglat = result.geocodes[0].location;
      lng.value = lnglat.lng;
      lat.value = lnglat.lat;
      map.value.add(marker.value);
      marker.value.setPosition([lng.value, lat.value]);
      map.value.setFitView(marker.value);
    } else {
      proxy.$modal.msgError("根据地址查询位置失败");
    }
  });
}

const handleClear = () => {
  lng.value = "";
  lat.value = "";
}

const getPosition = () => {
  return new Promise((resolve, reject) => {
    if (window.navigator.geolocation) {
      window.navigator.geolocation.getCurrentPosition(function (position) {
        console.log(latitude, '--------latitude')
        let latitude = position.coords.latitude
        let longitude = position.coords.longitude
        let data = {
          latitude: latitude,
          longitude: longitude
        }
        resolve(data)
      }, function () {
        reject(arguments)
      })
    } else {
      reject('你的浏览器不支持当前地理位置信息获取')
    }
  })
}

const submitForm = () => {
  let obj = {
    lng: lng.value,
    lat: lat.value,
    addr: searchKey.value
  };
  proxy?.$emit("getData", obj);
  dialog.visible = false;
}
const cancel = () =>{
  dialog.visible = false;
  lng.value = "";
  lat.value = "";
  searchKey.value = "";
}

onMounted(() => {});

const show = () => {
  dialog.visible = true;
  nextTick(() => {
    ininMap();
  });
}

defineExpose({
  show
});
</script>
<style scope>
.map-container {
  height: 100%;
  width: 100%;
  padding: 0px;
  margin: 0px;
  position: relative;
}

#map-wrap {
  height: 100%;
  width: 100%;
  padding: 0px;
  margin: 0px;
}
.f-item {
  display: flex;
}
</style>

五、效果展示

 

六、踩坑历程

上面有段代码重点注意下

 最开始我是想用  geolocation.getCurrentPosition   这个api获取设备的经纬度来设置高德地图默认展示的的地图信息,但是无论怎么尝试都是失败

常见问题 | 高德地图APIhttps://lbs.amap.com/faq/js-api/map-js-api/position-related/43361?page%3d&eqid=ebba979a00020ff20000000464741c40

 后来在官方文档中找解决办法时发现了一个替代方案,感觉还不错,也可以实现我这个项目的需求,真是太好了~  我就是被下面这句话启发的,哈哈哈

 geolocation.getCityInfo  这个api用法也很简单

 以上就是整个功能实现的完整步骤啦,特别是设置城市中心点的时候花费了好多时间,如果和我一样只要能拿到城市信息就行的小伙伴可以尝试用这个替代方案,踩坑的地方大家留意下,嘿嘿嘿

这世界很喧嚣,做你自己就好

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐