笔记来源:拉勾教育 - 大前端就业集训营
文章内容:学习过程中的笔记、感悟、和经验
提示:项目实战类文章资源无法上传,仅供参考
开发高德地图小项目
申请高德地图开发者
- 注册高德地图开发者账号:官网地址
- 创建应用:管理应用 => 我的应用 => 创建新应用
- 创建应用密钥:应用不同,密钥不同(安卓 / ios / web / 小程序)
详解高德微信小程序SDK
高德小程序SDK部分常用接口
API | 描述 |
---|---|
getWxLocation | 获取位置信息(通过高德API获取) |
getRegeo | 获取地理描述信息(将经纬度转成行政区划名称) |
getWeather | 当前位置的天气信息,数据较少建议使用和风天气 |
getPoiAround | 查询周围兴趣点(POI: Point of Interest),例如搜索 |
getStaticmap | 获取静态地图(不能拖动) |
getInputtips | 获取输入提示词(关键字查询) |
getWalkingRoute | 步行路线规划 |
getDrivingRoute | 驾车路线规划 |
getRidingRoute | 骑行路线规划 |
getTransitRoute | 公交地铁路线规划(和前三个参数有区别) |
高德地图的SDK中的接口函数大部实际上就是将小程序的云API进行二次封装的产物
首页接入高德地图
- 小程序启动时获取当前位置,并存到本地
- 拷贝高德SDK文件到项目中,并创建高德SDK配置文件
- 创建高德SDK实例对象,写入KEY,最后导出实例对象
- 首页页面加载时进行逆地址解析(高德 - getRegeo)获取实际地址
- 书写map地图组件,添加相关属性
- 首页js文件中解析之前存在本地的经纬度数据
- 直接使用高德返回的数据做定位点数据
- 调整样式,让地图全屏显示
- 添加底部地址栏,绝对定位,使用getRegeo返回数据
// app.json
{
"pages": [
// 添加一个页面
"pages/home/home",
"pages/index/index",
"pages/logs/logs"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "Weixin",
"navigationBarTextStyle": "black"
},
"style": "v2",
"sitemapLocation": "sitemap.json",
// 获取当前位置
"permission": {
"scope.userLocation": {
"desc": "尝试获取位置信息"
}
},
// 设置底部导航
"tabBar": {
"list": [{
"pagePath": "pages/home/home",
"text": "首页",
"iconPath": "./static/images/featured.png",
"selectedIconPath": "./static/images/featured-actived.png"
}, {
"pagePath": "pages/index/index",
"text": "欢迎",
"iconPath": "./static/images/featured.png",
"selectedIconPath": "./static/images/featured-actived.png"
}, {
"pagePath": "pages/logs/logs",
"text": "日志",
"iconPath": "./static/images/featured.png",
"selectedIconPath": "./static/images/featured-actived.png"
}]
}
}
// app.js
App({
onLaunch() {
// 展示本地存储能力
const logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
// 登录
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
}
})
// 获取当前位置
wx.getLocation({
type: 'gcj02',
// 成功后存储经纬度到本地
success (res) {
wx.setStorageSync('latitude', res.latitude)
wx.setStorageSync('longitude', res.longitude)
}
})
},
globalData: {
userInfo: null
}
})
// utils/amap-config.js 高德地图SDK配置
// 引入高德SDK
const amapfile = require('./amap-wx.130')
// 创建实例
const map = new amapfile.AMapWX({
key: '842828a8a2bce6537a91450390dd5471'
})
// 导出
module.exports = {
map
}
// pages/home/home.js
const amap = require('../../utils/amap-config')
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 存储this指向
const that = this
// 读取本地位置信息,存储进data
that.setData({
longitude: wx.getStorageSync('longitude'),
latitude: wx.getStorageSync('latitude')
})
// 调用高德逆地址解析,获取坐标的位置信息
amap.map.getRegeo({
// 成功调用
success: res => {
console.log(res);
// 使用数据作为标记信息
// 设置标记使用图片
res[0].iconPath = '/static/images/location.png'
// 存储标记数据到本地
that.setData({
markers: res
})
},
// 失败打印失败信息
fail: err => {
console.log(err)
}
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
<!--pages/home/home.wxml-->
<view class="container">
<!-- 地图组件,设置经纬度、标记点信息 -->
<map class="map" name="" longitude='{{longitude}}' latitude='{{latitude}}' markers='{{markers}}' scale="14"></map>
<!-- 底部浮动位置展示 -->
<view class="map-text">
<text>{{markers[0].name}}</text>
<text>{{markers[0].desc}}</text>
<view class="button-sp-area">
<a class="weui-btn weui-btn_mini weui-btn_primary">按钮</a>
</view>
</view>
</view>
/* pages/home/home.wxss */
/* // 首页单独设置样式 */
.container {
height: 100vh;
width: 100vw;
}
/* 地图 */
.map {
width: 100%;
height: 100%;
}
/* 底部文本 */
.map-text {
position: relative;
position: fixed;
left: 0;
bottom: 0;
width: 100%;
background-color: #fff;
/* text-align: center; */
}
.map-text > text {
display: block;
margin: 10px 20px;
}
.map-text > text:nth-child(2) {
font-size: 14px;
color: #666;
}
.map-text > .button-sp-area {
position: absolute;
right: 20px;
top: 50%;
margin-top: -16px;
}
输入提示
- 搜索框使用WEUI搜索框组件,拷贝js和WXML
- 在输入事件中添加逻辑,使用输入的内容调用API获取输入提示
- 可以把这个逻辑单独封装为一个函数
- 存储拿到的提示数据到data中
- 使用weUI的列表组件展示输入提示数据,如果有提示数据才显示
- 遍历数据列表,创建结构
- 可能会和之前写的文字提示冲突,把底部文字提示改成固定定位即可
- 添加判断条件,如果输入内容为空,清空数据,不为空才请求数据
- 记得取消按钮也要清空数据
/**app.wxss**/
/* 引入WeUI */
@import './weui.wxss';
.container {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
/* padding: 200rpx 0; */
box-sizing: border-box;
}
<!--pages/home/home.wxml-->
<view class="container">
<!-- 顶部搜索框 -->
<view class="page__bd">
<view class="weui-search-bar {{inputShowed ? 'weui-search-bar_focusing' : ''}}" id="searchBar">
<form class="weui-search-bar__form">
<view class="weui-search-bar__box">
<i class="weui-icon-search"></i>
<input type="text" class="weui-search-bar__input" placeholder="搜索" value="{{inputVal}}"
focus="{{inputShowed}}" bindinput="inputTyping" />
<span class="weui-icon-clear" wx:if="{{inputVal.length > 0}}" bindtap="clearInput"></span>
</view>
<label class="weui-search-bar__label" bindtap="showInput">
<i class="weui-icon-search"></i>
<span class="weui-search-bar__text">搜索</span>
</label>
</form>
<view class="weui-search-bar__cancel-btn" bindtap="hideInput">取消</view>
</view>
<view class="weui-cells searchbar-result" wx:if="{{inputVal.length > 0}}">
<!-- 遍历数据创建搜索提示结果 -->
<view class="weui-cell weui-cell_active weui-cell_access" wx:for="{{tips}}" wx:key='{{item.id}}}'>
<view class="weui-cell__bd weui-cell_primary">
<view>{{item.name}}</view>
</view>
</view>
</view>
</view>
<!-- 地图组件,设置经纬度、标记点信息 -->
<map class="map" name="" longitude='{{longitude}}' latitude='{{latitude}}' markers='{{markers}}' scale="14"></map>
<!-- 底部浮动位置展示 -->
<view class="map-text">
<text>{{markers[0].name}}</text>
<text>{{markers[0].desc}}</text>
<view class="button-sp-area">
<a class="weui-btn weui-btn_mini weui-btn_primary">按钮</a>
</view>
</view>
</view>
/* pages/home/home.wxss */
/* // 首页单独设置样式 */
.container {
height: 100vh;
width: 100vw;
}
/* 地图 */
.map {
width: 100%;
height: 100%;
}
/* 底部文本 */
.map-text {
position: relative;
position: fixed;
left: 0;
bottom: 0;
width: 100%;
background-color: #fff;
/* text-align: center; */
}
.map-text > text {
display: block;
margin: 10px 20px;
}
.map-text > text:nth-child(2) {
font-size: 14px;
color: #666;
}
.map-text > .button-sp-area {
position: absolute;
right: 20px;
top: 50%;
margin-top: -16px;
}
/* 搜索框 */
.page__bd {
width: 100%;
position: fixed;
top: 0;
left: 0;
z-index: 1;
}
.searchbar-result {
margin-top: 0;
font-size: 12px
}
.searchbar-result .weui-cell {
padding: 10px;
}
.searchbar-result .weui-cell__bd {
padding: 0 0 0 20px;
color: #999;
}
.searchbar-result:before {
display: none
}
// pages/home/home.js
const amap = require('../../utils/amap-config')
Page({
/**
* 页面的初始数据
*/
data: {
inputShowed: false,
inputVal: ""
},
// 点击电视搜索框时间事件函数
showInput: function () {
this.setData({
inputShowed: true
});
},
// 取消按钮点击事件函数
hideInput: function () {
this.setData({
inputVal: "",
inputShowed: false
});
},
// 清空按钮点击事件函数
clearInput: function () {
this.setData({
inputVal: ""
});
},
// 文本框输入事件
inputTyping: function (e) {
//存储输入内容
this.setData({
inputVal: e.detail.value
});
// 调用方法获取提示数据
this.getTips(e.detail.value)
},
// 获取输入提示数据
getTips: function (keywords) {
// 存储this指向
const that = this
// 调用高德方法获取输入提醒
amap.map.getInputtips({
// 输入内容
keywords,
// 位置信息
location: that.data.longitude + ',' + that.data.latitude,
// 成功后调用
success: (res) => {
// 如果获取成功存储数据
if(res && res.tips) that.setData({tips: res.tips})
console.log(that.data.tips);
}
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 存储this指向
const that = this
// 读取本地位置信息,存储进data
that.setData({
longitude: wx.getStorageSync('longitude'),
latitude: wx.getStorageSync('latitude')
})
// 调用高德逆地址解析,获取坐标的位置信息
amap.map.getRegeo({
// 成功调用
success: res => {
console.log(res);
// 使用数据作为标记信息
// 设置标记使用图片
res[0].iconPath = '/static/images/location.png'
// 存储标记数据到本地
that.setData({
markers: res
})
},
// 失败打印失败信息
fail: err => {
console.log(err)
}
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
查找周围兴趣点
调用高德地图 getPoiAround()
方法获取兴趣点数据
-
选中一个点:展示当前点文本信息、高亮当前点、导航到该点(后续再说)
-
另起一页:借助WeUI的九宫格组件,给出一些常用关键词,设置图标图片、尺寸
-
在新页面下另起一页,放置兴趣点地图
-
给九宫格添加点击事件,跳转兴趣点地图
- 跳转需要传参,使用data-参数名,读取使用
e.currentTarget.dataset.属性名
- 书写点击事件,判断是否有关键词属性,有则跳转 - navigateTo,使用?传参
- 跳转需要传参,使用data-参数名,读取使用
-
页面接受参数,使用onLader中参数可以获取
-
将关键字设置为标题 - setNavigationBarTitle
-
使用高德地图API - 查找周围兴趣点
- 页面引入高德地图,调用API,传递参数,获取数据
-
返回的markers可以作为定位点标记数据,注意保存一份全局数据,以便后期使用
-
存储定位点标记和当前位置经纬度数据到data
-
书写地图标签,展示地图,绑定数据 (参考首页地图)
-
添加两个函数:
- 展示当前点信息,存储到data中,然后绑定给底部展示区,记得绑定位置,后面导航需要用
- 修改当前点图标:更改当前点图标,恢复其他点图标,保存新的标记数据到data - markers
-
添加点击标记点事件 - bindmarkertap:参数e带有当前点信息,从里面获取id,再次调用上面的展示当前点信息和修改当前点图标两个方法
{
"pages": [
// 新页面
"pages/index/index",
// 二级页面
"pages/index/around",
"pages/home/home",
"pages/logs/logs"
],
...............
}
<!--index.wxml-->
<view class="page" data-weui-theme="{{theme}}">
<view class="page__hd">
<view class="page__desc">查找周边</view>
</view>
<!-- 宫格组件 -->
<view class="weui-grids">
<!-- 遍历数据创建宫格组件,添加点击事件跳转,设置自定义属性方便携带参数 -->
<a class="weui-grid" wx:for="{{around_title}}" wx:key="key" bindtap="toAround" data-keyword="{{item}}">
<view class="weui-grid__icon">
<image src="../../static/images/featured.png" alt></image>
</view>
<view class="weui-grid__label">{{item}}</view>
</a>
</view>
</view>
// index.js
const app = getApp()
Page({
data: {
// 创建宫格使用的文本
around_title: ['美食','酒店','加油站','医院','药店','银行','地铁','公交站','厕所']
},
onLoad() {
},
// 点击事件函数
toAround: (e) => {
// 微信跳转API
wx.navigateTo({
// 给路由携带参数
url: `around?keyword=${e.currentTarget.dataset.keyword}`,
})
}
})
/**index.wxss**/
.weui-grid image {
height: 30px;
width: 30px;
}
.page__hd {
margin-left: 20px;
}
<!--pages/index/around.wxml-->
<view class="container">
<!-- 地图组件,绑定数据,添加点击标记点事件 -->
<map class="map" name="" longitude='{{longitude}}' latitude='{{latitude}}' markers='{{markers}}' scale="14" bindmarkertap="chagenMarker"></map>
<!-- 底部浮动位置展示 -->
<view class="map-text">
<!-- 绑定数据 -->
<text>{{info.name}}</text>
<text>{{info.address}}</text>
<view class="button-sp-area">
<a class="weui-btn weui-btn_mini weui-btn_primary">按钮</a>
</view>
</view>
</view>
// pages/index/around.js
// 引入高德地图
const {
map
} = require('../../utils/amap-config')
// 创建全局标记点数据,后面获取到数据存到这
let markersData = []
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 绑定this指向
const that = this
// 获取搜索关键词
const keyword = options.keyword
// 修改顶部标题
wx.setNavigationBarTitle({
title: '周边' + keyword,
})
// 调用高德API获取兴趣点
map.getPoiAround({
// API参数 - 关键词
querykeywords: keyword,
// 成功后调用
success: res => {
// 存储获取数据
markersData = res.markers
// 如果获取到内容
if (markersData.length > 0) {
// 保存数据到data
that.setData({
markers: markersData,
// 经纬度
latitude: wx.getStorageSync('latitude'),
longitude: wx.getStorageSync('longitude')
})
}
// 调用方法修改文字,默认选中第一个数据
that.saveInfo(markersData, 0)
// 调用方法修改选中图标,默认选中第一个数据
that.chagenIcon(markersData, 0)
}
})
},
// 修改底部文字方法
// 参数:数据源、索引值
saveInfo: function (data, index) {
// 直接修改data中的数据
this.setData({
info: {
name: data[index].name,
address: data[index].address,
id: data[index].id
}
})
},
// 修改图标方法
// // 参数:数据源、索引值
chagenIcon: function (data, index) {
// 创建空数组获存放新数据
let newMarkersData = []
// 遍历数据源
for (let i = 0; i < data.length; i++) {
// 数据
const markerItem = data[i]
// 修改选中数据的图标,把其他图标恢复成默认
if (i === index) {
markerItem.iconPath = '../../static/images/marker_checked.png'
} else {
markerItem.iconPath = '../../static/images/marker.png'
}
// 将数据存放到数组
newMarkersData.push(markerItem)
}
// 最后保存新数据修改data
this.setData({
markers: newMarkersData
})
},
// 点击标记点事件函数
chagenMarker: function (e) {
// 获取id
const id = e.detail.markerId
// 直接调用上面两个函数传参即可
this.saveInfo(markersData, id)
this.chagenIcon(markersData, id)
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
/* pages/index/around.wxss */
/* // 首页单独设置样式 */
.container {
height: 100vh;
width: 100vw;
}
/* 地图 */
.map {
width: 100%;
height: 100%;
}
/* 底部文本 */
.map-text {
position: relative;
position: fixed;
left: 0;
bottom: 0;
width: 100%;
background-color: #fff;
/* text-align: center; */
}
/* // 底部文本 */
.map-text > text {
display: block;
margin: 10px 20px;
}
.map-text > text:nth-child(2) {
font-size: 14px;
color: #666;
}
.map-text > .button-sp-area {
position: absolute;
right: 20px;
top: 50%;
margin-top: -16px;
}
路径规划
步行出行
使用高德getWalkingRoute
-
两个点坐标
- 起点:当前定位
- 终点:其他方式获取,搜索或者兴趣点
-
底部可以查看步行导航描述
-
创建路径规划页面
-
给搜索框下拉列表绑定点击事件,点击后跳转到路径规划页面 - bindtap
-
跳转时携带参数,参数为终点坐标
-
路径规划页面顶部tab菜单使用WeUI - tabbar进行改造
-
tab上面不同的选项跳转到不同的页面(步行、骑行、驾车、公交),所以需要有四个导航页面,给四个tab都添加自定义属性(和页面名称一致),方便之后跳转
-
设置tab图标,调整样式
-
tab添加点击事件,点击后跳转相应页面,跳转路径不仅要有路径,还要传经纬度
-
跳转过来时判断是否传递了经纬度,没传递报错
-
给定起点和终点标记数据(图标、经纬度)
-
放入地图组件,绑定数据查看起点终点是否加载
-
起点终点连线使用polyline属性设置,绑定data数据
-
调用高德地图步行导航接口getWalkingRoute,传递起点和终点坐标,接收数据
-
返回数据中的steps中的每一个成员的polyline值即为路径每一个经过的点坐标,把所有点坐标拼接(成数组)起来就成为一条线
-
一个polyline可拆分出多个坐标,最红把这些都拆分成一组组经纬度
-
最后把这些点数据传递给data,另外设置颜色、宽度
-
获取导航文本信息,从路径接口返回数据中(保存在data中)
-
同时还需要把距离、预计时间保存
-
页面底部添加盒子书写结构 绑定数据
-
添加一个详情按钮,点击可展开详情,这里建议底部高度使用动态高度,在data里面指定,点击的时候只需要修改值即可
-
另外,文本列表也可以动态显示,没有点击详情时不显示,点击后才加载
-
给详情按钮添加点击事件,每次判断当前是否处于展开状态(列表是否显示),进行data修改
-
最后进行样式调整
// 添加四个页面分别放置四个导航页
"pages": [
"pages/home/home",
"pages/index/index",
"pages/index/around",
"pages/logs/logs",
"pages/route/walk",
"pages/route/bike",
"pages/route/bus",
"pages/route/car"
],
/**app.wxss**/
/* 引入WeUI */
@import './weui.wxss';
/* 页面大容器 */
.container {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
}
/* 出行方式选择Tab */
.weui-tabbar__item {
background: #3edfff;
}
/* 页面大容器 */
.page {
width: 100vw;
height: 100vh;
}
<!--pages/home/home.wxml-->
<view class="container">
<!-- 顶部搜索框 -->
<view class="page__bd">
<view class="weui-search-bar {{inputShowed ? 'weui-search-bar_focusing' : ''}}" id="searchBar">
<form class="weui-search-bar__form">
<view class="weui-search-bar__box">
<i class="weui-icon-search"></i>
<input type="text" class="weui-search-bar__input" placeholder="搜索" value="{{inputVal}}"
focus="{{inputShowed}}" bindinput="inputTyping" />
<span class="weui-icon-clear" wx:if="{{inputVal.length > 0}}" bindtap="clearInput"></span>
</view>
<label class="weui-search-bar__label" bindtap="showInput">
<i class="weui-icon-search"></i>
<span class="weui-search-bar__text">搜索</span>
</label>
</form>
<view class="weui-search-bar__cancel-btn" bindtap="hideInput">取消</view>
</view>
<view class="weui-cells searchbar-result" wx:if="{{inputVal.length > 0}}">
<!-- 遍历数据创建搜索提示结果, 添加点击事件、缇娜家自定义属性用来传递坐标 -->
<view class="weui-cell weui-cell_active weui-cell_access" wx:for="{{tips}}" wx:key='id' bindtap="toRoute"
data-location="{{item.location}}">
<view class="weui-cell__bd weui-cell_primary">
<view>{{item.name}}</view>
</view>
</view>
</view>
</view>
<!-- 地图组件,设置经纬度、标记点信息 -->
<map class="map" name="" longitude='{{longitude}}' latitude='{{latitude}}' markers='{{markers}}' scale="14"></map>
<!-- 底部浮动位置展示 -->
<view class="map-text">
<text>{{markers[0].name}}</text>
<text>{{markers[0].desc}}</text>
<view class="button-sp-area">
<a class="weui-btn weui-btn_mini weui-btn_primary">导航</a>
</view>
</view>
</view>
// pages/home/home.js
const amap = require('../../utils/amap-config')
Page({
/**
* 页面的初始数据
*/
data: {
inputShowed: false,
inputVal: ""
},
// 点击电视搜索框时间事件函数
showInput: function () {
this.setData({
inputShowed: true
});
},
// 取消按钮点击事件函数
hideInput: function () {
this.setData({
inputVal: "",
inputShowed: false
});
},
// 清空按钮点击事件函数
clearInput: function () {
this.setData({
inputVal: ""
});
},
// 文本框输入事件
inputTyping: function (e) {
//存储输入内容
this.setData({
inputVal: e.detail.value
});
// 调用方法获取提示数据
this.getTips(e.detail.value)
},
// 获取输入提示数据
getTips: function (keywords) {
// 存储this指向
const that = this
// 调用高德方法获取输入提醒
amap.map.getInputtips({
// 输入内容
keywords,
// 位置信息
location: that.data.longitude + ',' + that.data.latitude,
// 成功后调用
success: (res) => {
// 如果获取成功存储数据
if (res && res.tips) that.setData({
tips: res.tips
})
console.log(that.data.tips);
}
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 存储this指向
const that = this
// 读取本地位置信息,存储进data
that.setData({
longitude: wx.getStorageSync('longitude'),
latitude: wx.getStorageSync('latitude')
})
// 调用高德逆地址解析,获取坐标的位置信息
amap.map.getRegeo({
// 成功调用
success: res => {
console.log(res);
// 使用数据作为标记信息
// 设置标记使用图片
res[0].iconPath = '/static/images/location.png'
// 存储标记数据到本地
that.setData({
markers: res
})
},
// 失败打印失败信息
fail: err => {
console.log(err)
}
})
},
// 搜索结果提示列表点击事件
toRoute: function (e) {
// 跳转页面,携带参数
wx.navigateTo({
url: `../route/walk?location=${e.currentTarget.dataset.location}`,
})
}
})
<!--pages/route/walk.wxml-->
<view class="page">
<!-- 顶部Tab导航栏 -->
<view class="page__bd">
<view class="weui-tab">
<view class="weui-tab__panel">
</view>
<view class="weui-tabbar">
<!-- 设置自定义属性,跳转时传递参数,修改图标和名称 -->
<view class="weui-tabbar__item weui-bar__item_on" bindtap="toRoute" data-route='walk'>
<view style="display: inline-block; position: relative;">
<image src="../../static/images/walk-active.png" alt class="weui-tabbar__icon"></image>
</view>
<view class="weui-tabbar__label">步行</view>
</view>
<view class="weui-tabbar__item" bindtap="toRoute" data-route='car'>
<image src="../../static/images/car.png" alt class="weui-tabbar__icon"></image>
<view class="weui-tabbar__label">驾车</view>
</view>
<view class="weui-tabbar__item" bindtap="toRoute" data-route='bus'>
<view style="display: inline-block; position: relative;">
<image src="../../static/images/bus.png" alt class="weui-tabbar__icon"></image>
</view>
<view class="weui-tabbar__label">公交</view>
</view>
<view class="weui-tabbar__item" bindtap="toRoute" data-route='bike'>
<image src="../../static/images/bike.png" alt class="weui-tabbar__icon"></image>
<view class="weui-tabbar__label">骑行</view>
</view>
</view>
</view>
</view>
<!-- 地图组件,绑定数据,polyline - 用来组成路径渲染 -->
<map class="map" name="" longitude='{{markers[0].longitude}}' latitude='{{markers[0].latitude}}' markers='{{markers}}'
scale="14" polyline='{{polyline}}'></map>
<!-- 底部详细信息,绑定动态高度 -->
<view class='info' style="max-height: {{listHeight}};">
<!-- 时间和距离,绑定数据 -->
<text class='info-text'>全程{{distance}}公里,预计需要{{duration}}分钟</text>
<!-- 详情列表,遍历并绑定数据 -->
<view class='infoList' wx:if="{{listShow}}">
<text class='infoList-item' wx:for="{{steps}}" wx:key='steps'>{{item.instruction}}</text>
</view>
<!-- 按钮,绑定数据,添加点击事件 -->
<button class="mini-btn" size="mini" bindtap="clickBtn">{{buttonText}}</button>
</view>
</view>
// pages/route/walk.js
// 引入高德地图
const {
map
} = require('../../utils/amap-config')
Page({
/**
* 页面的初始数据
*/
data: {
// 详情列表是否显示
listShow: false,
// 详情高度
listHeight: '70px',
// 按钮文本
buttonText: '展开'
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 判读跳转过来时是否传递了终点坐标,没有传递则直接返回
if (options.location === '') {
return console.log('经纬度错误')
}
// 绑定this
const that = this
// 保存数据
that.setData({
// 终点坐标
location: options.location,
// 起点经纬度
longitude: wx.getStorageSync('longitude'),
latitude: wx.getStorageSync('latitude'),
// 两个标记点 - 起点和终点分别设置
markers: [{
longitude: wx.getStorageSync('longitude'),
latitude: wx.getStorageSync('latitude'),
iconPath: '../../static/images/nav_s.png'
}, {
longitude: options.location.split(',')[0],
latitude: options.location.split(',')[1],
iconPath: '../../static/images/nav_e.png'
}]
}),
// 调用高德地图API获取路径
map.getWalkingRoute({
// 参数 - 起点坐标
origin: that.data.longitude + ',' + that.data.latitude,
// 参数 - 终点坐标
destination: that.data.location,
// 成功调用
success: data => {
// 创建空数组存放路径坐标点
let points = []
// 判断是否请求到数据
if (data.paths && data.paths[0] && data.paths[0].steps) {
// 获取路径
const steps = data.paths[0].steps
// 遍历路径
for (let i = 0; i < steps.length; i++) {
// 获取路径对应坐标
const array = steps[i].polyline.split(';')
// 在遍历坐标
for (let j = 0; j < array.length; j++) {
// 将每一对经纬度存储为一个对象添加进数组
points.push({
longitude: array[j].split(',')[0],
latitude: array[j].split(',')[1],
})
}
}
}
// data保存数据
that.setData({
// 地图组件需要用到的参数
polyline: [{
// 路径坐标集合
points,
// 颜色
color: '#4da2fd',
// 线宽度
width: 5
}],
// 距离
distance: (data.paths[0].distance / 1000).toFixed(2),
// 时间
duration: (data.paths[0].duration / 60).toFixed(1),
// 保存一份路径副本
steps: data.paths[0].steps
})
},
})
},
// 点击顶部Tab跳转页面函数
toRoute: function (e) {
// 跳转页面。传递参数
wx.navigateTo({
url: `${e.currentTarget.dataset.route}?location=${this.data.location}`,
})
},
// 点击展开和收起事件函数
clickBtn: function () {
// 绑定this
const that = this
// 根据当前状态修改数据
if (!that.data.listShow) {
that.setData({
listShow: true,
listHeight: '80vh',
buttonText: '收起'
})
} else {
that.setData({
listShow: false,
listHeight: '70px',
buttonText: '展开'
})
}
}
})
/* pages/route/walk.wxss */
/* 顶部Tab */
.page__bd {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 1;
}
/* 地图 */
.map {
width: 100%;
height: 100%;
}
/* 底部详情 */
.info {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
padding: 10px;
background-color: #fff;
z-index: 1;
overflow: auto;
}
.info .info-text {
height: 50px;
line-height: 50px;
}
.info button {
position: absolute;
top: 19px;
right: 30px;
background-color: #009dfe;
color: #fff;
}
.info .infoList-item {
display: block;
padding: 5px 0;
color: #666;
font-size: 14px;
}
下面为其他三个页面通用的结构,还没有写到,线填充内容,这些内容都和步行导航一样
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 判断是否传递了终点坐标,没有传递直接报错返回
if (options.location === '') {
return console.log('经纬度错误')
}
// 绑定this
const that = this
// 保存数据
that.setData({
// 终点坐标
location: options.location,
// 起点经纬度
longitude: wx.getStorageSync('longitude'),
latitude: wx.getStorageSync('latitude')
})
},
// 点击Tab跳转事件
toRoute: function (e) {
wx.navigateTo({
// 传递参数
url: `${e.currentTarget.dataset.route}?location=${this.data.location}`,
})
}
})
<view class="page">
<!-- 顶部Tab -->
<view class="page__bd" style="height: 100%;">
<view class="weui-tab">
<view class="weui-tab__panel">
</view>
<view class="weui-tabbar">
<view class="weui-tabbar__item" bindtap="toRoute" data-route='walk'>
<view style="display: inline-block; position: relative;">
<image src="../../static/images/walk.png" alt class="weui-tabbar__icon"></image>
</view>
<view class="weui-tabbar__label">步行</view>
</view>
<view class="weui-tabbar__item" bindtap="toRoute" data-route='car'>
<image src="../../static/images/car.png" alt class="weui-tabbar__icon"></image>
<view class="weui-tabbar__label">驾车</view>
</view>
<view class="weui-tabbar__item" bindtap="toRoute" data-route='bus'>
<view style="display: inline-block; position: relative;">
<image src="../../static/images/bus.png" alt class="weui-tabbar__icon"></image>
</view>
<view class="weui-tabbar__label">公交</view>
</view>
<view class="weui-tabbar__item weui-bar__item_on" bindtap="toRoute" data-route='bike'>
<image src="../../static/images/bike-active.png" alt class="weui-tabbar__icon"></image>
<view class="weui-tabbar__label">骑行</view>
</view>
</view>
</view>
</view>
</view>
骑行和驾车导航
- 逻辑和步行导航类似,只不过使用API不同,直接在步行上修改即可
- 骑行导航:getRidingRoute
- 驾车导航:getDrivingRoute
这里直接拷贝步行代码进行修改
<!--pages/route/bike.wxml-->
<view class="page">
<!-- 顶部Tab导航栏 -->
<view class="page__bd">
<view class="weui-tab">
<view class="weui-tab__panel">
</view>
<view class="weui-tabbar">
<!-- 设置自定义属性,跳转时传递参数,修改图标和名称 -->
<view class="weui-tabbar__item" bindtap="toRoute" data-route='walk'>
<view style="display: inline-block; position: relative;">
<image src="../../static/images/walk.png" alt class="weui-tabbar__icon"></image>
</view>
<view class="weui-tabbar__label">步行</view>
</view>
<view class="weui-tabbar__item" bindtap="toRoute" data-route='car'>
<image src="../../static/images/car.png" alt class="weui-tabbar__icon"></image>
<view class="weui-tabbar__label">驾车</view>
</view>
<view class="weui-tabbar__item" bindtap="toRoute" data-route='bus'>
<view style="display: inline-block; position: relative;">
<image src="../../static/images/bus.png" alt class="weui-tabbar__icon"></image>
</view>
<view class="weui-tabbar__label">公交</view>
</view>
<view class="weui-tabbar__item weui-bar__item_on" bindtap="toRoute" data-route='bike'>
<image src="../../static/images/bike-active.png" alt class="weui-tabbar__icon"></image>
<view class="weui-tabbar__label">骑行</view>
</view>
</view>
</view>
</view>
<!-- 地图组件,绑定数据,polyline - 用来组成路径渲染 -->
<map class="map" name="" longitude='{{markers[0].longitude}}' latitude='{{markers[0].latitude}}' markers='{{markers}}'
scale="14" polyline='{{polyline}}'></map>
<!-- 底部详细信息,绑定动态高度 -->
<view class='info' style="max-height: {{listHeight}};">
<!-- 时间和距离,绑定数据 -->
<text class='info-text'>全程{{distance}}公里,预计需要{{duration}}分钟</text>
<!-- 详情列表,遍历并绑定数据 -->
<view class='infoList' wx:if="{{listShow}}">
<text class='infoList-item' wx:for="{{steps}}" wx:key='steps'>{{item.instruction}}</text>
</view>
<!-- 按钮,绑定数据,添加点击事件 -->
<button class="mini-btn" size="mini" bindtap="clickBtn">{{buttonText}}</button>
</view>
</view>
// pages/route/bike.js
// pages/route/car.js
// 引入高德地图
const {
map
} = require('../../utils/amap-config')
Page({
/**
* 页面的初始数据
*/
data: {
// 详情列表是否显示
listShow: false,
// 详情高度
listHeight: '70px',
// 按钮文本
buttonText: '展开'
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 判读跳转过来时是否传递了终点坐标,没有传递则直接返回
if (options.location === '') {
return console.log('经纬度错误')
}
// 绑定this
const that = this
// 保存数据
that.setData({
// 终点坐标
location: options.location,
// 起点经纬度
longitude: wx.getStorageSync('longitude'),
latitude: wx.getStorageSync('latitude'),
// 两个标记点 - 起点和终点分别设置
markers: [{
longitude: wx.getStorageSync('longitude'),
latitude: wx.getStorageSync('latitude'),
iconPath: '../../static/images/nav_s.png'
}, {
longitude: options.location.split(',')[0],
latitude: options.location.split(',')[1],
iconPath: '../../static/images/nav_e.png'
}]
}),
console.log('骑行');
// 调用高德地图API获取路径!!!!!!!!!!!!!!!!!!!!!!只修改调用接口,驾车、步行和骑行传递参数、返回结果结构都是一样的
map.getRidingRoute({
// 参数 - 起点坐标
origin: that.data.longitude + ',' + that.data.latitude,
// 参数 - 终点坐标
destination: that.data.location,
// 成功调用
success: data => {
// 创建空数组存放路径坐标点
let points = []
// 判断是否请求到数据
if (data.paths && data.paths[0] && data.paths[0].steps) {
// 获取路径
const steps = data.paths[0].steps
// 遍历路径
for (let i = 0; i < steps.length; i++) {
// 获取路径对应坐标
const array = steps[i].polyline.split(';')
// 在遍历坐标
for (let j = 0; j < array.length; j++) {
// 将每一对经纬度存储为一个对象添加进数组
points.push({
longitude: array[j].split(',')[0],
latitude: array[j].split(',')[1],
})
}
}
}
// data保存数据
that.setData({
// 地图组件需要用到的参数
polyline: [{
// 路径坐标集合
points,
// 颜色
color: '#4da2fd',
// 线宽度
width: 5
}],
// 距离
distance: (data.paths[0].distance / 1000).toFixed(2),
// 时间
duration: (data.paths[0].duration / 60).toFixed(1),
// 保存一份路径副本
steps: data.paths[0].steps
})
},
fail: info => {
console.log('失败');
}
})
},
// 点击顶部Tab跳转页面函数
toRoute: function (e) {
// 跳转页面。传递参数
wx.navigateTo({
url: `${e.currentTarget.dataset.route}?location=${this.data.location}`,
})
},
// 点击展开和收起事件函数
clickBtn: function () {
// 绑定this
const that = this
// 根据当前状态修改数据
if (!that.data.listShow) {
that.setData({
listShow: true,
listHeight: '80vh',
buttonText: '收起'
})
} else {
that.setData({
listShow: false,
listHeight: '70px',
buttonText: '展开'
})
}
}
})
/* pages/route/bike.wxss */
/* 顶部Tab */
.page__bd {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 1;
}
/* 地图 */
.map {
width: 100%;
height: 100%;
}
/* 底部详情 */
.info {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
padding: 10px;
background-color: #fff;
z-index: 1;
overflow: auto;
}
.info .info-text {
height: 50px;
line-height: 50px;
}
.info button {
position: absolute;
top: 19px;
right: 30px;
background-color: #009dfe;
color: #fff;
}
.info .infoList-item {
display: block;
padding: 5px 0;
color: #666;
font-size: 14px;
}
驾车出行这里不贴出来了,也只修改了一个接口
注意:骑行接口可能有点问题,还在尝试
公交出行
接口:getTransitRoute
和之前调用的接口不同,公交需要多传一个城市参数和换乘策略
提供多种换乘策略 - 这个值需要传给接口:
-
0:最快捷模式
-
1:最经济模式
-
2:最少换乘模式
-
3:最少步行模式
-
5:不乘地铁模式(注意)
-
提供选择城市功能
-
在data中添加一个换乘策略的数据(中文,用于展示),可以先写死
-
页面添加一个按钮用来修改换乘策略,设置样式
-
使用微信的API - showActionSheet进行选择换乘策略,修改data中的方案,注意不乘地铁
-
进入页面获取起点和终点坐标和两点标记
-
加载时直接调取公交接口,可以使用最便捷 - 0,单独封装这个函数
-
传递参数:七点坐标、终点坐标、出行策略、城市
-
城市可以先全局写死
-
把需要的数据进行处理然后保存到data
-
页面遍历并展示数据
-
给出行策略变更添加逻辑,再次调用API接口获取路径规划,传递参数
<!--pages/route/bus.wxml-->
<view class="page">
<!-- 顶部Tab导航栏 -->
<view class="page__bd">
<view class="weui-tab">
<view class="weui-tab__panel">
</view>
<view class="weui-tabbar">
<!-- 设置自定义属性,跳转时传递参数,修改图标和名称 -->
<view class="weui-tabbar__item" bindtap="toRoute" data-route='walk'>
<view style="display: inline-block; position: relative;">
<image src="../../static/images/walk.png" alt class="weui-tabbar__icon"></image>
</view>
<view class="weui-tabbar__label">步行</view>
</view>
<view class="weui-tabbar__item" bindtap="toRoute" data-route='car'>
<image src="../../static/images/car.png" alt class="weui-tabbar__icon"></image>
<view class="weui-tabbar__label">驾车</view>
</view>
<view class="weui-tabbar__item weui-bar__item_on" bindtap="toRoute" data-route='bus'>
<view style="display: inline-block; position: relative;">
<image src="../../static/images/bus-active.png" alt class="weui-tabbar__icon"></image>
</view>
<view class="weui-tabbar__label">公交</view>
</view>
<view class="weui-tabbar__item" bindtap="toRoute" data-route='bike'>
<image src="../../static/images/bike.png" alt class="weui-tabbar__icon"></image>
<view class="weui-tabbar__label">骑行</view>
</view>
</view>
</view>
</view>
<!-- 出行策略按钮 -->
<view class="button-sp-area cell">
<a class="weui-btn_cell weui-btn_cell-primary" bindtap="chagenStrategy">出行策略({{strategy}})</a>
</view>
<!-- 出行方案列表展示 -->
<view class="weui-panel weui-panel_access">
<view class="weui-panel__bd" wx:for="{{nameList}}" wx:key='nameList'>
<view class="weui-media-box weui-media-box_text">
<text>{{item}}</text>
<view class="weui-media-box__desc">其他要展示内容</view>
</view>
</view>
</view>
</view>
// pages/route/bus.js
const {
map
} = require('../../utils/amap-config')
Page({
/**
* 页面的初始数据
*/
data: {
strategy: '最便捷'
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 判断是否传递了终点坐标,没有传递直接报错返回
if (options.location === '') {
return console.log('经纬度错误')
}
// 绑定this
const that = this
// 保存数据
that.setData({
// 终点坐标
location: options.location,
// 起点经纬度
longitude: wx.getStorageSync('longitude'),
latitude: wx.getStorageSync('latitude')
})
// 调用方法进行初始化获取数据
that.getTransitRoute(0)
},
// 点击Tab跳转事件
toRoute: function (e) {
wx.navigateTo({
// 传递参数
url: `${e.currentTarget.dataset.route}?location=${this.data.location}`,
})
},
// 修改出行策略事件
chagenStrategy: function () {
// 绑定this
const that = this
// 五种出行策略
const itemList = ['最快捷', '最经济', '少换乘', '少步行', '不乘地铁', ]
// 调用接口弹出选择器
wx.showActionSheet({
// 数据来源
itemList,
// 选择成功调用
success(res) {
// 获取选择序号,这里注意因为高德API参数没有4,是一如果是4需要手动改一下
const strategyNum = res.tapIndex === 4 ? 5 : res.tapIndex
// 修改文本
that.setData({
strategy: itemList[res.tapIndex]
})
// 调用方法重新获取出行方案
that.getTransitRoute(strategyNum)
}
})
},
// 出行方案获取方法
// 参数:高德API需要用到的参数
getTransitRoute: function (type) {
// 绑定this
const that = this
// 调用高德API
map.getTransitRoute({
// 参数 - 当前位置
origin: wx.getStorageSync('longitude') + ',' + wx.getStorageSync('latitude'),
// 参数 - 钟点坐标
destination: that.data.location,
// 出行策略
strategy: type,
// 出发城市,还可以添加一个到达城市的参数,这里就不加了
city: '北京市',
// 成功
success: data => {
// 判断是否获取成功
if (data && data.transits) {
// 获取数据
const transits = data.transits
// 最终展示在页面上的数据,后面会存储到data中
const nameList = []
// 遍历全部方案
for (let i = 0; i < transits.length; i++) {
// 方案对应路径
const segments = transits[i].segments
// 用来保存方案对应的路径名称
const nameArr = []
// 遍历全部沿途路径
for (let j = 0; j < segments.length; j++) {
// 判断是否存在路径信息
if (segments[j].bus && segments[j].bus.buslines && segments[j].bus.buslines[0] && segments[j].bus.buslines[0].name) {
// 获取路径
let name = segments[j].bus.buslines[0].name
// 改造一下路径
if (j !== 0) {
name = '-->' + name
}
// 保存路径
nameArr.push(name)
}
}
// 把一条方案的所有路径拼接在一块形成路线
nameList.push(nameArr.join(''))
}
// 把最终获取到的全部方案信息保存到data
that.setData({
nameList
})
}
}
})
}
})
/* pages/route/bus.wxss */
.page__bd {
width: 100%;
margin-bottom: 10px;
}
.weui-btn_cell {
background: #ccc;
}
共交出行选择城市
可能用到的知识点
- 滚动式图:
<scroll-view>
- 获取系统信息:wx.getSystemInfo - 微信版本号、语言、平台信息、屏幕尺寸...
- 事件:touchstart - 手指触摸、touchmove - 手指触摸后移动、touchend - 手指触摸结束
- getCurrentPages - 获取当前路由站,可以获取上一个页面,从而可以实现跨页面修改数据
这里比较复杂,暂时不写了
发布小程序
- 设置小程序类目
- 提交代码
- 微信开发者工具
- 绑定真实小程序APPID(不要绑定公众号ID)
- 上传代码(没绑定无法上传)
- 小程序后台
- 管理 - 版本管理 - 提交代码
- 微信开发者工具
- 绑定合法域名
- 开发 - 开发管理 - 服务器域名 - request合法域名(HTTPS)