Skip to content

Commit 2d93a8f

Browse files
wip
1 parent b0a7202 commit 2d93a8f

File tree

6 files changed

+44
-36
lines changed

6 files changed

+44
-36
lines changed

packages/itwin/geo-tools/src/AddressProvider.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type { Cartographic } from "@itwin/core-common";
55
* See LICENSE.md in the project root for license terms and full copyright notice.
66
*--------------------------------------------------------------------------------------------*/
77
import type { Range2d } from "@itwin/core-geometry";
8-
import type { MapCartoRectangle } from "@itwin/core-frontend";
8+
import type { MapCartoRectangle, Viewport } from "@itwin/core-frontend";
99
export interface AddressData {
1010
formattedAddress: string;
1111
}
@@ -17,11 +17,19 @@ export interface AddressRequest {
1717
body?: string;
1818
}
1919

20+
export interface AddressProviderViewContext {
21+
viewport?: Viewport;
22+
}
23+
24+
2025
export interface GeoCoder {
2126
getLocation(data: AddressData): Promise<Cartographic>;
2227
}
2328

2429
export interface AddressProvider {
2530
getSuggestions(query: string, viewRect: MapCartoRectangle): Promise<AddressData[]>;
2631
supportsAddressLocation(): this is GeoCoder;
32+
33+
/** Indicates whether the address provider should be disabled in the current view context*/
34+
isDisabled(context: AddressProviderViewContext): boolean;
2735
}

packages/itwin/geo-tools/src/BingAddressProvider.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { IModelApp } from "@itwin/core-frontend";
33

44
import type { MapCartoRectangle } from "@itwin/core-frontend";
5-
import type { GeoCoder, AddressProvider, AddressRequest, AddressData } from "./AddressProvider";
5+
import type { GeoCoder, AddressProvider, AddressRequest, AddressData, AddressProviderViewContext } from "./AddressProvider";
66

77
export class BingAddressProvider implements AddressProvider {
88
private _radius = 5000;
@@ -15,6 +15,10 @@ export class BingAddressProvider implements AddressProvider {
1515
return false;
1616
}
1717

18+
public isDisabled(_context: AddressProviderViewContext) {
19+
return false;
20+
};
21+
1822
constructor(radius?: number, maxResults?: number, entityTypes?: string[]) {
1923
if (maxResults !== undefined) {
2024
this._maxResults = maxResults;

packages/itwin/geo-tools/src/GeoToolsItemDef.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import React from "react";
77
import { ToolbarItemUtilities } from "@itwin/appui-react";
88
import { SvgGeosearch } from "@itwin/itwinui-icons-react";
9+
import { BingAddressProvider } from "./BingAddressProvider";
910
import { GeoAddressSearch } from "./components/GeoAddressSearch";
1011
import { GeoTools } from "./GeoTools";
1112

@@ -25,7 +26,7 @@ export class GeoToolsItemDef {
2526
id: "geo-tools:geoAddressSearch",
2627
icon: <SvgGeosearch />,
2728
label: GeoTools.translate("geoAddressSearch.label"),
28-
panelContent: <GeoAddressSearch provider={opts?.addressProvider}/>,
29+
panelContent: <GeoAddressSearch provider={opts?.addressProvider?? new BingAddressProvider()}/>,
2930
});
3031
}
3132
}

packages/itwin/geo-tools/src/GoogleAddressProvider.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
* See LICENSE.md in the project root for license terms and full copyright notice.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { Cartographic } from "@itwin/core-common";
6+
import { BaseMapLayerSettings, Cartographic } from "@itwin/core-common";
77
import { IModelApp } from "@itwin/core-frontend";
88

9-
import type { MapCartoRectangle } from "@itwin/core-frontend";
10-
import type { AddressProvider, AddressRequest, AddressData, GeoCoder } from "./AddressProvider";
9+
import type { MapCartoRectangle, Viewport } from "@itwin/core-frontend";
10+
import type { AddressProvider, AddressRequest, AddressData, GeoCoder, AddressProviderViewContext } from "./AddressProvider";
1111

