微信小程序实现地图自定义大小画圆以及地图自适应(iview-Weapp+微信开发者工具)

iview-Weapp

本项目中使用的UI为iview-Weapp,可在百度自行进入官网并根据文档下载并引入至项目,此处就不多说了。

具体实现

主要实现了在微信小程序下使用地图的marker点击弹出画圆,并根据圆的大小实现地图缩放的问题。
注意!!!:目前半径不可超过60KM,过大会导致进入死循环卡死,如有需要请自行更改代码。

实现的效果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

目录如下:
在这里插入图片描述
map.js代码:

注意:代码中 drawingnumber 的单位是m(米),drawingnumberKM所代表的的是KM(千米), getCrlcle()方法所计算出的当前缩放半径单位为KM

// pages/map/map.js
// pages/map/map.js
const {
  $Message
} = require('../../dist/base/index');
var QQMapWX = require('../../lib/qqmap-wx-jssdk.js');
var qqmapsdk;
var mapapp;
const app = getApp();
var EARTH_RADIUS = 6378.137; //地球半径

function rad(d) {
  return d * Math.PI / 180.0;
}

function getDistance(lng1, lat1, lng2, lat2) {
  var radLat1 = rad(lat1);
  var radLat2 = rad(lat2);
  var a = radLat1 - radLat2;
  var b = rad(lng1) - rad(lng2);
  var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
    Math.cos(radLat1) * Math.cos(radLat2) *
    Math.pow(Math.sin(b / 2), 2)));
  s = s * EARTH_RADIUS;
  s = Math.round(s * 10000) / 10000;
  return s; //返回数值单位:公里
};

