应用场景: app添加地址,使用的是高德地图,实现功能有地图展示,移动地图切换点位,获取点位附近地址并展示,实现该功能需要去申请高德地图api。 该方案适用于h5端和app端。
前置配置: 需要将高德申请的key和密钥在manifest.json配置文件配置好
h5使用:
必须去高德申请Web端的ksy和密钥 然后再【manifest.json】配置定位地图
- 选择高德
- 把申请的web的key配置在key那里
- 把申请的web的秘钥配置在securityJsCode那里
app使用: 去高德申请安卓和ios的key--安卓申请安卓、ios申请ios
- 定位配置--配置系统定位、高德定位,然后配置【高德用户名】【appkey】
- 地图配置--配置高德,然后配置【高德用户名】【appkey】
还需要一个高德的【web服务】的key,项目中会使用到
另外还使用到了两个js文件, amap-wx.js 在lbs.amap.com/api/wx/down… 下载 jweixin.js 在unpkg.com/jweixin-mod… 下载 页面代码:
<template>
<view class="wraper-box">
<view class="map-container" v-if="maptype == 1">
<view class="map-box">
<map
id="myMap"
:longitude="longitude"
:latitude="latitude"
@regionchange="regionchangetab"
style="height: 100%; width: 100%"
>
<cover-image
:class="jump == 1 ? 'controls-play-img bounce-animation' : 'controls-play-img'"
src="@/static/mine/map-inx.png"
></cover-image>
</map>
</view>
<view class="sou-item-list">
<view class="u-search-box" @click="opensea">
<view class="search-min-box">
<image
src="https://lbs.gtimg.com/visual/miniprogram-plugin/location-picker/assets/s_search@2x.png"
mode=""
></image>
搜索地点
</view>
</view>
<view class="list-item-name-box">
<view class="category-scroll-view">
<scroll-view scroll-y="true" class="scroll-Y" @scrolltolower="lower">
<view class="scroll-view-item" v-for="(item, index) in list" :key="index" @click="setpoi(item, index)">
<view class="poi-item-name">
<image src="@/static/mine/item-inx.png" mode=""></image>
{{ item.name }}
</view>
<view class="poi-address">{{ item.address }}</view>
<view class="right-icon" v-if="locinx == index"></view>
</view>
<view class="loading-box" v-if="list.length == 0">
<view class="load-animation" v-if="loading">
<view class="spinner"></view>
<view class="txt-item">加载中</view>
</view>
</view>
</scroll-view>
</view>
</view>
<view class="but-box">
<view class="btn-location" @click="fixAddress">确认选点</view>
</view>
</view>
</view>
<view class="map-min-2" v-if="maptype == 2">
<view class="map-min-2-search-box">
<input
v-model="keyword"
placeholder="搜索地点"
@input="changeword"
@confirm="changeword"
class="locationpicker-search-content-ipt"
/>
<view class="locationpicker-search-clear" @click="onClearInput">
<image
src="https://lbs.gtimg.com/visual/miniprogram-plugin/location-picker/assets/btn_close@2x.png"
class="locationpicker-search-clear-ipt"
mode=""
></image>
</view>
<view class="locationpicker-search--content-btn-line"></view>
<view class="locationpicker-search-content-btn" @click="changeword">搜索</view>
</view>
<u-line></u-line>
<scroll-view scroll-y="true" class="scroll-Y">
<block>
<view class="scroll-view-item" v-for="(item, index) in seolist" :key="index" @click="seopoi(item, index)">
<view class="poi-item-name">
<image src="@/static/mine/item-inx.png" mode=""></image>
{{ item.name }}
</view>
<view class="poi-address">{{ item.address }}</view>
</view>
</block>
<view class="loading-box" v-if="seolist.length == 0 && keyword != ''">
<view class="load-animation" v-if="loading">
<view class="spinner"></view>
<view class="txt-item">加载中</view>
</view>
<view class="empty-box" v-if="!loading && seolist.length == 0">
<view class="value-txt-box-2">没有搜索到数据</view>
</view>
</view>
<!-- 历史搜索记录 -->
<view class="history-item-box" v-if="history.length == 0 && keyword == ''">
<view class="empty-box">
<view class="value-txt-box-1">还没有历史记录</view>
<view class="value-txt-box-2">快来体验世界吧</view>
</view>
</view>
<view class="history-item-box" v-if="history.length > 0 && keyword == ''">
<view class="scroll-view-item" v-for="(item, index) in history" :key="index" @click="seopoi(item, index)">
<view class="poi-item-name">
<image src="/static/Invite/item-inx.png" mode=""></image>
{{ item.name }}
</view>
<view class="poi-address">{{ item.address }}</view>
</view>
<view class="item-but-box" v-if="history.length > 0">
<view class="locationpicker-clear-history-btn" @click="Clearhistory">清空历史记录</view>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
var amapFile = require('@/static/map/amap-wx.js')
// #ifdef WEB
var wx = require('@/static/map/jweixin.js')
// #endif
import storage from '@/utils/storage.js'
export default {
data() {
return {
longitude: 116.3912757,
latitude: 39.906217,
jump: 1,
list: [], //附近地址列表
loading: true,
myAmapFun: '',
mapObj: '', //地图对象
locinx: '',
location: '', //经纬度字符串
history: [], // 搜索记录
keyword: '',
maptype: 1,
page: 1,
activeValue: {}
}
},
onLoad(e) {
// 进入页面传入的经纬度,用于编辑,可传可不传
console.log(e, '传入的')
if (e.lng == 'undefined') {
let a = storage.getLocalAddress()
if (a == '' || a == null) {
this.location = `${this.latitude},${this.longitude}`
return
}
this.longitude = a.longitude
this.latitude = a.latitude
this.location = `${this.latitude},${this.longitude}`
} else {
this.longitude = e.lng
this.latitude = e.lat
this.location = `${this.latitude},${this.longitude}`
}
},
created: function () {
var that = this
that.locinx = 0
that.mapObj = uni.createMapContext('myMap', this)
that.myAmapFun = new amapFile.AMapWX({
key: ************* // 高德申请的web服务key
})
that.attachments()
},
methods: {
// 选择定位坐标地址
setpoi(e, inx) {
var that = this
this.locinx = inx
this.changel = 2
let lon = e.location.split(',')
this.latitude = lon[1]
this.longitude = lon[0]
},
// 搜索选择
seopoi(e) {
var that = this
this.changel = 2
let lon = e.location.split(',')
this.latitude = lon[1]
this.longitude = lon[0]
this.page = 1
this.list.push(e)
const val = this.history.find(k => k.id == e.id)
if (!val) {
this.history.unshift(e)
uni.setStorage({
key: 'locationHistory',
data: this.history,
success: function () {
console.log('success')
}
})
}
that.location = e.location
that.attachments()
setTimeout(() => {
that.changel = 1
}, 1000)
this.maptype = 1
this.keyword = ''
},
// 搜索跳转
opensea() {
this.list = []
this.seolist = []
this.maptype = 2
let _this = this
uni.getStorage({
key: 'locationHistory',
success: function (res) {
_this.history = res.data
console.log(_this.history, 5656)
}
})
},
// 搜索
changeword() {
var that = this
that.loading = true
that.seolist = []
let formData = {}
if (that.Radius) {
formData = {
location: that.location,
keywords: that.keyword,
city: that.Radius,
citylimit: true
}
} else {
formData = {
location: that.location,
keywords: that.keyword
}
}
that.myAmapFun.getInputtips({
...formData,
success: function (data) {
console.log(data, '--1--')
data.tips.forEach((item, index) => {
//成功回调
if (item.location != '' && item.district != '') {
let province = ''
if (item.district.match(/^(.*?省|.*?自治区)/)) {
province = item.district.match(/^(.*?省|.*?自治区)/)[0]
}
let city = ''
if (item.district.replace(province, '').match(/^(.*?市|.*?地区)/)) {
city = item.district.replace(province, '').match(/^(.*?市|.*?地区)/)[0]
}
let district = ''
if ((district = item.district.replace(province + city, '').match(/^.*?(区|县|镇)/))) {
district = item.district.replace(province + city, '').match(/^.*?(区|县|镇)/)[0]
}
that.seolist.push({
id: item.id,
name: item.name,
address: item.address,
location: item.location,
province: province,
city: city,
district: district,
adcode: item.adcode
})
}
})
that.count = data.count
that.loading = false
uni.hideLoading()
},
fail: function (info) {
//失败回调
console.log(info.errCode, 2)
if (info.errCode == '10044') {
console.log('######################')
that.$u.toast('账号维度日调用量超出限制,超出部分的请求被拒绝。')
}
}
})
},
// 确定地址
fixAddress() {
this.activeValue = this.list[this.locinx]
console.log(this.activeValue)
let routes = getCurrentPages() // 获取当前打开过的页面路由数组
let prevPage = routes[routes.length - 2] //获取上一级路由
let data = prevPage.data
prevPage.$vm.getPath(this.activeValue)
uni.navigateBack()
},
isEmpty(obj) {
return Object.keys(obj).length === 0
},
Clearhistory() {
let _this = this
uni.showModal({
title: '提示',
content: '确定清空全部历史记录?',
success: function (res) {
if (res.confirm) {
uni.removeStorage({
key: 'locationHistory',
success: function (res) {
console.log('success')
_this.history = []
}
})
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
},
// 发生变化定位
regionchangetab(e) {
let _this = this
if (e.type == 'end') {
let location = [e.detail.centerLocation.longitude,e.detail.centerLocation.latitude]
this.location = location
this.page = 1
this.list = []
this.attachments()
}
},
// 获取附近poi
attachments() {
var that = this
that.myAmapFun.getPoiAround({
location: that.location,
page: that.page,
success: function (data) {
if (data) {
data.poisData.forEach((item, index) => {
//成功回调
that.list.push({
id: item.id,
name: item.name,
address: item.address,
location: item.location,
province: item.pname,
city: item.cityname,
district: item.adname,
pcode: item.pcode,
citycode: item.citycode,
adcode: item.adcode
})
})
if (!that.list[0].pcode) {
that.list[0].pcode = that.list[1].pcode
that.list[0].citycode = that.list[1].citycode
}
that.count = data.count
}
that.activeValue = that.list[0]
that.loading = false
uni.hideLoading()
},
fail: function (info) {
//失败回调
console.log(info, '错误信息')
if (info.errCode == '10044') {
that.$u.toast('账号维度日调用量超出限制,超出部分的请求被拒绝。')
}
}
})
},
// 下拉加载
lower() {
if (this.list.length != this.count) {
this.page++
uni.showLoading({
title: '加载中...'
})
this.attachments()
}
}
}
}
</script>
css样式:
<style lang="scss" scoped>
.wraper-box {
height: calc(100vh - 44px);
}
.map-container {
display: flex;
flex-direction: column;
overflow: hidden;
height: 100%;
}
.map-box {
width: 100%;
height: 55%;
}
.position-play-img {
bottom: 32rpx;
height: 66rpx;
right: 16rpx;
width: 66rpx;
border-radius: 50%;
background-color: #fff;
overflow: hidden;
z-index: 9999;
position: absolute;
}
.controls-play-img {
height: 88rpx;
left: 50%;
margin-left: -40rpx;
margin-top: -88rpx;
top: 50%;
width: 80rpx;
z-index: 9999;
position: absolute;
}
.load-animation {
height: 100rpx;
margin: auto;
}
.spinner {
width: 50rpx;
margin: auto;
height: 50rpx;
border: 6rpx solid rgba(0, 0, 0, 0.3);
border-top-color: #ffffff;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
.sou-item-list {
width: 100%;
height: 45%;
.u-search-box {
padding: 20rpx 24rpx;
.search-min-box {
background: #f2f2f2;
border-radius: 14rpx;
box-sizing: border-box;
color: #999;
font-size: 28rpx;
height: 68rpx;
line-height: 40rpx;
padding: 14rpx 22rpx;
image {
display: inline-block;
height: 32rpx;
vertical-align: middle;
width: 32rpx;
}
}
}
.bounce-animation {
animation: bounce 0.6s alternate;
/* 动画名称、持续时间、重复次数和交替方向 */
}
@keyframes bounce {
0% {
top: 50%;
animation-timing-function: ease-in;
}
/* 动画开始时图片位于原始位置 */
50% {
top: 40%;
}
/* 动画进行到一半时,图片向上移动10像素 */
100% {
top: 50%;
animation-timing-function: ease-out;
}
/* 动画结束时回到原始位置 */
}
.list-item-name-box {
height: calc(100% - 108rpx - 100rpx);
// width: calc(100% - 60rpx);
padding: 0 20rpx 0 40rpx;
.category-scroll-view {
width: 100%;
height: 100%;
.scroll-Y {
width: 100%;
height: 100%;
.scroll-view-item {
border-bottom: 2rpx solid #e5e5e5;
margin-right: 20rpx;
padding: 32rpx 0 30rpx;
position: relative;
.poi-item-name {
color: #333;
font-size: 32rpx;
line-height: 44rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 90%;
image {
display: inline-block;
height: 36rpx;
margin-right: 8rpx;
margin-top: -8rpx;
vertical-align: middle;
width: 36rpx;
}
}
.poi-address {
color: #666;
font-size: 26rpx;
line-height: 36rpx;
margin-left: 44rpx;
margin-top: 10rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 80%;
}
.right-icon {
border-bottom: 4rpx solid #427cff;
border-left: 4rpx solid #427cff;
height: 8rpx;
margin-top: -2rpx;
position: absolute;
right: 0;
top: 50%;
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
width: 20rpx;
}
}
.loading-box {
height: 100%;
width: 100%;
display: flex;
}
}
}
}
.but-box {
padding: 20rpx 40rpx 22rpx;
border-top: 2rpx solid #e5e5e5;
padding-bottom: 22rpx;
.btn-location {
background: #427cff;
border-radius: 200rpx;
color: #fff;
font-size: 32rpx;
height: 68rpx;
line-height: 68rpx;
text-align: center;
}
}
}
.map-min-2 {
padding-top: 30rpx;
}
// 搜索页面
.map-min-2-search-box {
height: 84rpx;
background: #efefef;
border-radius: 7px;
height: 42px;
margin: 0 14px 10px;
display: -webkit-flex;
display: flex;
-webkit-justify-content: space-around;
justify-content: space-around;
input {
cursor: auto;
display: block;
font-family: UICTFontTextStyleBody;
height: 1.4rem;
min-height: 1.4rem;
overflow: hidden;
text-overflow: clip;
white-space: nowrap;
}
.locationpicker-search-content-ipt {
height: 42px;
padding-left: 10px;
width: 70%;
}
.locationpicker-search-clear {
height: 43px;
text-align: center;
width: 33px;
.locationpicker-search-clear-ipt {
height: 16px;
margin-top: 13px;
width: 16px;
}
}
.locationpicker-search--content-btn-line {
background: #c7c7c7;
height: 16px;
margin: 13px -10px 0 0;
width: 1px;
}
.locationpicker-search-content-btn {
color: #427cff;
height: 42px;
line-height: 42px;
padding: 0 10px 0 20px;
}
}
.scroll-Y {
height: calc(100vh - 87px - 150rpx);
width: 100vw;
.scroll-view-item {
border-bottom: 2rpx solid #e5e5e5;
padding: 30rpx 40rpx 30rpx 40rpx;
position: relative;
.poi-item-name {
color: #333;
font-size: 32rpx;
line-height: 44rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 90%;
image {
display: inline-block;
height: 36rpx;
margin-right: 8rpx;
margin-top: -8rpx;
vertical-align: middle;
width: 36rpx;
}
}
.poi-address {
color: #666;
font-size: 26rpx;
line-height: 36rpx;
margin-left: 44rpx;
margin-top: 10rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 80%;
}
}
// 历史
.history-item-box {
width: 100vw;
height: 100%;
.empty-box {
padding: 200rpx 0;
text-align: center;
width: 100%;
.value-txt-box-1 {
margin: 10rpx auto;
}
.value-txt-box-2 {
color: #666;
font-size: 26rpx;
margin: 0 auto;
}
}
.item-but-box {
height: 160rpx;
padding-top: 20rpx;
.locationpicker-clear-history-btn {
border: 2rpx solid #c7c7c7;
border-radius: 32rpx;
color: #666;
font-size: 26rpx;
height: 60rpx;
line-height: 60rpx;
margin: 0 auto;
text-align: center;
width: 268rpx;
}
}
.scroll-view-item {
border-bottom: 2rpx solid #e5e5e5;
padding: 30rpx 40rpx 30rpx 40rpx;
position: relative;
.poi-item-name {
color: #333;
font-size: 32rpx;
line-height: 44rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 90%;
image {
display: inline-block;
height: 36rpx;
margin-right: 8rpx;
margin-top: -8rpx;
vertical-align: middle;
width: 36rpx;
}
}
.poi-address {
color: #666;
font-size: 26rpx;
line-height: 36rpx;
margin-left: 44rpx;
margin-top: 10rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 80%;
}
}
}
}
.loading-box {
height: 100%;
width: 100%;
display: flex;
.empty-box {
padding: 200rpx 0;
text-align: center;
width: 100%;
.value-txt-box-1 {
margin: 10rpx auto;
}
.value-txt-box-2 {
color: #666;
font-size: 26rpx;
margin: 0 auto;
}
}
}
</style>