2021-12-29 11:11:49 +05:00
|
|
|
|
import { Map, Overlay } from 'pigeon-maps'
|
|
|
|
|
import { Link } from 'react-router-dom'
|
|
|
|
|
import { useState, useEffect, memo } from 'react'
|
|
|
|
|
|
2022-01-24 17:32:45 +05:00
|
|
|
|
import { ClusterService } from '@api'
|
2022-02-07 15:01:07 +05:00
|
|
|
|
import { arrayOrDefault } from '@utils'
|
2022-01-24 17:32:45 +05:00
|
|
|
|
import { PointerIcon } from '@components/icons'
|
|
|
|
|
import LoaderPortal from '@components/LoaderPortal'
|
|
|
|
|
import { invokeWebApiWrapperAsync } from '@components/factory'
|
2021-12-29 11:11:49 +05:00
|
|
|
|
|
|
|
|
|
const defaultViewParams = { center: [60.81226, 70.0562], zoom: 5 }
|
2021-07-20 14:10:01 +05:00
|
|
|
|
|
|
|
|
|
const calcViewParams = (clusters) => {
|
2021-12-29 11:11:49 +05:00
|
|
|
|
if ((clusters?.length ?? 0) <= 0)
|
|
|
|
|
return defaultViewParams
|
2021-07-20 14:10:01 +05:00
|
|
|
|
|
|
|
|
|
const center = clusters.reduce((sum, cluster) => {
|
|
|
|
|
sum[0] += (cluster.latitude / clusters.length)
|
|
|
|
|
sum[1] += (cluster.longitude / clusters.length)
|
|
|
|
|
return sum
|
|
|
|
|
}, [0, 0])
|
|
|
|
|
|
|
|
|
|
const maxDeg = clusters.reduce((max, cluster) => {
|
|
|
|
|
const dLatitude = Math.abs(center[0] - cluster.latitude)
|
|
|
|
|
const dLongitude = Math.abs(center[1] - cluster.longitude)
|
|
|
|
|
const d = dLatitude > dLongitude ? dLatitude : dLongitude
|
|
|
|
|
return d > max ? d : max
|
|
|
|
|
}, 0)
|
|
|
|
|
|
2021-09-15 12:03:03 +05:00
|
|
|
|
// zoom max = 20 (too close)
|
|
|
|
|
// zoom min = 1 (mega far)
|
|
|
|
|
// 4 - full Russia (161.6 deg)
|
|
|
|
|
// 13.5 - Khanty-Mansiysk
|
2021-12-29 11:11:49 +05:00
|
|
|
|
const zoom = Math.min(Math.max(5, 5 + 5 / (maxDeg + 0.5)), 15)
|
2021-09-15 12:03:03 +05:00
|
|
|
|
|
2021-10-20 14:32:51 +05:00
|
|
|
|
return { center, zoom }
|
2021-07-20 14:10:01 +05:00
|
|
|
|
}
|
|
|
|
|
|
2021-12-29 11:11:49 +05:00
|
|
|
|
export const Deposit = memo(() => {
|
2021-07-20 14:10:01 +05:00
|
|
|
|
const [clustersData, setClustersData] = useState([])
|
|
|
|
|
const [showLoader, setShowLoader] = useState(false)
|
2021-12-29 11:11:49 +05:00
|
|
|
|
const [viewParams, setViewParams] = useState(defaultViewParams)
|
2021-07-20 14:10:01 +05:00
|
|
|
|
|
2021-12-29 11:11:49 +05:00
|
|
|
|
useEffect(() => invokeWebApiWrapperAsync(
|
|
|
|
|
async () => {
|
|
|
|
|
const data = await ClusterService.getClusters()
|
2022-02-07 15:01:07 +05:00
|
|
|
|
setClustersData(arrayOrDefault(data))
|
2021-12-29 11:11:49 +05:00
|
|
|
|
setViewParams(calcViewParams(data))
|
|
|
|
|
},
|
2021-10-20 14:32:51 +05:00
|
|
|
|
setShowLoader,
|
2021-12-29 11:11:49 +05:00
|
|
|
|
`Не удалось загрузить список кустов`
|
|
|
|
|
), [])
|
2021-07-26 14:44:00 +05:00
|
|
|
|
|
2021-07-20 14:10:01 +05:00
|
|
|
|
return (
|
|
|
|
|
<LoaderPortal show={showLoader}>
|
2021-09-02 16:33:02 +05:00
|
|
|
|
<div className={'h-100vh'}>
|
2021-09-15 12:03:03 +05:00
|
|
|
|
<Map {...viewParams}>
|
2022-02-07 15:01:07 +05:00
|
|
|
|
{clustersData.map(cluster => (
|
2021-10-20 14:32:51 +05:00
|
|
|
|
<Overlay
|
|
|
|
|
width={32}
|
|
|
|
|
anchor={[cluster.latitude, cluster.longitude]}
|
2021-12-29 11:11:49 +05:00
|
|
|
|
key={`${cluster.latitude} ${cluster.longitude}`}
|
|
|
|
|
>
|
|
|
|
|
<Link to={`/cluster/${cluster.id}`}>
|
|
|
|
|
<PointerIcon state={'active'} width={48} height={59} />
|
2021-10-20 14:32:51 +05:00
|
|
|
|
<span>{cluster.caption}</span>
|
|
|
|
|
</Link>
|
2021-12-29 11:11:49 +05:00
|
|
|
|
</Overlay>
|
2022-02-07 15:01:07 +05:00
|
|
|
|
))}
|
2021-09-02 16:33:02 +05:00
|
|
|
|
</Map>
|
|
|
|
|
</div>
|
2021-07-20 14:10:01 +05:00
|
|
|
|
</LoaderPortal>
|
2021-10-20 14:32:51 +05:00
|
|
|
|
)
|
2021-12-29 11:11:49 +05:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
export default Deposit
|