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
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"cSpell.words": [
"RMWC"
]
],
"files.eol": "\n"
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const ActiveLayersPanel: React.FC<IActiveLayersPanelProps> = ({ locale })
{ id: IMAGERY, values: [] },
{ id: SERVICE, values: [] },
{ id: DATA, values: [] },
{ id: THREE_D, values: [] }
{ id: THREE_D, values: [] },
]);
const [collapsedSections, setCollapsedSections] = useState<Record<string, boolean>>({});

Expand All @@ -79,47 +79,54 @@ export const ActiveLayersPanel: React.FC<IActiveLayersPanelProps> = ({ locale })
const getImageryLayers = (): IActiveLayer[] => {
const layerList = getLayerList();
return layerList.length > 0
? layerList.map((layer): IActiveLayer | undefined => {
const meta = get(layer, 'meta');
const layerId = getLayerId(layer);
if (!isManagedImageryLayer(layerId)) {
return undefined;
}
return {
id: layerId as string,
name: (getLayerName(layer) ?? layerId) as string,
rect: layer.rectangle,
isDisabled: isBaseMapLayer(meta as Record<string, unknown>)
};
}).filter((item): item is IActiveLayer => item !== undefined)
? layerList
.map((layer): IActiveLayer | undefined => {
const meta = get(layer, 'meta');
const layerId = getLayerId(layer);
if (!isManagedImageryLayer(layerId)) {
return undefined;
}
return {
id: layerId as string,
name: (getLayerName(layer) ?? layerId) as string,
rect: layer.rectangle,
isDisabled: isBaseMapLayer(meta as Record<string, unknown>),
};
})
.filter((item): item is IActiveLayer => item !== undefined)
: [];
};

const getServiceLayers = (): IActiveLayer[] => {
const layerList = getLayerList();
return layerList.length > 0
? layerList.map((layer, i): IActiveLayer | undefined => {
if (!isServiceLayer(getLayerId(layer))) {
return undefined;
}
return {
id: getServiceLayerId(layer, i),
name: getServiceLayerName(layer, i),
rect: layer.rectangle,
isDisabled: true
};
}).filter((item): item is IActiveLayer => item !== undefined)
? layerList
.map((layer, i): IActiveLayer | undefined => {
if (!isServiceLayer(getLayerId(layer))) {
return undefined;
}
return {
id: getServiceLayerId(layer, i),
name: getServiceLayerName(layer, i),
rect: layer.rectangle,
isDisabled: true,
};
})
.filter((item): item is IActiveLayer => item !== undefined)
: [];
};

const getDataLayers = (): IActiveLayer[] => {
return mapViewer.layersManager?.dataLayerList.map((dataLayer) => {
return {
id: getLayerId(dataLayer) as string,
name: (getDataLayerName(dataLayer.meta) ?? getLayerName(dataLayer)) as string,
rect: Rectangle.fromDegrees(...bbox(getLayerFootprint(dataLayer.meta))),
isDisabled: false
}; }) || [];
return (
mapViewer.layersManager?.dataLayerList.map((dataLayer) => {
return {
id: getLayerId(dataLayer) as string,
name: (getDataLayerName(dataLayer.meta) ?? getLayerName(dataLayer)) as string,
rect: Rectangle.fromDegrees(...bbox(getLayerFootprint(dataLayer.meta))),
isDisabled: false,
};
}) || []
);
};

const get3DModels = (): IActiveLayer[] => {
Expand Down Expand Up @@ -167,7 +174,9 @@ export const ActiveLayersPanel: React.FC<IActiveLayersPanelProps> = ({ locale })
}, []);

useEffect(() => {
if (!mapViewer.layersManager) { return; }
if (!mapViewer.layersManager) {
return;
}
const handleLayerEvent = (): void => {
refreshSections();
};
Expand All @@ -186,14 +195,16 @@ export const ActiveLayersPanel: React.FC<IActiveLayersPanelProps> = ({ locale })
}, [mapViewer.layersManager]);

