/* eslint-disable no-magic-numbers */ import { EXTENT_PADDING_MULTIPLICATOR, OPTIONS } from '@/constants/map'; import { mapDataInitialPositionSelector, mapDataSizeSelector } from '@/redux/map/map.selectors'; import { MapInstance, Point } from '@/types/map'; import { usePointToProjection } from '@/utils/map/usePointToProjection'; import { View } from 'ol'; import { Extent, boundingExtent } from 'ol/extent'; import { useEffect, useMemo } from 'react'; import { useSelector } from 'react-redux'; import { MapConfig } from '../../MapViewer.types'; interface UseOlMapViewInput { mapInstance: MapInstance; } export const useOlMapView = ({ mapInstance }: UseOlMapViewInput): MapConfig['view'] => { const mapInitialPosition = useSelector(mapDataInitialPositionSelector); const mapSize = useSelector(mapDataSizeSelector); const pointToProjection = usePointToProjection(); const extent = useMemo((): Extent => { const extentPadding = { horizontal: mapSize.width * EXTENT_PADDING_MULTIPLICATOR, vertical: mapSize.height * EXTENT_PADDING_MULTIPLICATOR, }; const topLeftPoint: Point = { x: mapSize.width + extentPadding.horizontal, y: mapSize.height + extentPadding.vertical, }; const bottomRightPoint: Point = { x: -extentPadding.horizontal, y: -extentPadding.vertical, }; return boundingExtent([topLeftPoint, bottomRightPoint].map(pointToProjection)); }, [pointToProjection, mapSize]); const center = useMemo((): Point => { const centerPoint: Point = { x: mapInitialPosition.x, y: mapInitialPosition.y, }; const [x, y] = pointToProjection(centerPoint); return { x, y, }; }, [mapInitialPosition, pointToProjection]); const viewConfig = useMemo( () => ({ center: [center.x, center.y], zoom: mapInitialPosition.z, showFullExtent: OPTIONS.showFullExtent, maxZoom: mapSize.maxZoom, minZoom: mapSize.minZoom, extent, }), [mapInitialPosition.z, mapSize.maxZoom, mapSize.minZoom, center, extent], ); const view = useMemo(() => new View(viewConfig), [viewConfig]); useEffect(() => { if (!mapInstance) { return; } mapInstance.setView(view); }, [view, mapInstance]); return view; };