1212
/**
1313
* Information requiered to retreive location from Google Places API.
@@ -25,6 +25,7 @@ export class GoogleAddressProvider implements AddressProvider {
2525
private _apiKey: string;
2626
public readonly hasAddressIds = true;
2727

28+
2829
constructor(locationBiasRadius?: number) {
2930
if (locationBiasRadius !== undefined) {
3031
this._radius = locationBiasRadius;
@@ -40,6 +41,18 @@ export class GoogleAddressProvider implements AddressProvider {
4041
return true;
4142
}
4243

44+
private isGoogleBaseMap (vp?: Viewport): boolean {
45+
return (
46+
vp?.viewFlags.backgroundMap === true
47+
&& vp?.displayStyle.backgroundMapBase instanceof BaseMapLayerSettings
48+
&& vp.displayStyle.backgroundMapBase.formatId === "GoogleMaps"
49+
);
50+
};
51+
52+
public isDisabled(context: AddressProviderViewContext) {
53+
return !this.isGoogleBaseMap(context.viewport);
54+
};
55+
4356
protected async getAuthRequestHeader(): Promise<Record<string, string>> {
4457
return { "X-Goog-Api-Key": this._apiKey};
4558
}

packages/itwin/geo-tools/src/components/GeoAddressSearch.tsx

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,9 @@
66
import "./GeoAddressSearch.scss";
77
import * as React from "react";
88
import { useActiveViewport } from "@itwin/appui-react";
9-
import { BaseMapLayerSettings } from "@itwin/core-common";
109
import { SvgCloseSmall, SvgSearch } from "@itwin/itwinui-icons-react";
1110
import { ComboBox, IconButton } from "@itwin/itwinui-react";
12-
import { BingAddressProvider } from "../BingAddressProvider";
1311
import { GeoTools } from "../GeoTools";
14-
import { GoogleAddressProvider } from "../GoogleAddressProvider";
1512
import { IModelGeoView } from "../IModelGeoView";
1613

1714
import type { Viewport } from "@itwin/core-frontend";
@@ -22,52 +19,37 @@ import type { AddressData, AddressProvider } from "../AddressProvider";
2219
*/
2320
export interface GeoAddressSearchProps {
2421
/** Address provider object */
25-
provider?: AddressProvider;
22+
provider: AddressProvider;
23+
2624
/** Indicates whether to set focus to the input element (default to true)*/
2725
setFocus?: boolean;
2826
}
29-
30-
const isGoogleBaseMap = (vp?: Viewport): boolean => {
31-
return (
32-
vp?.viewFlags.backgroundMap === true
33-
&& vp?.displayStyle.backgroundMapBase instanceof BaseMapLayerSettings
34-
&& vp.displayStyle.backgroundMapBase.formatId === "GoogleMaps"
35-
);
36-
};
37-
const isValidBaseMap = (provider: AddressProvider, vp?: Viewport) => {
38-
const isGoogleAddressProvider = provider instanceof GoogleAddressProvider;
39-
return !isGoogleAddressProvider || (isGoogleAddressProvider && isGoogleBaseMap(vp));
40-
}
41-
4227
/**
43-
* <GeoAddressSearch> react component
4428
*/
4529
export function GeoAddressSearch(props: GeoAddressSearchProps) {
30+
const {provider} = props;
31+
4632
const [inputValue, setInputValue] = React.useState("");
4733
const [options, setOptions] = React.useState<SelectOption<string>[]>([]);
4834
const [addressCache, setAddressCache] = React.useState<AddressData[]>([]);
4935
const activeViewport = useActiveViewport(); // Hook to ensure the component re-renders when the active viewport changes
50-
const [disabled, setDisabled] = React.useState<boolean>(() => isGoogleBaseMap(activeViewport));
51-
52-
// `React.useMemo' is used avoid creating new object on each render cycle
53-
// Default is Bing provider, but we might want to default to Google in the future
54-
const addressProvider = React.useMemo(() => props.provider ?? new BingAddressProvider(), [props.provider]);
36+
const [disabled, setDisabled] = React.useState<boolean>(() => provider.isDisabled({ viewport: activeViewport }) );
5537

5638
React.useEffect(() => {
57-
setDisabled(!isValidBaseMap(addressProvider, activeViewport));
39+
5840
return activeViewport?.onDisplayStyleChanged.addListener(
59-
(vp)=>{setDisabled(!isValidBaseMap(addressProvider, vp));}
41+
(vp)=>{setDisabled(provider?.isDisabled({ viewport: vp }) );}
6042
);
6143
}, [activeViewport]);
6244

6345
const onAddressSelected = async (selected: string) => {
6446
setInputValue(selected);
6547
let locatedByPosition = false
66-
if (addressProvider.supportsAddressLocation()) {
48+
if (provider.supportsAddressLocation()) {
6749
const address = addressCache.find((addr) => addr.formattedAddress === selected);
6850
if (address !== undefined) {
6951
try {
70-
const location = await addressProvider.getLocation(address);
52+
const location = await provider.getLocation(address);
7153
if (location) {
7254
locatedByPosition = await IModelGeoView.locatePosition(location);
7355
}
@@ -83,7 +65,7 @@ export function GeoAddressSearch(props: GeoAddressSearchProps) {
8365
const getAddressesFunc = async (value: string): Promise<AddressData[]> => {
8466
const viewBBox = IModelGeoView.getFrustumLonLatBBox();
8567
if (viewBBox && value) {
86-
const addr = await addressProvider.getSuggestions(value, viewBBox);
68+
const addr = await provider.getSuggestions(value, viewBBox);
8769
setAddressCache(addr);
8870
return addr;
8971
}

packages/itwin/geo-tools/src/test/GeoAddressSearch.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { expect } from "chai";
77
import { mount } from "enzyme";
8-
import * as React from "react";
8+
import React from "react";
99
import * as sinon from "sinon";
1010
import { stubObject } from "ts-sinon";
1111
import { SpecialKey } from "@itwin/appui-abstract";
@@ -60,7 +60,7 @@ describe("GeoAddressSearch", () => {
6060
});
6161

6262
it("renders", () => {
63-
const wrapper = mount(<GeoAddressSearch />);
63+
const wrapper = mount(<GeoAddressSearch provider={new BingAddressProvider()}/>);
6464

6565
expect(wrapper.find("input[type='text']").length).to.eq(1);
6666
wrapper.unmount();

0 commit comments

Comments
 (0)