-
Miłosz Grocholewski authoredMiłosz Grocholewski authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
useOlMapView.ts 2.25 KiB
/* 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,
zoomFactor: 2 ** (1 / 3),
maxZoom: mapSize.maxZoom * 3,
minZoom: mapSize.minZoom,
extent,
}),
[mapInitialPosition.z, mapSize.maxZoom, center, extent],
);
const view = useMemo(() => new View(viewConfig), [viewConfig]);
useEffect(() => {
if (!mapInstance) {
return;
}
mapInstance.setView(view);
}, [view, mapInstance]);
return view;
};