小程序项目有用到需要自定义地图的需求,于是记录下操作流程
1、引入高德地图sdk包 下载地址:https://lbs.amap.com/api/wx/download
2、项目中导入并初始化
//导入
import amapFile from '../../../utils/libs/amap-wx.js' //高德地图sdk
let myAmapFun
//初始化
componentWillMount = () => {
/// 初始化高德地图
myAmapFun = new amapFile.AMapWX({ key: ThirdPartKey.amapKey })
}
3、获取当前定位 并初始化气泡 并刷新地图底部poi商家显示
componentDidMount() {
/// 获取精准定位
let that = this
myAmapFun.getRegeo({
success: (data) => {
// markersData = data.markers;
console.log(data)
var {
latitude,
longitude
} = that.state
let { pois, addressComponent } = data[0].regeocodeData
latitude = data[0].latitude
longitude = data[0].longitude
let marker
if (pois.length > 0) {
marker = this.getMarker(pois[0])
/// 默认选中第0组数据
pois[0].checked = true
}
/// 加上省市区 让地址变得长一些
pois.map(item => {
item.realaddress = addressComponent.province + addressComponent.city + addressComponent.district + item.address
})
var markers: any = []
if (marker) {
markers.push(marker)
}
this.setState({ latitude, longitude, pois, markers })
},
fail: (err) => {
console.log(err)
}
})
}
3、点击搜索进入到键盘输入实时获取周边商家的页面
onInputValueChange = (e) => {
const { value } = e.detail
// console.log(value)
if (value.length == 0) {
this.setState({
searchResults: [],
// showSearch: false,
keyword: '',
}, () => {
// Taro.hideKeyboard()
});
return
}
/// 搜索POI功能
myAmapFun.getInputtips({
keywords: value,
// city: '杭州',
// location: '120.299221,30.419153',
success: (data) => {
console.log(data)
if (data && data.tips) {
this.setState({
keyword: value,
searchResults: data.tips
});
}
}
})
}
4、搜索结果点击后重新获取该点击定位的周边的POI并刷新显示
onResultItemClick = (item) => {
/// 根据搜索结果 重新定位
/// 将经纬度字符串转换出来
try {
let locations = item.location.split(',')
let longitude = locations[0]
let latitude = locations[1]
let marker = {
id: item.id,
latitude,
longitude,
name: item.name,
width: 20,
height: 30,
}
/// 根据经纬度 获取周边的poi
myAmapFun.getPoiAround({
location: item.location,
success: (data) => {
console.log(data)
let pois = data.poisData || []
if (pois.length > 0) {
pois[0].checked = true
}
pois.map(res => {
res.realaddress = res.pname + res.cityname + res.adname + res.address
})
this.setState({
keyword: '',
showSearch: false,
markers: [marker],
latitude, longitude,
searchResults: [],
pois
})
},
fail: (err) => {
this.setState({
keyword: '',
showSearch: false,
markers: [marker],
searchResults: [],
latitude, longitude
})
}
})
} catch (error) {
let e = {
detail: {
value: item.name,
}
}
this.onInputValueChange(e)
}
}
5、点击地图底部POI实时更新气泡角标
onPoiItemClick = (item: any, index: number) => {
/// 点击重新设置气泡
let marker = this.getMarker(item)
let { pois } = this.state
/// 清空所有的显示
pois.map(data => {
data.checked = false
return item
})
pois[index].checked = true
this.setState({
markers: [marker],
pois
})
}
全部源码
tsx
import React, { Component } from 'react'
import Taro from '@tarojs/taro'
import { ThirdPartKey } from '@/utils/const.js'
import { View, Map, Input, Image } from '@tarojs/components'
import Assets from '@/assets'
import amapFile from '../../../utils/libs/amap-wx.js' //高德地图sdk
import './index.scss'
let myAmapFun
interface State {
latitude: number,
longitude: number,
markers: any[],
searchResults: any[],
pois: any[],
showSearch: boolean,
keyword: string,
}
/// 修改和选择已有修理厂
export default class SelectFactoryAddress extends Component<{}, State> {
state: State = {
latitude: 23.099994,
longitude: 113.324520,
searchResults: [],
showSearch: false,
keyword: '',
pois: [],
markers: []
}
componentWillMount = () => {
/// 初始化高德地图
myAmapFun = new amapFile.AMapWX({ key: ThirdPartKey.amapKey })
}
componentDidMount() {
/// 获取精准定位
let that = this
myAmapFun.getRegeo({
success: (data) => {
// markersData = data.markers;
console.log(data)
var {
latitude,
longitude
} = that.state
let { pois, addressComponent } = data[0].regeocodeData
latitude = data[0].latitude
longitude = data[0].longitude
let marker
if (pois.length > 0) {
marker = this.getMarker(pois[0])
/// 默认选中第0组数据
pois[0].checked = true
}
/// 加上省市区 让地址变得长一些
pois.map(item => {
item.realaddress = addressComponent.province + addressComponent.city + addressComponent.district + item.address
})
var markers: any = []
if (marker) {
markers.push(marker)
}
this.setState({ latitude, longitude, pois, markers })
},
fail: (err) => {
console.log(err)
}
})
}
onInputValueChange = (e) => {
const { value } = e.detail
// console.log(value)
if (value.length == 0) {
this.setState({
searchResults: [],
// showSearch: false,
keyword: '',
}, () => {
// Taro.hideKeyboard()
});
return
}
/// 搜索POI功能
myAmapFun.getInputtips({
keywords: value,
// city: '杭州',
// location: '120.299221,30.419153',
success: (data) => {
console.log(data)
if (data && data.tips) {
this.setState({
keyword: value,
searchResults: data.tips
});
}
}
})
}
getMarker = (item: any) => {
/// 点击重新设置气泡
let locations = item.location.split(',')
let longitude = locations[0]
let latitude = locations[1]
let marker = {
id: item.id,
latitude,
longitude,
name: item.name,
width: 20,
height: 30,
}
return marker
}
/// 点击搜索结果
onResultItemClick = (item) => {
/// 根据搜索结果 重新定位
/// 将经纬度字符串转换出来
try {
let locations = item.location.split(',')
let longitude = locations[0]
let latitude = locations[1]
let marker = {
id: item.id,
latitude,
longitude,
name: item.name,
width: 20,
height: 30,
}
/// 根据经纬度 获取周边的poi
myAmapFun.getPoiAround({
location: item.location,
success: (data) => {
console.log(data)
let pois = data.poisData || []
if (pois.length > 0) {
pois[0].checked = true
}
pois.map(res => {
res.realaddress = res.pname + res.cityname + res.adname + res.address
})
this.setState({
keyword: '',
showSearch: false,
markers: [marker],
latitude, longitude,
searchResults: [],
pois
})
},
fail: (err) => {
this.setState({
keyword: '',
showSearch: false,
markers: [marker],
searchResults: [],
latitude, longitude
})
}
})
} catch (error) {
let e = {
detail: {
value: item.name,
}
}
this.onInputValueChange(e)
}
}
onPoiItemClick = (item: any, index: number) => {
/// 点击重新设置气泡
let marker = this.getMarker(item)
let { pois } = this.state
/// 清空所有的显示
pois.map(data => {
data.checked = false
return item
})
pois[index].checked = true
this.setState({
markers: [marker],
pois
})
// console.log(item.realaddress)
// Taro.eventCenter.trigger('selectAddress', {
// type: 'factory',
// address: item.realaddress,
// })
// Taro.navigateBack({})
}
cancleSearch = () => {
this.setState({
showSearch: false,
keyword: '',
searchResults: [],
})
}
onClear = () => {
this.setState({
keyword: '',
searchResults: [],
})
}
render() {
let { latitude, longitude, markers, searchResults, showSearch, keyword, pois } = this.state
return (
<View className='selectFactoryAddress'>
<View className='container'>
{/* 地图 */}
<View className='map-wrap'>
<Map
id="mapId"
className="map"
latitude={latitude || 0}
longitude={longitude}
showLocation={true}
markers={markers}
></Map>
</View>
{/* 搜索 */}
<View className='search-wrap'>
<View className='input-wrap'>
<Input className='input'
placeholder='请输入关键字搜索'
value={keyword}
onInput={this.onInputValueChange.bind(this)}
onFocus={() => this.setState({ showSearch: true })}
></Input>
{
keyword.length > 0 && <View className='clear-img' onClick={() => this.onClear()}>
<Image className='img' src={Assets('clear.png')} mode='widthFix'></Image>
</View>
}
</View>
{
showSearch && <View className='search' onClick={() => this.cancleSearch()}>取消</View>
}
</View>
{/* POI内容 */}
<View className='poi-wrap' >
{
pois.map((item, index) => {
return (
<View className={`poi-item ${item.checked ? 'active' : ''}`} key={index} onClick={() => this.onPoiItemClick(item, index)}>
<View className='content'>
<View className='name'>{item.name}</View>
<View className='address'>{item.realaddress}</View>
</View>
</View>
)
})
}
</View>
{/* 搜索结果页 */}
{
showSearch && <View className='search-result-wrap'>
{
searchResults.map((item, index) => {
return (<View className='result-item' key={index} onClick={() => this.onResultItemClick(item)}>
<View className='name'>{item.name}</View>
<View className='detail'>{item.district + item.address}</View>
</View>)
})
}
{
searchResults.length == 0 && <View className='nodata-wrap'>
<View>暂无数据</View>
</View>
}
</View>
}
</View >
</View >
)
}
}
scss
.selectFactoryAddress {
.container {
position: relative;
.search-wrap {
height: 120px;
background-color: white;
position: fixed;
padding: 0 20px;
left: 0;
top: 0;
right: 0;
display: flex;
justify-content: center;
align-items: center;
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
.input-wrap {
width: 90%;
height: 50%;
border: 1px solid #eee;
padding: 0 30px;
border-radius: 36px;
display: flex;
align-items: center;
.input {
flex: 1;
height: 100%;
font-size: 26px;
color: #333;
}
.clear-img {
width: 30px;
height: 30px;
// background-color: #e63c3d;
display: flex;
align-items: center;
justify-content: center;
margin-left: 15px;
.img {
width: 100%;
height: 100%;
}
}
}
.search {
width: 80px;
text-align: center;
color: #3c77df;
font-size: 28px;
font-weight: 400;
}
}
.search-result-wrap {
background-color: white;
position: absolute;
left: 0;
top: 120px;
right: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
.result-item {
// height: 80px;
border-bottom: 1px solid #eee;
color: #333;
font-size: 26px;
display: flex;
// align-items: center;
padding: 10px 20px;
flex-direction: column;
.detail {
font-size: 22px;
margin-top: 5px;
color: #999;
}
}
.nodata-wrap {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: #999;
font-size: 30px;
}
}
.map-wrap {
width: 100vw;
height: 100vh;
.map {
width: 100%;
height: 100%;
}
}
.item-wrap {
background-color: white;
position: fixed;
left: 0;
bottom: 0;
right: 0;
display: flex;
flex-direction: column;
color: #333;
padding: 20px;
.sname {
font-size: 30px;
font-weight: 500;
}
.address-wrap {
margin-top: 10px;
font-size: 25px;
display: flex;
.address {
flex: 1;
}
.distance {
min-width: 160px;
text-align: right;
}
}
.button-wrap {
margin-top: 10px;
display: flex;
background-color: white;
// border-top: 1px solid #eee;
height: 100px;
align-items: center;
padding: 0 20px;
.button {
display: flex;
justify-content: center;
align-items: center;
font-size: 26px;
color: #333;
height: 70%;
border: 1px solid #ddd;
border-radius: 10px;
}
.left {
width: 50%;
}
.right {
width: 50%;
margin-left: 20px;
color: white;
background-color: #e63c3d;
border: none;
}
}
}
.poi-wrap {
background-color: white;
position: fixed;
left: 0;
bottom: 0;
right: 0;
display: flex;
flex-direction: column;
color: #333;
padding: 0 20px;
max-height: 40%;
overflow: scroll; //这个属性是重点,要不然内容无法滚动
.poi-item {
position: relative;
padding: 15px;
display: flex;
align-items: center;
font-size: 24px;
color: #333;
border-bottom: 1px solid #eee;
.content {
flex: 1;
display: flex;
flex-direction: column;
margin-right: 100px;
.name {
font-weight: 500;
}
.address {
margin-top: 10px;
font-size: 20px;
color: #999;
}
}
}
.poi-item.active {
&::after {
content: "";
width: 8px;
height: 20px;
position: absolute;
right: 20px;
top: 30px;
border: 6px solid red;
border-top-color: transparent;
border-left-color: transparent;
transform: rotate(45deg);
}
}
}
}
}
标签:flex,Taro,自定义,pois,item,let,latitude,data,高德
From: https://www.cnblogs.com/qqcc1388/p/17079437.html