mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
Merge pull request #1085 from dbeaver/feat/CB-1857-srid-suggest
CB-1857 feat(plugin-gis-viewer): Add combobox for crs selecting
This commit is contained in:
@@ -90,7 +90,7 @@ const styles = css`
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Icon {
|
||||
@@ -112,12 +112,12 @@ const styles = css`
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 12px;
|
||||
|
||||
|
||||
& IconOrImage {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
||||
&:not(:empty) + input {
|
||||
padding-left: 34px !important;
|
||||
}
|
||||
@@ -131,8 +131,8 @@ type BaseProps<TKey, TValue> = Omit<React.InputHTMLAttributes<HTMLInputElement>,
|
||||
searchable?: boolean;
|
||||
defaultValue?: TKey;
|
||||
loading?: boolean;
|
||||
keySelector: (item: TValue, index: number) => TKey;
|
||||
valueSelector: (item: TValue) => string;
|
||||
keySelector?: (item: TValue, index: number) => TKey;
|
||||
valueSelector?: (item: TValue) => string;
|
||||
titleSelector?: (item: TValue) => string | undefined;
|
||||
iconSelector?: (item: TValue) => string | React.ReactElement | undefined;
|
||||
isDisabled?: (item: TValue) => boolean;
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import { Combobox } from '@cloudbeaver/core-blocks';
|
||||
|
||||
import type { CrsKey } from './LeafletMap';
|
||||
|
||||
const styles = css`
|
||||
root {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
label {
|
||||
margin-right: 4px;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
Combobox {
|
||||
width: 120px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
value: CrsKey;
|
||||
onChange: (value: CrsKey) => void;
|
||||
}
|
||||
|
||||
const items: CrsKey[] = [
|
||||
'Simple',
|
||||
'EPSG3395',
|
||||
'EPSG3857',
|
||||
'EPSG4326',
|
||||
'EPSG900913',
|
||||
];
|
||||
|
||||
export function CrsInput(props: Props) {
|
||||
return styled(styles)(
|
||||
<root>
|
||||
<label>CRS:</label>
|
||||
<Combobox
|
||||
items={items}
|
||||
value={props.value}
|
||||
onSelect={props.onChange}
|
||||
/>
|
||||
</root>
|
||||
);
|
||||
}
|
||||
@@ -5,18 +5,51 @@
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import styled, { css } from 'reshadow';
|
||||
import wellknown from 'wellknown';
|
||||
|
||||
import { TextPlaceholder } from '@cloudbeaver/core-blocks';
|
||||
import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
import { IDatabaseResultSet, ResultSetSelectAction, IResultSetElementKey, IDatabaseDataModel, ResultSetViewAction, ResultSetDataKeysUtils } from '@cloudbeaver/plugin-data-viewer';
|
||||
|
||||
import { IGeoJSONFeature, IAssociatedValue, LeafletMap } from './LeafletMap';
|
||||
import { CrsInput } from './CrsInput';
|
||||
import { IGeoJSONFeature, IAssociatedValue, LeafletMap, CrsKey } from './LeafletMap';
|
||||
import { ResultSetGISAction } from './ResultSetGISAction';
|
||||
|
||||
function getCrsKey(feature?: IGeoJSONFeature): CrsKey {
|
||||
switch (feature?.properties.srid) {
|
||||
case 3857:
|
||||
return 'EPSG3857';
|
||||
case 4326:
|
||||
return 'EPSG4326';
|
||||
case 3395:
|
||||
return 'EPSG3395';
|
||||
case 900913:
|
||||
return 'EPSG900913';
|
||||
default:
|
||||
return 'EPSG3857';
|
||||
}
|
||||
}
|
||||
|
||||
const styles = css`
|
||||
root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
map {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
toolbar {
|
||||
margin-top: 8px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
model: IDatabaseDataModel<any, IDatabaseResultSet>;
|
||||
resultIndex: number;
|
||||
@@ -87,11 +120,25 @@ export const GISValuePresentation = observer<Props>(function GISValuePresentatio
|
||||
return values;
|
||||
}, [view]);
|
||||
|
||||
|
||||
const defaultCrsKey = getCrsKey(parsedGISData[0]);
|
||||
const [crsKey, setCrsKey] = useState(defaultCrsKey);
|
||||
|
||||
if (!parsedGISData.length) {
|
||||
return <TextPlaceholder>{translate('gis_presentation_placeholder')}</TextPlaceholder>;
|
||||
}
|
||||
|
||||
return (
|
||||
<LeafletMap geoJSON={parsedGISData} getAssociatedValues={getAssociatedValues} />
|
||||
return styled(styles)(
|
||||
<root>
|
||||
<map>
|
||||
<LeafletMap key={crsKey} geoJSON={parsedGISData} crsKey={crsKey} getAssociatedValues={getAssociatedValues} />
|
||||
</map>
|
||||
<toolbar>
|
||||
<CrsInput
|
||||
value={crsKey}
|
||||
onChange={setCrsKey}
|
||||
/>
|
||||
</toolbar>
|
||||
</root>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -42,8 +42,11 @@ interface IBaseTile extends TileLayerProps {
|
||||
checked?: boolean;
|
||||
}
|
||||
|
||||
export type CrsKey = 'Simple' | 'EPSG3857' | 'EPSG4326' | 'EPSG3395' | 'EPSG900913';
|
||||
|
||||
interface Props {
|
||||
geoJSON: IGeoJSONFeature[];
|
||||
crsKey: CrsKey;
|
||||
getAssociatedValues: (cell: IResultSetElementKey) => IAssociatedValue[];
|
||||
}
|
||||
|
||||
@@ -87,17 +90,17 @@ function polyStyle() {
|
||||
};
|
||||
}
|
||||
|
||||
function getCRS(feature?: IGeoJSONFeature): leaflet.CRS {
|
||||
switch (feature?.properties.srid) {
|
||||
case 0:
|
||||
function getCRS(crsKey: CrsKey): leaflet.CRS {
|
||||
switch (crsKey) {
|
||||
case 'Simple':
|
||||
return leaflet.CRS.Simple;
|
||||
case 3857:
|
||||
case 'EPSG3857':
|
||||
return leaflet.CRS.EPSG3857;
|
||||
case 4326:
|
||||
case 'EPSG4326':
|
||||
return leaflet.CRS.EPSG4326;
|
||||
case 3395:
|
||||
case 'EPSG3395':
|
||||
return leaflet.CRS.EPSG3395;
|
||||
case 900913:
|
||||
case 'EPSG900913':
|
||||
return leaflet.CRS.EPSG900913;
|
||||
default:
|
||||
return leaflet.CRS.EPSG3857;
|
||||
@@ -111,14 +114,14 @@ const styles = css`
|
||||
}
|
||||
`;
|
||||
|
||||
export const LeafletMap: React.FC<Props> = function LeafletMap({ geoJSON, getAssociatedValues }) {
|
||||
export const LeafletMap: React.FC<Props> = function LeafletMap({ geoJSON, crsKey, getAssociatedValues }) {
|
||||
const splitContext = useSplit();
|
||||
const translate = useTranslate();
|
||||
|
||||
const [mapRef, setMapRef] = useState<leaflet.Map | null>(null);
|
||||
const [geoJSONLayerRef, setGeoJSONLayerRef] = useState<leaflet.GeoJSON | null>(null);
|
||||
|
||||
const crs = getCRS(geoJSON[0]);
|
||||
const crs = getCRS(crsKey);
|
||||
|
||||
const onEachFeature = useCallback((feature: IGeoJSONFeature, layer: leaflet.Layer) => {
|
||||
const associatedValues = getAssociatedValues(feature.properties.associatedCell);
|
||||
|
||||
Reference in New Issue
Block a user