Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@
"@loaders.gl/gis": "4.3.2",
"@loaders.gl/schema": "4.3.2",
"@loaders.gl/wkt": "4.3.2",
"@loaders.gl/wms": "4.3.2",
"@luma.gl/constants": "8.5.21",
"@luma.gl/core": "8.5.21",
"@luma.gl/experimental": "8.5.21",
Expand Down
1 change: 1 addition & 0 deletions src/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"@kepler.gl/utils": "3.1.8",
"@loaders.gl/mvt": "^4.3.2",
"@loaders.gl/pmtiles": "^4.3.2",
"@loaders.gl/wms": "4.3.2",
"@mapbox/mapbox-sdk": "^0.15.3",
"@nebula.gl/edit-modes": "1.0.2-alpha.1",
"@tippyjs/react": "^4.2.0",
Expand Down
3 changes: 2 additions & 1 deletion src/components/src/modals/export-data-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ const ExportDataModalFactory = () => {
const showTiledDatasetWarning = Object.keys(datasets).some(datasetId => {
return (
(datasets[datasetId].type === DatasetType.VECTOR_TILE ||
datasets[datasetId].type === DatasetType.RASTER_TILE) &&
datasets[datasetId].type === DatasetType.RASTER_TILE ||
datasets[datasetId].type === DatasetType.WMS_TILE) &&
(selectedDataset === datasetId || exportAllDatasets)
);
});
Expand Down
4 changes: 3 additions & 1 deletion src/components/src/modals/tilesets-modals/common.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project

import type {WMSCapabilities} from '@loaders.gl/wms';

import type {VectorTileMetadata} from '@kepler.gl/table';
import type {StacTypes} from '@kepler.gl/types';

Expand All @@ -11,7 +13,7 @@ export type DatasetCreationAttributes = {
};