useEffect(() => {
if (!mapViewer.layersManager) { return; }
if (!mapViewer.layersManager) {
return;
}
const handleDataLayerEvent = (): void => {
setSections((prev) =>
prev.map((item) =>
item.id === DATA
? {
...item,
values: getDataLayers()
values: getDataLayers(),
}
: item
)
Expand All @@ -206,14 +217,16 @@ export const ActiveLayersPanel: React.FC<IActiveLayersPanelProps> = ({ locale })
}, [mapViewer.layersManager?.dataLayerList]);

useEffect(() => {
if (!mapViewer.layersManager) { return; }
if (!mapViewer.layersManager) {
return;
}
const handle3DModelEvent = (): void => {
setSections((prev) =>
prev.map((item) =>
item.id === THREE_D
? {
...item,
values: get3DModels()
values: get3DModels(),
}
: item
)
Expand Down Expand Up @@ -241,8 +254,9 @@ export const ActiveLayersPanel: React.FC<IActiveLayersPanelProps> = ({ locale })

return (
<Box className="activeLayersPanel">
{
sections.filter(item => item.values.length > 0).map((section) => (
{sections
.filter((item) => item.values.length > 0)
.map((section) => (
<Box
key={section.id}
className={`cesium-cesiumInspector-section ${collapsedSections[section.id] ? 'cesium-cesiumInspector-section-collapsed' : ''}`}
Expand All @@ -252,36 +266,41 @@ export const ActiveLayersPanel: React.FC<IActiveLayersPanelProps> = ({ locale })
{getLabel(section.id)}
</Typography>
<Box className="cesium-cesiumInspector-sectionContent">
{
section.values.map((activeLayer: IActiveLayer) => (
<Box key={activeLayer.id} className="layer">
<Tooltip content={activeLayer.name}>
<Box className={`name ${activeLayer.isDisabled ? 'disabled' : ''}`}><bdi>{activeLayer.name}</bdi></Box>
{section.values.map((activeLayer: IActiveLayer) => (
<Box key={activeLayer.id} className="layer">
<Tooltip content={activeLayer.name}>
<Box className={`name ${activeLayer.isDisabled ? 'disabled' : ''}`}>
<bdi>{activeLayer.name}</bdi>
</Box>
</Tooltip>
<Box className="icons">
<Tooltip content={get(locale, 'FLY_TO') ?? 'Fly To'}>
<Box
className="icon"
onClick={(event) => {
event.stopPropagation();
handleFlyTo(activeLayer);
}}
>
<svg fill="var(--mdc-theme-cesium-color)" width="100%" height="100%" viewBox="0 0 256 256">
<path d="M236,120H223.66406A96.15352,96.15352,0,0,0,136,32.33618V20a8,8,0,0,0-16,0V32.33618A96.15352,96.15352,0,0,0,32.33594,120H20a8,8,0,0,0,0,16H32.33594A96.15352,96.15352,0,0,0,120,223.66382V236a8,8,0,0,0,16,0V223.66382A96.15352,96.15352,0,0,0,223.66406,136H236a8,8,0,0,0,0-16Zm-40,16h11.59912A80.14164,80.14164,0,0,1,136,207.59912V196a8,8,0,0,0-16,0v11.59912A80.14164,80.14164,0,0,1,48.40088,136H60a8,8,0,0,0,0-16H48.40088A80.14164,80.14164,0,0,1,120,48.40088V60a8,8,0,0,0,16,0V48.40088A80.14164,80.14164,0,0,1,207.59912,120H196a8,8,0,0,0,0,16Z" />
<polygon points="128,80 80,170 128,150 176,170" fill="var(--mdc-theme-cesium-color)" />
</svg>
</Box>
</Tooltip>
<Box className="icons">
<Tooltip content={get(locale, 'FLY_TO') ?? 'Fly To'}>
<Box className="icon" onClick={(event) => { event.stopPropagation(); handleFlyTo(activeLayer); }}>
<svg fill="var(--mdc-theme-cesium-color)" width="100%" height="100%" viewBox="0 0 256 256">
<path d="M236,120H223.66406A96.15352,96.15352,0,0,0,136,32.33618V20a8,8,0,0,0-16,0V32.33618A96.15352,96.15352,0,0,0,32.33594,120H20a8,8,0,0,0,0,16H32.33594A96.15352,96.15352,0,0,0,120,223.66382V236a8,8,0,0,0,16,0V223.66382A96.15352,96.15352,0,0,0,223.66406,136H236a8,8,0,0,0,0-16Zm-40,16h11.59912A80.14164,80.14164,0,0,1,136,207.59912V196a8,8,0,0,0-16,0v11.59912A80.14164,80.14164,0,0,1,48.40088,136H60a8,8,0,0,0,0-16H48.40088A80.14164,80.14164,0,0,1,120,48.40088V60a8,8,0,0,0,16,0V48.40088A80.14164,80.14164,0,0,1,207.59912,120H196a8,8,0,0,0,0,16Z"/>
<polygon points="128,80 80,170 128,150 176,170" fill="var(--mdc-theme-cesium-color)"/>
</svg>
</Box>
</Tooltip>
{/* <Tooltip content={get(locale, 'REMOVE') ?? 'Remove'}>
{/* <Tooltip content={get(locale, 'REMOVE') ?? 'Remove'}>
<Box className={`icon ${activeLayer.isDisabled ? 'disabled' : ''}`} onClick={(event) => { event.stopPropagation(); }}>
<svg width="100%" height="100%" viewBox="0 0 16 16" fill="var(--mdc-theme-cesium-color)">
<path fillRule="evenodd" clipRule="evenodd" d="M10 3h3v1h-1v9l-1 1H4l-1-1V4H2V3h3V2a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1v1zM9 2H6v1h3V2zM4 13h7V4H4v9zm2-8H5v7h1V5zm1 0h1v7H7V5zm2 0h1v7H9V5z"/>
</svg>
</Box>
</Tooltip> */}
</Box>
</Box>
))
}
</Box>
))}
</Box>
</Box>
))
}
))}
</Box>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ type RequestResult = {
status: number;
url: string;
headers: Record<string, string>;
}
};

export const GeocoderPanel: React.FC<GeocoderPanelProps> = ({ options, isOpen, locale }) => {
const mapViewer = useCesiumMap();
Expand Down Expand Up @@ -213,55 +213,61 @@ export const GeocoderPanel: React.FC<GeocoderPanelProps> = ({ options, isOpen, l
[mapViewer]
);

const fetchData = useCallback(async (text: string, isInMapExtent: boolean) => {
if (!text) {
setSearchResults([]);
return;
}
const queryPromises = options.map(async (option) => {
if (option.url) {
const url = buildQueryParams(option.url, option.params, text, isInMapExtent);
return fetch(url, {
method: 'GET',
});
} else {
return Promise.reject({
message: "No URL provided. Please provide one",
});
const fetchData = useCallback(
async (text: string, isInMapExtent: boolean) => {
if (!text) {
setSearchResults([]);
return;
}
});
const rawResponses = await Promise.all(queryPromises);
const parsedResponses = await Promise.all(
rawResponses
.filter((res): res is Response => res !== undefined)
.map(async (res) => {
const body = await res.json();
body.features = body.features?.map((feat: Feature) => {
return {
...feat,
properties: {
...feat.properties,
headers: res.headers
}
} as Feature;
const queryPromises = options.map(async (option) => {
if (option.url) {
const url = buildQueryParams(option.url, option.params, text, isInMapExtent);
return fetch(url, {
method: 'GET',
});
} else {
return Promise.reject({
message: 'No URL provided. Please provide one',
});
}
});
const rawResponses = await Promise.all(queryPromises);
const parsedResponses = await Promise.all(
rawResponses
.filter((res): res is Response => res !== undefined)
.map(async (res) => {
const body = await res.json();
body.features = body.features?.map((feat: Feature) => {
return {
...feat,
properties: {
...feat.properties,
headers: res.headers,
},
} as Feature;
});

return {
body,
status: res.status,
url: res.url,
headers: Object.fromEntries(res.headers.entries()),
};
})
);
return {
body,
status: res.status,
url: res.url,
headers: Object.fromEntries(res.headers.entries()),
};
})
);

setSearchResults(parsedResponses);
}, [buildQueryParams, options]);
setSearchResults(parsedResponses);
},
[buildQueryParams, options]
);

const debouncedSearch = useMemo(() =>
debounce((value: string, isInMapExtent: boolean) => {
fetchData(value, isInMapExtent);
}, DEFAULT_DEBOUNCE), [fetchData]);
const debouncedSearch = useMemo(
() =>
debounce((value: string, isInMapExtent: boolean) => {
fetchData(value, isInMapExtent);
}, DEFAULT_DEBOUNCE),
[fetchData]
);

useEffect(() => {
return () => debouncedSearch.cancel();
Expand Down Expand Up @@ -290,14 +296,28 @@ export const GeocoderPanel: React.FC<GeocoderPanelProps> = ({ options, isOpen, l
case 'LineString':
typedIcon = (
<svg width="18px" height="18px" viewBox="0 0 24 24">
<path fill="var(--mdc-theme-cesium-color)" stroke="var(--mdc-theme-cesium-color)" strokeWidth={0.5} d="M21 6h.046l-5.25 9h-.944L10 9.455V7H7v2.926L1.862 18H0v3h3v-2.926L8.138 10h1.01L14 15.545V18h3v-3h-.046l5.25-9H24V3h-3zM8 8h1v1H8zM2 20H1v-1h1zm14-3h-1v-1h1zm7-13v1h-1V4z" />
<path
fill="var(--mdc-theme-cesium-color)"
stroke="var(--mdc-theme-cesium-color)"
strokeWidth={0.5}
d="M21 6h.046l-5.25 9h-.944L10 9.455V7H7v2.926L1.862 18H0v3h3v-2.926L8.138 10h1.01L14 15.545V18h3v-3h-.046l5.25-9H24V3h-3zM8 8h1v1H8zM2 20H1v-1h1zm14-3h-1v-1h1zm7-13v1h-1V4z"
/>
<path fill="none" d="M0 0h24v24H0z" />
</svg>
);
break;
default:
typedIcon = (
<svg width="18px" height="18px" viewBox="0 0 24 24" fill="none" stroke="var(--mdc-theme-cesium-color)" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round">
<svg
width="18px"
height="18px"
viewBox="0 0 24 24"
fill="none"
stroke="var(--mdc-theme-cesium-color)"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M11 4 L20 14 L20 20 L4 20 L4 10 Z" />
</svg>
);
Expand Down Expand Up @@ -384,7 +404,11 @@ export const GeocoderPanel: React.FC<GeocoderPanelProps> = ({ options, isOpen, l
} else if (featuresLength === 0) {
return <ListItemSecondaryText className="generalListItem queryNoResults">{noResults}</ListItemSecondaryText>;
} else if (message) {
return <ListItemSecondaryText className={`generalListItem ${status === 400 ? 'queryWarning' : 'queryError'}`}>{message}</ListItemSecondaryText>;
return (
<ListItemSecondaryText className={`generalListItem ${status === 400 ? 'queryWarning' : 'queryError'}`}>
{message}
</ListItemSecondaryText>
);
} else {
return <ListItemSecondaryText className="generalListItem"></ListItemSecondaryText>;
}
Expand Down
Loading