pc端高德地图选点、拾取坐标

功能:地点搜索、点击地图拾取坐标和地址。

效果图:

npm下载高德插件:

npm i @amap/amap-jsapi-loader
全部代码:
<template>
  <el-dialog v-model="dialogVisible" title="选择地点" width="800" :before-close="handleClose">
    <div class="map-container">
      <div id="container" class="map-content"></div>
      <div class="search-box">
        <el-input v-model="searchKeyword" placeholder="请输入地址" @keyup.enter="searchPlace">
          <template #append>
            <el-button @click="searchPlace">搜索</el-button>
          </template>
        </el-input>
        <div v-if="searchResults.length > 0" class="search-results">
          <div
v-for="(item, index) in searchResults" :key="index" class="result-item"
            @click="selectSearchResult(item)">
            {{ item.name }} - {{ item.address }}
          </div>
        </div>
      </div>
      <div class="location-info" v-if="selectedLocation">
        <p>当前选择位置:{{ selectedLocation.address }}</p>
        <p>经度:{{ selectedLocation.lng }} 纬度:{{ selectedLocation.lat }}</p>
      </div>
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" @click="sure" :disabled="!selectedLocation">
          确定
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { ref, watch, nextTick, onUnmounted } from 'vue'
import AMapLoader from '@amap/amap-jsapi-loader'

// 分别定义 JS API key 和 Web 服务 key
const JSAPI_KEY = '' // JS API key
const WEBSERVICE_KEY = ''  // Web 服务 key

