Skip to content

Commit 594e702

Browse files
authored
Merge pull request #7718 from TerriaJS/leaflet-background
Change leaflet map background color
2 parents b302179 + 1cf5398 commit 594e702

File tree

5 files changed

+112
-19
lines changed

5 files changed

+112
-19
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- Update docs for Client-side config: change `searchBar` parameter to `searchBarConfig`
66
- Fix to show preview map when used outside the explorer panel.
77
- Update `csv-geo-au` support to include the latest Australian Government regions.
8+
- Add `backgroundColor` trait to base maps for changing the map container background in 2D/Leaflet mode ([7718](https://github.com/TerriaJS/terriajs/pull/7718))
89
- Keep camera steady when switching between viewer modes.
910
- [The next improvement]
1011

lib/Models/BaseMaps/BaseMapsModel.ts

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { action, computed, makeObservable } from "mobx";
22
import DeveloperError from "terriajs-cesium/Source/Core/DeveloperError";
3-
import isDefined from "../../Core/isDefined";
4-
import { isJsonObject, JsonObject } from "../../Core/Json";
3+
import { JsonObject, isJsonObject } from "../../Core/Json";
54
import Result from "../../Core/Result";
65
import TerriaError from "../../Core/TerriaError";
6+
import isDefined from "../../Core/isDefined";
77
import MappableMixin from "../../ModelMixins/MappableMixin";
88
import ModelReference from "../../Traits/ModelReference";
99
import {
10-
BaseMapsTraits,
11-
BaseMapTraits
10+
BaseMapTraits,
11+
BaseMapsTraits
1212
} from "../../Traits/TraitsClasses/BaseMapTraits";
1313
import BingMapsCatalogItem from "../Catalog/CatalogItems/BingMapsCatalogItem";
1414
import CommonStrata from "../Definition/CommonStrata";
@@ -35,6 +35,7 @@ export type BaseMapsJson = Partial<
3535
export interface BaseMapItem {
3636
image?: string;
3737
contrastColor?: string;
38+
backgroundColor?: string;
3839
item: MappableMixin.Instance;
3940
}
4041

@@ -65,6 +66,7 @@ export class BaseMapsModel extends CreateModel(BaseMapsTraits) {
6566
enabledBaseMaps.push({
6667
image: baseMapItem.image,
6768
contrastColor: baseMapItem.contrastColor,
69+
backgroundColor: baseMapItem.backgroundColor,
6870
item: itemModel
6971
});
7072
}
@@ -113,17 +115,19 @@ export class BaseMapsModel extends CreateModel(BaseMapsTraits) {
113115
if (items !== undefined) {
114116
const { items: itemsTrait } = this.traits;
115117
const newItemsIds = itemsTrait.fromJson(this, stratumId, items);
116-
newItemsIds.pushErrorTo(errors)?.forEach((member: BaseMapModel) => {
117-
const existingItem = this.items.find(
118-
(baseMap) => baseMap.item === member.item
119-
);
120-
if (existingItem) {
121-
// object array trait doesn't automatically update model item
122-
existingItem.setTrait(stratumId, "image", member.image);
123-
} else {
124-
this.add(stratumId, member);
125-
}
126-
});
118+
newItemsIds
119+
.pushErrorTo(errors)
120+
?.forEach((member: BaseMapModel, i: number) => {
121+
const existingItem = this.items.find(
122+
(baseMap) => baseMap.item === member.item
123+
);
124+
if (existingItem) {
125+
// object array trait doesn't automatically update model item
126+
updateModelFromJson(existingItem, stratumId, items[i]);
127+
} else {
128+
this.add(stratumId, member);
129+
}
130+
});
127131
}
128132

129133
if (isJsonObject(rest))

lib/ReactViews/Map/TerriaViewerWrapper/TerriaViewerWrapper.tsx

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { FC, useEffect, useRef } from "react";
2-
3-
import { Splitter } from "./Splitter/Splitter";
4-
import { useViewState } from "../../Context";
1+
import { autorun } from "mobx";
2+
import { FC, RefObject, useEffect, useRef } from "react";
53
import styled from "styled-components";
4+
import ViewerMode from "../../../Models/ViewerMode";
5+
import { useViewState } from "../../Context";
6+
import { Splitter } from "./Splitter/Splitter";
67

78
export const TerriaViewerWrapper: FC = () => {
89
const viewState = useViewState();
@@ -21,13 +22,18 @@ export const TerriaViewerWrapper: FC = () => {
2122
};
2223
}, [viewState]);
2324

25+
// Use an effect hook to change map container background so that we don't
26+
// re-render the whole component when the map container background changes.
27+
useMapBackground(containerRef);
28+
2429
return (
2530
<TerrriaViewerContainer>
2631
<StyledMapPlaceholder>
2732
Loading the map, please wait...
2833
</StyledMapPlaceholder>
2934
<Splitter />
3035
<div
36+
data-testid="mapContainer"
3137
id="cesiumContainer"
3238
css={`
3339
cursor: auto;
@@ -43,6 +49,32 @@ export const TerriaViewerWrapper: FC = () => {
4349
);
4450
};
4551

52+
/**
53+
* A hook to reactively set the map container background color from the base
54+
* map background color setting
55+
*/
56+
const useMapBackground = (containerRef: RefObject<HTMLElement>) => {
57+
const terria = useViewState().terria;
58+
59+
useEffect(() => {
60+
const disposer = autorun(() => {
61+
// Only relevant when using leaflet mode
62+
if (terria.mainViewer.viewerMode !== ViewerMode.Leaflet) {
63+
return;
64+
}
65+
66+
const containerBackground = terria.baseMapsModel.baseMapItems.find(
67+
(it) => it.item === terria.mainViewer.baseMap
68+
)?.backgroundColor;
69+
70+
if (containerRef.current) {
71+
containerRef.current.style.backgroundColor = containerBackground ?? "";
72+
}
73+
});
74+
return disposer;
75+
}, [containerRef, terria]);
76+
};
77+
4678
const TerrriaViewerContainer = styled.aside`
4779
position: absolute;
4880
top: 0;

lib/Traits/TraitsClasses/BaseMapTraits.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ export class BaseMapTraits extends ModelTraits {
2222
})
2323
contrastColor?: string = "#ffffff";
2424

25+
@primitiveTrait({
26+
type: "string",
27+
name: "Background color",
28+
description:
29+
"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."
30+
})
31+
backgroundColor?: string;
32+
2533
@modelReferenceTrait({
2634
factory: CatalogMemberFactory,
2735
name: "Base map item",
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { screen } from "@testing-library/react";
2+
import { runInAction } from "mobx";
3+
import CommonStrata from "../../../../lib/Models/Definition/CommonStrata";
4+
import Terria from "../../../../lib/Models/Terria";
5+
import ViewerMode from "../../../../lib/Models/ViewerMode";
6+
import ViewState from "../../../../lib/ReactViewModels/ViewState";
7+
import { TerriaViewerWrapper } from "../../../../lib/ReactViews/Map/TerriaViewerWrapper";
8+
import { renderWithContexts } from "../../withContext";
9+
10+
describe("TerriaViewerWrapper", function () {
11+
let viewState: ViewState;
12+
let terria: Terria;
13+
14+
beforeEach(function () {
15+
terria = new Terria();
16+
viewState = new ViewState({ terria, catalogSearchProvider: undefined });
17+
});
18+
19+
describe("when main viewer is in leaflet mode", function () {
20+
beforeEach(function () {
21+
runInAction(() => {
22+
terria.mainViewer.viewerMode = ViewerMode.Leaflet;
23+
});
24+
});
25+
26+
it("sets container background if the active base map specifies a backgroundColor", async function () {
27+
terria.baseMapsModel.loadFromJson(CommonStrata.user, {
28+
items: [
29+
{
30+
item: {
31+
id: "test-basemap",
32+
type: "url-template-imagery"
33+
},
34+
backgroundColor: "lime"
35+
}
36+
]
37+
});
38+
await terria.mainViewer.setBaseMap(
39+
terria.baseMapsModel.baseMapItems[0].item
40+
);
41+
42+
renderWithContexts(<TerriaViewerWrapper />, viewState);
43+
const container = screen.queryByTestId("mapContainer");
44+
console.log(container?.dataset, container?.classList);
45+
expect(container).toHaveStyle(`background-color: rgb(0, 255, 0)`);
46+
});
47+
});
48+
});

0 commit comments

Comments
 (0)