微信公众号定位

系列文章目录

通过高德地图坐标转换接口,完成微信wx.getLocation()jsdk坐标转换,实现定位高精确度效果



前言

一起开始在百度找了坐标转换,腾讯地图转换成百度地图坐标等等方法但是误差还是很多很难搞,后来看高德原生的地图api里面有浏览器精确定位,我就想着搬到微信公众号,但是公司比较穷,用不起https,没办法,只能试试高德坐标转换api希望误差不要太大,结果还是很好的


高德文档

一、下载高德

//建议用yarn速度快
npm install vue-amap --save
 yarn add vue-amap

//main.js
AmapVue.config.version = '2.0'; // 默认2.0,这里可以不修改
AmapVue.config.key = 'xx';
AmapVue.config.plugins = [
    'AMap.ToolBar',
    'AMap.MoveAnimation',
    'AMap.AutoComplete',
    'AMap.PlaceSearch',
    'AMap.Geocoder',
    'AMap.Geolocation'
    // 在此配置你需要预加载的插件,如果不配置,在使用到的时候会自动异步加载
];

代码如下(示例):

二、封装地图组件,vantUI

代码如下(示例):

<template>
  <div>
    <van-popup width="600"

               :style="{ height: '100%',width:'100%' }"
               v-model="open"
    >
      <van-cell style="margin-top:10px;padding: 0px">
        <van-row type="flex" justify="space-between">
          <van-col span="12"><van-button plain hairline type="primary"  @click="closeAlertDialog">取消</van-button></van-col>
          <van-col span="12" style="text-align: end" > <van-button plain hairline type="primary" @click="OKAlertDialog">确定</van-button></van-col>
        </van-row>
        当前已选中地点:{{addressName}}
        <van-search class="page-select-lump" v-model="keyword" placeholder="请输入搜索关键词" :show-action="keyword !== ''"
                    @cancel="onCancel">
          <template v-if="loading" #left-icon>
            <van-loading size="24"/>
          </template>
        </van-search>
      </van-cell>

      <mu-button slot="left" icon @click="closeAlertDialog">
        <mu-icon value="close"></mu-icon>
      </mu-button>

      <amap
          ref="myMap"
          :style="{height:'80vh'}"
          cache-key="coord-picker-map"
          async
          :center.sync="center"
          :zoom.sync="zoom"
          is-hotspot
          map-style="amap://styles/makaron"
          @click="onMapClick"
      >
        <amap-satellite-layer :visible="satellite"/>
        <amap-marker v-if="position" ref="mapMarker" :position.sync="position"
                     :label="{
                      content: SearchAddress.formattedAddress,
                       direction: 'bottom',
                  }"/>
        <div class="operation" style="margin-bottom: 20px;">
          <div class="operation-box" @click="addressPositon()">
            <van-icon name="location"/>
            <p>定位</p>
          </div>
        </div>
      </amap>
      <van-popup v-model="searchH" position="bottom" :overlay="false" closeable :style="{ height: '30%' }">
        <van-list
            v-if="list.length > 0"
            v-model="loading"
            :finished="finished"
            finished-text="没有更多了"
            @load="onLoad"
        >
          <van-cell v-for="item in list" :key="item.id" :title="item.name" :label="item.address" @click="goMap(item)"/>
        </van-list>
        <div class="noAd" v-else>
          搜索不到地址,请重新输入
        </div>
      </van-popup>
    </van-popup>
    <div class="operation" style="margin-bottom: 20px;">
      <div class="operation-box" @click="()=>{open=true}">
        <van-icon name="location"/>
        <p>定位</p>
      </div>
    </div>
  </div>
</template>

