uni-app(微信小程序)编写小程序加载map地图总结

因为自己想在手机端开发一个应用要应用Vue框架,所以就想到了uni-app,其中一个模块就要加载地图并获取位置信息。这个uni官网给了api,调用也还方面,现就开发中的思路和几个关键方法进行说明,由于uni-app最开始就是以微信小程序为主的,所以他和微信开发者工具基本很类似,他们两个可以互相参考着学习。这里我还是以uni-app为主。

这里要特别注意的一点就是:绘制地图和获取位置信息是两件事。先获取位置信息,再将位置信息展现在地图上。


目录

1.绘制地图在手机端

2.获取位置

3.点击地图确定位置

4.效果图展示:

5.源码展示:

6.打包注意


1.绘制地图在手机端

直接将<map></map>标签放上去就可以通过浏览器F12看到一个小地图了,map标签的属性中中心经度longitude,中心纬度latitude,缩放级别scale是要给的,这些数据都放在data中,绑定在标签里,遵守vue以数据为中心驱动的方式。layer-style是腾讯地图中地图样式,可以不设定使用默认的,markers是用来标记你当前位置的。@tap用来获取你点击地图的操作的,后面会说。

详细信息属性看这里:https://uniapp.dcloud.io/component/map

这里有个小坑,就是你通过获取当前手机屏幕高度,宽度设置750rpx的方式想让地图全屏显示,在H5端调试确实没有问题,但是在HbuilderX中运行到真机基座上就会出现宽度不能填充的情况,无论你设置啥,宽度死活留白。后来发现只有在map标签中style设置width:100%,height:100vh。才能让地图在手机端满屏。

2.获取位置

获取位置在API中的位置模块里。注意的是这部分获取位置在H5端可能获取不到,官方说是因为请求的谷歌浏览器,谷歌被墙了。所以在调试这一块的时候一定要在手机上测试,使用HbuilderX上的真机运行调试基座。连接手机测试

app平台高德SDK仅支持返回gcj02 

下面看一下我都设置了那些参数:

 

这里说明一下,想获取address必须将geocode设置为true,在上面的data里。否则为空,要设置下timeout超时时间,这样不会无限请求位置。

基本思路就是先获取坐标,之后将坐标给map标签和markers各一份,就可以实现刚进入进行定位绘图功能。这里要注意下vue的生命周期函数执行的顺序时机问题。

3.点击地图确定位置

主要通过uni.chooseLocation接口

uni.chooseLocation({
    success: function (res) {
        console.log('位置名称:' + res.name);
        console.log('详细地址:' + res.address);
        console.log('纬度:' + res.latitude);
        console.log('经度:' + res.longitude);
    }
});

在map标签上注册tap事件,在对应的方法中调用这个接口即可。

4.效果图展示:

 

5.源码展示:

<!-- 获取位置的界面 -->
<template>
   <view class='objView'>
     <u-row class="myInfoRow">
       <u-col span='12' style="font-size:17px">
         经度:{
   
   {longitude}} &nbsp&nbsp 纬度:{
   
   {latitude}}
       </u-col>
     </u-row>
     <u-row class="myInfoRow">
       <u-col span='12'>
         <textarea v-show="geocode" disabled=true type="primary" :value='position' placeholder="未加载出位置信息"> </textarea>
       </u-col>
     </u-row>
     <u-row>
       <u-col span='6'>
          <u-button type="success" shape="square" @click="changePosition">刷新当前位置</u-button>
       </u-col>
       <u-col span='6'>
          <u-button type="success" shape="square" @click="returnPosition">返回定位位置</u-button>
       </u-col>
     </u-row><br/>
     <u-row>
        <!-- style内嵌标签的写法才能让app端地图全屏展示 -->
        <u-col span='12'>
           <map 
            id="myMap"
            ref="myMap"
            :longitude="longitude"
            :latitude="latitude" 
            :scale="scale"
            @tap='clickmap'
            :markers='covers'
            style="width: 100%; height: 100vh;"
            > 
          </map>
        </u-col>     
     </u-row>     
   </view>
</template>

<script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';

