Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
useOverlayFeatures.ts 3.88 KiB
import { ZERO } from '@/constants/common';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import { markersSufraceOfCurrentMapDataSelector } from '@/redux/markers/markers.selectors';
import { getOverlayOrderSelector } from '@/redux/overlayBioEntity/overlayBioEntity.selector';
import { LinePoint } from '@/types/reactions';
import { usePointToProjection } from '@/utils/map/usePointToProjection';
import type Feature from 'ol/Feature';
import { SimpleGeometry } from 'ol/geom';
import type Polygon from 'ol/geom/Polygon';
import { useMemo } from 'react';
import { createOverlayGeometryFeature } from './createOverlayGeometryFeature';
import { createOverlayLineFeature } from './createOverlayLineFeature';
import { createOverlaySubmapLinkRectangleFeature } from './createOverlaySubmapLinkRectangleFeature';
import { getPolygonLatitudeCoordinates } from './getPolygonLatitudeCoordinates';
import { parseSurfaceMarkersToBioEntityRender } from './parseSurfaceMarkersToBioEntityRender';
import { useBioEntitiesWithSubmapsLinks } from './useBioEntitiesWithSubmapLinks';
import { useGetOverlayColor } from './useGetOverlayColor';

export const useOverlayFeatures = (): Feature<Polygon>[] | Feature<SimpleGeometry>[] => {
  const pointToProjection = usePointToProjection();
  const { getOverlayBioEntityColorByAvailableProperties } = useGetOverlayColor();
  const overlaysOrder = useAppSelector(getOverlayOrderSelector);
  const currentMarkers = useAppSelector(markersSufraceOfCurrentMapDataSelector);
  const markersRender = parseSurfaceMarkersToBioEntityRender(currentMarkers);
  const bioEntities = useBioEntitiesWithSubmapsLinks();

  const markersFeatures = useMemo(
    () =>
      markersRender.map(entity => {
        const color = getOverlayBioEntityColorByAvailableProperties(entity);

        return createOverlayGeometryFeature(
          [
            ...pointToProjection({ x: entity.x1, y: entity.y1 }),
            ...pointToProjection({ x: entity.x2, y: entity.y2 }),
          ],
          entity?.hexColor || color,
        );
      }),
    [getOverlayBioEntityColorByAvailableProperties, markersRender, pointToProjection],
  );

  const features = useMemo(
    () =>
      bioEntities.map(entity => {
        /**
         * Depending on number of active overlays
         * it's required to calculate xMin and xMax coordinates of the polygon
         * so "entity" might be devided equality between active overlays
         */
        const { xMin, xMax } = getPolygonLatitudeCoordinates({
          width: entity.width,
          nOverlays: overlaysOrder.length,
          xMin: entity.x1,
          overlayIndexBasedOnOrder:
            overlaysOrder.find(({ id }) => id === entity.overlayId)?.index || ZERO,
        });

        const calculatedColor = getOverlayBioEntityColorByAvailableProperties(entity);
        const hexColor = entity?.hexColor;
        const color = hexColor || calculatedColor;

        if (entity.type === 'submap-link') {
          return createOverlaySubmapLinkRectangleFeature(
            [
              ...pointToProjection({ x: xMin, y: entity.y1 }),
              ...pointToProjection({ x: xMax, y: entity.y2 }),
            ],
            entity.value === Infinity ? null : color,
          );
        }

        if (entity.type === 'rectangle') {
          return createOverlayGeometryFeature(
            [
              ...pointToProjection({ x: xMin, y: entity.y1 }),
              ...pointToProjection({ x: xMax, y: entity.y2 }),
            ],
            color,
          );
        }

        return createOverlayLineFeature(
          [
            { x: entity.x1, y: entity.y1 },
            { x: entity.x2, y: entity.y2 },
          ] as LinePoint,
          {
            color,
            pointToProjection,
          },
        );
      }),
    [overlaysOrder, pointToProjection, getOverlayBioEntityColorByAvailableProperties, bioEntities],
  );

  return [...features, ...markersFeatures];
};