Skip to content

Commit

Permalink
feat(texture): support selecting textures (#356)
Browse files Browse the repository at this point in the history
  • Loading branch information
mspivak-actionengine authored Mar 7, 2024
1 parent 21bf82d commit dbd3241
Show file tree
Hide file tree
Showing 33 changed files with 777 additions and 204 deletions.
Binary file added public/images/uvTexture1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/uvTexture1.thumb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/uvTexture2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/uvTexture2.thumb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/uvTexture3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/uvTexture3.thumb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/uvTexture4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/uvTexture4.thumb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/uvTexture5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/uvTexture5.thumb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const THEMES: AppThemes = {
mainAttibuteItemColor: color_brand_primary,
mainAttributeHighlightColor: hilite_canvas_primary,
mainHistogramColor: color_brand_secondary,
bookmarkFileInteracrions: dim_canvas_primary,
bookmarkFileInteractions: dim_canvas_primary,
validateTileOk: color_brand_secondary_dark,
validateTileWarning: color_accent_tertiary,
filtrationImage: color_brand_quaternary,
Expand Down
3 changes: 2 additions & 1 deletion src/components/bookmarks-panel/bookmarks-panel.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import { PageId } from "../../types";
import { useAppLayout } from "../../utils/hooks/layout";
import { renderWithTheme } from "../../utils/testing-utils/render-with-theme";
import { BookmarksPanel } from "./bookmarks-panel";
import { dragAndDropText } from "./upload-panel";

jest.mock("../../utils/hooks/layout");

const dragAndDropText = "Drag and drop your json file here";

const TEST_BOOKMARKS = [
{
id: "testId1",
Expand Down
23 changes: 16 additions & 7 deletions src/components/bookmarks-panel/bookmarks-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import ConfirmationIcon from "../../../public/icons/confirmation.svg";
import CloseIcon from "../../../public/icons/close.svg";
import ConfirmIcon from "../../../public/icons/confirmation.svg";
import { BookmarkOptionsMenu } from "./bookmark-option-menu";
import { UploadPanel } from "./upload-panel";
import { UploadPanel } from "../upload-panel/upload-panel";
import { UnsavedBookmarkWarning } from "./unsaved-bookmark-warning";
import { Popover } from "react-tiny-popover";
import { color_brand_tertiary } from "../../constants/colors";
Expand All @@ -27,6 +27,9 @@ import {
useAppLayout,
} from "../../utils/hooks/layout";

import { FileType, FileUploaded } from "../../types";
import { parseBookmarks } from "../../utils/bookmarks-utils";

enum PopoverType {
options,
upload,
Expand Down Expand Up @@ -55,13 +58,13 @@ const Container = styled.div<LayoutProps>`
tablet: "0",
mobile: "0",
})};
bottom: ${getCurrentLayoutProperty({
bottom: ${getCurrentLayoutProperty({
desktop: "24px;",
tablet: "0",
mobile: "0",
})};
width: ${getCurrentLayoutProperty({
desktop: "60%",
tablet: "100%",
Expand Down Expand Up @@ -238,9 +241,12 @@ export const BookmarksPanel = ({
setPopoverType(PopoverType.none);
};

const onBookmarksUploadedHandler = (bookmarks) => {
const onBookmarksUploadedHandler = async ({ fileContent }: FileUploaded) => {
setPopoverType(PopoverType.none);
onBookmarksUploaded(bookmarks);
if (typeof fileContent === "string") {
const bookmarksParsed = await parseBookmarks(fileContent);
bookmarksParsed && onBookmarksUploaded(bookmarksParsed);
}
};

const renderPopoverContent = () => {
Expand All @@ -256,8 +262,11 @@ export const BookmarksPanel = ({
if (popoverType === PopoverType.upload) {
return (
<UploadPanel
title={"Upload Bookmarks"}
dragAndDropText={"Drag and drop your json file here"}
fileType={FileType.text}
onCancel={() => setPopoverType(PopoverType.none)}
onBookmarksUploaded={onBookmarksUploadedHandler}
onFileUploaded={onBookmarksUploadedHandler}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import styled from "styled-components";
import { UploadPanelItem } from "./upload-panel-item";
import { UploadPanelItem } from "../upload-panel/upload-panel-item";

const Continer = styled.div`
box-sizing: border-box;
Expand Down
86 changes: 0 additions & 86 deletions src/components/bookmarks-panel/upload-panel.spec.tsx

This file was deleted.

86 changes: 86 additions & 0 deletions src/components/debug-panel/debug-panel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import { ReactEventHandler } from "react";
import styled from "styled-components";
import { useState } from "react";
import { addIconItem } from "../../redux/slices/icon-list-slice";
import { IIconItem, IconListSetName } from "../../types";
import md5 from "md5";
import { IconListPanel } from "../icon-list-panel/icon-list-panel";
import { ActionIconButton } from "../action-icon-button/action-icon-button";
import PlusIcon from "../../../public/icons/plus.svg";
import { ButtonSize } from "../../types";
import { UploadPanel } from "../upload-panel/upload-panel";
import { FileType, FileUploaded } from "../../types";

import {
BoundingVolumeColoredBy,
Expand All @@ -25,6 +35,8 @@ import {
selectDebugOptions,
} from "../../redux/slices/debug-options-slice";

export const TEXTURE_ICON_SIZE = 54;

const CloseButtonWrapper = styled.div`
position: absolute;
right: 6px;
Expand Down Expand Up @@ -56,15 +68,58 @@ const RadioButtonWrapper = styled.div`
margin: 0 16px;
`;

const TextureControlPanel = styled.div`
display: flex;
flex-direction: column;
justify-content: start;
align-items: start;
margin: 0px 16px 0px 16px;
`;

const UploadPanelContainer = styled.div`
position: absolute;
top: 24px;
// Make upload panel centered related to debug panel.
// 168px is half upload panel width.
left: calc(50% - 168px);
`;

type DebugPanelProps = {
onClose: ReactEventHandler;
};

export const DebugPanel = ({ onClose }: DebugPanelProps) => {
const layout = useAppLayout();
const dispatch = useAppDispatch();
const [showFileUploadPanel, setShowFileUploadPanel] = useState(false);
const debugOptions = useAppSelector(selectDebugOptions);

const onTextureInsertClick = () => {
setShowFileUploadPanel(true);
};

const onFileUploadedHandler = async ({ fileContent, info }: FileUploaded) => {
setShowFileUploadPanel(false);
const url = info.url as string;
const hash = md5(url);
const blob = new Blob([fileContent as ArrayBuffer]);
const objectURL = URL.createObjectURL(blob);

const texture: IIconItem = {
id: `${hash}`,
icon: objectURL,
extData: { imageUrl: fileContent },
custom: true,
};
dispatch(
addIconItem({
iconListSetName: IconListSetName.uvDebugTexture,
iconItem: texture,
setCurrent: true,
})
);
};

return (
<PanelContainer layout={layout}>
<PanelHeader panel={Panels.Debug}>
Expand Down Expand Up @@ -159,6 +214,37 @@ export const DebugPanel = ({ onClose }: DebugPanelProps) => {
}
/>
</ItemContainer>
{debugOptions.showUVDebugTexture && (
<TextureControlPanel>
<IconListPanel
iconListSetName={IconListSetName.uvDebugTexture}
iconSize={TEXTURE_ICON_SIZE}
/>
<ActionIconButton
Icon={PlusIcon}
size={ButtonSize.Small}
onClick={onTextureInsertClick}
>
Insert Texture
</ActionIconButton>
</TextureControlPanel>
)}

{showFileUploadPanel && (
<UploadPanelContainer>
<UploadPanel
title={"Upload Texture"}
dragAndDropText={"Drag and drop your texture file here"}
fileType={FileType.binary}
multipleFiles
onCancel={() => {
setShowFileUploadPanel(false);
}}
onFileUploaded={onFileUploadedHandler}
/>
</UploadPanelContainer>
)}

<Title top={8} left={16} bottom={16} id={"color-section-title"}>
Color
</Title>
Expand Down
7 changes: 1 addition & 6 deletions src/components/deck-gl-wrapper/deck-gl-wrapper.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import { MapController } from "@deck.gl/core";
import { TerrainLayer, Tile3DLayer } from "@deck.gl/geo-layers";
import { load } from "@loaders.gl/core";
import { LineLayer, ScatterplotLayer } from "@deck.gl/layers";
import { ImageLoader } from "@loaders.gl/images";
import { Tileset3D } from "@loaders.gl/tiles";
import { BoundingVolumeLayer, CustomTile3DLayer } from "../../layers";
import { COORDINATE_SYSTEM, I3SLoader } from "@loaders.gl/i3s";
Expand Down Expand Up @@ -184,14 +183,10 @@ describe("Deck.gl I3S map component", () => {
expect(controller2).toEqual(controllerExpected);
});

it("Should load UV debug texture", () => {
it("Should load UV debug texture", async () => {
const { rerender } = callRender(renderWithProvider, {
loadDebugTextureImage: true,
});
expect(load).toHaveBeenCalledWith(
"https://raw.githubusercontent.com/visgl/deck.gl-data/master/images/uv-debug-texture.jpg",
ImageLoader
);
expect(load).toHaveBeenCalledTimes(1);
callRender(rerender);
expect(load).toHaveBeenCalledTimes(1);
Expand Down
26 changes: 19 additions & 7 deletions src/components/deck-gl-wrapper/deck-gl-wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,15 @@ import {
} from "../../utils/debug/normals-utils";
import { getLonLatWithElevationOffset } from "../../utils/elevation-utils";

import { useAppDispatch, useAppSelector } from "../../redux/hooks";
import { useAppSelector, useAppDispatch } from "../../redux/hooks";
import { selectColorsByAttribute } from "../../redux/slices/symbolization-slice";
import { selectDragMode } from "../../redux/slices/drag-mode-slice";
import { selectIconItemPicked } from "../../redux/slices/icon-list-slice";
import {
fetchUVDebugTexture,
selectUVDebugTexture,
} from "../../redux/slices/uv-debug-texture-slice";
import { IconListSetName } from "../../types";
import {
selectMiniMap,
selectMiniMapViewPort,
Expand Down Expand Up @@ -290,11 +292,17 @@ export const DeckGlWrapper = ({
},
});
const [terrainTiles, setTerrainTiles] = useState({});
const uvDebugTexture = useAppSelector(selectUVDebugTexture);
const iconItemPicked = useAppSelector(
selectIconItemPicked(IconListSetName.uvDebugTexture)
);
const imageUrl = (iconItemPicked?.extData?.imageUrl as string) || "";
const uvDebugTexture = useAppSelector(selectUVDebugTexture(imageUrl));
const uvDebugTextureRef = useRef<ImageBitmap | null>(null);
uvDebugTextureRef.current = uvDebugTexture;
const [needTransitionToTileset, setNeedTransitionToTileset] = useState(false);

const [forceRefresh, setForceRefresh] = useState(false);

const showDebugTextureRef = useRef<boolean>(false);
showDebugTextureRef.current = showDebugTexture;

Expand All @@ -304,12 +312,11 @@ export const DeckGlWrapper = ({

const dispatch = useAppDispatch();

/** Load debug texture if necessary */
useEffect(() => {
if (loadDebugTextureImage && !uvDebugTexture) {
dispatch(fetchUVDebugTexture());
if (loadDebugTextureImage && imageUrl) {
dispatch(fetchUVDebugTexture(imageUrl));
}
}, [loadDebugTextureImage]);
}, [imageUrl]);

/**
* Hook to call multiple changing function based on selected tileset.
Expand Down Expand Up @@ -345,14 +352,19 @@ export const DeckGlWrapper = ({
}, [loadTiles]);

useEffect(() => {
let c = 0;
loadedTilesets.forEach(async (tileset) => {
if (showDebugTexture) {
await selectDebugTextureForTileset(tileset, uvDebugTexture);
} else {
selectOriginalTextureForTileset();
}
c++;
if (c === loadedTilesets.length) {
setForceRefresh(!forceRefresh);
}
});
}, [showDebugTexture]);
}, [showDebugTexture, uvDebugTexture]);

const getViewState = () =>
parentViewState || (showMinimap && viewState) || { main: viewState.main };
Expand Down
Loading

0 comments on commit dbd3241

Please sign in to comment.