微信小程序地图开发,选择省市区,拖动地图选择地址,显示周边,关键字搜索

用到的图片
在这里插入图片描述
预览图
在这里插入图片描述在这里插入图片描述在这里插入图片描述
HTML

<!-- pages/map1/index.wxml -->
<!-- 搜索位置 -->
<view class="map-search-wrap" wx:if="{{!show}}">
  <view catchtap='showProvince' class="map-district">{{currentDistrict}}</view>
  <view catchtap='showSearch' class="map-input-wrap">
    <input value='{{value}}' class="map-input" type="text" placeholder="请输入您的位置" />
  </view>
</view>
<!-- 显示选择省份城市区 -->
<view class="map-search-province" wx:if="{{show_1}}">
  <view class="map-flex-1">
    <view class="map-icon-1 iconfont icon-arrow-left-bold" catchtap='showProvince'></view>
    <view bind:tap='showFirst' class="s-p-wrap">{{currentProvince}}</view>
    <view wx:if="{{currentCity}}" bind:tap='filtersecondList' class="s-p-wrap">{{currentCity}}</view>
    <view style="width:60rpx" wx:if="{{!currentCity}}"></view>
    <view wx:if="{{currentDistrict}}" class="s-p-wrap">{{currentDistrict}}</view>
    <view style="width:60rpx" wx:if="{{!currentDistrict}}"></view>
  </view>
  <view style="height:80rpx"></view>
  <scroll-view scroll-y style="height:{{scrollviewHeigth}}px">
    <view class="p-scroll-wrap">
      <!-- 一级行政 -->
      <view wx:if="{{status==2}}"  bind:tap='changeDistrict' class="p-s-p-item" wx:for="{{citysList}}" wx:key="key" data-id='{{item.id}}' data-lat="{{item.location.lat}}" data-lng='{{item.location.lng}}' data-currentDistrict='{{item.fullname}}'>{{item.fullname}}</view>
      <!-- 二级行政 -->
      <view bind:tap='clickSecond' class="p-s-p-item" wx:if="{{status==1}}" wx:for="{{showSecond}}" wx:key="key" data-id='{{item.id}}' data-lat="{{item.location.lat}}" data-lng='{{item.location.lng}}' data-currentDistrict='{{item.fullname}}'>{{item.fullname}}</view>
      <!---->
      <view bind:tap='clickFirst' class="p-s-p-item" wx:if="{{status==0}}" wx:for="{{firstList}}" wx:key="key" data-id='{{item.id}}' data-lat="{{item.location.lat}}" data-lng='{{item.location.lng}}' data-currentDistrict='{{item.fullname}}'>{{item.fullname}}</view>
    </view>
  </scroll-view>
  <!-- {id: "510104", fullname: "锦江区", location: {lat: 30.598118, lng: 104.117356}}
1: {id: "510105", fullname: "青羊区", location: {lat: 30.67485, lng: 104.06291}} -->
</view>
<!-- 显示搜索列表 -->
<view class="map-search-list" wx:if="{{show}}">
  <view class="map-flex">
    <view class="map-icon iconfont icon-arrow-left-bold" catchtap='showSearch'></view>
    <view catchtap='showProvince' class="map-search-district">{{currentDistrict}}</view>
    <view class="map-search-input">
      <input bindinput='changeValue' value='{{value}}' type="text" placeholder="请输入您的位置" />
    </view>
  </view>
  <view bindtap='confirmContent' class="map-search-item" wx:for="{{keywordsList}}" wx:key="key" data-lat='{{item.location.lat}}' data-lng='{{item.location.lng}}' data-value='{{item.title}}' data-id='{{item.id}}' data-address='{{item.address}}' data-district='{{item.district}}'>
    <view class="m-s-t-1">{{item.title}}</view>
    <view class="m-s-t-2">{{item.address}}</view>
  </view>
