Skip to content

Commit b0a7202

Browse files
wip
1 parent 4c54635 commit b0a7202

File tree

4 files changed

+46
-3
lines changed

4 files changed

+46
-3
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,17 @@ import { IModelApp } from "@itwin/core-frontend";
99
import type { MapCartoRectangle } from "@itwin/core-frontend";
1010
import type { AddressProvider, AddressRequest, AddressData, GeoCoder } from "./AddressProvider";
1111

12-
12+
/**
13+
* Information requiered to retreive location from Google Places API.
14+
**/
1315
export interface GoogleAddressData extends AddressData {
1416
placeId: string;
1517
}
1618

19+
/**
20+
* Address provider for Google Places API.
21+
* It supports address suggestions and location retrieval based on place IDs.
22+
*/
1723
export class GoogleAddressProvider implements AddressProvider {
1824
private _radius = 5000;
1925
private _apiKey: string;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66

77
.geotools-geoaddresssearch__container {
8-
width: 300px;
8+
width: 400px;
99
margin-left: -7px;
1010
margin-right: -7px;
1111
}

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

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,61 @@
55

66
import "./GeoAddressSearch.scss";
77
import * as React from "react";
8+
import { useActiveViewport } from "@itwin/appui-react";
9+
import { BaseMapLayerSettings } from "@itwin/core-common";
810
import { SvgCloseSmall, SvgSearch } from "@itwin/itwinui-icons-react";
911
import { ComboBox, IconButton } from "@itwin/itwinui-react";
1012
import { BingAddressProvider } from "../BingAddressProvider";
1113
import { GeoTools } from "../GeoTools";
14+
import { GoogleAddressProvider } from "../GoogleAddressProvider";
1215
import { IModelGeoView } from "../IModelGeoView";
1316

17+
import type { Viewport } from "@itwin/core-frontend";
1418
import type { SelectOption } from "@itwin/itwinui-react";
1519
import type { AddressData, AddressProvider } from "../AddressProvider";
20+
/**
21+
* Properties for the <GeoAddressSearch> component.
22+
*/
1623
export interface GeoAddressSearchProps {
1724
/** Address provider object */
1825
provider?: AddressProvider;
1926
/** Indicates whether to set focus to the input element (default to true)*/
2027
setFocus?: boolean;
2128
}
2229

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+
42+
/**
43+
* <GeoAddressSearch> react component
44+
*/
2345
export function GeoAddressSearch(props: GeoAddressSearchProps) {
2446
const [inputValue, setInputValue] = React.useState("");
2547
const [options, setOptions] = React.useState<SelectOption<string>[]>([]);
2648
const [addressCache, setAddressCache] = React.useState<AddressData[]>([]);
49+
const activeViewport = useActiveViewport(); // Hook to ensure the component re-renders when the active viewport changes
50+
const [disabled, setDisabled] = React.useState<boolean>(() => isGoogleBaseMap(activeViewport));
2751

2852
// `React.useMemo' is used avoid creating new object on each render cycle
2953
// Default is Bing provider, but we might want to default to Google in the future
3054
const addressProvider = React.useMemo(() => props.provider ?? new BingAddressProvider(), [props.provider]);
3155

56+
React.useEffect(() => {
57+
setDisabled(!isValidBaseMap(addressProvider, activeViewport));
58+
return activeViewport?.onDisplayStyleChanged.addListener(
59+
(vp)=>{setDisabled(!isValidBaseMap(addressProvider, vp));}
60+
);
61+
}, [activeViewport]);
62+
3263
const onAddressSelected = async (selected: string) => {
3364
setInputValue(selected);
3465
let locatedByPosition = false
@@ -69,12 +100,14 @@ export function GeoAddressSearch(props: GeoAddressSearchProps) {
69100
<div className="geotools-geoaddresssearch__container">
70101
<div className="geotools-geoaddresssearch__combobox">
71102
<ComboBox
103+
72104
options={options}
73105
filterFunction={(options)=>options} // disable filtering as it can interfere with the address provider
74106
emptyStateMessage={GeoTools.translate("geoAddressSearch.noResults")}
75107
onHide={()=>clearValue()}
76108
inputProps={{
77-
placeholder: GeoTools.translate("geoAddressSearch.inputPlaceHolder"),
109+
disabled,
110+
placeholder: disabled ? GeoTools.translate("geoAddressSearch.invalidBaseMap") : GeoTools.translate("geoAddressSearch.inputPlaceHolder"),
78111
onChange: async (event: React.ChangeEvent<HTMLInputElement>) => {
79112

80113
const items = await getAddressesFunc(inputValue);
@@ -87,12 +120,15 @@ export function GeoAddressSearch(props: GeoAddressSearchProps) {
87120
}}
88121
onChange={(value: any) => {
89122
onAddressSelected(value);
123+
90124
}}
91125
value={inputValue}
92126
enableVirtualization
93127
/>
94128
</div>
129+
95130
<IconButton
131+
disabled={disabled}
96132
className="geotools-geoaddresssearch__button"
97133
onClick={clearValue}
98134
label={!inputValue ? "" : GeoTools.translate("geoAddressSearch.clearTooltip")} >

packages/itwin/geo-tools/src/public/locales/en/GeoTools.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"geoAddressSearch": {
33
"label": "Search Address",
44
"inputPlaceHolder": "Search Address..",
5+
"invalidBaseMap": "Invalid Base Map",
56
"clearTooltip": "Clear",
67
"noResults": "No results found"
78
}

0 commit comments

Comments
 (0)