腾讯地图服务

@LBS for Vue3
提供更为深度的地图应用场景支持
开发文档 → JavaScript:Javascript API GL是基于WebGL技术打造的3D版地图API,3D化的视野更为自由,交互更加流畅
更多使用信息,请参考 腾讯地图服务 LBSjavascript GL
准备
注册账号
创建应用

控制台 → 应用管理 → 我的应用 → 创建应用

申请 KEY

勾选产品 Webservice API,需要使用 定位服务 - IP定位 服务和 搜索服务 - 关键字输入提示

Webservice API:腾讯地图面向企业开发者提供的地图服务,是基于HTTPS/HTTP协议的数据接口。 开发者可以使用任何客户端、服务器和开发语言,按照腾讯地图WebService API规范,按需构建HTTPS请求,并获取结果数据(目前支持JSON/JSONP方式返回)

JavaScript API GL:基于 WebGL 技术,主要面向 js 的使用

同一个账号所有的 key 共享免费额度

暂时不用的 key 不要分配额度;或者应先释放已经分配的额度

key 的配额分配

使用
使用方法很多,常见的有 WebService API JavaScript API
以下以 JavaScript API 中面向 Vue 的 tlbs-map 地图组件库为例介绍其基本使用
1. 安装
npm install --save tlbs-map-vue
2. 引入 - 在 main.js 作为中间件使用
import TlbsMap from "tlbs-map-vue";

app.use(TlbsMap);
3. 使用 - 按照自定义组件的形式在组件内使用;修改示例,调整为 Vue3 的 setup 语法糖格式
地图 Map
更多信息,请访问 Map
结构
请使用自己的 api-key
<tlbs-map ref="mapRef" api-key="YI6BZ-XXXX-YYYY-ZZZZ-MK7MQ-3GBRU" 
  :center="center" 
  :zoom="zoom" 
  :control="control"
  @click="onClick"
  @map_inited="onMapInited"
  @dragend="onDragEnd">
</tlbs-map>
属性
1. 开发密钥 api-key
2. 中心点 center
构建地图时,通过 Webservice API 和获取;这里采用静态值
const center = ref({ lat: 23.02067, lng: 113.75179 });
3. 缩放 zoom
应显示指定;不指定可能影响点标记的显示
const zoom = ref(15);
4. 控制 control
标尺、缩放和旋转等控件
默认显示
interface Control {
  scale: { position: string; className: string } | boolean;
  zoom: { position: string; className: string,  numVisible: boolean} | boolean;
  rotation: { position: string; className: string } | boolean;
}
如果项目中不想显示,设置为 false
const control = ref({
  scale: false,
  zoom: false,
  rotation: false
})
事件
1. map_inited
地图实例初始化事件,可以在回调中获取地图实例
获取到地图实例就可以使用对应的 地图实例方法
const onMapInited = () => {
  // 地图加载完成后,可以获取地图实例,调用地图实例方法
  console.log('map', mapRef.value);
  console.log('map', mapRef.value.map);
  console.log('map', mapRef.value.map.getCenter());
};
2. dragstart、drag、dragend
地图拖动结束时获取中心点并设置/更新中心点
const onDragEnd = (e) => {
  console.log('map dragend');
  console.log(e);
  const newCenter = mapRef.value.map.getCenter();
  console.log('New center:', newCenter.lat, newCenter.lng);
  center.value = { lat: newCenter.lat, lng: newCenter.lng };
}
方法
通过引用拿到地图实例后 - mapRef.value.map,可以使用相关的方法
1. 获取中心点 getCenter()
const getMapCenter = () => {
  console.log(mapRef.value.center.lat, mapRef.value.center.lng);
  console.log(mapRef.value.map.getCenter());
}
2. 返回中心点 setCenter()
默认没有返回地图中心
结构 - 使用 Iconfont,添加事件、
<button class="pos" @click="setMapCenter">
  <span class="iconfont icon-location2"></span>
</button>
还可以直接修改中心点
  const setMapCenter = () => {
    mapRef.value.map.setCenter({ lat: 30.91799, lng: 110.397027 });
    // center.value = { lat: 23.02067, lng: 113.75179 }
  }
