腾讯地图Api开发 地址选点,地址搜索,轨迹播放(个人学习记录)

在index.html文件中导入腾讯地图的组件api

<script src="https://map.qq.com/api/gljs?v=1.exp&key=<输入你的KEY>"></script>

创建文件components/map/index.vue

<template>
  <div style="position: relative;">
    <div
      v-if="!mapLoaded"
      class="loadingPage"
    >
      <div class="loading loader" />
    </div>
    <!-- 控制台 -->
    <div
      v-if="searchShow && mapLoaded"
      class="control"
    >
      <el-autocomplete
        v-model="searchAddress"
        class="inline-input"
        :fetch-suggestions="querySearch"
        placeholder="请输入市区名+地名"
        clearable
        :trigger-on-focus="false"
        @input="inputAddress"
        @select="search"
        @click.native.stop
      />
      <el-button
        :disabled="isDisabled"
        @click.stop="search"
      >搜索地址</el-button>
    </div>
    <div
      v-if="mapType === 'route' && mapLoaded"
      class="control"
    >
      <div class="item">
        <div class="label">播放速度:</div>
        <el-input-number
          v-model="speedNum"
          :min="1"
          :max="999"
          label="播放速度"
          @change="speedChange"
        />
        <el-button
          style="margin-left: 20px;"
          @click.stop="speedChange(10)"
        >10倍速</el-button>
        <el-button @click.stop="speedChange(100)">100倍速</el-button>
        <el-button @click.stop="speedChange(999)">1000倍速</el-button>
      </div>

    </div>
    <!-- 地图容器 -->
    <div
      id="qqmap"
      :style="'width:' + width + ';height:' + height + ';'"
    />
  </div>
</template>

