Skip to content

Commit eaea916

Browse files
committed
mdd-improve-azure-react-sample
mdd-improve-azure-react-sample
1 parent 37574ac commit eaea916

1 file changed

Lines changed: 246 additions & 91 deletions

File tree

  • samples/maps/geo-map/display-azure-imagery/src

samples/maps/geo-map/display-azure-imagery/src/index.tsx

Lines changed: 246 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,271 @@
11
import React from 'react';
22
import ReactDOM from 'react-dom/client';
33
import './index.css';
4-
import { MapUtils, MapRegion } from './MapUtils';
5-
import { IgrGeographicMapModule } from 'igniteui-react-maps';
6-
import { IgrGeographicMap } from 'igniteui-react-maps';
7-
import { IgrAzureMapsMapImagery } from 'igniteui-react-maps';
8-
import { AzureMapsImageryStyle } from 'igniteui-react-maps';
9-
import { IgrButton, IgrDialog, IgrInput } from 'igniteui-react';
10-
import { IgrDataChartInteractivityModule } from 'igniteui-react-charts';
11-
// for handling of maps events and styling
12-
import 'igniteui-webcomponents/themes/light/bootstrap.css';
4+
import {
5+
IgrGeographicMapModule,
6+
IgrGeographicMap,
7+
IgrAzureMapsMapImagery,
8+
AzureMapsImageryStyle,
9+
IgrGeographicTileSeries
10+
} from "igniteui-react-maps";
11+
import { IgrButton, IgrDialog, IgrInput, IgrSelect, IgrSelectItem } from "igniteui-react";
12+
import { IgrDataChartInteractivityModule } from "igniteui-react-charts";
13+
import "igniteui-webcomponents/themes/light/bootstrap.css";
1314

1415
IgrGeographicMapModule.register();
1516
IgrDataChartInteractivityModule.register();
1617

