<template>
<view class="map-container">
<view class="map" id="map">
<image class="backIcon" @click="onBackClick" src="../../static/image/pulice/arrow_right.png"
mode="scaleToFill"></image>
<view class="pin"></view>
<view class="btnCommit" @click="onCommitClick">确定</view>
</view>
<!--搜索内容-->
<view class="searchLayout">
<view class="inputLayout">
<u-input fontSize="26rpx" placeholder=" 搜索地点" v-model="searchTxt" @change="onInputChage"></u-input>
<view class="cancelTxt" @click="onCancelSearchClick">取消</view>
</view>
<view class="searchContent">
<scroll-view id="panel" scroll-y @scrolltolower="onScrolltolower" lower-threshold="100">
<view :class="item.isChecked?'listItemSelect':'listItem'" v-for="(item,index) in poiList"
:key="index" @click="onItemClick(item)">
<u-image width="120rpx" height="120rpx"
:src="item.photos[0]&&item.photos[0].url?item.photos[0].url:'../../static/image/pulice/loadingIcon.png'"
mode="scaleToFill"
loadingIcon="../../static/image/pulice/loadingIcon.png"
radius="10rpx"></u-image>
<view class="txtLayout">
<view>{{ item.name }}</view>
<view>地址:{{ item.pname }}{{ item.cityname }}{{ item.adname }}{{ item.address }}</view>
<view v-if="item.id != 0">直线距离:{{ item.distance }}米</view>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
<u-toast ref="uToast"></u-toast>
</template>
<script setup>
import {onLoad, onReady} from "@dcloudio/uni-app";
import {getCurrentInstance, ref} from "vue";
const {proxy} = getCurrentInstance();
const poiList = ref([])
let isSelect = false
let center = new AMap.LngLat(114.270821, 35.703706)
let name = ""
let address = ""
let location = ""
let map = null
let placeSearch = null
let geocoder = null
let pageSize = 10
let pageIndex = 1
let count = 0
const searchTxt = ref("")
let centerAddress = ""
let cityCode = "0392"
onLoad(() => {
let address = uni.getStorageSync("address")
if (address && address.location) {
let result = address.location.split(",")
center = new AMap.LngLat(result[0], result[1])
console.log("存储 center = " + center)
}
})
onReady(() => {
// 创建地图实例
map = new AMap.Map('map', {
resizeEnable: true, //是否监控地图容器尺寸变化
zoom: 16,
center: center
});
//获取精准定位
try {
AMap.plugin('AMap.Geolocation', function () {
var geolocation = new AMap.Geolocation({
enableHighAccuracy: true,//是否使用高精度定位,默认:true
timeout: 5000, //超过x秒后停止定位,默认:5s
buttonPosition: 'RB', //定位按钮的停靠位置
buttonOffset: new AMap.Pixel(10, 20),//定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
zoomToAccuracy: true, //定位成功后是否自动调整地图视野到定位点
});
map.addControl(geolocation);
geolocation.getCurrentPosition(function (status, result) {
if (status == 'complete') {
center = result.position
console.log("Geolocation result = ", result)
} else {
console.log("Geolocation error = " + status)
}
});
});
} catch (e) {
console.log("Geolocation catch error = " + e)
}
//加载完成
map.on('complete', async () => {
console.log("地图初始化完成")
await AMap.plugin(["AMap.Geocoder"], () => {
//构造地点查询类
geocoder = new AMap.Geocoder({
city: cityCode,
radius: 500,
extensions: 'all'
});
});
await getPlaceSearchData("")
});
//拖拽地图
map.on('dragend', async () => {
var zoom = map.getZoom(); //获取当前地图级别
center = map.getCenter(); //获取当前地图中心位置
poiList.value[0].location = center
pageIndex = 1
await getPlaceSearchData("")
console.log("屏幕拖动 centerPosition = " + center)
});
//缩放地图
map.on('zoomend', async () => {
var zoom = map.getZoom(); //获取当前地图级别
center = map.getCenter(); //获取当前地图中心位置
poiList.value[0].location = center
pageIndex = 1
await getPlaceSearchData("")
console.log("缩放地图 centerPosition = " + center)
});
//http://restapi.amap.com/v3/geocode/regeo?output=json&location=114.270821,%2035.703706&key=364f4e515a574681470232e26e5d3d65&extensions=base
})
//搜索周边
const searchPlace = async (searchTxt) => {
console.log(pageIndex + "==" + pageSize)
await getCenterAddress()
//关键字搜索
if (searchTxt != "") {
placeSearch.search(searchTxt, (status, result) => {
resultData(result)
});
}
//周边搜素
else {
await placeSearch.searchNearBy('', center, 300, (status, result) => {
resultData(result)
});
}
}
//获取中心点的位置名称
const getCenterAddress = async () => {
await geocoder.getAddress(center, (status, result) => {
if (status === 'complete' && result.regeocode) {
centerAddress = result.regeocode.formattedAddress;
}
console.log('根据经纬度查询地址 = ' + centerAddress)
});
}
//处理结果数据
const resultData = (result) => {
console.log("result = ", result)
if (result != null && result.poiList != null) {
count = result.poiList.count
pageIndex = result.poiList.pageIndex
let pageSize = result.poiList.pageSize
let pois = result.poiList.pois
for (let i = 0; i < pois.length; i++) {
pois[i].isChecked = false//设置为选中状态
//如果距离不存在,计算距离
if (!pois[i].distance) {
//计算搜索位置到中心点距离
let distance = center.distance(pois[i].location)
pois[i].distance = Math.round(distance)
}
}
if (pageIndex == 1) {
//添加我的精准定位条目
let curAddress = {
id: '0',
name: "当前位置(精确到当前点坐标)",
pname: "",
cityname: "",
adname: "",
address: centerAddress == "" ? "未知的地址" : centerAddress,
distance: 0,
photos: [{'url': '../../static/image/pulice/logo.png'}],
location: center,
isChecked: false
}
pois.unshift(curAddress)
poiList.value = pois
} else {
poiList.value.push(...pois)
}
} else {
if (pageIndex == 1) {
//添加我的精准定位条目
if (poiList.value.length == 0) {
let curAddress = {
id: '0',
name: "当前位置(精确到当前点坐标)",
pname: "",
cityname: "",
adname: "",
distance: 0,
address: centerAddress == "" ? "未知的地址" : centerAddress,
photos: [{'url': '../../static/image/pulice/logo.png'}],
location: center,
}
poiList.value.push(curAddress)
}
//未搜索到周边就显示我的精准定位条目
else {
let newArr = poiList.value
newArr[0].address = centerAddress
poiList.value = []
poiList.value.push(newArr[0])
}
}
}
}
//点击返回
const onBackClick = () => {
uni.navigateBack(-1)
}
//点击确定
const onCommitClick = () => {
console.log("确定")
if (isSelect) {
console.log("选中条目 = " + "name = " + name + ",address = " + address + ",location = " + location + ",center = " + center)
let data = {
location: location.toString(),
detailAddress: name ? name : address,
specificAddress: address,
}
uni.setStorageSync("takeOverAddress", data)
uni.navigateBack(-1)
} else {
proxy.$API(proxy).Toast("请先选择地址", 'error')
}
}
//选中条目
const onItemClick = (item) => {
isSelect = true
for (let i = 0; i < poiList.value.length; i++) {
poiList.value[i].isChecked = poiList.value[i].id == item.id
}
name = item.name
address = item.pname + item.cityname + item.adname + item.address
location = item.location
console.log("选中条目 = " + "name = " + name + ",address = " + address + ",location = " + location + ",center = " + center)
map.setCenter(item.location);
}
//列表滑动到底部
const onScrolltolower = async (val) => {
if (poiList.value.length - 1 < count) {
pageIndex = pageIndex + 1
await getPlaceSearchData("")
}
}
//初始化周边参数
const getPlaceSearchData = async (searchTxt) => {
await AMap.plugin(["AMap.PlaceSearch"], () => {
//构造地点查询类
placeSearch = new AMap.PlaceSearch({
type: '010000|020000|030000|040000|050000|060000|070000|080000|090000|100000|110000|120000|130000|140000|150000|180000|190000|200000|990000', // 兴趣点类别
pageSize: pageSize, // 单页显示结果条数
pageIndex: pageIndex, // 页码
city: cityCode, // 兴趣点城市 10009
citylimit: true, //是否强制限制在设置的城市内搜索
// map: map, // 展现结果的地图实例
// panel: "panel", // 结果列表将在此容器中进行展示。
// autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
extensions: 'all'
});
});
await searchPlace(searchTxt)
}
//搜索监听
const onInputChage = (val) => {
console.log(val)
pageIndex = 1
getPlaceSearchData(val)
}
//取消搜索
const onCancelSearchClick = () => {
searchTxt.value = ''
pageIndex = 1
}
</script>
<style scoped lang="scss">
.map-container {
width: 100%;
height: 100%;
min-height: 100vh;
}
.map {
width: 100%;
height: 100%;
min-height: 50vh;
}
.pin {
font-size: 20rpx;
width: 40rpx;
height: 40rpx;
line-height: 40rpx;
text-align: center;
color: #FFFFFF;
position: absolute;
left: 50%;
bottom: 50%;
z-index: 99999;
}
.pin:before {
content: '';
display: block;
position: absolute;
z-index: 99999;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: red;
-webkit-transform: rotateZ(45deg);
transform: rotateZ(45deg);
border-radius: 50% 50% 0 50%;
}
.backIcon {
width: 50rpx;
height: 50rpx;
position: fixed;
top: 30rpx;
left: 30rpx;
z-index: 99999;
}
.btnCommit {
font-size: 20rpx;
text-align: center;
color: white;
position: fixed;
top: 30rpx;
right: 30rpx;
z-index: 99999;
background-color: red;
padding: 8rpx 34rpx;
border-radius: 8rpx;
}
.search {
width: 100%;
height: 80rpx;
box-sizing: border-box;
padding: 10rpx 20rpx;
}
.search > view {
height: 100%;
background-color: #E8E8E8;
border-radius: 20rpx;
padding-left: 30rpx;
color: #999999;
font-size: 26rpx;
display: flex;
align-items: center;
}
#panel {
width: 100%;
height: calc(50vh - 80rpx);
box-sizing: border-box;
border-top: 1rpx solid #D8D8D8;
overflow: auto;
padding-bottom: 50rpx;
}
.listItem {
width: 100%;
box-sizing: border-box;
border-bottom: 1rpx solid #D8D8D8;
padding: 20rpx;
display: flex;
align-items: center;
}
.listItemSelect {
width: 100%;
box-sizing: border-box;
border-bottom: 1rpx solid #D8D8D8;
padding: 20rpx;
display: flex;
align-items: center;
background-color: #DDDDDD;
}
.txtLayout {
margin-left: 30rpx;
box-sizing: border-box;
}
.txtLayout > view:nth-child(1) {
color: #333333;
font-size: 30rpx;
letter-spacing: 1rpx;
font-weight: bold;
}
.txtLayout > view:nth-child(2), .txtLayout > view:nth-child(3) {
color: #999999;
font-size: 24rpx;
letter-spacing: 1rpx;
margin: 6rpx 0;
}
.searchLayout {
width: 100%;
height: 50%;
background-color: #FFFFFF;
position: fixed;
bottom: 0;
left: 0;
}
.inputLayout {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
background-color: #FFFFFF;
padding: 20rpx;
box-sizing: border-box;
}
.cancelTxt {
margin-left: 40rpx;
font-size: 28rpx;
color: #666666;
letter-spacing: 1rpx;
}
.searchContent {
width: 100%;
height: 100%;
box-sizing: border-box;
}
</style>
index.html 添加内容
<script type="text/javascript">
window._AMapSecurityConfig = {
securityJsCode: '你的securityJsCode',
}
</script>
<script src="https://webapi.amap.com/maps?v=2.0&key=你的Key"
type="text/javascript"></script>