<script>
import { addressResolution, addressInverseResolution, keywordAssociation } from './mapApi'
export default {
  props: {
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '100%'
    },
    // 启用点击事件
    clickEvent: {
      type: Boolean,
      default: false
    },
    // 启用搜索功能
    searchShow: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      mapType: null,
      mapLoaded: false, // 地图是否加载完成
      map: null, // 地图对象实例
      center: null, // 地图中心点
      maker: null, // 标记点实例
      markGeo: [], // 点标记列表
      polylineLayer: null,
      path: [],
      // 初始化地图数据
      location: {
        lng: undefined, // 经度
        lat: undefined // 纬度
      },
      // 轨迹开始坐标
      startLocation: {
        lng: undefined, // 经度
        lat: undefined // 纬度
      },
      // 轨迹结束坐标
      endLocation: {
        lng: undefined, // 经度
        lat: undefined // 纬度
      },
      searchAddress: '', // 地址搜索数据
      searchList: undefined, // 地址搜索结果
      isDisabled: true, // 搜索按钮是否禁用
      province: undefined, // 省
      city: undefined, // 市
      district: undefined, // 区
      addressValue: undefined, // 详细地址
      speedNum: 1
    }
  },
  created() {
  },
  methods: {
    launch(res, type) {
      if (type === 'point') {
        this.mapType = 'point'
        this.getLocation(res) // 初始化经纬度
      } else if (type === 'route') {
        this.mapType = 'route'
        this.getLocationRoute(res) // 初始化经纬度
      }
      if (!this.mapLoaded) {
        this.initMap() // 初始化地图
      }
    },
    devastate() {
      this.speedNum = 1
      this.map.destroy()
      this.mapLoaded = false
    },
    // 地图初始化
    initMap() {
      // 定义地图中心点坐标
      this.center = new window.TMap.LatLng(
        this.location.lat,
        this.location.lng
      )
      // 定义map变量,调用 TMap.Map() 构造函数创建地图
      this.map = new window.TMap.Map(document.getElementById('qqmap'), {
        center: this.center, // 设置地图中心点坐标
        zoom: 17.2, // 设置地图缩放级别
        pitch: 43.5, // 设置俯仰角
        rotation: 45, // 设置地图旋转角度
        viewMode: '3D' // 设置地图展示形式 默认3D
      })
      if (this.$props.clickEvent) {
        this.map.on('click', this.clickHandler) // 添加地图点击事件
      }
      // 创建点标记
      if (this.mapType === 'point') {
        this.markGeo = [
          {
            id: '1', // 点标记唯一标识,后续如果有删除、修改位置等操作,都需要此id
            styleId: 'myStyle', // 指定样式id
            position: new window.TMap.LatLng(
              this.location.lat,
              this.location.lng
            )
          }
        ]
      } else if (this.mapType === 'route') {
        this.markGeo = [
          {
            id: 'car',
            styleId: 'car-down',
            position: new window.TMap.LatLng(
              this.location.lat,
              this.location.lng
            )
          }, {
            id: 'start',
            styleId: 'start',
            position: new TMap.LatLng(
              this.startLocation.lat,
              this.startLocation.lng
            )
          }, {
            id: 'end',
            styleId: 'end',
            position: new TMap.LatLng(
              this.endLocation.lat,
              this.endLocation.lng
            )
          }
        ]
      }

      this.maker = new window.TMap.MultiMarker({
        map: this.map, // 绑定地图对象
        styles: {
          'car-down': new TMap.MarkerStyle({
            'width': 40,
            'height': 40,
            'anchor': {
              x: 20,
              y: 20
            },
            'faceTo': 'map',
            'rotate': 0,
            'src': 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/car.png'
          }),
          'start': new TMap.MarkerStyle({
            'width': 25,
            'height': 35,
            'anchor': { x: 16, y: 32 },
            'src': 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/start.png'
          }),
          'end': new TMap.MarkerStyle({
            'width': 25,
            'height': 35,
            'anchor': { x: 16, y: 32 },
            'src': 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/end.png'
          })
        },
        geometries: this.markGeo // 点标记数据
      })
      // 添加路线轨迹
      if (this.mapType === 'route') {
        this.polylineLayer = new TMap.MultiPolyline({
          map: this.map, // 绘制到目标地图
          // 折线样式定义
          styles: {
            'style_route': new TMap.PolylineStyle({
              'color': '#3777FF', // 线填充色
              'width': 5, // 折线宽度
              'borderWidth': 1, // 边线宽度
              'borderColor': '#eee', // 边线颜色
              'lineCap': 'round' // 线端头方式
            })
          },
          geometries: [{
            styleId: 'style_route',
            paths: this.path
          }]
        })
        this.maker.moveAlong({
          'car': {
            path: this.path,
            speed: 888 * this.speedNum
          }
        }, {
          autoRotation: true
        })
      }

      this.mapLoaded = true
      console.log('地图加载完成')
    },
    // 单点地图数据初始化
    getLocation(res) {
      this.location.lng = res.longitudeX
      this.location.lat = res.latitubeY
      if (this.mapLoaded) {
        // 设置标记点
        this.setMaker(this.location.lat, this.location.lng)
        // 移动地图中心点
        this.map.setCenter(new TMap.LatLng(this.location.lat, this.location.lng))
      }
    },
    // 地图点击事件
    clickHandler(evt) {
      this.location.lat = evt.latLng.getLat().toFixed(6) // 获取纬度
      this.location.lng = evt.latLng.getLng().toFixed(6) // 获取经度
      // 设置标记点
      this.setMaker(this.location.lat, this.location.lng)
      // 地址逆解析
      addressInverseResolution(this.location.lat + ',' + this.location.lng).then(res => {
        this.addressValue = res.result.address
        this.province = res.result.address_component.province
        this.city = res.result.address_component.city
        this.district = res.result.address_component.district
        // 传递地址数据
        this.postAddressData()
      })
    },
    // 设置标记点
    setMaker(latitude, longitude) {
      // 修改标记点
      this.maker.updateGeometries({
        id: '1', // 点标记唯一标识,后续如果有删除、修改位置等操作,都需要此id
        styleId: 'myStyle', // 指定样式id
        position: new window.TMap.LatLng(
          latitude, longitude
        )
      })
    },
    // 搜索地址
    search() {
      // 地址解析
      addressResolution(this.searchAddress).then(res => {
        const searchOption = this.searchList.find(f => f.result.title === this.searchAddress)
        if (res.message !== 'Success') {
          if (searchOption && searchOption.result.title !== this.searchAddress) {
            this.$message({
              message: '请注意搜索格式是否正确',
              type: 'error',
              duration: 2000,
              offset: 70
            })
            return
          } else if (searchOption && searchOption.result.title) {
            res = searchOption
          }
        }
        // 设置标记点
        this.setMaker(res.result.location.lat, res.result.location.lng)
        // 移动地图中心点
        this.map.setCenter(new TMap.LatLng(res.result.location.lat, res.result.location.lng))
        // 获取详细地址信息
        this.addressValue = res.result.title
        this.province = res.result.address_components.province
        this.city = res.result.address_components.city
        this.district = res.result.address_components.district
        // 传递地址数据
        this.postAddressData()
      })
    },
    // 查询联想词
    querySearch(queryString, cb) {
      keywordAssociation(queryString).then(({ data }) => {
        for (var i = 0; i < data.length; i++) {
          data[i].value = data[i].title
        }
        this.searchList = data.map(m => {
          const location = m.location
          const title = m.title
          const province = m.province
          const district = m.district
          const city = m.city
          const address_components = { province, district, city }
          const searchOption = { result: { title, location, address_components }}
          return searchOption
        })
        cb(data)
      })
    },
    // 判断输入地址是否为空
    inputAddress(value) {
      if (value) {
        this.isDisabled = false
      } else {
        this.isDisabled = true
      }
    },
    // 传递地址数据
    postAddressData() {
      // this.$emit('postAddress', {
      //   province: this.province,
      //   city: this.city,
      //   district: this.district,
      //   addressValue: this.addressValue,
      //   latitubeY: this.location.lat,
      //   longitudeX: this.location.lng
      // })
    },
    // 路径地图数据初始化
    getLocationRoute(res) {
      // 获取起点坐标信息
      this.startLocation.lng = res[0].longitudeX
      this.startLocation.lat = res[0].latitudeY
      // 获取终点坐标信息
      this.endLocation.lng = res[res.length - 1].longitudeX
      this.endLocation.lat = res[res.length - 1].latitudeY
      const LastPosition = res[0]// 最新的坐标信息
      this.location.lng = LastPosition.longitudeX
      this.location.lat = LastPosition.latitudeY
      console.log(this.endLocation);
      console.log(this.startLocation);
      res.forEach(item => {
        this.path.push(new TMap.LatLng(item.latitudeY, item.longitudeX))
      })
      if (this.mapLoaded) {
        // 移动地图中心点
        this.map.setCenter(new TMap.LatLng(this.location.lat, this.location.lng))
      }
    },
    speedChange(num) {
      if (num) {
        this.speedNum = num
      }
      this.maker.moveAlong({
        'car': {
          path: this.path,
          speed: 800 * this.speedNum
        }
      }, {
        autoRotation: true
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.control {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 1999;

  .item {
    display: flex;
    align-items: center;

    .label {
      font-size: 16px;
      color: #666;
      margin-right: 10px;
    }
  }
}

.loadingPage {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 3999;

  .loading {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }
}

@keyframes rotation {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

.loader {
  width: 48px;
  height: 48px;
  border: 5px solid #00afee;
  border-bottom-color: #90cf5b;
  border-radius: 50%;
  -webkit-animation: rotation 1s linear infinite;
  animation: rotation 1s linear infinite;
}
</style>

创建文件components/map/map_api.js

// 地址解析
export function addressResolution(address) {
  return new Promise(function(resolve, reject) {
    window.handleResponse = function(data) {
      resolve(data)
    }
    const url = 'https://apis.map.qq.com/ws/geocoder/v1/?address=' + address + '&key=<输入你的KEY>&output=jsonp&callback=handleResponse'
    var script = document.createElement('script')
    script.src = url
    document.body.appendChild(script)
  })
}
// 地址逆解析
export function addressInverseResolution(location) {
  return new Promise(function(resolve, reject) {
    window.handleResponse = function(data) {
      resolve(data)
    }
    const url = 'https://apis.map.qq.com/ws/geocoder/v1/?location=' + location + '&key=<输入你的KEY>&output=jsonp&callback=handleResponse'
    var script = document.createElement('script')
    script.src = url
    document.body.appendChild(script)
  })
}
// 关键词联想
export function keywordAssociation(keyword) {
  return new Promise(function(resolve, reject) {
    window.handleResponse = function(data) {
      resolve(data)
    }
    const url = 'https://apis.map.qq.com/ws/place/v1/suggestion?keyword=' + keyword + '&key=<输入你的KEY>&output=jsonp&callback=handleResponse&policy=1'
    var script = document.createElement('script')
    script.src = url
    document.body.appendChild(script)
  })
}

调用方式:

<template>
  <div>
    <el-button type="primary" @click="handleOpen">打开地图</el-button>
    <el-button type="primary" @click="handlePlay">播放轨迹</el-button>
    <el-drawer
      :visible.sync="drawerShow"
      direction="btt"
      :before-close="handleClose"
      wrapperClosable
      size="800px"
      :with-header="false"
    >
      <TXmap ref="TXmapRef" :height="'797px'" :clickEvent="true" :searchShow="true" />
    </el-drawer>
  </div>
</template>

<script>
// 引入地图组件
import TXmap from "@/components/TXmap";
export default {
  components: {
    TXmap,
  },
  data() {
    return {
      // 是否显示弹出层
      drawerShow: false,
    };
  },
  methods: {
    async handleOpen() {
      // 打开弹窗
      this.drawerShow = true;
      // 加载地图数据
      const data = {
        longitudeX: "116.397477",
        latitubeY: "39.908692",
      };
      this.$nextTick(() => {
        this.$refs.TXmapRef.launch(data, "point"); //加载地图数据 单点标记
      });
    },
    handlePlay() {
      // 打开弹窗
      this.drawerShow = true;
      // 加载地图数据
      const data = [
        {longitudeX:116.30571126937866,latitudeY:39.98481500648338},
        {longitudeX:116.30596876144409,latitudeY:39.982266575222155},
        {longitudeX:116.3111400604248,latitudeY:39.982348784165886},
        {longitudeX:116.3111400604248,latitudeY:39.978813710266024},
        {longitudeX:116.31699800491333,latitudeY:39.978813710266024},
      ];
      this.$nextTick(() => {
        this.$refs.TXmapRef.launch(data, "route"); //加载地图数据 播放轨迹
      });
    },
    handleClose() {
      // 关闭弹窗
      this.drawerShow = false;
      this.$refs.TXmapRef.devastate(); //销毁地图
    },
  },
};
</script>

您可以使用百度地图API来实现前端内网开发的地图选点获取坐标和具体省市区地址。以下是实现步骤: 1. 注册百度地图开发者账号,创建应用,获取密钥。 2. 在前端页面中引入百度地图APIJavaScript库: ``` <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=您的密钥"></script> ``` 3. 创建地图容器: ``` <div id="map" style="width: 100%; height: 500px;"></div> ``` 4. 初始化地图: ``` var map = new BMap.Map("map"); // 创建地图实例 var point = new BMap.Point(116.404, 39.915); // 创建点坐标 map.centerAndZoom(point, 15); // 初始化地图,设置中心点坐标和缩放级别 map.enableScrollWheelZoom(true); // 启用滚轮缩放 ``` 5. 添加地图控件: ``` var geolocationControl = new BMap.GeolocationControl(); // 定位控件 var navigationControl = new BMap.NavigationControl(); // 缩放平移控件 var overviewMapControl = new BMap.OverviewMapControl(); // 缩略图控件 var scaleControl = new BMap.ScaleControl(); // 比例尺控件 map.addControl(geolocationControl); map.addControl(navigationControl); map.addControl(overviewMapControl); map.addControl(scaleControl); ``` 6. 添加地图事件监听: ``` map.addEventListener("click", function(e) { var point = e.point; // 获取点击的点坐标 var geoc = new BMap.Geocoder(); // 创建地理编码实例 geoc.getLocation(point, function(rs) { var addComp = rs.addressComponents; // 获取地址信息 var address = addComp.province + addComp.city + addComp.district + addComp.street + addComp.streetNumber; // 拼接地址信息 console.log(point.lng + ", " + point.lat); // 输出坐标 console.log(address); // 输出地址 }); }); ``` 以上就是实现前端内网开发的地图选点获取坐标和具体省市区地址的步骤。百度地图API提供了丰富的功能和文档,您可以参考官方文档进行更详细的开发
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值