微信小程序 循迹功能制作

规划地图的路径,实时获取用户当前的定位,进行路线循迹导航功能的开发:

效果图:

实现代码:




<map id="map" enable-satellite longitude="{{longitude1}}" latitude="{{latitude1}}" scale="{{scale}}" controls="{{controls}}" bindcontroltap="controltap" markers="{{markers}}" bindmarkertap="markertap" polyline="{{polyline}}" bindregionchange="regionchange" show-location style="width: 100%; height: 348px;">

</map>

<view class="title">路线:{{title}}</view>
<view style="margin-top: 20rpx;"></view>

<button type='primary' catchtap="start_dian">路线起点开始循迹</button>
<button type='primary' catchtap="end_dian">路线终点开始循迹</button>
<button type='primary' catchtap="dom">下载</button>
var that;
const app = getApp()
const util = require("../../utils/util.js")
const txt = require("../../utils/txt.js")
// const txt = require("../../utils/gcoord.js")
import gcoord from '../../utils/gcoord.js'
var polyline_points = [];
var x_PI = 3.14159265358979324 * 3000.0 / 180.0;

var PI = 3.1415926535897932384626;

var a = 6378245.0;

var ee = 0.00669342162296594323;
Page({
  data: {
    pageShow:false,
    scale:10,
    obj: {},
    longitude: 116.34665554470486,
    latitude: 39.9463560655382,
    in_val: '',
    showModalStatus: false,
    key: 'sadsad',
    markers: [{
      iconPath: "/img/map.png",
      id: 0,
      longitude: 116.34903966083392,
      latitude: 39.94907287783573,
      width: 30,
      height: 30
    }, {
      iconPath: "/img/map.png",
      id: 0,
      longitude: 116.3431299221213,
      latitude: 39.94493766291209,
      width: 30,
      height: 30
    }, {
      iconPath: "/img/map.png",
      id: 0,
      longitude: 116.34090281579688,
      latitude: 39.946849743723874,
      width: 30,
      height: 30
    }],
    polyline: [{
      points: [],
      color: "#3F51B5",
      width: 5,
    }],
  },
    dom(){
      wx.navigateTo({
        url: '../myList/myList',
      })
    },
  // 设置地图路线
  setMapXian() {
    var kmlLines = this.data.obj.kmlLines.points;
    kmlLines.forEach((item, idx) => {
      // if (idx <= 1000) {
        this.setMapItemPoints(item.longitude, item.latitude, idx)
      // }
    })
  },
  // 设置路线
  setMapItemPoints(longitude, latitude, idx) {
    var result = gcoord.transform(
      [longitude, latitude],    // 经纬度坐标
      gcoord.WGS84,                 // 当前坐标系(百度)
      gcoord.GCJ02); 
    console.log('result', result)
    var points = {
      longitude: result[0],
      latitude: result[1]
    }
    
    polyline_points.push(points)
    // console.log('设置路线', polyline_points, longitude, latitude)

    // 设置地图标记点
    if (idx == this.data.obj.kmlLines.points.length-1) {
      // 终点坐标
      this.setMapItemMarkers(result[0], result[1])
      this.setData({
        ['polyline[0].points']: polyline_points,
        zhongdian_longitude: result[0],
        zhongdian_latitude: result[1]
      })
    } else if (idx ==0){
      // 起点坐标
      this.setMapItemMarkers(result[0], result[1])
      this.setData({
        qidian_longitude: result[0],
        qidian_latitude: result[1]
      })
    }
  },

  // 从路线起点开始循迹
  start_dian() {
    var longitude1 = this.data.qidian_longitude
    var latitude1 = this.data.qidian_latitude
    this.setData({
      scale: 15,
      longitude1: longitude1,
      latitude1: latitude1,
    })
  },
  // 从路线终点开始循迹
  end_dian() {
    var longitude1 = this.data.zhongdian_longitude
    var latitude1 = this.data.zhongdian_latitude
    this.setData({
      scale: 15,
      longitude1: longitude1,
      latitude1: latitude1,
    })
  },
  // 点击当前位置
  now_loction() {
    var that=this;
    wx.getLocation({
      type: 'wgs84',
      success(res) {
        const latitude = res.latitude
        const longitude = res.longitude

        that.setData({
          longitude1: longitude,
          latitude1: latitude,
        })
      }
    })
  },
  // 导航
  daohang(daohang_latitude, daohang_longitude) {
    console.log(daohang_latitude, daohang_longitude)
    wx.openLocation({
      latitude: daohang_latitude,
      longitude: daohang_longitude,
      scale: 10
    })
  },
  // 导航到起点
  navigation_start_ll() {
    var trackPoints = this.data.obj.trackPoints
    var start_latitude = trackPoints[0].points.latitude
    var start_longitude = trackPoints[0].points.altitude
    this.daohang(start_latitude, start_longitude);
  },
  // 导航到终点
  navigation_end_ll() {
    var trackPoints = this.data.obj.trackPoints
    var end_latitude = trackPoints[1].points.latitude
    var end_longitude = trackPoints[1].points.altitude
    this.daohang(end_latitude, end_longitude);

  },
  onLoad(options) {
    var obj = {};
    console.log('txt:', txt)
    options.title = "洗马林长城导航轨迹";
    txt.forEach(item => {
      if (item.title == options.title) {
        console.log('1111111111111111')
        obj = item
      } else {
        console.log('22222222222222222', item.title, options, options.title)
      }
    })
    console.log('obj:', obj)
    this.setData({
      title: options.title,
      obj
    })

    var trackPoints = this.data.obj.trackPoints
    var start_latitude = trackPoints[0].points.latitude
    var start_longitude = trackPoints[0].points.altitude
    console.log('11111111',trackPoints,start_latitude, start_longitude)
    this.setData({
      latitude1: start_latitude,
      longitude1: start_longitude
    })

    this.setMapXian()
  },
  // 设置起点终点坐标
  setMapItemMarkers(longitude, latitude) {
    var obj_item = {
      iconPath: "/img/map.png",
      id: 0,
      longitude: longitude,
      latitude: latitude,
      width: 30,
      height: 30
    };
    var markers = this.data.markers;
    markers.push(obj_item);
    this.setData({
      markers
    })
    return obj_item;
  },
  // 设置地图绿色的点
  map_ll(nowTime) {
    const _locationChangeFn = res => {
      console.log('location change', res.latitude, res.longitude)
      if (nowTime) {
        nowTime = false
        this.setData({
          latitude1: res.latitude,
          longitude1: res.longitude
        })
      }
    }
    wx.onLocationChange(_locationChangeFn);
  },
  onShow() {
    this.getUserLocation();
  },
  markertap(e) {
    console.log(e.markerId)
    this.showModal(e.markerId)
  },
  controltap(e) {
    console.log(e.controlId)
  },
  getUserLocation() {
    wx.getSetting({
      success(res) {
        console.log(res)
        if (res.authSetting['scope.userLocationBackground']) {
          wx.startLocationUpdateBackground({
            success: (res) => {
              console.log('startLocationUpdate-res', res)
            },
            fail: (err) => {
              console.log('startLocationUpdate-err', err)
            }
          })
        } else {
          if (res.authSetting['scope.userLocation'] == false) {
            console.log('打开设置页面去授权')
          } else {
            wx.startLocationUpdateBackground({
              success: (res) => {
                console.log('startLocationUpdate-res', res)
              },
              fail: (err) => {
                console.log('startLocationUpdate-err', err)
              }
            })
          }
        }
      }
    })
  },
  //显示对话框
  showModal: function(idx) {
    //console.log(event.markerId);
    var myall = {
      longitude: this.data.list[idx].longitude,
      latitude: this.data.list[idx].latitude,
      tel: this.data.list[idx].linktel,
      name: this.data.list[idx].name,
      introduce: this.data.list[idx].introduce,
      linkName: this.data.list[idx].linkName,
      time: util.js_date_time(new Date().getTime() / 1000),
      id: idx,
    }
    this.setData({
      myall
    })
    var that = this;

    // 显示遮罩层
    var animation = wx.createAnimation({
      duration: 200,
      timingFunction: "linear",
      delay: 0
    })
    this.animation = animation
    animation.translateY(300).step()
    this.setData({
      animationData: animation.export(),
      showModalStatus: true
    })
    setTimeout(function() {
      animation.translateY(0).step()
      this.setData({
        animationData: animation.export()
      })
    }.bind(this), 200)
  },
  //隐藏对话框
  hideModal: function() {
    // 隐藏遮罩层
    var animation = wx.createAnimation({
      duration: 200,
      timingFunction: "linear",
      delay: 0
    })
    this.animation = animation
    animation.translateY(300).step()
    this.setData({
      animationData: animation.export(),
    })
    setTimeout(function() {
      animation.translateY(0).step()
      this.setData({
        animationData: animation.export(),
        showModalStatus: false
      })
    }.bind(this), 200)
  },
  calling: function(event) {
    var tel = this.data.myall.tel;
    wx.makePhoneCall({
      phoneNumber: tel,
      success: function() {
        console.log("拨打电话成功!")
      },
      fail: function() {
        console.log("拨打电话失败!")
      }
    })
  },
  nav_register() {
    wx.navigateTo({
      url: '../register/register',
    })
  },
  regionchange(e) {
    if (e.type == 'end' && (e.causedBy == 'scale' || e.causedBy == 'drag')) {
      // console.log(e)   
      var that = this;
      this.mapCtx = wx.createMapContext("map");
      this.mapCtx.getCenterLocation({
        type: 'gcj02',
        success: function(res) {
          var coordinate = that.gcj02towgs84(res.longitude, res.latitude)  ;
          console.log(coordinate, 2222)
          that.setData({
            lat2: res.latitude.toFixed(6),
            lng2: res.longitude.toFixed(6),
            circles: [{
              latitude: res.latitude,
              longitude: res.longitude,
              color: '#FF0000DD',
              fillColor: '#d1edff88',
              radius: 0, //定位点半径              
              strokeWidth: 1
            }]
          })
        }
      })
    }
  },
  out_of_china(lng, lat) {
    return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false);

  },
  gcj02towgs84(lng, lat) {
    var that = this;
    if (that.out_of_china(lng, lat)) {
      return [lng, lat]
    } else {
      var dlat = that.transformlat(lng - 105.0, lat - 35.0);
      var dlng = that.transformlng(lng - 105.0, lat - 35.0);
      var radlat = lat / 180.0 * PI;
      var magic = Math.sin(radlat);
      magic = 1 - ee * magic * magic;
      var sqrtmagic = Math.sqrt(magic);
      dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
      dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
      var mglat = lat + dlat;
      var mglng = lng + dlng;
      return [lng * 2 - mglng, lat * 2 - mglat]
    }
  },
  transformlat(lng, lat) {
    var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
    ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
    ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
    ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
    return ret
  },
  transformlng(lng, lat) {
    var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
    ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
    ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
    ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
    return ret
  },

})
map{
  margin-top: 30rpx;
}
button{
  margin-bottom: 10rpx;
  width: 80%;
  margin-left: 10%;

}
.title{
  margin: 30rpx;
  font-size: 45rpx;
}
.detail{
  margin-left: 30rpx;
  font-size: 38rpx;
  color: #999;
  margin: 20rpx 20rpx 20rpx 30rpx;
}
.top{
  padding: 30rpx;
}
.top view{
  margin-bottom: 10rpx;
  border-bottom: 1px solid;
}
input{
  margin-top: 10rpx;
}
.in_val{
  margin: 20rpx;
  border: 1px solid #d0d0d0;
  width: 340rpx;
  height: 60rpx;
  padding-left: 10rpx;
  border-radius: 5rpx;
}
.btn{
  height: 64rpx;
  margin-top: 20rpx;
  font-size: 30rpx;
  line-height: 64rpx;
}
.input_block{
  display: flex;
  flex-direction: row;
}
.aaa{
  margin-top: 20rpx;
  margin-left: 20rpx;
  background: darkorange;
  padding: 10rpx 30rpx 10rpx 30rpx;
  width: 200rpx;
  border-radius: 10rpx;
  color: white;
}
.bbb{
  top: 20rpx;
  margin-left: 20rpx;
  position: absolute;
  right: 30rpx;
  background: darkorange;
  padding: 10rpx 30rpx 10rpx 30rpx;
  width: 200rpx;
  border-radius: 10rpx;
  color: white;
}
.nav_register{
  background: #7DD43C;
  color: white;
  position: absolute;
  /* margin-top: 10rpx; */
  right: 30rpx;
  padding: 5rpx 20rpx 5rpx 20rpx;
  border-radius: 5rpx;
}
.nav_register2{
  background: #7DD43C;
  color: white;
  position: absolute;
  /* margin-top: 10rpx; */
  right: 230rpx;
  padding: 5rpx 20rpx 5rpx 20rpx;
  border-radius: 5rpx;
}
.c_icon{
  position: fixed;
  top: 50%;
  left: 50%;
  width: 50rpx;
  height: 60rpx;
  margin-top: -35rpx;
  margin-left: -30rpx;
}
/* index/index.wxss */
page{
  height: 100%;
}
.index_bt1{
  width: 100rpx;
  height: 100rpx;
  padding-top:30rpx;
  margin-left: 600rpx;
}