<script>
import DragRise from '@/components/action/drag-rise' // 拖拽升起组件
import {loadPlugins} from '@amap/amap-vue';
import axios from 'axios'
export default {
  name: "AddressAmap",
  components: {DragRise},
  props: {

    open: {
      default: false
    },
    TypeData: {
      type: Array,
      default: function () {
        return []
      }
    },
  },
  data() {
    return {
      map: null,
      value: null,
      BMap: null, // 地图组件是否就绪 地图实例
      h: window.innerHeight,
      ak: "xxxx",
      zoom: 14, // 画布大小
      center: null, // 画布中心位置
      location: "广东", // 搜索固定区域
      keyword: "", // 搜索内容
      SearchAddress: {address: "", point: null}, // 检索点详细信息
      point: null, // 点击地图设置家或学校位置
      nowAddress: {lng: 0, lat: 0}, // 当前定位位置
      type: false,
      address: {},
        addlist: {},
      addressName: '',
      satellite: false,
      position: null,
      list: [],
      loading: false,
      finished: false,
      searchH: false,
      pageSize: 15,
      pageIndex: 1,
      searchState: false,

    }
  },
  watch: {
    // 检索点详细信息
    keyword(newValue) {
      //  this.$refs.dragRise.shrink();
      // let Hei = this.$refs.dragRise.Hei - 34;
      // console.log('this.$refs.dragRise.dragRiseHei', this.$refs.dragRise.dragRiseHei);
      let h = window.innerHeight * 2;
      let _this = this;
      let timer = null;
      console.log(newValue, 'asss');
      if (newValue === "") {
        _this.searchH = false;
        this.SearchAddress = {address: "", point: null};

      } else {
        this.searchAD(true);
        _this.searchH = true;

      }
    },
    async open(v) {

      if (v == true) {
        await loadPlugins(['AMap.AutoComplete', 'AMap.PlaceSearch', 'AMap.Geocoder', 'AMap.Geolocation']);
        this.ps = new AMap.PlaceSearch({
          pageSize: this.pageSize,
          city: '全国',
          citylimit: true,
        });
        this.ac = new AMap.AutoComplete()
          var options = {
              'showButton': false,//是否显示定位按钮
              'buttonPosition': 'LB',//定位按钮的位置
              /* LT LB RT RB */
              'buttonOffset': new AMap.Pixel(10, 20),//定位按钮距离对应角落的距离
              'showMarker': true,//是否显示定位点
              'markerOptions':{//自定义定位点样式,同Marker的Options
                  'offset': new AMap.Pixel(-18, -36),
                  'content':'<img src="https://a.amap.com/jsapi_demos/static/resource/img/user.png" style="width:36px;height:36px"/>'
              },
              'showCircle': true,//是否显示定位精度圈
              'circleOptions': {//定位精度圈的样式
                  'strokeColor': '#0093FF',
                  'noSelect': true,
                  'strokeOpacity': 0.5,
                  'strokeWeight': 1,
                  'fillColor': '#02B0FF',
                  'fillOpacity': 0.25
              }
          }
          this.geocoder = new AMap.Geocoder(options)
          console.log(this.$refs.myMap,'this.$refs.myMapthis.$refs.myMap');

         this.addressPositon()
        // this.WXlocation()
          console.log('geocoder', )



      }

    }
  },
  mounted() {
      axios.get()
    this.$nextTick(() => {
      this.$refs.dragRise.load() // 初始化组件
      this.mapcontent()

    })
  },
  methods: {
      //定位
      addressPositon() {
          var _this = this
          _this.wx.error(function (res) {
              console.log(res, '错误')
          })
          _this.wx.ready(function () {
              _this.wx.getLocation({
                  type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
                  success: function (res) {
                      console.log(res,'111');
                      var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
                      var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
                      var speed = res.speed; // 速度,以米/每秒计
                      var accuracy = res.accuracy; // 位置精度
                      // _this.form.coordinateLeft  = latitude
                      // _this.form.coordinateRight   =longitude
                      //_this.form.address=latitude+'-'+longitude
                      console.log( longitude,latitude, '定位11111')
                      var addegt=[]
                      addegt.push(longitude)
                      addegt.push(latitude)
                       axios.get('https://restapi.amap.com/v3/assistant/coordinate/convert',{
                           params: {
                               key:'xxxx',
                               coordsys:'gps',
                               locations:addegt.join(','),
                           }
                       }).then(res => {
                           console.log(res,res.data.locations,'sad');
                        var address=res.data.locations.split(',')

                           if (res.data.status == 1) {

                             var lat =address[1] // 纬度,浮点数,范围为90 ~ -90
                             var lng = address[0]// 经度,浮点数,范围为180 ~ -180。
                              _this.position=[lng,lat]
                               console.log(_this.position,'_this.position=_this.position=');
                               // this.position=[114.0705726454,22.71638671875]
                               _this.center = [lng,lat];
                              _this.getAddress(_this.position)
                          }
                          // console.log(JSON.parse(res.msg),data)
                      })
                      // _this.wx.openLocation({
                      //            latitude: parseFloat(latitude), // 纬度,浮点数,范围为90 ~ -90
                      //             longitude: parseFloat(longitude), // 经度,浮点数,范围为180 ~ -180。
                      //             name: 'a', // 位置名
                      //             address: '', // 地址详情说明
                      //             scale: 18, // 地图缩放级别,整型值,范围从1~28。默认为最大
                      //             infoUrl: '', // 在查看位置界面底部显示的超链接,可点击跳转
                      //     success: function (res) {
                      //             console.log(res,'asas')
                      //     }
                      // });
                  }
              });
              // _this.$toast('定位')
          })
      },
        WXlocation() {
      console.log('点击定位')

        var options = {
            noIpLocate:0,
            noGeoLocation:0,
            useNative:true,
            'showButton': false,//是否显示定位按钮
            'buttonPosition': 'LB',//定位按钮的位置
            /* LT LB RT RB */
            'buttonOffset': new AMap.Pixel(10, 20),//定位按钮距离对应角落的距离
            'showMarker': true,//是否显示定位点
            'markerOptions':{//自定义定位点样式,同Marker的Options
                'offset': new AMap.Pixel(-18, -36),
                'content':'<img src="https://a.amap.com/jsapi_demos/static/resource/img/user.png" style="width:36px;height:36px"/>'
            },
            'showCircle': true,//是否显示定位精度圈
            'circleOptions': {//定位精度圈的样式
                'strokeColor': '#0093FF',
                'noSelect': true,
                'strokeOpacity': 0.5,
                'strokeWeight': 1,
                'fillColor': '#02B0FF',
                'fillOpacity': 0.25
            }
        }


        // var geolocation = new AMap.Geolocation(options)
        //     this.$nextTick(()=>{
        //         var geolocation = new AMap.Geolocation(options);
        //         this.$refs.myMap.$map.addControl(geolocation);
        //         geolocation.getCurrentPosition((status,result)=>{
        //             if(status=='complete'){
        //                 console.log(result,'aaaaa');
        //               this.position=[result.position.lng,result.position.lat]
        //               // this.position=[114.0705726454,22.71638671875]
        //                 this.getAddress(this.position)
        //             }else{
        //
        //             }
        //         });
        //     })


    },
    goMap(val) {
      this.keyword = '';
      this.center = [val.location.lng, val.location.lat];
      this.position = [val.location.lng, val.location.lat];
      this.getAddress(this.position);
    },
    onMapClick(e) {
      if (e.lnglat) {
        this.position = [e.lnglat.lng, e.lnglat.lat];
        this.center = [e.lnglat.lng, e.lnglat.lat];
        this.getAddress(this.position)
      } else {
        this.position = null;
      }
    },
    mapcontent() {
    },
    onCancel() {
    },
    searchAD(state) {
      console.log(state)
      if (state) {
        this.searchState = true;
        //     this.$refs.searchList.scrollTo(0, 0, true);
        this.finished = false;
        this.pageIndex = 1;
        this.ps.setPageIndex(this.pageIndex);
        this.ps.search(this.keyword, (status, result) => {
          this.searchState = false;
          this.loading = false;
          console.log(status, result);
          // this.searching = false;
          // if (query !== this.query) return;
          if (status === 'complete' && result.poiList) {
            this.list = result.poiList.pois;
            if (this.list.length < 15) {
              this.finished = true
            }
          } else {
            this.list = [];
            this.finished = true
          }
        });
      } else {
        this.pageIndex += 1;
        this.ps.setPageIndex(this.pageIndex);
        this.ps.search(this.keyword, (status, result) => {
          this.loading = false;

          // this.searching = false;
          // if (query !== this.query) return;
          if (status === 'complete' && result.poiList) {
            this.list = this.list.concat(result.poiList.pois);
            console.log(status, result)
          } else {
            this.finished = true
            // this.results = [];
            // this.total = 0;
          }
        });
      }
    },
    AddOrUpdate() {

    },
    onLoad() {
      this.searchAD(false);
    },
    /**
     * 根据经纬度获取位置信息
     * @param position
     */
    getAddress(position) {
      console.log(position, 'position');
      var this_ = this;
      this.geocoder.getAddress(position, function(status, result) {
        if (status === 'complete' && result.regeocode) {
          this_.SearchAddress = result.regeocode;
          this_.$refs.mapMarker.label = {
            content: this_.SearchAddress.formattedAddress,
            direction: 'bottom',
          };
          console.log('status', status);
          console.log('result', result)
            this_.addressName= this_.SearchAddress.formattedAddress
            this_.addlist={poresultsition: position, result: result}
          //    this_.searchH=true
        } else {
          this_.SearchAddress = {
            formattedAddress: '高德暂无此地址信息'
          }
        }
      })
    },
    onSearch(v) {


      //输入提示
      var autoOptions = {
        input: "tipinput"
      };
      var auto = new AMap.Autocomplete(autoOptions);
      var placeSearch = new AMap.PlaceSearch({
        map: this.map
      });  //构造地点查询类
      AMap.event.addListener(auto, "select", select);//注册监听,当选中某条记录时会触发
      function select(e) {
        placeSearch.setCity(e.poi.adcode);
        placeSearch.search(e.poi.name);  //关键字查询查询
      }
    },
    closeAlertDialog(v) {
      this.open=false
      this.$emit('closeDialog', false)

    },
      OKAlertDialog(v) {
      this.open=false
          this.$emit('change',this.addlist)


    },
    SetADDoptions() {
    },
  }
}
</script>