export type MetaResponse = {
metadata?: VectorTileMetadata | StacTypes.CompleteSTACObject | null;
metadata?: VectorTileMetadata | StacTypes.CompleteSTACObject | WMSCapabilities | null;
dataset?: DatasetCreationAttributes | null;
loading?: boolean;
error?: Error | null;
Expand Down
4 changes: 1 addition & 3 deletions src/components/src/modals/tilesets-modals/load-tileset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import JSONPretty from 'react-json-pretty';
import {AutoSizer} from 'react-virtualized';
import styled from 'styled-components';

import {VectorTileIcon, RasterTileIcon} from '@kepler.gl/layers';
import {VectorTileIcon, RasterTileIcon, WMSLayerIcon} from '@kepler.gl/layers';
import {getError, getApplicationConfig} from '@kepler.gl/utils';

import {MetaResponse} from './common';
Expand All @@ -16,7 +16,6 @@ import TilesetIcon from './tileset-icon';
import TilesetVectorForm from './tileset-vector-form';
import TilesetRasterForm from './tileset-raster-form';

import WMSLayerIcon from 'src/layers/src/wms-layer/wms-layer-icon';
import TilesetWMSForm from './tileset-wms-form';

const WIDTH_ICON = '70px';
Expand Down Expand Up @@ -165,7 +164,6 @@ function LoadTilesetTabFactory() {
</TilesetTypeContainer>
<div>
<CurrentForm setResponse={setResponse} />
{error && <div>{getError(error)}</div>}
</div>
</div>
<MetaContainer>
Expand Down
69 changes: 31 additions & 38 deletions src/components/src/modals/tilesets-modals/tileset-wms-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@

import React, {useCallback, useEffect, useState} from 'react';
import styled from 'styled-components';
import {WMSCapabilities, WMSCapabilitiesLoader} from '@loaders.gl/wms';
import {load} from '@loaders.gl/core';
import {WMSCapabilities} from '@loaders.gl/wms';

import {validateUrl} from '@kepler.gl/common-utils';
import {DatasetType, REMOTE_TILE, RemoteTileFormat, WMSDatasetMetadata} from '@kepler.gl/constants';
import {getWMSCapabilities, wmsCapabilitiesToDatasetMetadata} from '@kepler.gl/table';

import {DatasetType, REMOTE_TILE, RemoteTileFormat} from '@kepler.gl/constants';
import {MetaResponse} from './common';
import {InputLight} from '../../common';

Expand All @@ -26,14 +28,18 @@ type WMSTileFormProps = {
setResponse: (response: MetaResponse) => void;
};

type WMSData = {
metadata: WMSCapabilities | null;
layers: WMSDatasetMetadata['layers'];
version: string;
};

const TilesetWMSForm: React.FC<WMSTileFormProps> = ({setResponse}) => {
const [layerName, setLayerName] = useState<string>('');
const [wmsUrl, setWmsUrl] = useState<string>('');
const [metadata, setMetadata] = useState<any>(null);
const [loading, setLoading] = useState<boolean>(false);
const [error, setError] = useState<Error | null>(null);
const [availableLayers, setAvailableLayers] = useState<{name: string; title: string}[]>([]);
const [wmsVersion, setWmsVersion] = useState<string>('1.3.0');
const [wmsData, setWMSData] = useState<WMSData | null>(null);

const onLayerNameChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
Expand All @@ -49,47 +55,34 @@ const TilesetWMSForm: React.FC<WMSTileFormProps> = ({setResponse}) => {
const newWmsUrl = event.target.value;
setWmsUrl(newWmsUrl);

if (!validateUrl(newWmsUrl)) {
setWMSData(null);
return;
}

// Fetch WMS GetCapabilities
try {
setLoading(true);
setError(null);
const data = (await load(
`${newWmsUrl}?service=WMS&request=GetCapabilities`,
WMSCapabilitiesLoader
)) as WMSCapabilities;

const data = await getWMSCapabilities(newWmsUrl);

const datasetMetadata = wmsCapabilitiesToDatasetMetadata(data);

// Extract name or title from GetCapabilities response
const serviceTitle = data?.title;
const serviceTitle = data?.title || data?.name;
if (serviceTitle && !layerName) {
setLayerName(serviceTitle);
}

// Flatten layers if they are nested
const layers = data.layers.flatMap(layer => {
if (layer.layers && layer.layers.length > 0) {
return layer.layers;
}
return layer;
setWMSData({
metadata: data,
layers: datasetMetadata.layers,
version: datasetMetadata.version
});

if (Array.isArray(layers)) {
const layerOptions = layers.map((layer: any) => ({
name: layer.name,
title: layer.title || layer.name
}));
setAvailableLayers(layerOptions);
} else {
setAvailableLayers([]);
}

// Set WMS version
const version = data.version || '1.3.0';
setWmsVersion(version);

setMetadata(data);
} catch (err) {
setError(err instanceof Error ? err : new Error('Unknown error'));
setMetadata(null);
setWMSData(null);
} finally {
setLoading(false);
}
Expand All @@ -107,12 +100,12 @@ const TilesetWMSForm: React.FC<WMSTileFormProps> = ({setResponse}) => {
remoteTileFormat: RemoteTileFormat.WMS,
tilesetDataUrl: wmsUrl,
tilesetMetadataUrl: `${wmsUrl}?service=WMS&request=GetCapabilities`,
layers: availableLayers,
wmsVersion: wmsVersion
layers: wmsData?.layers || [],
wmsVersion: wmsData?.version || '1.3.0'
}
};
setResponse({
metadata,
metadata: wmsData?.metadata ?? null,
dataset,
loading,
error
Expand All @@ -125,7 +118,7 @@ const TilesetWMSForm: React.FC<WMSTileFormProps> = ({setResponse}) => {
error
});
}
}, [setResponse, layerName, wmsUrl, metadata, loading, error, availableLayers, wmsVersion]);
}, [setResponse, layerName, wmsUrl, wmsData, loading, error]);

return (
<TilesetInputContainer>
Expand Down
21 changes: 13 additions & 8 deletions src/components/src/side-panel/layer-panel/layer-configurator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1032,14 +1032,10 @@ export default function LayerConfiguratorFactory(
}) {
return (
<StyledLayerVisualConfigurator>
<LayerConfigGroup label={'layer.wms'} collapsible>
<VisConfigSlider {...layer.visConfigSettings.opacity} {...visConfiguratorProps} />
<VisConfigSwitch
label={'layerVisConfigs.transparentBackground'}
{...layer.visConfigSettings.transparent}
{...visConfiguratorProps}
property="transparent"
/>
<LayerConfigGroup label={'layer.service'}>
<PanelLabel>
<FormattedMessage id={'layer.layer'} />
</PanelLabel>
<ItemSelector
selectedItems={layer.config.visConfig.wmsLayer}
options={layerChannelConfigProps.dataset.metadata.layers}
Expand Down Expand Up @@ -1067,6 +1063,15 @@ export default function LayerConfiguratorFactory(
}}
/>
</LayerConfigGroup>
<LayerConfigGroup label={'layer.appearance'}>
<VisConfigSlider {...layer.visConfigSettings.opacity} {...visConfiguratorProps} />
<VisConfigSwitch
label={'layerVisConfigs.transparentBackground'}
{...layer.visConfigSettings.transparent}
{...visConfiguratorProps}
property="transparent"
/>
</LayerConfigGroup>
</StyledLayerVisualConfigurator>
);
}
Expand Down
9 changes: 9 additions & 0 deletions src/constants/src/dataset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,12 @@ export type RasterTileMetadataSourceType = {
*/
export type RasterTileDatasetMetadata = (RasterTileLocalMetadata | RasterTileRemoteMetadata) &
RasterTileMetadataSourceType;

export type WMSDatasetMetadata = {
type: typeof REMOTE_TILE;
remoteTileFormat: RemoteTileFormat.WMS;
tilesetDataUrl: string;
tilesetMetadataUrl: string;
version: string;
layers: {name: string; title: string; boundingBox: number[] | null}[];
};
3 changes: 1 addition & 2 deletions src/constants/src/layers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,5 @@ export const EDITOR_AVAILABLE_LAYERS: string[] = [
LAYER_TYPES.arc,
LAYER_TYPES.line,
LAYER_TYPES.hexagonId,
LAYER_TYPES.geojson,
LAYER_TYPES.wms
LAYER_TYPES.geojson
];
1 change: 1 addition & 0 deletions src/deckgl-layers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"@kepler.gl/constants": "3.1.8",
"@kepler.gl/types": "3.1.8",
"@kepler.gl/utils": "3.1.8",
"@loaders.gl/wms": "4.3.2",
"@luma.gl/constants": "^8.5.20",
"@luma.gl/core": "^8.5.20",
"@mapbox/geo-viewport": "^0.4.1",
Expand Down
2 changes: 2 additions & 0 deletions src/deckgl-layers/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export {default as RasterLayer} from './raster/raster-layer/raster-layer';
export {default as RasterMeshLayer} from './raster/raster-mesh-layer/raster-mesh-layer';
export * as RasterWebGL from './raster/webgl';

export {default as WMSLayer} from './wms/wms-layer';

export * from './layer-utils/shader-utils';

export * from './3d-building-layer/types';
Expand Down
Loading