Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- Update docs for Client-side config: change `searchBar` parameter to `searchBarConfig`
- Fix to show preview map when used outside the explorer panel.
- Update `csv-geo-au` support to include the latest Australian Government regions.
- Add `backgroundColor` trait to base maps for changing the map container background in 2D/Leaflet mode ([7718](https://github.com/TerriaJS/terriajs/pull/7718))
- Keep camera steady when switching between viewer modes.
- [The next improvement]

Expand Down
34 changes: 19 additions & 15 deletions lib/Models/BaseMaps/BaseMapsModel.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { action, computed, makeObservable } from "mobx";
import DeveloperError from "terriajs-cesium/Source/Core/DeveloperError";
import isDefined from "../../Core/isDefined";
import { isJsonObject, JsonObject } from "../../Core/Json";
import { JsonObject, isJsonObject } from "../../Core/Json";
import Result from "../../Core/Result";
import TerriaError from "../../Core/TerriaError";
import isDefined from "../../Core/isDefined";
import MappableMixin from "../../ModelMixins/MappableMixin";
import ModelReference from "../../Traits/ModelReference";
import {
BaseMapsTraits,
BaseMapTraits
BaseMapTraits,
BaseMapsTraits
} from "../../Traits/TraitsClasses/BaseMapTraits";
import BingMapsCatalogItem from "../Catalog/CatalogItems/BingMapsCatalogItem";
import CommonStrata from "../Definition/CommonStrata";
Expand All @@ -35,6 +35,7 @@ export type BaseMapsJson = Partial<
export interface BaseMapItem {
image?: string;
contrastColor?: string;
backgroundColor?: string;
item: MappableMixin.Instance;
}

Expand Down Expand Up @@ -65,6 +66,7 @@ export class BaseMapsModel extends CreateModel(BaseMapsTraits) {
enabledBaseMaps.push({
image: baseMapItem.image,
contrastColor: baseMapItem.contrastColor,
backgroundColor: baseMapItem.backgroundColor,
item: itemModel
});
}
Expand Down Expand Up @@ -113,17 +115,19 @@ export class BaseMapsModel extends CreateModel(BaseMapsTraits) {
if (items !== undefined) {
const { items: itemsTrait } = this.traits;
const newItemsIds = itemsTrait.fromJson(this, stratumId, items);
newItemsIds.pushErrorTo(errors)?.forEach((member: BaseMapModel) => {
const existingItem = this.items.find(
(baseMap) => baseMap.item === member.item
);
if (existingItem) {
// object array trait doesn't automatically update model item
existingItem.setTrait(stratumId, "image", member.image);
} else {
this.add(stratumId, member);
}
});
newItemsIds
.pushErrorTo(errors)
?.forEach((member: BaseMapModel, i: number) => {
const existingItem = this.items.find(
(baseMap) => baseMap.item === member.item
);
if (existingItem) {
// object array trait doesn't automatically update model item
updateModelFromJson(existingItem, stratumId, items[i]);
Comment on lines +125 to +126
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actual (non-prettier) change is this line which updates all traits from the new definition instead of just the image trait.

} else {
this.add(stratumId, member);
}
});
}

if (isJsonObject(rest))
Expand Down
40 changes: 36 additions & 4 deletions lib/ReactViews/Map/TerriaViewerWrapper/TerriaViewerWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { FC, useEffect, useRef } from "react";

import { Splitter } from "./Splitter/Splitter";
import { useViewState } from "../../Context";
import { autorun } from "mobx";
import { FC, RefObject, useEffect, useRef } from "react";
import styled from "styled-components";
import ViewerMode from "../../../Models/ViewerMode";
import { useViewState } from "../../Context";
import { Splitter } from "./Splitter/Splitter";

export const TerriaViewerWrapper: FC = () => {
const viewState = useViewState();
Expand All @@ -21,13 +22,18 @@ export const TerriaViewerWrapper: FC = () => {
};
}, [viewState]);

// Use an effect hook to change map container background so that we don't
// re-render the whole component when the map container background changes.
useMapBackground(containerRef);

return (
<TerrriaViewerContainer>
<StyledMapPlaceholder>
Loading the map, please wait...
</StyledMapPlaceholder>
<Splitter />
<div
data-testid="mapContainer"
id="cesiumContainer"
css={`
cursor: auto;
Expand All @@ -43,6 +49,32 @@ export const TerriaViewerWrapper: FC = () => {
);
};

/**
* A hook to reactively set the map container background color from the base
* map background color setting
*/
const useMapBackground = (containerRef: RefObject<HTMLElement>) => {
const terria = useViewState().terria;

useEffect(() => {
const disposer = autorun(() => {
// Only relevant when using leaflet mode
if (terria.mainViewer.viewerMode !== ViewerMode.Leaflet) {
return;
}

const containerBackground = terria.baseMapsModel.baseMapItems.find(
(it) => it.item === terria.mainViewer.baseMap
)?.backgroundColor;

if (containerRef.current) {
containerRef.current.style.backgroundColor = containerBackground ?? "";
}
});
return disposer;
}, [containerRef, terria]);
};

const TerrriaViewerContainer = styled.aside`
position: absolute;
top: 0;
Expand Down
8 changes: 8 additions & 0 deletions lib/Traits/TraitsClasses/BaseMapTraits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ export class BaseMapTraits extends ModelTraits {
})
contrastColor?: string = "#ffffff";

@primitiveTrait({
type: "string",
name: "Background color",
description:
"Background color to use for the map container when showing this base map. This setting is currently only applicable in Leaflet or 2D mode. It is useful when the base map does not cover the entire screen and a background color matching the overall base map style is desired."
})
backgroundColor?: string;

@modelReferenceTrait({
factory: CatalogMemberFactory,
name: "Base map item",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { screen } from "@testing-library/react";
import { runInAction } from "mobx";
import CommonStrata from "../../../../lib/Models/Definition/CommonStrata";
import Terria from "../../../../lib/Models/Terria";
import ViewerMode from "../../../../lib/Models/ViewerMode";
import ViewState from "../../../../lib/ReactViewModels/ViewState";
import { TerriaViewerWrapper } from "../../../../lib/ReactViews/Map/TerriaViewerWrapper";
import { renderWithContexts } from "../../withContext";

describe("TerriaViewerWrapper", function () {
let viewState: ViewState;
let terria: Terria;

beforeEach(function () {
terria = new Terria();
viewState = new ViewState({ terria, catalogSearchProvider: undefined });
});

describe("when main viewer is in leaflet mode", function () {
beforeEach(function () {
runInAction(() => {
terria.mainViewer.viewerMode = ViewerMode.Leaflet;
});
});

it("sets container background if the active base map specifies a backgroundColor", async function () {
terria.baseMapsModel.loadFromJson(CommonStrata.user, {
items: [
{
item: {
id: "test-basemap",
type: "url-template-imagery"
},
backgroundColor: "lime"
}
]
});
await terria.mainViewer.setBaseMap(
terria.baseMapsModel.baseMapItems[0].item
);

renderWithContexts(<TerriaViewerWrapper />, viewState);
const container = screen.queryByTestId("mapContainer");
console.log(container?.dataset, container?.classList);
expect(container).toHaveStyle(`background-color: rgb(0, 255, 0)`);
});
});
});
Loading