export default {
  //import引入的组件需要注入到对象中才能使用
  components: {},
  data() {
    //这里存放数据
    return {
      id:0,
      longitude:0,//记录实时点击位置
      latitude:0,   
      originalLongitude:0,//记录用户当前真实位置随时返回
      originalLatitude:0,
      scale:'16',
      //是否解析地址信息
      geocode:true,
      // 定位标记
      covers:[
        {
          longitude:this.longitude,
          latitude:this.latitude,
          iconPath: '../../static/imgs/nowPosition.png',
          width:30,
          height:30,
          label:{
            content:'当前位置',
            textAlign:'center',
            color:'#FB3109'
          }
        }
      ],
      //获取的地址信息
      position:'',
      //记录用户当前真实位置随时返回
      originalPosition:''
    };
  },
  //监听属性 类似于data概念
  computed: {},
  //监控data中的数据变化
  watch: {

  },
  //方法集合
  methods: {
    //点击地图时触发
    clickmap(info)
    {
      //console.log('点击地图时候触发',info),
      uni.chooseLocation({
        success: (res)=>{
          this.position='位置名称:'+res.name+'  详细地址:'+res.address;
          this.longitude=res.longitude;
          this.latitude=res.latitude;
          //为标记点经纬度重新赋值【在data中赋坐标的方式无效】
          this.covers[0].longitude=res.longitude;
          this.covers[0].latitude=res.latitude;
          // console.log('位置名称:' + res.name);
          // console.log('详细地址:' + res.address);
          // console.log('纬度:' + res.latitude);
          // console.log('经度:' + res.longitude);
        },
        fail:(err)=>{
          uni.showToast({
            title:'获取位置失败'
          });
        }     
      });
    },
    //返回原始定位位置
    returnPosition(){
      this.position=this.originalPosition;
      this.longitude=this.originalLongitude;
      this.latitude=this.originalLatitude;
      //为标记点经纬度重新赋值【在data中赋坐标的方式无效】
      this.covers[0].longitude=this.originalLongitude;
      this.covers[0].latitude=this.originalLatitude;
    },
    //点击更改坐标
    changePosition()
    {     
      this.longitude=this.longitude;
      this.latitude= this.latitude;
      console.log('坐标刷新成功');
      uni.showToast({
        title:'坐标刷新成功'
      });    
    }, 
    //获取定位信息
    getLocation()
    {
      uni.showLoading({
        title:'正在获取定位'
      });
      uni.getLocation(
      {
        type:"gcj02",
        timeout:'1000',
        geocode:this.geocode,
        success:(res) =>{
          uni.hideLoading();
          this.longitude=res.longitude;
          this.latitude=res.latitude;
          //把原始定位另存一份,便于返回
          this.originalLongitude=res.longitude;
          this.originalLatitude=res.latitude;
          //为标记点经纬度重新赋值【在data中赋坐标的方式无效】
          this.covers[0].longitude=res.longitude;
          this.covers[0].latitude=res.latitude;         
          //将地址信息进行存储
          let {address}=res
          let {country,province,city,district,street,streetNum,poiName}=address;
          // console.log('获取定位数据成功',res)
          //拼接地址
          let myPosition=country+'-'+province+'-'+city+'-'+district+'-'+street+'-'+streetNum+'-'+poiName;
          this.position=myPosition;
          //把原始定位另存一份,便于返回
          this.originalPosition=myPosition;
          //console.log(this.country,city)
        },
        fail:(err)=>{
          uni.hideLoading();
          uni.showModal({
            title:'提示',
            content:'位置信息获取失败(请确定定位功能是否打开)',
            showCancel:false
          });
        }
      },
    );
  }
},
  //生命周期 - 创建完成(可以访问当前this实例)
  created() {
    //获取位置信息
    this.getLocation();
  },
  //生命周期 - 挂载完成(可以访问DOM元素)
  mounted() {
    //获取当前地图的信息
    // let myMapInfo=this.$refs.myMap
    // console.log(myMapInfo)
  },
  beforeCreate() {}, //生命周期 - 创建之前
  beforeMount() {}, //生命周期 - 挂载之前
  beforeUpdate() {}, //生命周期 - 更新之前
  updated() {}, //生命周期 - 更新之后
  beforeDestroy() {}, //生命周期 - 销毁之前
  destroyed() {}, //生命周期 - 销毁完成
  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
  }
</script>


<style lang='css' scoped>
#myMap{
  width: 750rpx ;
}
/* 信息栏高度 */
.myInfoRow{
  height: 50px;
}
/* 让地址栏通栏展示 */
textarea{
  width: 100%;
}
</style>

6.打包注意

最后要注意的是,若打包发布要申请对应地图的key ,要是手机APP要申请高德地图的key,微信要申请腾讯地图的key。

不同端,使用地图选择时基于的底层地图引擎不一样,如微信小程序和H5是腾讯地图,App和阿里小程序是高德地图,百度小程序是百度地图,详见地图map组件的使用注意事项。app中也可以使用百度定位,在manifest中配置,打包后生效。但app-nvue里只能用百度定位,不能用百度地图。另外选择地图、查看地图位置的API也仅支持高德地图。所以App端如无特殊必要,建议使用高德地图。

详细参考在这里:https://uniapp.dcloud.io/component/map

猜你喜欢

转载自blog.csdn.net/qq_42539194/article/details/110925044