Skip to content

Commit

Permalink
Merge branch 'refactor-clean-shared' into dev-landcover
Browse files Browse the repository at this point in the history
  • Loading branch information
vannizhang committed Mar 28, 2024
2 parents 037cb2b + 8286816 commit b9999b2
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 17 deletions.
16 changes: 14 additions & 2 deletions src/landsat-explorer/components/Map/Map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,22 @@ import { MapMagnifier } from '@shared/components/MapMagnifier';
import CustomMapArrtribution from '@shared/components/CustomMapArrtribution/CustomMapArrtribution';
import { MapActionButtonsGroup } from '@shared/components/MapActionButton';
import { CopyLinkWidget } from '@shared/components/CopyLinkWidget';
import { LANDSAT_LEVEL_2_SERVICE_URL } from '@shared/services/landsat-level-2/config';
import { useDispatch } from 'react-redux';
import { updateQueryLocation4TrendTool } from '@shared/store/TrendTool/thunks';
import { updateQueryLocation4SpectralProfileTool } from '@shared/store/SpectralProfileTool/thunks';

const Map = () => {
const dispatch = useDispatch();

return (
<MapViewContainer>
<MapViewContainer
mapOnClick={(point) => {
dispatch(updateQueryLocation4TrendTool(point));

dispatch(updateQueryLocation4SpectralProfileTool(point));
}}
>
<GroupLayer
// this group layer should be added at index of one so that the
// hillsahde/terrain layer can be added on top of it with blend mode applied
Expand All @@ -48,7 +60,7 @@ const Map = () => {
<MapPopUpAnchorPoint />
</GroupLayer>
<SwipeWidget />
<AnimationLayer />
<AnimationLayer imageryServiceUrl={LANDSAT_LEVEL_2_SERVICE_URL} />
<HillshadeLayer />

<MapActionButtonsGroup>
Expand Down
13 changes: 12 additions & 1 deletion src/landsat-surface-temp/components/Map/Map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,21 @@ import { MaskLayer } from '@landsat-explorer/components/MaskLayer';
import { LandsatLayer } from '../LandsatLayer';
import { SwipeWidget } from '../SwipeWidget';
import { CrosshairCursor } from './CrosshairCursor';
import { updateQueryLocation4TrendTool } from '@shared/store/TrendTool/thunks';
import { updateQueryLocation4SpectralProfileTool } from '@shared/store/SpectralProfileTool/thunks';
import { useDispatch } from 'react-redux';

const Map = () => {
const dispatch = useDispatch();

return (
<MapViewContainer>
<MapViewContainer
mapOnClick={(point) => {
dispatch(updateQueryLocation4TrendTool(point));

dispatch(updateQueryLocation4SpectralProfileTool(point));
}}
>
<GroupLayer
// this group layer should be added at index of one so that the
// hillsahde/terrain layer can be added on top of it with blend mode applied
Expand Down
10 changes: 9 additions & 1 deletion src/shared/components/AnimationLayer/AnimationLayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,17 @@ import { saveAnimationWindowInfoToHashParams } from '@shared/utils/url-hash-para
import { useFrameDataForDownloadJob } from './useFrameDataForDownloadJob';

type Props = {
/**
* The URL of the Imagery Service that will be used to provide image for theframes of Animation Layer
*/
imageryServiceUrl: string;
mapView?: MapView;
};

export const AnimationLayer: FC<Props> = ({ mapView }: Props) => {
export const AnimationLayer: FC<Props> = ({
imageryServiceUrl,
mapView,
}: Props) => {
const dispatch = useDispatch();

const mediaLayerRef = useRef<MediaLayer>();
Expand All @@ -70,6 +77,7 @@ export const AnimationLayer: FC<Props> = ({ mapView }: Props) => {
* Array of Imagery Elements for each scene in `sortedQueryParams4ScenesInAnimationMode`
*/
const mediaLayerElements = useMediaLayerImageElement({
imageryServiceUrl,
mapView,
animationStatus,
QueryParams4ImageryScenes: sortedQueryParams4ScenesInAnimationMode,
Expand Down
13 changes: 10 additions & 3 deletions src/shared/components/AnimationLayer/useMediaLayerImageElement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,23 @@ import ImageElement from '@arcgis/core/layers/support/ImageElement';
import ExtentAndRotationGeoreference from '@arcgis/core/layers/support/ExtentAndRotationGeoreference';
import { AnimationStatus } from '@shared/store/UI/reducer';
import { QueryParams4ImageryScene } from '@shared/store/ImageryScene/reducer';
import { exportImage as exportLandsatImage } from '@shared/services/landsat-level-2/exportImage';
// import { exportImage as exportLandsatImage } from '@shared/services/landsat-level-2/exportImage';
import { getAnimationWindowInfoFromHashParams } from '@shared/utils/url-hash-params';
import { getNormalizedExtent } from '@shared/utils/snippets/getNormalizedExtent';
import { exportImage } from '@shared/services/helpers/exportImage';

type Props = {
/**
* The URL of the Imagery Service that will be used to provide image for the media layer elements
*/
imageryServiceUrl: string;
mapView?: MapView;
animationStatus: AnimationStatus;
QueryParams4ImageryScenes: QueryParams4ImageryScene[];
};

const useMediaLayerImageElement = ({
imageryServiceUrl,
mapView,
animationStatus,
QueryParams4ImageryScenes,
Expand Down Expand Up @@ -58,7 +64,7 @@ const useMediaLayerImageElement = ({
const animationWindowInfoFromHashParams =
getAnimationWindowInfoFromHashParams();

console.log(animationWindowInfoFromHashParams);
// console.log(animationWindowInfoFromHashParams);

let { extent, width, height } =
animationWindowInfoFromHashParams || {};
Expand All @@ -73,7 +79,8 @@ const useMediaLayerImageElement = ({
const requests = QueryParams4ImageryScenes.filter(
(queryParam) => queryParam.objectIdOfSelectedScene !== null
).map((queryParam) => {
return exportLandsatImage({
return exportImage({
serviceUrl: imageryServiceUrl,
extent,
width,
height,
Expand Down
22 changes: 12 additions & 10 deletions src/shared/components/MapView/MapViewContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import { centerChanged, zoomChanged } from '../../store/Map/reducer';
import { saveMapCenterToHashParams } from '../../utils/url-hash-params';
import { MapLoadingIndicator } from './MapLoadingIndicator';
// import { queryLocation4TrendToolChanged } from '@shared/store/TrendTool/reducer';
import { updateQueryLocation4TrendTool } from '@shared/store/TrendTool/thunks';
// import { updateQueryLocation4TrendTool } from '@shared/store/TrendTool/thunks';
import { Point } from '@arcgis/core/geometry';
import { ReferenceLayersToggleControl } from '../ReferenceLayersToggleControl';
import ReferenceLayers from './ReferenceLayers';
Expand All @@ -48,14 +48,20 @@ import {
} from '@shared/store/ImageryScene/selectors';
// import { selectActiveAnalysisTool } from '@shared/store/Analysis/selectors';
import { MapCenterIndicator } from './MapCenterIndicator';
import { updateQueryLocation4SpectralProfileTool } from '@shared/store/SpectralProfileTool/thunks';
// import { updateQueryLocation4SpectralProfileTool } from '@shared/store/SpectralProfileTool/thunks';
import { appConfig } from '@shared/config';

type Props = {
/**
* emits when user click on the map
* @param point map point where the user has clicked
* @returns
*/
mapOnClick?: (point: Point) => void;
children?: React.ReactNode;
};

const MapViewContainer: FC<Props> = ({ children }) => {
const MapViewContainer: FC<Props> = ({ mapOnClick, children }) => {
const dispatch = useDispatch();

const center = useSelector(selectMapCenter);
Expand Down Expand Up @@ -144,13 +150,9 @@ const MapViewContainer: FC<Props> = ({ children }) => {
},
} as Point;

dispatch(updateQueryLocation4TrendTool(queryLocation));

dispatch(
updateQueryLocation4SpectralProfileTool(
queryLocation
)
);
if (mapOnClick) {
mapOnClick(queryLocation);
}
}}
mapViewUpdatingOnChange={setIsUpdating}
/>
Expand Down
76 changes: 76 additions & 0 deletions src/shared/services/helpers/exportImage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/* 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 IExtent from '@arcgis/core/geometry/Extent';
import { getMosaicRuleByObjectId } from './getMosaicRuleByObjectId';

type ExportImageParams = {
/**
* imagery service URL
*/
serviceUrl: string;
/**
* Map Extent
*/
extent: Pick<IExtent, 'xmin' | 'ymin' | 'xmax' | 'ymax'>;
/**
* width of map container
*/
width: number;
/**
* height of map container
*/
height: number;
/**
* raster function name that will be used in the rendering rule
*/
rasterFunctionName: string;
/**
* object Id of the imagery scene
*/
objectId: number;
abortController: AbortController;
};

export const exportImage = async ({
serviceUrl,
extent,
width,
height,
rasterFunctionName,
objectId,
abortController,
}: ExportImageParams) => {
const { xmin, xmax, ymin, ymax } = extent;

const params = new URLSearchParams({
f: 'image',
bbox: `${xmin},${ymin},${xmax},${ymax}`,
bboxSR: '102100',
imageSR: '102100',
format: 'jpgpng',
size: `${width},${height}`,
mosaicRule: JSON.stringify(getMosaicRuleByObjectId(objectId)),
renderingRule: JSON.stringify({ rasterFunction: rasterFunctionName }),
});

const requestURL = `${serviceUrl}/exportImage?${params.toString()}`;

const res = await fetch(requestURL, { signal: abortController.signal });

const blob = await res.blob();

return blob;
};
23 changes: 23 additions & 0 deletions src/shared/services/helpers/getMosaicRuleByObjectId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* 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.
*/

export const getMosaicRuleByObjectId = (objectId: number) => {
return {
ascending: false,
lockRasterIds: [objectId],
mosaicMethod: 'esriMosaicLockRaster',
where: `objectid in (${objectId})`,
};
};

0 comments on commit b9999b2

Please sign in to comment.