<style scoped lang="less">
#panel {
  position: absolute;
  background-color: white;
  max-height: 30%;
  overflow-y: auto;
  top: 10px;
  right: 10px;
  width: 280px;
}

.noAd {
  color: silver;
  text-align: center;
  margin: 14px 0px;
}

.search-list {
  z-index: 999;
  position: fixed;
  width: 100%;
  overflow: auto;
  bottom: 0;
  background-color: white;
  transition: 0.6s;
}

.AddreseSearch {
  z-index: 2010;
  position: fixed;
  top: 0px;
  width: 100%;

  .van-search__content, .van-search__content--square {
    background-color: #F6F6F6 !important;
  }

  .van-cell, .van-cell--borderless, .van-field {
    background-color: #F6F6F6 !important;
  }
}

// 搜索框
.btnMap {
  padding-top: 6px;
  overflow: hidden;
  font-size: 12px;

  button {
    height: 35px;
    line-height: 35px;
    width: 95px;
  }

  button:nth-child(1) {
    float: left;
    margin-left: 10px;
  }

  button:nth-child(2) {
    float: right;
    margin-right: 10px;
  }
}

// 修改保存按钮
.WatchAdderss_menu {
  z-index: 99;
  position: fixed;
  bottom: 25px;
  left: 10px;

  div {
    width: 40px;
    height: 40px;
    padding: 6px;
    margin: 6px;
    background-color: #8dc63f;
    border-radius: 5px;
    text-align: center;

    p {
      color: rgba(25, 31, 37, 0.56);
    }

    img {
      margin-top: 3px;
      width: 18px;
      height: 18px;
    }
  }
}