样式 - 绝对定位在左下角;地图渲染的图层层级为1000,为了不被覆盖,应该大于1000
.pos {
  position: absolute;
  left: 2rem;
  bottom: 2rem;
  background-color: rgb(255, 255, 255, 1);
  width: 4rem;
  height: 4rem;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 50%;
  z-index: 1001;
}
点标记 Marker
更多信息,请访问 Marker
结构
<tlbs-map> 的子元素
<tlbs-multi-marker
  ref="markerRef"
  :geometries="geometries"
  :styles="styles"
  :options="options" 
  @click="onMarkerClick"/>
属性
1. 位置 Geometries
常见有: id、样式ID styleId、位置 position
以数组的形式,提供多个点标记;可以由 API 获取点数据
使用 styleId 可以为每个点标记设置不同的样式
const geometries = ref([
  { styleId: 'marker', position: { lat: 39.91799, lng: 116.397027 } },
])
2. 样式 Styles
常见有:styleId 及对应的 width、height 和 src;图片采用静态导入,根据大小,等比例设置大小
大小只能为正整数
styleId 和上面的 styleId 对应;如果位置中指定相同的 styleId,则所有的点标记应用同样的样式
如果不指定 src,则使用默认的标记 - 一个红色的地图标记
import src from '@/assets/logo-small.png';

const styles = ref({
  marker: {
    width: 20,
    height: 25,
    anchor: { x: 10, y: 30 },
    src,
  },
})
3. 选项 Options
常见有:缩放比例
可以使用默认值
const options = ref({
  minZoom: 5,
  maxZoom: 15,
})
事件
1. click
点击事件,可以获取到点击的点标记
WebService API
项目中主要使用到了搜索服务和定位服务
需要使用代理
更多信息,请访问 WebService API
搜索服务 - 地点搜索
结果包括:
{
  "id": "1902176000166755090",
  "title": "瑞幸咖啡(桂林文化宫店)",
  "address": "广西壮族自治区桂林市秀峰区依仁路38号文化宫名品街3号楼3-1-2号门面",
  "tel": "",
  "category": "娱乐休闲:咖啡厅",
  "type": 0,
  "location": {
    "lat": 25.277125,
    "lng": 110.296377
  },
  "_distance": 1928.57,
  "ad_info": {
    "adcode": 450302,
    "province": "广西壮族自治区",
    "city": "桂林市",
    "district": "秀峰区"
  }
}
页面中,还需要营业时间,需要对结果二次处理;默认营业时间为 08:30 - 21:30
locs.value = res.data.data.map(item => ({
  ...item,
  open: '08:30 - 21:30'
}))
获取的信息,需要提供给点标记 geometries
geometries.value = res.data.data.map(item => ({
  styleId: 'marker',
  position: item.location,
  content: item.title
}));
定位服务 - IP定位
结果包括:
{
  "status": 0,
  "message": "Success",
  "request_id": "9a7b4858d8de4ab381ce4ac4489d56f7",
  "result": {
    "ip": "117.183.223.153",
    "location": {
      "lat": 25.25235,
      "lng": 110.31771
    },
    "ad_info": {
      "nation": "中国",
      "province": "广西壮族自治区",
      "city": "桂林市",
      "district": "七星区",
      "adcode": 450305,
      "nation_code": 156
    }
  }
}
[] 业务流分析
地图 Map.vue 加载时先利用 定位服务 获取中心点 center,再根据中心点使用 搜索服务 搜索附近的POI
对搜索结果分别处理

. 添加营业时间 open 给列表数据负责在页面视图底部渲染门店信息

. 构建点标记 geometries

import { ref, onMounted, inject } from 'vue';
const axios = inject('axios');
const apiKey = 'YI6BZ-MTZW4-xxxx-yyyy-zzzz-3GBRU'
const keyword = '瑞幸咖啡';
const radius = 1000
const locs = ref([]);
const center = ref({})
const geometries = ref([])

onMounted(() => {
  axios.get(`/map-api/ws/location/v1/ip?ip=&key=${apiKey}`)
    .then(res => {
      center.value = res.data.result.location
      axios.get(`/map-api/ws/place/v1/search?boundary=nearby(${center.value.lat},${center.value.lng},${radius})&keyword=${keyword}&page_size=10&page_index=1&key=${apiKey}`)
        .then(res => {
          locs.value = res.data.data.map(item => ({
            ...item,
            open: '08:30 - 21:30'
          }))
          geometries.value = res.data.data.map(item => ({
            styleId: 'marker',
            position: item.location,
            content: item.title
          }));
        })
    })
})

axios 使用依赖注入的方式使用,并进行了代理处理