</view>
<map wx:if="{{!show}}" id="myMap" style="width:100vw;height:50vh" longitude='{{longitude}}' latitude='{{latitude}}' markers='{{markers}}' bindregionchange="mapChange">
  <image class="current-site-icon" src="../../images/current.png"></image>
  <view class="reload" bindtap="reload">
    <view class="center1">
      <view class="center2"></view>
    </view>
  </view>
</map>
<scroll-view class="nearlist" scroll-y wx:if="{{!show}}">
  <view bindtap='selectAddress' wx:for="{{nearList}}" wx:for-index="index" wx:key="key" class="map-item-wrap" data-lat='{{item.latitude}}' data-lng='{{item.longitude}}' data-index='{{index}}' data-title='{{item.title}}' data-province='{{item.province}}'>
    <view style="width: 10%;">
      <view wx:if="{{currentIndex==index}}" class="map-icon-wrap">
        <image style="width:100%;height:100%" src="../../images/current.png"></image>
      </view>
    </view>
    <view class="map-item-text-wrap">
      <view class="map-nearitem-text1" style="color:{{currentIndex==index?'#287ff0':''}}">
        {{item.title}}
      </view>
      <view class="map-nearitem-text2" style="color:{{currentIndex==index?'#287ff0':''}}">
        {{item.address}}
      </view>
    </view>
  </view>
</scroll-view>
<view class="btn-wrap" wx:if="{{!show}}">
  <view class="btn-confirm" bindtap='confirm'>确定选择</view>
</view>

CSS

/* pages/map1/index.wxss */
.current-site-icon {
    width: 70rpx;
    height: 70rpx;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
}
.reload {
  width: 80rpx;
  height: 80rpx;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 0 10rpx rgba(0,0,0,0.1);
  position: absolute;
  bottom: 30rpx;
  right: 30rpx;
}
.reload .center1 {
  width: 30rpx;
  height: 30rpx;
  border: 1rpx solid #3095F9;
  border-radius: 50%;
  margin: 24rpx auto;
}
.reload .center2 {
  width: 25rpx;
  height: 25rpx;
  background: #3095F9;
  border-radius: 50%;
  margin: 3rpx auto;
}
.nearlist {
  height: 50vh;
  box-sizing: border-box;
  border-top: 2rpx solid rgb(230, 223, 223);
  padding-bottom: 100rpx;
}
.map-icon-wrap {
  width: 50rpx;
  height: 50rpx;
  line-height: 50rpx;
}
.map-item-wrap {
  display: flex;
  align-items: center;
  padding: 20rpx;
  border-bottom: 2rpx solid rgb(223, 221, 221);
}
.map-nearitem-text1 {
  color: #282828;
  font-size: 32rpx;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* color:#287ff0; */
}
.map-nearitem-text2 {
  color: #707070;
  font-size: 24rpx;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* color:#287ff0; */
  margin-top: 20rpx;
}
.map-item-text-wrap {
  /* margin-left: 30rpx; */
  width: 90%;
}
.btn-wrap {
  width: 100%;
  background-color: white;
  height: 80rpx;
  position: fixed;
  bottom: 0rpx;
  color: white;
  box-sizing: border-box;
  display: flex;
  justify-content: center;
  align-items: center;
  padding-bottom: 20rpx;
}
.btn-confirm {
  width: 500rpx;
  height: 80rpx;
  background-color: #3095F9;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 32rpx;
  border-radius: 20rpx;
}
.map-input-wrap {
  display: flex;
  justify-content: center;
  align-items: center;
}
.map-search-wrap {
  height: 70rpx;
  background-color: white;
  z-index: 1000;
  font-size: 28rpx;
  position: absolute;
  top: 20rpx;
  left: 0;
  right: 0;
  margin: 0 auto;
  width: 70%;
  display: flex;
  padding: 0rpx 30rpx;
  border-radius: 35rpx;
  border: 1rpx solid rgb(207, 203, 203);
}
.map-district {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 10rpx;
  border-right: 1rpx solid rgb(182, 179, 179);
  padding-right: 20rpx;
}
.map-search-list {
  width: 100vw;
  height: 100vh;
  background-color: white;
  z-index: 1001;
  position: absolute;
}
.map-search-district {
  background-color: #e2e2e2;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 0 20rpx;
  border-radius: 16rpx 0 0 16rpx;
  border-right: 1rpx solid rgb(165, 162, 162);
}
.map-search-input {
  width: 350rpx;
  height: 100%;
  background-color: #e4e4e4;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 0 20rpx;
  border-radius: 0 16rpx 16rpx 0;
}
.map-flex {
  display: flex;
  margin-top: 20rpx;
  justify-content: center;
  align-items: center;
  font-size: 28rpx;
  height: 90rpx;
  position: relative;
  padding-bottom: 30rpx;
  border-bottom: 2rpx solid rgb(190, 187, 187);
}
.map-icon {
  height: 100%;
  position: absolute;
  left: 40rpx;
  display: flex;
  align-items: center;
}
.map-search-item {
  font-size: 28rpx;
  /* line-height: 40rpx; */
  padding: 30rpx 50rpx;
  text-align: left;
  border-top: 1px solid #eee;
}
.m-s-t-1 {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: #282828;
}
.m-s-t-2 {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: #707070;
}
.map-search-province {
  width: 100vw;
  height: 100vh;
  background-color: white;
  z-index: 1001;
  position: absolute;
}
.map-flex-1 {
  display: flex;
  position: fixed;
  top: 0;
  height: 80rpx;
  border-bottom: 1rpx solid #b6b6b6;
  width: 100%;
  justify-content: space-between;
  align-items: center;
  font-size: 28rpx;
  padding: 0 50rpx;
  box-sizing: border-box;
}
.s-p-wrap {
  height: 60rpx;
  border-radius: 30rpx;
  border: 1rpx solid rgb(20, 110, 245);
  color: rgb(20, 110, 245);
  display: flex;
  justify-content: center;
  align-items: center;
  box-sizing: border-box;
  padding: 0 20rpx;
}
.p-scroll-wrap {
  height: 100%;
}
.p-s-p-item {
  font-size: 32rpx;
  padding: 20rpx 30rpx;
}