.xiaoer{
  width: 100rpx;
  height: 100rpx;
}

.index_shuaxin{
  width: 60rpx;
  height: 60rpx;
  padding-top: 860rpx;
  margin-left: 20rpx;
}

.shuaxin{
  width: 60rpx;
  height: 60rpx;
}

.sch{
  display: block;
	z-index: 999999;
  height: 69rpx;
  width:100%; 
  margin:0 auto;
  padding-top: 30rpx;
}

/*底部弹窗开始 -使屏幕变暗  */
.commodity_screen {
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  background: #000;
  opacity: 0.2;
  overflow: hidden;
  z-index: 1000;
  color: #fff;
}
/*对话框 */
.commodity_attr_box {
  height: 280rpx;
  width: 100%;
  overflow: hidden;
  position: fixed;
  bottom: 0;
  left: 0;
  z-index: 2000;
  background: #fff;
  padding-top: 0rpx;
}

.placeBox{
  width: 100%;
  height: 150rpx;
}

.placeViewLt{
  display: inline-block;
  width: 620rpx;
  height: 140rpx;

  vertical-align: middle;
}

.viewTitle{
  display: block;
  font-size: 38rpx;
  color: #3F51B5;
  margin-left: 20rpx;
  padding-top: 34rpx;
}

.viewDis{
  display: inline-block;
  font-size: 26rpx;
  color: gray;
  margin-left: 20rpx;
}

