Skip to content

Commit

Permalink
Merge branch 'dev-landcover'
Browse files Browse the repository at this point in the history
  • Loading branch information
vannizhang committed Apr 3, 2024
2 parents feacbd1 + 753b721 commit f7057af
Show file tree
Hide file tree
Showing 47 changed files with 1,223 additions and 607 deletions.
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<body>
<div id='root'>
<div class="theme-background flex items-center justify-center top-0 left-0 w-full h-full absolute">
<div class="text-custom-light-blue-90">
<div class="text-custom-light-blue-90 mx-6 md:mx-auto">
<h4 class="text-2xl mb-4"><%= htmlWebpackPlugin.options.title %></h4>
<h5>Loading...</h5>
</div>
Expand Down
Binary file modified public/thumbnails/landcover-explorer.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@

import React, { FC, useEffect, useMemo, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import { selectAnimationStatus } from '@shared/store/UI/selectors';
import {
selectAnimationSpeed,
selectAnimationStatus,
} from '@shared/store/UI/selectors';

import IMapView from '@arcgis/core/views/MapView';
import MediaLayer from '@arcgis/core/layers/MediaLayer';
Expand Down Expand Up @@ -51,6 +54,8 @@ const AnimationPanel: FC<Props> = ({ mapView }: Props) => {
const frameData4DownloadJob: AnimationFrameData[] =
useFrameDataForDownloadJob({ mediaLayerElements, mapView });

const animationSpeed = useSelector(selectAnimationSpeed);

useMediaLayerAnimation(mediaLayerElements);

const initMediaLayer = () => {
Expand Down Expand Up @@ -124,14 +129,14 @@ const AnimationPanel: FC<Props> = ({ mapView }: Props) => {
}}
/>

{/* <AnimationDownloadPanel
<AnimationDownloadPanel
frameData4DownloadJob={frameData4DownloadJob}
animationSpeed={1000}
animationSpeed={animationSpeed}
mapViewWindowSize={{
width: mapView.width,
height: mapView.height,
}}
/> */}
/>
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@

import React, { FC, useEffect, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import { selectAnimationStatus } from '@shared/store/UI/selectors';
import {
selectAnimationSpeed,
selectAnimationStatus,
} from '@shared/store/UI/selectors';
import IImageElement from '@arcgis/core/layers/support/ImageElement';
import { selectYear } from '@shared/store/LandcoverExplorer/selectors';
import { getAvailableYears } from '@shared/services/sentinel-2-10m-landcover/timeInfo';
import { useDispatch } from 'react-redux';
import { yearUpdated } from '@shared/store/LandcoverExplorer/reducer';

const ANIMATION_SPEED_IN_MILLISECONDS = 1000;
// const ANIMATION_SPEED_IN_MILLISECONDS = 1000;

/**
* Animate media layer elements
Expand All @@ -43,6 +46,10 @@ const useMediaLayerAnimation = (mediaLayerElements: IImageElement[]) => {

const indexOfNextFrame = useRef<number>(0);

const animationSpeed = useSelector(selectAnimationSpeed);

const animationSpeedRef = useRef<number>(animationSpeed);

const showNextFrame = () => {
// use has stopped animation, no need to show next frame
if (!isPlayingRef.current) {
Expand All @@ -55,7 +62,7 @@ const useMediaLayerAnimation = (mediaLayerElements: IImageElement[]) => {
const millisecondsSinceLastFrame = now - timeLastFrameDisplayed.current;

// if last frame was shown within the time window, no need to display next frame
if (millisecondsSinceLastFrame < ANIMATION_SPEED_IN_MILLISECONDS) {
if (millisecondsSinceLastFrame < animationSpeedRef.current) {
requestAnimationFrame(showNextFrame);
return;
}
Expand Down Expand Up @@ -97,6 +104,10 @@ const useMediaLayerAnimation = (mediaLayerElements: IImageElement[]) => {
requestAnimationFrame(showNextFrame);
}
}, [animationMode, mediaLayerElements]);

useEffect(() => {
animationSpeedRef.current = animationSpeed;
}, [animationSpeed]);
};

export default useMediaLayerAnimation;
5 changes: 5 additions & 0 deletions src/landcover-explorer/components/AppLayout/AppLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ import MapView from '@landcover-explorer/components/MapView/MapViewContainer';
import { SaveWebMap } from '@landcover-explorer/components/SaveWebMap';
import { AppHeader } from '@shared/components/AppHeader';
import { appConfig } from '@shared/config';
import { useSaveAppState2HashParams } from '@landcover-explorer/hooks/useSaveAppState2HashParams';
import { useRevalidateToken } from '@shared/hooks/useRevalidateToken';

const AppLayout = () => {
useSaveAppState2HashParams();
useRevalidateToken();

return (
<ErrorBoundary>
<MapView />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/* Copyright 2024 Esri
*
* Licensed under the Apache License Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http:https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import classNames from 'classnames';
import React, { FC, useEffect, useMemo, useRef, useState } from 'react';
import { useDispatch } from 'react-redux';
import { useSelector } from 'react-redux';
import useOnClickOutside from '@shared/hooks/useOnClickOutside';
import { sentinel2AquisitionMonthChanged } from '@shared/store/LandcoverExplorer/reducer';
import { selectSentinel2AquisitionMonth } from '@shared/store/LandcoverExplorer/selectors';
import { saveActiveMonthToHashParams } from '@landcover-explorer/utils/URLHashParams';
import { Dropdown, DropdownData } from '@shared/components/Dropdown';

const MONTH_ABBR = [
'JAN',
'FEB',
'MAR',
'APR',
'MAY',
'JUN',
'JUL',
'AUG',
'SEP',
'OCT',
'NOV',
'DEC',
];

type Props = {
disabled?: boolean;
};

const MonthPicker: FC<Props> = ({ disabled }: Props) => {
const dispatch = useDispatch();

const selectedMonth = useSelector(selectSentinel2AquisitionMonth);

const dropdownData: DropdownData[] = useMemo(() => {
return MONTH_ABBR.map((month, index) => {
return {
value: index.toString(),
label: month,
selected: selectedMonth === index + 1,
};
});
}, [selectedMonth]);

useEffect(() => {
saveActiveMonthToHashParams(selectedMonth);
}, [selectedMonth]);

return (
<div
className={classNames('relative', {
'disabled-when-animation-mode-is-on': disabled,
})}
>
<Dropdown
data={dropdownData}
onChange={(indexOfSelectedMOnth) => {
const monthVal = parseInt(indexOfSelectedMOnth) + 1;

dispatch(sentinel2AquisitionMonthChanged(monthVal));
// setShouldShowOptions(false);
}}
/>
</div>
);
};

export default MonthPicker;
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const CloseButton = (
</svg>
);

const AnimationButton = () => {
export const AnimationStatusButton = () => {
const dispatch = useDispatch();

const animationMode = useSelector(selectAnimationStatus);
Expand Down Expand Up @@ -116,4 +116,4 @@ const AnimationButton = () => {
);
};

export default AnimationButton;
export default AnimationStatusButton;
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';
import AnimationStatusButton from './AnimationStatusButton';
import { useSelector } from 'react-redux';
import { selectAnimationStatus } from '@shared/store/UI/selectors';
import {
selectIsSentinel2LayerOutOfVisibleRange,
selectMapMode,
selectShouldShowSentinel2Layer,
} from '@shared/store/LandcoverExplorer/selectors';
import MonthPicker from '../AcquisitionMonthPicker/MonthPicker';

export const AnimationControls = () => {
const mode = useSelector(selectMapMode);

const animationMode = useSelector(selectAnimationStatus);

const isSentinel2LayerOutOfVisibleRange = useSelector(
selectIsSentinel2LayerOutOfVisibleRange
);

const shouldShowSentinel2Layer = useSelector(
selectShouldShowSentinel2Layer
);

const shouldShowMonthPicker =
shouldShowSentinel2Layer && isSentinel2LayerOutOfVisibleRange === false;

if (mode !== 'step' || isSentinel2LayerOutOfVisibleRange) {
return null;
}

return (
<div className="relative hidden lg:block pt-4">
<AnimationStatusButton />

<div
className="w-full mt-2"
style={{
height: 26,
}}
>
{shouldShowMonthPicker && (
<MonthPicker disabled={animationMode !== null} />
)}
</div>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const ClassificationsList: FC<Props> = ({

return (
<div
className="text-center mx-4 my-4 md:my-0 shrink-0"
className="text-center mx-4 my-12 md:my-0 shrink-0"
ref={containerRef}
>
<HeaderText
Expand All @@ -67,9 +67,11 @@ const ClassificationsList: FC<Props> = ({
/>

<div
className={classNames('grid grid-cols-3 h-28 text-sm mt-8', {
'disabled-when-animation-mode-is-on': disabled,
})}
className={classNames(
'grid grid-cols-3 h-28 text-sm',
'mt-0 md:mt-8', // only add top margin space for the desktop view
{ 'disabled-when-animation-mode-is-on': disabled }
)}
>
{data
.filter((d) => d.ClassName !== 'No Data')
Expand Down Expand Up @@ -108,13 +110,13 @@ const ClassificationsList: FC<Props> = ({
}}
>
<div
className="w-4 h-4 border-2 border-white rounded-full"
className="w-4 h-4 shrink-0 border-2 border-white rounded-full"
style={{
background: `rgb(${Red}, ${Green}, ${Blue})`,
}}
></div>

<span className="ml-2 text-xs lg:text-sm">
<span className="ml-2 text-xs 2xl:text-sm">
{ClassName}
</span>
</div>
Expand Down
Loading

0 comments on commit f7057af

Please sign in to comment.