JS

// pages/map1/index.js
const app = getApp()
var QQMapWX = require('../../utils/qqmap-wx-jssdk.min.js');
Page({

  /**
   * 页面的初始数据
   */
  data: {
    //经度
    longitude: '',
    //纬度
    latitude: '',
    //当前位置
    currentAddress: '',
    //当前位置地点
    currentLocation: '',
    //周边
    pois: [],
    //周边设施标记点
    markers: [],
    //调用getlocation的时间戳
    getlocationTime: '',
    //周边列表显示数组
    nearList: [],
    //当前列表选中的下标
    currentIndex: 0,
    //当前地区
    currentDistrict: '',
    //显示或隐藏搜索页
    show: false,
    //显示或隐藏选择省份页
    show_1: false,
    scrollviewHeigth: 0,
    //当前行政区
    currentProvince: '',
    provinceId: '',
    //当前城市
    currentCity: '',
    //用户搜索输入
    value: '',
    //关键字搜索列表
    keywordsList: [],
    //搜索后选中id
    id: '',
    //当前城市选择列表
    citysList: [],
    //当一级行政区id
    firstId: '',
    //所有一级行政市
    firstList: [],
    //当前二级行政区id
    secondId: '',
    //所有二级行政市
    secondList: [],
    showSecond:[],
    status:2,
  },


  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    let self = this;
    self.mapCtx = wx.createMapContext('myMap', this)
    self.qqmapsdk = new QQMapWX({
      key: 'DYPBZ-A23WX-AJC43-T7YXW-W5NZV-MIBBJ'
    });
    this.CurrentLocation()
  },
  changeValue(e) {
    let self = this
    this.setData({
      value: e.detail.value
    }, _ => {
      self.searchKeywords(self.data.value)
    })
  },
  //点击搜索显示搜索页
  showSearch() {
    let self = this
    this.setData({
      show: !this.data.show,
      show_1: false
    }, _ => {
      // if (this.data.show) {
      //   this.getCitys()
      // }
    })
  },
  //点击搜索显示省份页
  showProvince() {
    let self = this
    this.setData({
      show_1: !this.data.show_1,
      show: false
    }, _ => {
      if (this.data.show_1) {
        wx.createSelectorQuery().select('.map-flex-1').boundingClientRect(rect => {
          self.setData({
            scrollviewHeigth: wx.getSystemInfoSync().windowHeight - rect.height
          }, _ => {
            // console.log(wx.getSystemInfoSync().windowHeight - rect.height)
          })
        }).exec();
        this.getCitys()
        this.currentCitys()
      }
    })
  },
  //搜索用户输入关键字
  searchKeywords(keyword) {
    let self = this
    this.qqmapsdk.getSuggestion({
      keyword,
      region: this.data.currentCity,
      success({ data }) {
        // console.log(data)
        let keywordsList = data
        self.setData({
          keywordsList
        })
      }
    })
  },
  //关键字搜索内容点击
  confirmContent(options) {
    let self = this
    // console.log(options.currentTarget)
    let { lat, lng, value, id, address, district, province } = options.currentTarget.dataset
    this.setData({
      latitude: lat,
      longitude: lng,
      show: false,
      value,
      id,
      markers: [],
      nearList: [],
      currentIndex: 0,
      //当前位置
      currentAddress: value,
      //当前位置地点
      currentLocation: address,
      //当前地区
      currentDistrict: district,
      //当前行政区
      currentProvince: province
    }, _ => {
      // console.log("=====")
      let nearList = []
      nearList.push({
        latitude: self.data.latitude,
        longitude: self.data.longitude,
        title: value,
        address: address,
      })
      // console.log(nearList)
      self.setData({
        nearList
      })
      // self.inverseTransform()
    })
  },
  //点击当前城市区列表
  changeDistrict(options){
    let self = this
    let {id,lat,lng,currentDistrict} = options.currentTarget.dataset
    this.setData({
      latitude: lat,
      longitude: lng,
      show_1: false,
      markers: [],
      nearList: [],
      currentIndex: 0,
      //当前地区
      currentDistrict,
    },_=>{
      self.inverseTransform()
    })
  },
  //获取当前城市列表
  currentCitys() {
    let self = this
    this.qqmapsdk.getDistrictByCityId({
      id: this.data.provinceId,
      success({ result }) {
        // console.log(result)
        self.setData({
          citysList: result[0]
        })
      }
    })
  },
  //获取城市列表
  getCitys() {
    let self = this
    this.qqmapsdk.getCityList({
      success({ result }) {
        // console.log(result)
        //获取一级行政区
        let firstList = result[0]
        //获取二级行政区
        let secondList = result[1]
        self.setData({
          firstList,
          secondList,
        })
      }
    })
  },
  //显示一级行政区
  showFirst(){
    this.setData({
      status:0
    })
  },
  //筛选二级行政区
  filtersecondList(){
    // console.log(this.data.secondId)
    let secondList = this.data.secondList
    // console.log(secondList)
    let newList = secondList.filter(value=>{
      if(value.id.substring(0,3)==this.data.secondId){
        return value
      }
    })
    this.setData({
      showSecond:newList,
      status:1
    })
    // console.log(newList)
  },
  //点击一级行政区
  clickFirst(options){
    let self = this
    let {id,lat,lng,currentdistrict} = options.currentTarget.dataset
    // console.log(options.currentTarget.dataset)
    this.setData({
      secondId:id.substring(0,3),
      status:1,
      currentProvince:currentdistrict,
      currentCity:'',
      currentDistrict:''
    },_=>{
      self.filtersecondList()
    })
  },
  //点击二级行政区
  clickSecond(options){
    let self = this
    // console.log(options.currentTarget.dataset)
    let {id,lat,lng,currentdistrict} = options.currentTarget.dataset
    this.setData({
      provinceId:id,
      status:2,
      currentCity:currentdistrict,
      currentDistrict:''
    },_=>{
      // console.log(this.data.currentCity)
      self.currentCitys()
    })
  },

  //确认选择
  confirm() {
    console.log('经度', this.data.longitude)
    console.log('纬度', this.data.latitude)
    console.log('当前位置', this.data.currentAddress)
    console.log('当前位置地点', this.data.currentLocation)
  },

  //列表点击事件
  selectAddress(options) {
    let { lng, lat, index, title } = options.currentTarget.dataset
    // console.log(options.currentTarget.dataset)
    this.setData({
      longitude: lng,
      latitude: lat,
      currentIndex: index,
      currentAddress: title
    })
  },

  //重新定位当前位置
  reload() {
    let newTime = new Date() - this.data.getlocationTime
    if (!this.data.getlocationTime || newTime >= 5000) {
      this.onLoad()
    } else {
      wx.showToast({
        title: '获取当前位置太频繁,请稍后再试',
        icon: 'none'
      })
    }
  },

  //移动地图事件
  mapChange(e) {
    let self = this;
    if (e.type == 'end' && e.causedBy == 'drag') {
      // console.log(1)
      self.mapCtx.getCenterLocation({
        success({ longitude, latitude }) {
          // console.log(longitude, latitude)
          self.setData({
            latitude,
            longitude,
            currentIndex: 0,
            value: ''
          }, _ => {
            self.inverseTransform()
          })
        }
      })
    }
  },

  //地址逆解析
  inverseTransform() {
    let self = this
    self.qqmapsdk.reverseGeocoder({
      location: {
        latitude: self.data.latitude,
        longitude: self.data.longitude
      },
      get_poi: 1,
      success({ result }) {
        // console.log('inverseTransform', result)
        let pois = result.pois
        let currentAddress = result.formatted_addresses.recommend
        // 当前位置地点
        let currentLocation = result.address
        // 当前地区
        let currentDistrict = result.address_component.district
        // 当前行政区
        let currentProvince = result.address_component.province
        let provinceId = result.ad_info.city_code.substring(3)
        let firstId = result.ad_info.adcode.substring(0, 3)
        // console.log(firstId)
        //当前城市
        let currentCity = result.address_component.city
        let markers = []
        //周边添加到markers中
        pois.forEach(value => {
          markers.push({
            id: value.id,
            latitude: value.location.lat,
            longitude: value.location.lng,
            title: value.title,
            address: value.address,
            width: 25,
            height: 40
          })
        })
        //构建周边列表+向数组第一位加入自己当前位置
        let nearList = [...markers]
        nearList.unshift({
          latitude: self.data.latitude,
          longitude: self.data.longitude,
          title: result.formatted_addresses.recommend,
          address: result.address,
        })
        self.setData({
          longitude: self.data.longitude,
          latitude: self.data.latitude,
          markers,
          currentAddress,
          currentLocation,
          nearList,
          currentDistrict,
          currentProvince,
          currentCity,
          id: '',
          provinceId,
          firstId,
          secondId:provinceId.substring(0, 3),
          status:2
        }, _ => {
          // console.log(self.data.provinceId)
        })
      }
    })
  },

  // 获取当前位置
  CurrentLocation() {
    wx.showLoading({
      title: '加载中',
    })
    //定位
    let self = this;
    wx.getLocation({
      type: 'wgs84',
      success(res) {
        let getlocationTime = new Date()
        const latitude = res.latitude
        const longitude = res.longitude
        //逆地址解析
        self.setData({
          latitude: latitude,
          longitude: longitude,
          getlocationTime,
        }, _ => {
          self.inverseTransform()
          wx.hideLoading()
        })
      },
      fail(err) {
        wx.hideLoading();
        wx.showToast({
          title: '定位失败',
          icon: 'none',
          duration: 1500
        })
        setTimeout(function () {
          wx.navigateBack({
            delta: 1
          })
        }, 1500)
      }
    })
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

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

  },

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

  },

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

  },

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

  },

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

  },

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

  }
})
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值