.operation {
  position: fixed;
  bottom: 20px;
  right: 20px;
  border-radius: 10px;
  box-shadow: 1px 2px 4px #bbbbbb;
// background-color: #fffdef;
  .operation-box {
    padding: 12px;
    text-align: center;
    font-size: 14px;
    color: #707070;
  }
}

// 菜单样式

</style>

三、拖拽组件,vantUI

代码如下(示例):

//DragRise
<template>
    <div class="dragRiseHei" :style="{ top: '-' + dragRiseInitial + 'px', boxShadow: searchFig ? '0px 0px 2px #bbbbbb' : '' }" >
        <div ref="dragRiseVal">
            <!--<div class="interval-8 back-default"/>-->
            <div class="dragRiseVal" :style="{ height: dragRiseVal !== 0 ? dragRiseVal+ 'px' : ''}">
                <slot name="value"></slot>
            </div>
        </div>
        <div ref="dragRiseInitial" style="overflow: hidden">
            <div style="overflow: hidden">
                <slot name="title"></slot>
            </div>
            <img class="dragRiseHei_img" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend" :class="searchFig ? 'dragRiseHei_imgFZ' : ''"
                  src="require('@/assets/map/ic_sl.png')">
        </div>
    </div>
</template>

<script>
export default {
  data () {
    return{
      Hei: 0, // 记录初始高度
      clientY: 0, // 记录滑动距离
      dragRiseInitial:0, // 初始高度、以及改变的高度
      dragRiseVal: 0, // 内容高度
      dragRiseHei: 0, // 组件高度
      dragState: false,
      searchFig: false, // 搜索升起或隐藏
    }
  },
  created () {},
  watch: {
    clientY (val, oldVal) {
      let H = this.dragRiseVal // 页面可视高度
      if (oldVal !== 0 && this.dragRiseInitial <= H) {
        let num = Math.abs(oldVal - val) > 50 ? 30 : oldVal - val
        this.dragRiseInitial += num
        if (this.dragRiseInitial < 0) { this.dragRiseInitial = 0 }
        if (this.dragRiseInitial > H) { this.dragRiseInitial = H }
      }
    }
  },
  methods: {
    open () {
      this.searchFig = true
    },
    load () {
      const THIS = this // 页面渲染比数据渲染快需要稍等一下
      setTimeout(function () {
        const Height = document.body.clientHeight // 页面可视高度
        THIS.Hei = (THIS.$refs.dragRiseInitial.offsetHeight)
        // THIS.dragRiseInitial = (THIS.$refs.dragRiseVal.offsetHeight)
        THIS.dragRiseVal = THIS.$refs.dragRiseVal.offsetHeight
          // console.log('wudi3', THIS.dragRiseVal)
        // 组件高度等于初始高度 + 内容高度
        THIS.dragRiseHei = THIS.dragRiseVal + THIS.Hei
          console.log('dragRiseHei', THIS.dragRiseHei)
        // 当组件高度大于页面高度时重新内容高度赋值
        if (THIS.dragRiseHei > Height) {
          THIS.dragRiseHei = Height // 组件高度
          THIS.dragRiseVal = Height - THIS.dragRiseInitial // 得出内容高度
        }
      }, 200)
    },
    touchstart () {
    },
    touchmove (e) {
        this.dragState = true
      let H = this.dragRiseVal
      if (this.dragRiseInitial - Math.ceil((H + 20) / 2) > 0) {this.searchFig = true } else { this.searchFig = false }
      // 当拉起高度高于元素高度时禁止拉动
        console.log(this.dragRiseInitial,this.dragRiseVal);
        if (this.dragRiseInitial <= this.dragRiseVal) {
          console.log('wudi2', H)
          this.clientY = e.touches[0].clientY
      } else {
          this.dragRiseInitial = this.dragRiseVal
      }
    },
      animation () {
          let H = this.dragRiseVal;
          let _this = this
          let timer = null
          timer = requestAnimationFrame(function fn () {
              if (_this.searchFig) {
                  if (_this.dragRiseInitial < H) {
                      _this.dragRiseInitial += 20;
                      timer = requestAnimationFrame(fn)
                  } else {
                      _this.dragRiseInitial = H;
                      cancelAnimationFrame(timer)
                  }
              } else {
                  console.log('fig', _this.dragRiseInitial, _this.Hei)
                  if (_this.dragRiseInitial > 0) {
                      _this.dragRiseInitial -= 20;
                      timer = requestAnimationFrame(fn)
                  } else {
                      _this.dragRiseInitial = 0;
                      cancelAnimationFrame(timer)
                  }
              }
          })
      },
    shrink() {
      this.searchFig = true
      this.animation()
    },
    touchend (fig) {
      let H = this.dragRiseVal
      let _this = this
        if (this.dragState) {
            if (fig) {
                if (this.dragRiseInitial - Math.ceil((H + 20) / 2) > 0) { _this.searchFig = true } else {  _this.searchFig = false }
            } else { _this.searchFig = false }
        } else {
            this.searchFig = !this.searchFig
        }
        this.dragState = false
        this.animation()
    },
  },
}
</script>

<style lang="less" scoped>
.dragRiseHei{
    overflow: hidden;
    position: fixed;
    top: 0px;
    width: 100%;
    border-radius: 0px 0px 10px 10px;
background-color: red;
    .dragRiseHei_img{
        display: block;
        margin: 0 auto;
        padding: 12px 120px;
        position: relative;
        width: 40px;
        height: 12px;
    }
    .dragRiseHei_imgFZ {
        transform:rotate(180deg);
        -ms-transform:rotate(180deg); /* Internet Explorer */
        -moz-transform:rotate(180deg); /* Firefox */
        -webkit-transform:rotate(180deg); /* Safari 和 Chrome */
        -o-transform:rotate(180deg); /* Opera */
    } /* 水平镜像翻转 */
    .dragRiseVal{
      overflow:auto;
    }
}
</style>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值