From 7383646cb2ff1bf3aee872f69abc02a656ce1d0f Mon Sep 17 00:00:00 2001 From: Max Tobias Weber Date: Thu, 11 Dec 2025 15:15:20 +0100 Subject: [PATCH 1/3] fix WmsLoader catalogue demo --- .../MlWmsLoader/MlWmsLoader.stories.tsx | 3 +- .../components/MlWmsLoader/MlWmsLoader.tsx | 101 +++++++++++------- .../components/MlWmsLoader/utils/WMSLinks.tsx | 8 +- 3 files changed, 69 insertions(+), 43 deletions(-) diff --git a/packages/react-maplibre/src/components/MlWmsLoader/MlWmsLoader.stories.tsx b/packages/react-maplibre/src/components/MlWmsLoader/MlWmsLoader.stories.tsx index 2ceb83be..fa6f10ef 100644 --- a/packages/react-maplibre/src/components/MlWmsLoader/MlWmsLoader.stories.tsx +++ b/packages/react-maplibre/src/components/MlWmsLoader/MlWmsLoader.stories.tsx @@ -24,7 +24,7 @@ interface MlWmsLoaderStoryProps { url: string; } const Template: any = (props: MlWmsLoaderStoryProps) => { - const [url, setUrl] = useState(props.url || 'https://magosm.magellium.com/geoserver/wms'); + const [url, setUrl] = useState(props.url || 'https://img.nj.gov/imagerywms/Infrared1995'); const [demoMode, setDemoMode] = useState(false); const [guide, setGuide] = useState(false); const [openSidebar, setOpenSidebar] = useState(true); @@ -100,6 +100,7 @@ const Template: any = (props: MlWmsLoaderStoryProps) => { url={url} onConfigChange={(config) => console.log(config)} zoomToExtent={true} + layerId='WMS-layer' featureInfoActive={featureInfoActive} setFeatureInfoActive={setFeatureInfoActive} /> diff --git a/packages/react-maplibre/src/components/MlWmsLoader/MlWmsLoader.tsx b/packages/react-maplibre/src/components/MlWmsLoader/MlWmsLoader.tsx index 1f072a69..68ddf0eb 100644 --- a/packages/react-maplibre/src/components/MlWmsLoader/MlWmsLoader.tsx +++ b/packages/react-maplibre/src/components/MlWmsLoader/MlWmsLoader.tsx @@ -10,7 +10,6 @@ import ListItem from '@mui/material/ListItem'; import ListItemText from '@mui/material/ListItemText'; import IconButton from '@mui/material/IconButton'; import { LngLat, MapMouseEvent } from 'maplibre-gl'; -import { Layer2, Layer3 } from 'wms-capabilities'; import useMap from '../../hooks/useMap'; import { Box, Checkbox, ListItemIcon, Snackbar } from '@mui/material'; import ExpandLessIcon from '@mui/icons-material/ExpandLess'; @@ -66,7 +65,7 @@ export interface MlWmsLoaderProps { /** * WMS URL */ - url: string; + url?: string; /** * Id of the target MapLibre instance in mapContext */ @@ -124,12 +123,56 @@ export interface MlWmsLoaderProps { sortable?: boolean; } +export interface WmsLayer { + Name?: string; + Title?: string; + Abstract?: string; + KeywordList?: string[]; + CRS?: string | string[]; + SRS?: string | string[]; + EX_GeographicBoundingBox?: number[]; + LatLonBoundingBox?: number[]; + BoundingBox?: any[]; + Dimension?: any; + Attribution?: { Title: string; OnlineResource?: string; LogoURL?: any }; + AuthorityURL?: any[]; + Identifier?: any[]; + MetadataURL?: any[]; + DataURL?: any[]; + FeatureListURL?: any[]; + Style?: any[]; + MinScaleDenominator?: number; + MaxScaleDenominator?: number; + Layer?: WmsLayer[]; + queryable?: boolean; + opaque?: boolean; + noSubsets?: boolean; + fixedWidth?: number; + fixedHeight?: number; +} + export type LayerType = { visible: boolean; Name: string; Attribution?: { Title: string }; -} & Omit & - Partial>; +} & Omit & + Partial>; + +const defaultProps = { + mapId: undefined, + url: '', + urlParameters: { + SERVICE: 'WMS', + VERSION: '1.3.0', + REQUEST: 'GetCapabilities', + }, + wmsUrlParameters: { + TRANSPARENT: 'TRUE', + }, + featureInfoEnabled: true, + zoomToExtent: false, + showDeleteButton: false, +}; /** * Loads a WMS getCapabilities xml document and adds a MlWmsLayer component for each layer that is * offered by the WMS. @@ -137,6 +180,7 @@ export type LayerType = { * @component */ const MlWmsLoader = (props: MlWmsLoaderProps) => { + props = { ...defaultProps, ...props }; const { capabilities: _capabilities, error, @@ -146,6 +190,7 @@ const MlWmsLoader = (props: MlWmsLoaderProps) => { }: useWmsReturnType = useWms({ urlParameters: props.urlParameters, }); + const [open, setOpen] = useState(props?.config?.open || false); const [visible, setVisible] = useState(props?.config?.visible || true); const [showDeletionConfirmationDialog, setShowDeletionConfirmationDialog] = useState(false); @@ -168,6 +213,7 @@ const MlWmsLoader = (props: MlWmsLoaderProps) => { return props?.config?.wmsUrl || _wmsUrl; }, [props?.config?.wmsUrl, _wmsUrl]); + const getFeatureInfoUrl = useMemo(() => { return props?.config?.getFeatureInfoUrl || _getFeatureInfoUrl; }, [props?.config?.getFeatureInfoUrl, _getFeatureInfoUrl]); @@ -259,8 +305,8 @@ const MlWmsLoader = (props: MlWmsLoaderProps) => { let _gfiUrl: string | undefined = getFeatureInfoUrl; let _gfiUrlParts; if (_gfiUrl?.indexOf?.('?') !== -1) { - _gfiUrlParts = props.url.split('?'); - _gfiUrl = _gfiUrlParts[0]; + _gfiUrlParts = props?.url?.split('?') || props?.config?.wmsUrl?.split('?'); + _gfiUrl = _gfiUrlParts?.[0]; } const _urlParamsFromUrl = new URLSearchParams(_gfiUrlParts?.[1]); @@ -317,6 +363,8 @@ const MlWmsLoader = (props: MlWmsLoaderProps) => { useEffect(() => { if (!capabilities?.Service) return; + let _LatLonBoundingBox: Array = []; + if ( capabilities?.Capability?.Layer?.CRS?.indexOf?.('EPSG:3857') === -1 && capabilities?.Capability?.Layer?.CRS?.indexOf?.('CRS:84') === -1 @@ -329,38 +377,34 @@ const MlWmsLoader = (props: MlWmsLoaderProps) => { 'MlWmsLoader (' + capabilities.Service.Title + '): WGS 84/Pseudo-Mercator supported' ); - let _LatLonBoundingBox: Array = []; - // collect queriable Layer2 layers let _layers: LayerType[] = capabilities?.Capability?.Layer?.Layer.filter( - (el) => !el.Layer?.length - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error - ).map((layer: Layer2 & { Name: string }, idx: number) => { + (el: WmsLayer) => !el.Layer?.length + ).map((layer: WmsLayer, idx: number) => { if (idx === 0) { - _LatLonBoundingBox = layer.EX_GeographicBoundingBox; + _LatLonBoundingBox = layer.EX_GeographicBoundingBox || layer?.LatLonBoundingBox || []; } return { visible: capabilities?.Capability?.Layer?.Layer?.length > 2 ? idx > 1 : true, Attribution: { Title: '' }, // eslint-disable-next-line @typescript-eslint/no-unused-vars ...(({ CRS, ..._layer }) => _layer)(layer), - }; + } as LayerType; }); // collect queriable Layer3 layers - capabilities?.Capability?.Layer?.Layer.forEach((el) => { - const tmpLayers = el?.Layer?.filter((el) => el.CRS.length).map( - (layer: Layer3, idx: number) => { + capabilities?.Capability?.Layer?.Layer.forEach((el: WmsLayer) => { + const tmpLayers = el?.Layer?.filter((el) => el.CRS?.length).map( + (layer: WmsLayer, idx: number) => { if (idx === 0) { - _LatLonBoundingBox = layer.EX_GeographicBoundingBox; + _LatLonBoundingBox = layer.EX_GeographicBoundingBox || layer?.LatLonBoundingBox || []; } return { visible: false, Attribution: { Title: '' }, // eslint-disable-next-line @typescript-eslint/no-unused-vars ...(({ CRS, ..._layer }) => _layer)(layer), - }; + } as LayerType; } ); @@ -542,24 +586,5 @@ const MlWmsLoader = (props: MlWmsLoaderProps) => { ); }; -//

-// {capabilities?.Capability?.Layer?.['Abstract']} -//

- -MlWmsLoader.defaultProps = { - mapId: undefined, - url: '', - urlParameters: { - SERVICE: 'WMS', - VERSION: '1.3.0', - REQUEST: 'GetCapabilities', - }, - wmsUrlParameters: { - TRANSPARENT: 'TRUE', - }, - featureInfoEnabled: true, - zoomToExtent: false, - showDeleteButton: false, -}; export default MlWmsLoader; diff --git a/packages/react-maplibre/src/components/MlWmsLoader/utils/WMSLinks.tsx b/packages/react-maplibre/src/components/MlWmsLoader/utils/WMSLinks.tsx index b8349926..f5e2a4f4 100644 --- a/packages/react-maplibre/src/components/MlWmsLoader/utils/WMSLinks.tsx +++ b/packages/react-maplibre/src/components/MlWmsLoader/utils/WMSLinks.tsx @@ -48,14 +48,14 @@ const wmsServices = [ id: '1', title: 'HistOSM', description: 'Historic objects stored in the OpenStreetMap database', - link: 'https://maps.heigit.org/histosm/wms', + link: 'https://maps.heigit.org/histosm/wms/', }, { id: '2', - title: 'MagOSM', + title: 'New Jersey Infrared 1995', description: - 'MagOSM is a project of the company Magellium which offers services related to thematic data from OpenStreetMap. Currently these services are provided at the scale of metropolitan France. The data of the different services are updated daily.', - link: 'https://magosm.magellium.com/geoserver/wms', + 'This service was created to provide convenient internet access to 1995 - 1997 New Jersey orthophotos in false color infrared.', + link: 'https://img.nj.gov/imagerywms/Infrared1995', }, { id: '3', From ab49123026afcd46fdb20e6d2923b96b6353d614 Mon Sep 17 00:00:00 2001 From: Max Tobias Weber Date: Thu, 11 Dec 2025 15:49:55 +0100 Subject: [PATCH 2/3] fix formatting --- .../react-maplibre/src/components/MlWmsLoader/MlWmsLoader.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react-maplibre/src/components/MlWmsLoader/MlWmsLoader.tsx b/packages/react-maplibre/src/components/MlWmsLoader/MlWmsLoader.tsx index 68ddf0eb..cf08a0cb 100644 --- a/packages/react-maplibre/src/components/MlWmsLoader/MlWmsLoader.tsx +++ b/packages/react-maplibre/src/components/MlWmsLoader/MlWmsLoader.tsx @@ -213,7 +213,6 @@ const MlWmsLoader = (props: MlWmsLoaderProps) => { return props?.config?.wmsUrl || _wmsUrl; }, [props?.config?.wmsUrl, _wmsUrl]); - const getFeatureInfoUrl = useMemo(() => { return props?.config?.getFeatureInfoUrl || _getFeatureInfoUrl; }, [props?.config?.getFeatureInfoUrl, _getFeatureInfoUrl]); From 7fce730101e72dbb0735a2bbe081bb26114a8bd7 Mon Sep 17 00:00:00 2001 From: Max Tobias Weber Date: Thu, 11 Dec 2025 15:52:23 +0100 Subject: [PATCH 3/3] fix formatting --- .../src/components/MlWmsLoader/MlWmsLoader.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-maplibre/src/components/MlWmsLoader/MlWmsLoader.stories.tsx b/packages/react-maplibre/src/components/MlWmsLoader/MlWmsLoader.stories.tsx index fa6f10ef..c6be954f 100644 --- a/packages/react-maplibre/src/components/MlWmsLoader/MlWmsLoader.stories.tsx +++ b/packages/react-maplibre/src/components/MlWmsLoader/MlWmsLoader.stories.tsx @@ -100,7 +100,7 @@ const Template: any = (props: MlWmsLoaderStoryProps) => { url={url} onConfigChange={(config) => console.log(config)} zoomToExtent={true} - layerId='WMS-layer' + layerId="WMS-layer" featureInfoActive={featureInfoActive} setFeatureInfoActive={setFeatureInfoActive} />