react-native-amap3d
react-native-amap3d copied to clipboard
有没有什么方法能在可视范围内显示所有覆盖物
就是能计算是一个缩放级别能把所有的覆盖物显示出来
同求展示所有标记点
后面我找了个方法,可以计算出合适的缩放级别和中心点
什么方法,可以参考下吗?
这是个显示轨迹的页面
import { useEffect, useState, useMemo, useCallback, useRef } from 'react'
import { View, Text, Image } from '@tarojs/components'
import { useRouter } from '@tarojs/taro'
import { TopView, Header, Icon, Map, Calendar, Layout } from '@/components'
import { dateToStr, request, useDevice, loading, gcjEncrypt, toast, distance } from '@/utils'
import pointBlue from './images/point-blue.png'
import pointGreen from './images/point-green.png'
import pointOrange from './images/point-orange.png'
import './track.scss'
export default function Fence() {
const { params } = useRouter()
const deviceInfo = useDevice(params.id)
const [dateMore, setDateMore] = useState(false)
const [day, setDay] = useState(dateToStr('yyyy-MM-dd'))
const [polyline, setPolyline] = useState([])
const [startEnd, setStartEnd] = useState([])
const [playIndex, setPlayIndex] = useState(-1)
const [center, setCenter] = useState(null)
const [zoom, setZoom] = useState(18)
useEffect(() => {
// 请求路径数据
request({
url: 'device/watchData/gps',
loading,
toast: true,
data: {
family_id: deviceInfo.familyId,
id: deviceInfo.id,
date: day
}
}).then(res => {
if (timer.current) {
clearInterval(timer.current)
timer.current = null
setPlayIndex(-1)
}
const range = {
maxLng: 0,
minLng: 200,
maxLat: 0,
minLat: 90,
} // 最小纬度 最大纬度 最小经度 最大经度
const _list = res.filter(v => v.lat && v.lng).map(item => {
const { lat, lon } = gcjEncrypt(item.lat, item.lng)
if (lat > range.maxLat) {
range.maxLat = lat
}
if (lat < range.minLat) {
range.minLat = lat
}
if (lon > range.maxLng) {
range.maxLng = lon
}
if (lon < range.minLng) {
range.minLng = lon
}
return { lat, lng: lon, time: item.time.substr(11, 5) }
})
if (_list.length > 1) {
setTimeout(() => {
// 计算两点之间的距离
const rangeDistance = distance(range.minLat, range.minLng, range.maxLat, range.maxLng)
// 求出地图容器的对角线长度
const nowDivLine = Math.sqrt(mapLayout.current.width * mapLayout.current.width + mapLayout.current.height * mapLayout.current.height)
// 求出覆盖物范围和地图容器的比例
const nowScale = rangeDistance / nowDivLine
// 求出可以显示出所有覆盖物的级别
const nowNum = 16 - Math.ceil(Math.log(nowScale) / Math.log(2))
setZoom(nowNum)
setCenter([(range.minLng + range.maxLng) / 2, (range.minLat + range.maxLat) / 2])
}, 500)
setStartEnd([_list[0], _list[_list.length - 1]])
} else if (_list.length) {
setCenter([_list[0].lng, _list[0].lat])
}
setPolyline(_list)
polylineData.current = _list
})
}, [day, deviceInfo.familyId, deviceInfo.id])
const polylines = useMemo(() => {
return polyline.length ? [{
colors: ['#4caf50'],
points: polyline
}] : []
}, [polyline])
const timer = useRef(null)
const polylineData = useRef([])
const markers = useMemo(() => {
if(~playIndex) {
const item = polylineData.current[playIndex]
return [{
...item,
children: <View className='track-point'>
<View className='track-point__time'>{item.time}</View>
<View className='track-point__icon'>
<Image className='track-point__image' src={pointOrange} />
<Text className='track-point__text'>此</Text>
</View>
</View>
}]
} else if (startEnd.length) {
return startEnd.map((item, index) => {
return {
...item,
children: <View className='track-point'>
<View className='track-point__time'>{item.time}</View>
<View className='track-point__icon'>
<Image className='track-point__image' src={index ? pointBlue : pointGreen} />
<Text className='track-point__text'>{index ? '终' : '起'}</Text>
</View>
</View>
}
})
}
return []
}, [playIndex, startEnd])
useEffect(() => {
const _timer = timer
return () => {
if (_timer.current) {
clearInterval(_timer.current)
}
}
}, [])
const mapLayout = useRef({})
const layout = useCallback(e => {
mapLayout.current = e
}, [])
const play = useCallback(() => {
if (timer.current) {
return
}
if (polylineData.current?.length < 2) {
return toast('轨迹过少 无法播放')
}
let i = 0
const item = polylineData.current[0]
setPlayIndex(i)
// setCenter([item.lng, item.lat])
setPolyline([item])
timer.current = setInterval(() => {
i++
const _item = polylineData.current[i]
if (!_item) {
clearInterval(timer.current)
setPlayIndex(-1)
timer.current = null
return toast('播放完毕')
}
// setCenter([_item.lng, _item.lat])
setPolyline(old => [...old, _item])
setPlayIndex(i)
}, 1500)
}, [])
return <TopView>
<Header title='历史轨迹' rightRender={<Text onClick={play}>播放</Text>} />
<View className='track-date'>
<Calendar onlyCurrentWeek={!dateMore} value={day} onChange={setDay} />
<View className='track-date__more' onClick={() => setDateMore(!dateMore)}>
<Text className='track-date__more__text'>{dateMore ? '收起' : '展开'}</Text>
<Icon name={dateMore ? 'shang3' : 'xia1'} />
</View>
</View>
<Layout className='track-map' onLayout={layout}>
<Map
center={center}
polylines={polylines}
markers={markers}
zoom={zoom}
/>
</Layout>
</TopView>
}
谢谢,我明白你的计算思路了。