Page({

  /**
   * 页面的初始数据
   */
  data: {
    longitude: "",
    latitude: "",
    markers: [],
    markerseeion:[],
    visible: false,
    drawingnumber: 0,
    drawingnumberKM: 0,
    circles: [],
    //点击标记点的经纬度
    markerlongitude: "",
    markerlatitude: "",
    scale: 16,
    //页面加载时的半径
    nowradius: 0,
    //地图加载
    mapload:false,
    //地图
    hidden:false,
    buttonhidden:true,
    localhidden:true,
    localplace:"",
    //判断getCrlcle方法走完没有
    Crlcleisfinish:false,
    markere:"",
    //调用查询当前地图半径方法位置(0:点击标记时  1:在得到地图缩放等级后)
    markerbechange:0
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function(options) {
    // this.getCrlcle();
    var that = this;
    qqmapsdk = new QQMapWX({
      key: '自行填写KEY'
    });
    //获取当前位置
    wx.getLocation({
      type: 'gcj02',
      success: function(res) {
        var latitude = res.latitude
        var longitude = res.longitude
        that.setData({
          latitude: latitude,
          longitude: longitude
        })
        console.log(latitude+"纬度")
        console.log(longitude + "精度")
        //逆地址坐标解析
        qqmapsdk.reverseGeocoder({
          location: {
            latitude: latitude,
            longitude: longitude
          },
          success: function (addressres){
            var address = addressres.result.formatted_addresses.recommend;
            that.setData({
              localplace:address
            })
          },
          fail:function(err){
            var errr=err.message;
            console.log(errr+"进来错误了")
          }
        })
      }
    })
    //定义个marker,并设置点击事件
    var getmarkers = []; 
    var allmarkersession=[];
    app.wxRequest("GET","/markers/getAllMarkers",{},(res)=>{
      var usermarkers=res;
      console.log(res);
      for (var i = 0; i < usermarkers.length;i++){
        allmarkersession.push(usermarkers[i]);
        //如果是指挥中心
        if (usermarkers[i].type==0){
            getmarkers.push({
              id: parseInt(usermarkers[i].id),
              iconPath: "/images/CommandingOrganization.png",
              longitude: usermarkers[i].longitude,
              latitude: usermarkers[i].latitude,
              width: 50,
              height: 50,
            })
          }
        //如果是器材库
        if (usermarkers[i].type == 1) {
          getmarkers.push({
            id: parseInt(usermarkers[i].id),
            iconPath: "/images/Equipment.Repository.png",
            longitude: usermarkers[i].longitude,
            latitude: usermarkers[i].latitude,
            width: 50,
            height: 50,
          })
        } 
        //如果是重点保护目标
        if (usermarkers[i].type == 2) {
          getmarkers.push({
            id: parseInt(usermarkers[i].id),
            iconPath: "/images/Key.Protection.Objectives.png",
            longitude: usermarkers[i].longitude,
            latitude: usermarkers[i].latitude,
            width: 50,
            height: 50,
          })
        }
        //如果是应急力量
        if (usermarkers[i].type == 3) {
          getmarkers.push({
            id: parseInt(usermarkers[i].id),
            iconPath: "/images/Emergency.Force.png",
            longitude: usermarkers[i].longitude,
            latitude: usermarkers[i].latitude,
            width: 35,
            height: 35,
          })
        }
      }
      that.setData({
        markers: getmarkers,
        mapload: true,
        localhidden:false,
        markerseeion: allmarkersession
      })
    },(err)=>{
      console.log("错误信息"+err.errMsg);
    })
    if (this.data.Crlcleisfinish){
      this.setData({
        Crlcleisfinish:false
      })
    }

  },
  //点击标记点
  markertap(e) {
    this.setData({
      markere:e,
      markerbechange:0
    })
    this.getCrlcle();
  
  },
  //点击确定关闭画圆选择
  handleCloseOK() {
    //判断异步是否执行完了
    console.log(this.data.Crlcleisfinish + "当前状态")
    console.log(this.data.hidden + "当前状态2")
    var that=this;
    if (this.data.Crlcleisfinish) {
      mapapp.getScale({
        success:function(res){
          var scale=res.scale;
          console.log("这是当前的缩放等级"+scale);
          var nowscale = scale + 1
          console.log("这是当前的缩放等级+2" + nowscale);
          that.setData({
            scale: scale,
            Crlcleisfinish: false,
            markerbechange: 1
          },
          ()=>{
            that.getCrlcle();
          }
          )
          console.log("点击后的半径" + that.data.nowradius)
    //首先清空原来的圆
    var clearCircles = [];
          that.setData({
      circles: clearCircles,
    });
    //计算当前地图缩放级别是否过小或者过大
      var frequency=0;
    while (true) {
      frequency = frequency+1;
      if (frequency>50){
        console.log("===========超过50次退出==============")
        frequency=0;
        break;
      }
      console.log("当前的地图半径" + that.data.nowradius)
      console.log("当前的选择画圆的半径" + that.data.drawingnumberKM)
      if (that.data.drawingnumberKM == 0) {
        var thescale = 15;
        frequency = 0;
        that.setData({
          scale: thescale
        })
        break;
      } else if (that.data.nowradius < that.data.drawingnumberKM) {
        var thescale = that.data.scale - 1;
        var thenowradius = that.data.nowradius * 2;
        that.setData({
          scale: thescale,
          nowradius: thenowradius
        })
      } else if (that.data.nowradius > that.data.drawingnumberKM * 2) {
        var thescale = that.data.scale + 1;
        var thenowradius = that.data.nowradius / 2;
        that.setData({
          scale: thescale,
          nowradius: thenowradius
        })
      } else {
        frequency = 0;
        break;
      }

    }

    //定义一个圆
    var drawCircles = [{
      latitude: that.data.markerlatitude,
      longitude: that.data.markerlongitude,
      color: '#FF0000DD',
      fillColor: '#7cb5ec88',
      //半径为M
      radius: that.data.drawingnumber,
      strokeWidth: 1
    }]
    //将当前中心点定位到画圆的marker
          if (that.data.drawingnumberKM==0){
            that.setData({
        hidden: false,
        visible: false,
        buttonhidden: true,
        localhidden: false,
        circles: drawCircles,
        longitude: that.data.markerlongitude,
        latitude: that.data.markerlatitude
      });
    }
    else{
            that.setData({
        hidden: false,
        visible: false,
        buttonhidden: false,
        localhidden: true,
        circles: drawCircles,
              longitude: that.data.markerlongitude,
              latitude: that.data.markerlatitude
      });
    }


        }
      })


//if的结尾符
    }

    


  },
  //点击取消关闭画圆选择
  handleCloseCancel() {
    this.setData({
      hidden: false,
      visible: false,
      Crlcleisfinish:false
    });
    // console.log(this.data.drawingnumber+"取消关闭");
  },
  //监听圆输入框的范围大小
  drawingnumberchange({
    detail
  }) {
    this.setData({
      drawingnumberKM: detail.value,
      drawingnumber: detail.value * 1000
    })
  },

//抽屉遮罩层'取消'关闭
  drawerclose(){
  this.setData({
    drawervisible:false
  })
  },
  //抽屉遮罩层'确定'关闭
  drawerclose() {
    this.setData({
      drawervisible: false
    })
  },

  //计算当前屏幕的半径
  getCrlcle() {
    var that = this;
    var mapradius1 = 0;
    mapapp = wx.createMapContext('map')
    mapapp.getRegion({
      success: function(res) {
        let lng1 = res.northeast.longitude;
        let lat1 = res.northeast.latitude;
        let lng2 = res.southwest.longitude;
        let lat2 = res.southwest.latitude;
        let longitude = lng1 - lng2;
        let latitude = lat1 - lat2;
        let flag = longitude > latitude ? true : false;
        let radius = 0;
        //计算得到短边,除2得到半径,*0.8优化显示,让圈圈只占界面的80%
        if (flag) {
          radius = getDistance(lng1, lat1, lng1, lat2) / 2 * 0.8;
        } else {
          radius = getDistance(lng1, lat1, lng2, lat1) / 2 * 0.8;
        }
        mapradius1 = radius;
        console.log(radius+" 当前地图的半径")
        that.setData({
          nowradius: radius,
          Crlcleisfinish:true
        })
        var allmarkers = that.data.markerseeion;
        //如果不是应急力量(人员),则打开画圆
        for (var i = 0; i < allmarkers.length; i++) {
          if (allmarkers[i].id == that.data.markere.markerId) {
            if (allmarkers[i].type != 3) {
              if(that.data.markerbechange==0){
              that.setData({
                hidden: true,
                visible: true,
                markerlongitude: allmarkers[i].longitude,
                markerlatitude: allmarkers[i].latitude
              })
              }
              else{

              }
            }
          }
        }

      },
    });

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function() {

  }
})

map.json代码:

{
  "usingComponents": {
    "i-modal": "../../dist/modal/index",
    "i-input-number": "../../dist/input-number/index",
    "i-drawer": "../../dist/drawer/index",
    "i-button": "../../dist/button/index"
  }
}

map.wxml代码:

<!--pages/map/map.wxml-->
<!--pages/map/map.wxml-->
<view>
<!-- <view>地图展示</view> -->
<map hidden="{{hidden}}" id="map" style="width: 100%"  class="container" longitude="{{longitude}}" latitude="{{latitude}}" bindmarkertap="markertap" show-location="true" 
markers="{{markers}}"  circles="{{circles}}" bindregionchange="regionchange" 
scale="{{scale}}" wx:if="{{mapload}}" ></map>
<i-modal title="选择画圆半径(单位为KM)" visible="{{ visible }}"  
  bind:ok="handleCloseOK" bind:cancel="handleCloseCancel">
   <view style="padding: 16px">
        <i-input-number value="{{ drawingnumberKM }}" min="0" max="60" bindchange="drawingnumberchange" />
    </view>
</i-modal>
<view class="mapbutton" >
<view hidden="{{buttonhidden}}">
<i-button bind:click="handleClick" type="primary">选择人员</i-button>
</view>
<view class="localin" hidden="{{localhidden}}">
<view class="local">当前位置</view>
<view class="place">{{localplace}}</view>
</view>
</view>
</view>

map.wxss代码:

//如有需要可自行增加样式
//此样式必须存在,否则会导致地图显示失败
.container {
height: 90vh
} 
.mapbutton{
height: 7vh
}
::-webkit-scrollbar {
display: none;
}
.local{
  font-weight: bold;
   font-size: 23px;
   margin-left: 2px
}
.place{
  padding-top: 3px;
  color: #8a8a8a;
  font-size: 13px;
  margin-left: 2px
}

以上为具体示例,如果有问题可加qq:1016400304

  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值