18+
enum MapRegion { UnitedStates }
19+
20+
class MapUtils {
21+
public static navigateTo(geoMap: IgrGeographicMap | undefined, region: MapRegion) {
22+
if (!geoMap) return;
23+
if (region === MapRegion.UnitedStates)
24+
geoMap.zoomToGeographic({ left: -125, top: 50, width: 60, height: 25 });
25+
}
26+
27+
public static zoomToNYC(geoMap: IgrGeographicMap | undefined) {
28+
if (!geoMap) return;
29+
geoMap.zoomToGeographic({ left: -74.2591, top: 40.9176, width: -73.7004 - (-74.2591), height: 40.4774 - 40.9176 });
30+
}
31+
}
32+
33+
const placeholderImages: Record<string, string> = {
34+
Satellite: "https://static.infragistics.com/xplatform/images/browsers/azure-maps/azure_satellite.png",
35+
Road: "https://static.infragistics.com/xplatform/images/browsers/azure-maps/azure_road.png",
36+
DarkGrey: "https://static.infragistics.com/xplatform/images/browsers/azure-maps/azure_darkgrey.png",
37+
TerraOverlay: "https://static.infragistics.com/xplatform/images/browsers/azure-maps/azure_terra_overlay.png",
38+
HybridRoadOverlay: "https://static.infragistics.com/xplatform/images/browsers/azure-maps/AzureHybridRoad.png",
39+
HybridDarkGreyOverlay: "https://static.infragistics.com/xplatform/images/browsers/azure-maps/azure_hybriddarkgrey.png",
40+
LabelsRoadOverlay: "https://static.infragistics.com/xplatform/images/browsers/azure-maps/azure_labelsroad.png",
41+
LabelsDarkGreyOverlay: "https://static.infragistics.com/xplatform/images/browsers/azure-maps/azure_labelsdarkgrey.png",
42+
TrafficDelayOverlay: "https://static.infragistics.com/xplatform/images/browsers/azure-maps/azure_trafficdelay.png",
43+
TrafficAbsoluteOverlay: "https://static.infragistics.com/xplatform/images/browsers/azure-maps/azure_traffic_absolute.png",
44+
TrafficReducedOverlay: "https://static.infragistics.com/xplatform/images/browsers/azure-maps/azure_traffic_light.png",
45+
TrafficRelativeOverlay: "https://static.infragistics.com/xplatform/images/browsers/azure-maps/azure_traffic_relative.png",
46+
WeatherInfraredOverlay: "https://static.infragistics.com/xplatform/images/browsers/azure-maps/azure_weather_Infrared_road.png",
47+
WeatherRadarOverlay: "https://static.infragistics.com/xplatform/images/browsers/azure-maps/azure_weather_radar.png"
48+
};
49+
50+
const trafficWeatherStyles = [
51+
AzureMapsImageryStyle.TrafficDelay,
52+
AzureMapsImageryStyle.TrafficAbsolute,
53+
AzureMapsImageryStyle.TrafficReduced,
54+
AzureMapsImageryStyle.TrafficRelativeDark,
55+
AzureMapsImageryStyle.WeatherInfrared,
56+
AzureMapsImageryStyle.WeatherRadar
57+
];
58+
1759
export default class MapDisplayImageryAzure extends React.Component<any, any> {
60+
private geoMap?: IgrGeographicMap;
61+
private dialogRef?: IgrDialog;
1862

19-
public mapWeather?: IgrGeographicMap;
20-
public mapAerial?: IgrGeographicMap;
21-
public mapRoad?: IgrGeographicMap;
22-
public apiKey: string;
23-
public dialogRef: IgrDialog;
63+
constructor(props: any) {
64+
super(props);
65+
this.state = { apiKey: "", styleName: "Satellite", mapVisible: false };
2466

25-
constructor(props: any) {
26-
super(props);
27-
this.state = { apiKey: "" };
28-
this.onDialogRef = this.onDialogRef.bind(this);
29-
this.onDialogShow = this.onDialogShow.bind(this);
30-
this.onDialogHide = this.onDialogHide.bind(this);
31-
this.onApiKeyChange = this.onApiKeyChange.bind(this);
67+
this.onDialogRef = this.onDialogRef.bind(this);
68+
this.onDialogShow = this.onDialogShow.bind(this);
69+
this.onDialogHide = this.onDialogHide.bind(this);
70+
this.onApiKeyChange = this.onApiKeyChange.bind(this);
71+
this.onApplyKey = this.onApplyKey.bind(this);
72+
this.onResetKey = this.onResetKey.bind(this);
73+
this.onStyleChange = this.onStyleChange.bind(this);
74+
}
3275

33-
}
76+
render(): JSX.Element {
77+
return (
78+
<div
79+
style={{
80+
display: "flex",
81+
flexDirection: "column",
82+
alignItems: "center",
83+
gap: "16px",
84+
width: "100%",
85+
padding: "16px",
86+
boxSizing: "border-box"
87+
}}
88+
>
89+
{/* Controls panel */}
90+
<div
91+
style={{
92+
display: "flex",
93+
gap: "12px",
94+
alignItems: "center",
95+
justifyContent: "center",
96+
flexWrap: "wrap"
97+
}}
98+
>
99+
<IgrButton variant="contained" onClick={this.onDialogShow}>
100+
Enter Azure Maps API Key
101+
</IgrButton>
34102

35-
public render(): JSX.Element {
36-
return (
37-
<div className="container horizontal" >
38-
<IgrButton variant="contained" onClick={this.onDialogShow}>
39-
<span>Show Dialog</span>
40-
</IgrButton>
41-
42-
<IgrDialog title="Confirmation" ref={this.onDialogRef}>
43-
<IgrInput label="AzureKey" value={this.state.apiKey} inputMode='text' onInput={this.onApiKeyChange}>
44-
45-
</IgrInput>
46-
47-
<div slot="footer">
48-
<IgrButton onClick={this.onDialogHide} variant="flat"><span>Cancel</span></IgrButton>
49-
<IgrButton onClick={this.onDialogHide} variant="flat"><span>OK</span></IgrButton>
50-
</div>
51-
</IgrDialog>
52-
53-
<div className="container" >
54-
<IgrGeographicMap
55-
ref={(ref) => { this.mapWeather = ref!; }}
56-
width="100%" height="100%" zoomable="true"/>
57-
</div>
58-
<div className="container" >
59-
<IgrGeographicMap
60-
ref={(ref) => { this.mapAerial = ref!; }}
61-
width="100%" height="100%" zoomable="true"/>
62-
</div>
63-
<div className="container" >
64-
<IgrGeographicMap
65-
ref={(ref) => { this.mapRoad = ref!; }}
66-
67-
width="100%" height="100%" zoomable="true"/>
68-
</div>
69-
<div className="overlay-bottom-right overlay-border">Imagery Tiles: @Azure Maps</div>
70-
</div>
71-
);
72-
}
103+
<IgrSelect
104+
value={this.state.styleName}
105+
onChange={this.onStyleChange}
106+
style={{ minWidth: "220px" }}
107+
>
108+
{Object.keys(placeholderImages).map((key) => (
109+
<IgrSelectItem key={key} value={key}>
110+
{key}
111+
</IgrSelectItem>
112+
))}
113+
</IgrSelect>
114+
</div>
73115

74-
public onApiKeyChange(e: any) {
75-
console.log(e.detail);
76-
this.setState({ apiKey: e.detail}, () => {
77-
this.updateAzureMap(this.mapWeather, AzureMapsImageryStyle.WeatherInfrared);
78-
this.updateAzureMap(this.mapAerial, AzureMapsImageryStyle.Imagery);
79-
this.updateAzureMap(this.mapRoad, AzureMapsImageryStyle.Road);
80-
}
81-
);
82-
}
116+
{/* Placeholder image */}
117+
{!this.state.mapVisible && (
118+
<div
119+
style={{
120+
width: "640px",
121+
height: "480px",
122+
display: "flex",
123+
justifyContent: "center",
124+
alignItems: "center",
125+
border: "1px solid #ccc",
126+
borderRadius: "6px",
127+
overflow: "hidden",
128+
boxShadow: "0 2px 6px rgba(0,0,0,0.2)"
129+
}}
130+
>
131+
<img
132+
src={placeholderImages[this.state.styleName]}
133+
alt={this.state.styleName}
134+
style={{ width: "100%", height: "100%", objectFit: "cover" }}
135+
/>
136+
</div>
137+
)}
138+
139+
{/* Map container */}
140+
<div
141+
style={{
142+
width: "100%",
143+
maxWidth: "100%",
144+
height: "1000px",
145+
overflow: "hidden",
146+
display: this.state.mapVisible ? "block" : "none"
147+
}}
148+
>
149+
<IgrGeographicMap
150+
ref={(r) => (this.geoMap = r!)}
151+
width="100%"
152+
height="100%"
153+
zoomable={true}
154+
/>
155+
</div>
83156

84-
public updateAzureMap = (geoMap: IgrGeographicMap | undefined, style: AzureMapsImageryStyle) => {
85-
if (!geoMap || !this.state.apiKey) { return; }
157+
{/* Dialog for API key */}
158+
<IgrDialog title="Azure Key" ref={this.onDialogRef}>
159+
<IgrInput
160+
label="Azure Key"
161+
value={this.state.apiKey}
162+
inputMode="text"
163+
onInput={this.onApiKeyChange}
164+
/>
165+
<div
166+
slot="footer"
167+
style={{
168+
display: "flex",
169+
justifyContent: "flex-end",
170+
gap: "8px"
171+
}}
172+
>
173+
<IgrButton variant="flat" onClick={this.onResetKey}>
174+
Reset
175+
</IgrButton>
176+
<IgrButton variant="flat" onClick={this.onApplyKey}>
177+
Submit
178+
</IgrButton>
179+
</div>
180+
</IgrDialog>
181+
</div>
182+
);
183+
}
86184

87-
const tileSource = new IgrAzureMapsMapImagery();
88-
tileSource.apiKey = this.state.apiKey;
89-
tileSource.imageryStyle = style;
90-
91-
geoMap.backgroundContent = tileSource;
185+
private onDialogRef(dialog: IgrDialog) { this.dialogRef = dialog; }
186+
private onDialogShow() { this.dialogRef?.show(); }
187+
private onDialogHide() { this.dialogRef?.hide(); }
188+
private onApiKeyChange(e: any) { this.setState({ apiKey: e.detail ?? e.target?.value ?? "" }); }
189+
private onResetKey() { this.setState({ apiKey: "", mapVisible: false }); this.onDialogHide(); }
92190

93-
// optional - navigating to a map region
94-
MapUtils.navigateTo(geoMap, MapRegion.Caribbean);
95-
}
191+
private onApplyKey() {
192+
if (!this.state.apiKey) { this.onDialogHide(); return; }
193+
this.setState({ mapVisible: true }, () => this.updateAzureMap(this.mapStyleFromName(this.state.styleName)));
194+
this.onDialogHide();
195+
}
96196

97-
public onDialogRef(dialog: IgrDialog){
98-
if (!dialog) { return; }
99-
this.dialogRef = dialog;
100-
}
197+
private onStyleChange(e: CustomEvent) {
198+
const selected = e.detail.value as string;
199+
this.setState({ styleName: selected }, () => {
200+
if (this.state.apiKey) this.updateAzureMap(this.mapStyleFromName(selected));
201+
});
202+
}
101203

102-
public onDialogShow() {
103-
if(this.dialogRef){
104-
this.dialogRef.show();
105-
}
204+
private mapStyleFromName(name: string): AzureMapsImageryStyle {
205+
switch (name) {
206+
case "Satellite": return AzureMapsImageryStyle.Imagery;
207+
case "Road": return AzureMapsImageryStyle.Road;
208+
case "DarkGrey": return AzureMapsImageryStyle.DarkGrey;
209+
case "TerraOverlay": return AzureMapsImageryStyle.Terra;
210+
case "HybridRoadOverlay": return AzureMapsImageryStyle.HybridRoad;
211+
case "HybridDarkGreyOverlay": return AzureMapsImageryStyle.HybridDarkGrey;
212+
case "LabelsRoadOverlay": return AzureMapsImageryStyle.LabelsRoad;
213+
case "LabelsDarkGreyOverlay": return AzureMapsImageryStyle.LabelsDarkGrey;
214+
case "TrafficDelayOverlay": return AzureMapsImageryStyle.TrafficDelay;
215+
case "TrafficAbsoluteOverlay": return AzureMapsImageryStyle.TrafficAbsolute;
216+
case "TrafficReducedOverlay": return AzureMapsImageryStyle.TrafficReduced;
217+
case "TrafficRelativeOverlay": return AzureMapsImageryStyle.TrafficRelativeDark;
218+
case "WeatherInfraredOverlay": return AzureMapsImageryStyle.WeatherInfrared;
219+
case "WeatherRadarOverlay": return AzureMapsImageryStyle.WeatherRadar;
220+
default: return AzureMapsImageryStyle.Imagery;
106221
}
222+
}
223+
224+
private updateAzureMap(style: AzureMapsImageryStyle) {
225+
if (!this.geoMap || !this.state.apiKey) return;
226+
227+
this.geoMap.series.clear();
228+
const tileSource = new IgrAzureMapsMapImagery();
229+
tileSource.apiKey = this.state.apiKey;
107230

108-
public onDialogHide() {
109-
if(this.dialogRef){
110-
this.dialogRef.hide();
111-
}
231+
const series = new IgrGeographicTileSeries({ name: "AzureTileSeries", tileImagery: tileSource });
232+
series.tileImagery = tileSource;
233+
234+
if (trafficWeatherStyles.includes(style)) {
235+
const bg = new IgrAzureMapsMapImagery();
236+
bg.apiKey = this.state.apiKey;
237+
bg.imageryStyle = AzureMapsImageryStyle.DarkGrey;
238+
this.geoMap.backgroundContent = bg;
239+
240+
tileSource.imageryStyle = style;
241+
this.geoMap.series.add(series);
242+
243+
if (style === AzureMapsImageryStyle.WeatherInfrared || style === AzureMapsImageryStyle.WeatherRadar) {
244+
MapUtils.navigateTo(this.geoMap, MapRegion.UnitedStates);
245+
} else {
246+
MapUtils.zoomToNYC(this.geoMap);
247+
}
112248
}
249+
else if (style === AzureMapsImageryStyle.Terra) {
250+
const bg = new IgrAzureMapsMapImagery();
251+
bg.apiKey = this.state.apiKey;
252+
bg.imageryStyle = AzureMapsImageryStyle.Imagery;
253+
this.geoMap.backgroundContent = bg;
113254

255+
tileSource.imageryStyle = style;
256+
this.geoMap.series.add(series);
257+
MapUtils.navigateTo(this.geoMap, MapRegion.UnitedStates);
258+
}
259+
else {
260+
tileSource.imageryStyle = style;
261+
this.geoMap.series.add(series);
262+
const bg = new IgrAzureMapsMapImagery();
263+
bg.apiKey = this.state.apiKey;
264+
bg.imageryStyle = AzureMapsImageryStyle.Imagery;
265+
this.geoMap.backgroundContent = bg;
266+
MapUtils.navigateTo(this.geoMap, MapRegion.UnitedStates);
267+
}
268+
}
114269
}
115270

116271
// rendering above class to the React DOM

0 commit comments

Comments
 (0)