Skip to content

Commit

Permalink
center maps
Browse files Browse the repository at this point in the history
  • Loading branch information
anamontiaga committed Sep 18, 2023
1 parent c2d251c commit 8b2aad8
Show file tree
Hide file tree
Showing 13 changed files with 180 additions and 77 deletions.
4 changes: 3 additions & 1 deletion app/components/map/component.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import FitBoundsControl from 'components/map/controls/fit-bounds';
import ZoomControl from 'components/map/controls/zoom';

// Map
import Map, { MapProps } from './component';
import { MapProps } from 'types/map';

import Map from './component';
import LAYERS from './layers';

const cartoProvider = new CartoProvider();
Expand Down
37 changes: 1 addition & 36 deletions app/components/map/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,9 @@ import cx from 'classnames';
import { fitBounds } from '@math.gl/web-mercator';
import { easeCubic } from 'd3-ease';
import isEmpty from 'lodash/isEmpty';
import { InteractiveMapProps } from 'react-map-gl/src/components/interactive-map';
import { useDebouncedCallback } from 'use-debounce';

export interface MapProps extends InteractiveMapProps {
// /** A function that returns the map instance */
children?: (map: any) => React.ReactNode;

/** Custom css class for styling */
className?: string;

/** An object that defines the viewport
* @see https://uber.github.io/react-map-gl/#/Documentation/api-reference/interactive-map?section=initialization
*/
viewport?: Partial<ViewportProps>;

/** An object that defines the bounds */
bounds?: {
bbox: number[];
options?: {};
viewportOptions?: Partial<ViewportProps>;
};

screenshot?: boolean;

/** A function that exposes when the map is mounted.
* It receives and object with the `mapRef` and `mapContainerRef` reference. */
onMapReady?: ({ map, mapContainer }) => void;

/** A function that exposes when the map is loaded.
* It receives and object with the `mapRef` and `mapContainerRef` reference. */
onMapLoad?: ({ map, mapContainer }) => void;

/** A function that exposes the viewport */
onMapViewportChange?: (viewport: Partial<ViewportProps>) => void;

/** A function that exposes if current tiles on the viewport are loaded */
onMapTilesLoaded?: (loaded: boolean) => void;
}
import { MapProps } from 'types/map';