const props = defineProps({
  show: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['update:show', 'select-location','handleClose'])

const dialogVisible = ref(false)
const map = ref(null)
const marker = ref(null)
const searchKeyword = ref('')
const searchResults = ref([])
const selectedLocation = ref(null)
const placeSearch = ref(null)


watch(() => props.show, (newValue) => {
  dialogVisible.value = newValue
  if (newValue) {
    // 延迟初始化地图,确保容器已经渲染
    nextTick(() => {
      initMap()
    })
  }
})

watch(() => dialogVisible.value, (val) => {
  emit('update:show', val)
})

const initMap = async () => {
  if (map.value) return

  try {
    const AMap = await AMapLoader.load({
      key: JSAPI_KEY,  // 使用 JS API key
      version: '2.0'
    })

    map.value = new AMap.Map('container', {
      zoom: 11,
      center: [116.397428, 39.90923]
    })

    // 点击地图事件
    map.value.on('click', async (e) => {
      const lnglat = e.lnglat
      let lnglatArr = [lnglat.lng, lnglat.lat]
      updateMarker(lnglatArr)
      await getAddress(lnglatArr)
    })

  } catch (e) {
    console.error('地图加载失败:', e)
  }
}

const updateMarker = (lnglat) => {
  if (marker.value) {
    marker.value.setPosition(new AMap.LngLat(lnglat[0], lnglat[1]))
  } else {
    marker.value = new AMap.Marker({
      position: new AMap.LngLat(lnglat[0], lnglat[1]),
      map: map.value
    })
  }
}

const getAddress = async (lnglat) => {
  try {
    const response = await fetch(
      `https://restapi.amap.com/v3/geocode/regeo?key=${WEBSERVICE_KEY}&location=${lnglat[0]},${lnglat[1]}&extensions=base&batch=false&roadlevel=0`
    )
    const data = await response.json()
    
    if (data.status === '1' && data.info === 'OK') {
      selectedLocation.value = {
        address: data.regeocode.formatted_address,
        lng: lnglat[0],
        lat: lnglat[1]
      }
    } else {
      console.error('获取地址失败:', data)
      throw new Error('获取地址失败')
    }
  } catch (error) {
    console.error('获取地址失败:', error)
  }
}

const searchPlace = async () => {
  if (!searchKeyword.value) return

  try {
    const response = await fetch(
      `https://restapi.amap.com/v3/place/text?key=${WEBSERVICE_KEY}&keywords=${encodeURIComponent(searchKeyword.value)}&city=全国&children=1&offset=20&page=1&extensions=base`
    )
    const data = await response.json()
    
    if (data.status === '1' && data.info === 'OK') {
      searchResults.value = data.pois.map(poi => ({
        name: poi.name,
        address: poi.address,
        location: {
          lng: poi.location.split(',')[0],
          lat: poi.location.split(',')[1]
        }
      }))
    }
  } catch (error) {
    console.error('搜索地点失败:', error)
  }
}

const selectSearchResult = (item) => {
  const lnglatArr = [item.location.lng, item.location.lat]
  map.value.setCenter(new AMap.LngLat(lnglatArr[0], lnglatArr[1]))
  updateMarker(lnglatArr)
  selectedLocation.value = {
    address: item.address,
    lng: lnglatArr[0],
    lat: lnglatArr[1]
  }
  searchResults.value = [] // 清空搜索结果
}

const handleClose = () => {
  dialogVisible.value = false
  selectedLocation.value = null
  searchResults.value = []
  searchKeyword.value = ''
  emit('handleClose')
}

const sure = () => {
  if (selectedLocation.value) {
    emit('select-location', selectedLocation.value)
  }
  handleClose()
}

// 组件销毁时清理地图实例
onUnmounted(() => {
  if (map.value) {
    map.value.destroy()
    map.value = null
  }
})
</script>

<style lang="scss" scoped>
.map-container {
  position: relative;
  width: 100%;
  height: 500px;
}

.map-content {
  width: 100%;
  height: 100%;
}

.search-box {
  position: absolute;
  top: 10px;
  left: 10px;
  width: 300px;
  z-index: 1;
}

.search-results {
  background: white;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  margin-top: 4px;
  max-height: 200px;
  overflow-y: auto;
}

.result-item {
  padding: 8px 12px;
  cursor: pointer;

  &:hover {
    background-color: #f5f7fa;
  }
}

.location-info {
  position: absolute;
  bottom: 10px;
  left: 10px;
  background: white;
  padding: 10px;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  z-index: 1;

  p {
    margin: 5px 0;
  }
}
</style>

### 集成高德地图API到UniApp实现选点和定位 #### 权限与配置准备 为了能够在UniApp项目中使用高德地图的服务,需要先完成必要的权限设置以及环境准备工作。这包括但不限于注册成为高德开放平台的开发者,并创建相应的Web服务密钥用于后续接口调用[^1]。 #### 安装依赖包 对于基于Vue框架构建的应用程序来说,在HBuilderX环境下可以通过npm安装`amap-js-api`来引入官方JavaScript API库: ```bash npm install amap-js-api --save ``` #### 初始化地图组件 在页面初始化阶段加载地图实例之前,需确保已经成功导入了上述提到的地图SDK文件。接着可以在mounted生命周期钩子函数内执行如下操作以显示默认中心点为中国北京的位置信息作为初始视图展示给用户查看[^2]: ```javascript import AMapLoader from '@amap/amap-jsapi-loader'; export default { mounted() { AMapLoader.load({ key: 'your_amap_web_service_key', // 替换成自己的key version: "2.0", plugins: [] }).then((AMap) => { this.map = new AMap.Map('container', { zoom: 10, center: [116.397428, 39.90923], // 设置地图中心点坐标为北京市区经纬度值 }); }) } } ``` #### 获取当前设备位置 借助于浏览器内置Geolocation API能够方便快捷地取得终用户的实时地理坐标数据。这里给出一段简单的代码片段用来请求访问GPS硬件资源并更新至地图界面上相应地标记处: ```javascript navigator.geolocation.getCurrentPosition( (position) => { const { latitude, longitude } = position.coords; // 更新地图中心点 map.setCenter([longitude, latitude]); // 添加标记 var marker = new AMap.Marker({ position: new AMap.LngLat(longitude, latitude), title: '当前位置' }); map.add(marker); }, error => console.error(error) ); ``` #### 使用POI检索插件查找周边兴趣点 为了让应用程序具备更强大的交互能力,还可以考虑接入高德提供的POI(Point Of Interest)查询工具,允许访客输入关键词后返回匹配的结果列表供其挑选感兴趣的目的地之一再进一步规划出行路线等动作. ```javascript // 加载搜索模块 const placeSearch = new AMap.PlaceSearch({ pageSize: 5, pageIndex: 1, citylimit: true }); document.getElementById('search').addEventListener('click', () => { let keyword = document.querySelector('#keyword').value; placeSearch.search(keyword); placeSearch.on('markerclick', function(e){ alert(`您选择了${e.poi.name}`); }); }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值