.viewAddr{
  display: inline-block;
  font-size: 28rpx;
  color: gray;
  margin-left: 20rpx;
}

.placeViewRt{
  display: inline-block;
  width: 120rpx;
  height: 120rpx;
  padding-top: 6rpx;
  vertical-align: middle;
}

.viewIcon{
  display: block;
  height: 100rpx;
  width: 100%;
  border-top: 1px solid #ebebeb;
  padding-top: 40rpx;
}

.indexIcon{
  display: inline-block;
  width: 50rpx;
  height: 50rpx;
  margin-left: 40rpx;
  margin-top: -26rpx;
  vertical-align: middle;
}

.timeText{
  display: inline-block;
  line-height: 45rpx;
  margin-left: 12rpx;
  text-align: center;
  width: 200rpx;
  height: 45rpx;
  background-color: rgb(230, 234, 255);
  border-radius: 10px;
  color: #3F51B5;
  font-size: 24rpx;
}

.indexIcon1{
  display: inline-block;
  width: 50rpx;
  height: 50rpx;
  margin-top: -10rpx;

  margin-left: 110rpx;
  vertical-align: middle;
}

.indexIcon2{
  display: inline-block;
  width: 50rpx;
  margin-top: -10rpx;
  height: 50rpx;
  margin-left: 20rpx;
  vertical-align: middle;
}

.timeText1{
  display: inline-block;
  line-height: 45rpx;
  margin-left: 12rpx;
  width: 100rpx;
  height: 45rpx;
  color: #3F51B5;
  font-size: 24rpx;
}

.timeText2{
  display: inline-block;
  line-height: 45rpx;
  margin-left: 12rpx;
  width: 200rpx;
  height: 45rpx;
  color: #3F51B5;
  font-size: 24rpx;
}
.btn-area{ width: 100%;}
.btn_no{ float:left;width: 40%; margin-left: 5%;border: 0px;}
.btn_ok{ float:left;width: 40%; margin-left: 10%;margin-right: 5%; border: 0px;}
发布了387 篇原创文章 · 获赞 774 · 访问量 183万+

猜你喜欢

转载自blog.csdn.net/qq_35713752/article/details/103683902