const DEFAULT_VIEWPORT = {
zoom: 2,
Expand Down
14 changes: 10 additions & 4 deletions app/components/map/controls/component.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
import React from 'react';

import cx from 'classnames';
import { useAppSelector } from 'store/hooks';

import { cn } from 'utils/cn';

export interface ControlsProps {
className?: string;
children: React.ReactNode;
}

export const Controls: React.FC<ControlsProps> = ({
className = 'absolute w-6 top-14 right-5',
className = 'absolute w-6 bottom-[62px]',
children,
}: ControlsProps) => {
const { isSidebarOpen } = useAppSelector((state) => state['/projects/[id]']);

return (
<div
className={cx({
className={cn({
'left-[570px]': isSidebarOpen,
'left-6': !isSidebarOpen,
[className]: !!className,
})}
>
{React.Children.map(children, (child, i) => {
return (
<div
className={cx({
className={cn({
'mt-2': i !== 0,
})}
>
Expand Down
1 change: 1 addition & 0 deletions app/layout/project/sidebar/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const SIDEBAR_WIDTH = 550;
7 changes: 6 additions & 1 deletion app/layout/project/sidebar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { cn } from 'utils/cn';

import ARROW_RIGHT_SVG from 'svgs/ui/arrow-right.svg?sprite';

import { SIDEBAR_WIDTH } from './constants';

export const Sidebar = ({
children,
className,
Expand All @@ -22,10 +24,13 @@ export const Sidebar = ({
return (
<aside
className={cn({
'absolute z-20 flex h-full w-[550px] rounded-r-2xl bg-black transition-transform': true,
'absolute z-20 flex h-full rounded-r-2xl bg-black transition-transform': true,
'-translate-x-full': !isSidebarOpen,
[className]: !!className,
})}
style={{
width: SIDEBAR_WIDTH,
}}
>
<div className="flex h-full w-full flex-col overflow-hidden px-8 py-6">{children}</div>
<button
Expand Down
24 changes: 18 additions & 6 deletions app/layout/projects/new/map/component.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useState } from 'react';
import React, { useCallback, useEffect, useRef, useState } from 'react';

import { useSelector } from 'react-redux';
import { useAppSelector } from 'store/hooks';

import PluginMapboxGl from '@vizzuality/layer-manager-plugin-mapboxgl';
import { LayerManager, Layer } from '@vizzuality/layer-manager-react';
Expand All @@ -17,12 +17,13 @@ import {

import Loading from 'components/loading';
import Map from 'components/map';
// Controls
import Controls from 'components/map/controls';
import FitBoundsControl from 'components/map/controls/fit-bounds';
import LoadingControl from 'components/map/controls/loading';
import ZoomControl from 'components/map/controls/zoom';
import type { NewProjectFields } from 'layout/projects/new/form';
import { MapProps } from 'types/map';
import { centerMap } from 'utils/map';

const minZoom = 2;
const maxZoom = 20;
Expand All @@ -41,17 +42,21 @@ export const ProjectNewMap = ({
region: NewProjectFields['adminAreaLevel1Id'];
subregion: NewProjectFields['adminAreaLevel2Id'];
}): JSX.Element => {
const { uploadingPlanningArea, uploadingPlanningAreaId, uploadingGridId } = useSelector(
const { uploadingPlanningArea, uploadingPlanningAreaId, uploadingGridId } = useAppSelector(
(state) => state['/projects/new']
);

const { isSidebarOpen } = useAppSelector((state) => state['/projects/[id]']);

const BBOX = useBBOX({ bbox });

const [viewport, setViewport] = useState({});
const [bounds, setBounds] = useState(null);
const [bounds, setBounds] = useState<MapProps['bounds']>(null);
const [mapInteractive, setMapInteractive] = useState(false);
const [mapTilesLoaded, setMapTilesLoaded] = useState(false);

const mapRef = useRef<mapboxgl.Map | null>(null);

const accessToken = useAccessToken();

const LAYERS = [
Expand Down Expand Up @@ -101,6 +106,10 @@ export const ProjectNewMap = ({
}
}, [BBOX]);

useEffect(() => {
centerMap({ ref: mapRef.current, isSidebarOpen });
}, [isSidebarOpen]);

const handleViewportChange = useCallback((vw) => {
setViewport(vw);
}, []);
Expand Down Expand Up @@ -149,7 +158,10 @@ export const ProjectNewMap = ({
mapboxApiAccessToken={process.env.NEXT_PUBLIC_MAPBOX_API_TOKEN}
mapStyle="mapbox://styles/marxan/ckn4fr7d71qg817kgd9vuom4s"
onMapViewportChange={handleViewportChange}
onMapLoad={() => setMapInteractive(true)}
onMapLoad={({ map }) => {
mapRef.current = map;
setMapInteractive(true);
}}
onMapTilesLoaded={(loaded) => setMapTilesLoaded(loaded)}
transformRequest={handleTransformRequest}
>
Expand Down
28 changes: 21 additions & 7 deletions app/layout/projects/show/map/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';

import { useRouter } from 'next/router';

Expand Down Expand Up @@ -42,7 +42,9 @@ import LegendTypeGradient from 'components/map/legend/types/gradient';
import LegendTypeMatrix from 'components/map/legend/types/matrix';
import HelpBeacon from 'layout/help/beacon';
import { Scenario } from 'types/api/scenario';
import { MapProps } from 'types/map';
import { cn } from 'utils/cn';
import { centerMap } from 'utils/map';

import PRINT_SVG from 'svgs/ui/print.svg?sprite';

Expand All @@ -63,10 +65,12 @@ export const ProjectMap = (): JSX.Element => {
const minZoom = 2;
const maxZoom = 20;
const [viewport, setViewport] = useState({});
const [bounds, setBounds] = useState(null);
const [bounds, setBounds] = useState<MapProps['bounds']>(null);
const [mapInteractive, setMapInteractive] = useState(false);
const [mapTilesLoaded, setMapTilesLoaded] = useState(false);

const mapRef = useRef<mapboxgl.Map | null>(null);

const { query } = useRouter();
const { pid, tab } = query as { pid: string; tab: string };
const { data } = useProject(pid);
Expand Down Expand Up @@ -235,9 +239,16 @@ export const ProjectMap = (): JSX.Element => {
});
}, [BBOX]);

const handleViewportChange = useCallback((vw) => {
setViewport(vw);
}, []);
useEffect(() => {
centerMap({ ref: mapRef.current, isSidebarOpen });
}, [isSidebarOpen]);

const handleViewportChange = useCallback(
(vw) => {
setViewport(vw);
},
[isSidebarOpen]
);

const handleZoomChange = useCallback(
(zoom) => {
Expand Down Expand Up @@ -442,7 +453,10 @@ export const ProjectMap = (): JSX.Element => {
mapboxApiAccessToken={process.env.NEXT_PUBLIC_MAPBOX_API_TOKEN}
mapStyle="mapbox://styles/marxan/ckn4fr7d71qg817kgd9vuom4s"
onMapViewportChange={handleViewportChange}
onMapLoad={() => setMapInteractive(true)}
onMapLoad={({ map }) => {
mapRef.current = map;
setMapInteractive(true);
}}
onMapTilesLoaded={(loaded) => setMapTilesLoaded(loaded)}
transformRequest={handleTransformRequest}
onClick={(e) => {
Expand All @@ -465,6 +479,7 @@ export const ProjectMap = (): JSX.Element => {
</HelpBeacon>

<Controls>
<LoadingControl loading={!mapTilesLoaded} />
<ZoomControl
viewport={{
...viewport,
Expand All @@ -483,7 +498,6 @@ export const ProjectMap = (): JSX.Element => {
}}
onFitBoundsChange={handleFitBoundsChange}
/>
<LoadingControl loading={!mapTilesLoaded} />
</Controls>
{/* Print */}
{!tab && sid1 && sid2 && (
Expand Down
22 changes: 17 additions & 5 deletions app/layout/scenarios/edit/map/component.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useState, useMemo } from 'react';
import React, { useCallback, useEffect, useState, useMemo, useRef } from 'react';

import { useRouter } from 'next/router';

Expand Down Expand Up @@ -28,7 +28,6 @@ import { useWDPACategories } from 'hooks/wdpa';

import Loading from 'components/loading';
import Map from 'components/map';
// Controls
import Controls from 'components/map/controls';
import FitBoundsControl from 'components/map/controls/fit-bounds';
import LoadingControl from 'components/map/controls/loading';
Expand All @@ -41,12 +40,18 @@ import LegendTypeGradient from 'components/map/legend/types/gradient';
import LegendTypeMatrix from 'components/map/legend/types/matrix';
import { TABS } from 'layout/project/navigation/constants';
import ScenariosDrawingManager from 'layout/scenarios/edit/map/drawing-manager';
import { MapProps } from 'types/map';
import { centerMap } from 'utils/map';

export const ScenariosEditMap = (): JSX.Element => {
const [open, setOpen] = useState(true);
const [mapInteractive, setMapInteractive] = useState(false);
const [mapTilesLoaded, setMapTilesLoaded] = useState(false);

const mapRef = useRef<mapboxgl.Map | null>(null);

const { isSidebarOpen } = useAppSelector((state) => state['/projects/[id]']);

const accessToken = useAccessToken();

const { query } = useRouter();
Expand Down Expand Up @@ -181,7 +186,7 @@ export const ScenariosEditMap = (): JSX.Element => {
const minZoom = 2;
const maxZoom = 20;
const [viewport, setViewport] = useState({});
const [bounds, setBounds] = useState(null);
const [bounds, setBounds] = useState<MapProps['bounds']>(null);

const include = useMemo(() => {
if (tab === TABS['scenario-protected-areas']) {
Expand Down Expand Up @@ -436,6 +441,10 @@ export const ScenariosEditMap = (): JSX.Element => {
});
}, [BBOX]);

useEffect(() => {
centerMap({ ref: mapRef.current, isSidebarOpen });
}, [isSidebarOpen]);

useEffect(() => {
// ? Previously, with the navigation by tabs, whenever the user clicked to continue, the cache used by the layers on the map
// ? was updated and the flow continued to the next tab.
Expand Down Expand Up @@ -635,7 +644,10 @@ export const ScenariosEditMap = (): JSX.Element => {
mapStyle="mapbox://styles/marxan/ckn4fr7d71qg817kgd9vuom4s"
onClick={handleClick}
onMapViewportChange={handleViewportChange}
onMapLoad={() => setMapInteractive(true)}
onMapLoad={({ map }) => {
mapRef.current = map;
setMapInteractive(true);
}}
onMapTilesLoaded={(loaded) => setMapTilesLoaded(loaded)}
transformRequest={handleTransformRequest}
>
Expand All @@ -657,6 +669,7 @@ export const ScenariosEditMap = (): JSX.Element => {

{/* Controls */}
<Controls>
<LoadingControl loading={!mapTilesLoaded} />
<ZoomControl
viewport={{
...viewport,
Expand All @@ -675,7 +688,6 @@ export const ScenariosEditMap = (): JSX.Element => {
}}
onFitBoundsChange={handleFitBoundsChange}
/>
<LoadingControl loading={!mapTilesLoaded} />
</Controls>

{/* Legend */}
Expand Down
Loading

0 comments on commit 8b2aad8

Please sign in to comment.