@jupytergis/base 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/lib/classificationModes.d.ts +13 -0
  2. package/lib/classificationModes.js +326 -0
  3. package/lib/commands.js +1 -1
  4. package/lib/dialogs/symbology/classificationModes.d.ts +13 -0
  5. package/lib/dialogs/symbology/classificationModes.js +326 -0
  6. package/lib/dialogs/symbology/components/color_ramp/CanvasSelectComponent.d.ts +11 -0
  7. package/lib/dialogs/symbology/components/color_ramp/CanvasSelectComponent.js +119 -0
  8. package/lib/dialogs/symbology/components/color_ramp/ColorRamp.d.ts +15 -0
  9. package/lib/dialogs/symbology/components/color_ramp/ColorRamp.js +33 -0
  10. package/lib/dialogs/symbology/components/color_ramp/ColorRampEntry.d.ts +9 -0
  11. package/lib/dialogs/symbology/components/color_ramp/ColorRampEntry.js +24 -0
  12. package/lib/dialogs/symbology/components/color_ramp/ModeSelectRow.d.ts +10 -0
  13. package/lib/dialogs/symbology/components/color_ramp/ModeSelectRow.js +11 -0
  14. package/lib/dialogs/symbology/components/color_stops/StopContainer.d.ts +9 -0
  15. package/lib/dialogs/symbology/components/color_stops/StopContainer.js +28 -0
  16. package/lib/dialogs/{components/symbology → symbology/components/color_stops}/StopRow.js +9 -2
  17. package/lib/dialogs/symbology/hooks/useGetProperties.d.ts +12 -0
  18. package/lib/dialogs/symbology/hooks/useGetProperties.js +47 -0
  19. package/lib/dialogs/{symbologyDialog.js → symbology/symbologyDialog.js} +3 -3
  20. package/lib/dialogs/symbology/symbologyUtils.d.ts +9 -0
  21. package/lib/dialogs/symbology/symbologyUtils.js +94 -0
  22. package/lib/dialogs/symbology/tiff_layer/TiffRendering.d.ts +4 -0
  23. package/lib/dialogs/{components/symbology/BandRendering.js → symbology/tiff_layer/TiffRendering.js} +3 -3
  24. package/lib/dialogs/{components/symbology → symbology/tiff_layer/components}/BandRow.d.ts +1 -1
  25. package/lib/dialogs/{components/symbology → symbology/tiff_layer/types}/SingleBandPseudoColor.d.ts +9 -1
  26. package/lib/dialogs/{components/symbology → symbology/tiff_layer/types}/SingleBandPseudoColor.js +115 -59
  27. package/lib/dialogs/{components/symbology → symbology/vector_layer}/VectorRendering.d.ts +1 -1
  28. package/lib/dialogs/{components/symbology → symbology/vector_layer}/VectorRendering.js +10 -13
  29. package/lib/dialogs/symbology/vector_layer/components/ValueSelect.d.ts +8 -0
  30. package/lib/dialogs/symbology/vector_layer/components/ValueSelect.js +7 -0
  31. package/lib/dialogs/symbology/vector_layer/types/Categorized.d.ts +4 -0
  32. package/lib/dialogs/symbology/vector_layer/types/Categorized.js +94 -0
  33. package/lib/dialogs/symbology/vector_layer/types/Graduated.js +169 -0
  34. package/lib/dialogs/{components/symbology → symbology/vector_layer/types}/SimpleSymbol.js +8 -13
  35. package/lib/formbuilder/objectform/vectorlayerform.js +1 -0
  36. package/lib/formbuilder/objectform/webGlLayerForm.js +1 -0
  37. package/lib/index.d.ts +6 -4
  38. package/lib/index.js +6 -4
  39. package/lib/mainview/mainView.d.ts +3 -1
  40. package/lib/mainview/mainView.js +66 -18
  41. package/lib/store.d.ts +9 -0
  42. package/lib/store.js +25 -0
  43. package/lib/toolbar/widget.d.ts +2 -2
  44. package/lib/toolbar/widget.js +5 -5
  45. package/lib/types.d.ts +14 -0
  46. package/package.json +16 -17
  47. package/style/symbologyDialog.css +104 -3
  48. package/lib/dialogs/components/symbology/BandRendering.d.ts +0 -4
  49. package/lib/dialogs/components/symbology/Graduated.js +0 -188
  50. /package/lib/dialogs/{components/symbology → symbology/components/color_stops}/StopRow.d.ts +0 -0
  51. /package/lib/dialogs/{symbologyDialog.d.ts → symbology/symbologyDialog.d.ts} +0 -0
  52. /package/lib/dialogs/{components/symbology → symbology/tiff_layer/components}/BandRow.js +0 -0
  53. /package/lib/dialogs/{components/symbology → symbology/vector_layer/types}/Graduated.d.ts +0 -0
  54. /package/lib/dialogs/{components/symbology → symbology/vector_layer/types}/SimpleSymbol.d.ts +0 -0
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ export interface IColorMap {
3
+ name: string;
4
+ colors: string[];
5
+ }
6
+ interface ICanvasSelectComponentProps {
7
+ selectedRamp: string;
8
+ setSelected: (item: any) => void;
9
+ }
10
+ declare const CanvasSelectComponent: ({ selectedRamp, setSelected }: ICanvasSelectComponentProps) => React.JSX.Element;
11
+ export default CanvasSelectComponent;
@@ -0,0 +1,119 @@
1
+ import { Button } from '@jupyterlab/ui-components';
2
+ import colormap from 'colormap';
3
+ import React, { useEffect, useRef, useState } from 'react';
4
+ import ColorRampEntry from './ColorRampEntry';
5
+ const CanvasSelectComponent = ({ selectedRamp, setSelected }) => {
6
+ const colorRampNames = [
7
+ 'jet',
8
+ // 'hsv', 11 steps min
9
+ 'hot',
10
+ 'cool',
11
+ 'spring',
12
+ 'summer',
13
+ 'autumn',
14
+ 'winter',
15
+ 'bone',
16
+ 'copper',
17
+ 'greys',
18
+ 'YiGnBu',
19
+ 'greens',
20
+ 'YiOrRd',
21
+ 'bluered',
22
+ 'RdBu',
23
+ // 'picnic', 11 steps min
24
+ 'rainbow',
25
+ 'portland',
26
+ 'blackbody',
27
+ 'earth',
28
+ 'electric',
29
+ 'viridis',
30
+ 'inferno',
31
+ 'magma',
32
+ 'plasma',
33
+ 'warm',
34
+ // 'rainbow-soft', 11 steps min
35
+ 'bathymetry',
36
+ 'cdom',
37
+ 'chlorophyll',
38
+ 'density',
39
+ 'freesurface-blue',
40
+ 'freesurface-red',
41
+ 'oxygen',
42
+ 'par',
43
+ 'phase',
44
+ 'salinity',
45
+ 'temperature',
46
+ 'turbidity',
47
+ 'velocity-blue',
48
+ 'velocity-green'
49
+ // 'cubehelix' 16 steps min
50
+ ];
51
+ const containerRef = useRef(null);
52
+ const [isOpen, setIsOpen] = useState(false);
53
+ const [colorMaps, setColorMaps] = useState([]);
54
+ useEffect(() => {
55
+ const colorMapList = [];
56
+ colorRampNames.forEach(name => {
57
+ const colorRamp = colormap({
58
+ colormap: name,
59
+ nshades: 255,
60
+ format: 'rgbaString'
61
+ });
62
+ const colorMap = { name: name, colors: colorRamp };
63
+ colorMapList.push(colorMap);
64
+ setColorMaps(colorMapList);
65
+ });
66
+ }, []);
67
+ useEffect(() => {
68
+ if (colorMaps.length > 0) {
69
+ updateCanvas(selectedRamp);
70
+ }
71
+ }, [selectedRamp]);
72
+ const toggleDropdown = () => {
73
+ setIsOpen(!isOpen);
74
+ };
75
+ const selectItem = (item) => {
76
+ setSelected(item);
77
+ setIsOpen(false);
78
+ updateCanvas(item);
79
+ };
80
+ const handleOutsideClick = (event) => {
81
+ if (!containerRef.current) {
82
+ return;
83
+ }
84
+ if (!containerRef.current.contains(event.target)) {
85
+ setIsOpen(false);
86
+ }
87
+ };
88
+ const updateCanvas = (rampName) => {
89
+ // update canvas for displayed color ramp
90
+ const canvas = document.getElementById('cv');
91
+ if (!canvas) {
92
+ return;
93
+ }
94
+ canvas.style.visibility = 'hidden';
95
+ const ctx = canvas.getContext('2d');
96
+ if (!ctx) {
97
+ return;
98
+ }
99
+ const ramp = colorMaps.filter(c => c.name === rampName);
100
+ for (let i = 0; i <= 255; i++) {
101
+ ctx.beginPath();
102
+ const color = ramp[0].colors[i];
103
+ ctx.fillStyle = color;
104
+ ctx.fillRect(i * 2, 0, 2, 50);
105
+ }
106
+ canvas.style.visibility = 'initial';
107
+ };
108
+ useEffect(() => {
109
+ document.addEventListener('mousedown', handleOutsideClick);
110
+ return () => {
111
+ document.removeEventListener('mousedown', handleOutsideClick);
112
+ };
113
+ }, []);
114
+ return (React.createElement("div", { ref: containerRef, className: "jp-gis-canvas-button-wrapper" },
115
+ React.createElement(Button, { id: "jp-gis-canvas-button", onClick: toggleDropdown, className: "jp-Dialog-button jp-gis-canvas-button" },
116
+ React.createElement("canvas", { id: "cv", className: "jp-gis-color-canvas-display", height: "30" })),
117
+ React.createElement("div", { className: `jp-gis-color-ramp-dropdown ${isOpen ? 'jp-gis-open' : ''}` }, colorMaps.map((item, index) => (React.createElement(ColorRampEntry, { index: index, colorMap: item, onClick: selectItem }))))));
118
+ };
119
+ export default CanvasSelectComponent;
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import { IDict } from '@jupytergis/schema';
3
+ interface IColorRampProps {
4
+ modeOptions: string[];
5
+ layerParams: IDict;
6
+ classifyFunc: (selectedMode: string, numberOfShades: string, selectedRamp: string, setIsLoading: (isLoading: boolean) => void) => void;
7
+ showModeRow: boolean;
8
+ }
9
+ export type ColorRampOptions = {
10
+ selectedRamp: string;
11
+ numberOfShades: string;
12
+ selectedMode: string;
13
+ };
14
+ declare const ColorRamp: ({ layerParams, modeOptions, classifyFunc, showModeRow }: IColorRampProps) => React.JSX.Element;
15
+ export default ColorRamp;
@@ -0,0 +1,33 @@
1
+ import { Button } from '@jupyterlab/ui-components';
2
+ import React, { useEffect, useState } from 'react';
3
+ import CanvasSelectComponent from './CanvasSelectComponent';
4
+ import { faSpinner } from '@fortawesome/free-solid-svg-icons';
5
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
6
+ import ModeSelectRow from './ModeSelectRow';
7
+ const ColorRamp = ({ layerParams, modeOptions, classifyFunc, showModeRow }) => {
8
+ const [selectedRamp, setSelectedRamp] = useState('');
9
+ const [selectedMode, setSelectedMode] = useState('');
10
+ const [numberOfShades, setNumberOfShades] = useState('');
11
+ const [isLoading, setIsLoading] = useState(false);
12
+ useEffect(() => {
13
+ populateOptions();
14
+ }, []);
15
+ const populateOptions = async () => {
16
+ let nClasses, singleBandMode, colorRamp;
17
+ if (layerParams.symbologyState) {
18
+ nClasses = layerParams.symbologyState.nClasses;
19
+ singleBandMode = layerParams.symbologyState.mode;
20
+ colorRamp = layerParams.symbologyState.colorRamp;
21
+ }
22
+ setNumberOfShades(nClasses ? nClasses : '9');
23
+ setSelectedMode(singleBandMode ? singleBandMode : 'equal interval');
24
+ setSelectedRamp(colorRamp ? colorRamp : 'cool');
25
+ };
26
+ return (React.createElement("div", { className: "jp-gis-color-ramp-container" },
27
+ React.createElement("div", { className: "jp-gis-symbology-row" },
28
+ React.createElement("label", { htmlFor: "color-ramp-select" }, "Color Ramp:"),
29
+ React.createElement(CanvasSelectComponent, { selectedRamp: selectedRamp, setSelected: setSelectedRamp })),
30
+ showModeRow && (React.createElement(ModeSelectRow, { modeOptions: modeOptions, numberOfShades: numberOfShades, setNumberOfShades: setNumberOfShades, selectedMode: selectedMode, setSelectedMode: setSelectedMode })),
31
+ isLoading ? (React.createElement(FontAwesomeIcon, { icon: faSpinner, className: "jp-gis-loading-spinner" })) : (React.createElement(Button, { className: "jp-Dialog-button jp-mod-accept jp-mod-styled", onClick: () => classifyFunc(selectedMode, numberOfShades, selectedRamp, setIsLoading) }, "Classify"))));
32
+ };
33
+ export default ColorRamp;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { IColorMap } from './CanvasSelectComponent';
3
+ interface IColorRampEntryProps {
4
+ index: number;
5
+ colorMap: IColorMap;
6
+ onClick: (item: any) => void;
7
+ }
8
+ declare const ColorRampEntry: ({ index, colorMap, onClick }: IColorRampEntryProps) => React.JSX.Element;
9
+ export default ColorRampEntry;
@@ -0,0 +1,24 @@
1
+ import React, { useEffect } from 'react';
2
+ const ColorRampEntry = ({ index, colorMap, onClick }) => {
3
+ const canvasHeight = 30;
4
+ useEffect(() => {
5
+ const canvas = document.getElementById(`cv-${index}`);
6
+ if (!canvas) {
7
+ return;
8
+ }
9
+ const ctx = canvas.getContext('2d');
10
+ if (!ctx) {
11
+ return;
12
+ }
13
+ for (let i = 0; i <= 255; i++) {
14
+ ctx.beginPath();
15
+ const color = colorMap.colors[i];
16
+ ctx.fillStyle = color;
17
+ ctx.fillRect(i * 2, 0, 2, canvasHeight);
18
+ }
19
+ }, []);
20
+ return (React.createElement("div", { key: colorMap.name, onClick: () => onClick(colorMap.name), className: "jp-gis-color-ramp-entry" },
21
+ React.createElement("span", { className: "jp-gis-color-label" }, colorMap.name),
22
+ React.createElement("canvas", { id: `cv-${index}`, height: canvasHeight, className: "jp-gis-color-canvas" })));
23
+ };
24
+ export default ColorRampEntry;
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ interface IModeSelectRowProps {
3
+ numberOfShades: string;
4
+ setNumberOfShades: (value: string) => void;
5
+ selectedMode: string;
6
+ setSelectedMode: (value: string) => void;
7
+ modeOptions: string[];
8
+ }
9
+ declare const ModeSelectRow: ({ numberOfShades, setNumberOfShades, selectedMode, setSelectedMode, modeOptions }: IModeSelectRowProps) => React.JSX.Element;
10
+ export default ModeSelectRow;
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ const ModeSelectRow = ({ numberOfShades, setNumberOfShades, selectedMode, setSelectedMode, modeOptions }) => {
3
+ return (React.createElement("div", { className: "jp-gis-symbology-row" },
4
+ React.createElement("div", { className: "jp-gis-color-ramp-div" },
5
+ React.createElement("label", { htmlFor: "class-number-input" }, "Classes:"),
6
+ React.createElement("input", { className: "jp-mod-styled", name: "class-number-input", type: "number", value: selectedMode === 'continuous' ? 52 : numberOfShades, onChange: event => setNumberOfShades(event.target.value), disabled: selectedMode === 'continuous' })),
7
+ React.createElement("div", { className: "jp-gis-color-ramp-div" },
8
+ React.createElement("label", { htmlFor: "mode-select" }, "Mode:"),
9
+ React.createElement("select", { name: "mode-select", onChange: event => setSelectedMode(event.target.value) }, modeOptions.map(mode => (React.createElement("option", { className: "jp-mod-styled", value: mode, selected: selectedMode === mode }, mode)))))));
10
+ };
11
+ export default ModeSelectRow;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { IStopRow } from '../../symbologyDialog';
3
+ interface IStopContainerProps {
4
+ selectedMethod: string;
5
+ stopRows: IStopRow[];
6
+ setStopRows: (stops: IStopRow[]) => void;
7
+ }
8
+ declare const StopContainer: ({ selectedMethod, stopRows, setStopRows }: IStopContainerProps) => React.JSX.Element;
9
+ export default StopContainer;
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import { Button } from '@jupyterlab/ui-components';
3
+ import StopRow from './StopRow';
4
+ const StopContainer = ({ selectedMethod, stopRows, setStopRows }) => {
5
+ const addStopRow = () => {
6
+ setStopRows([
7
+ {
8
+ stop: 0,
9
+ output: [0, 0, 0, 1]
10
+ },
11
+ ...stopRows
12
+ ]);
13
+ };
14
+ const deleteStopRow = (index) => {
15
+ const newFilters = [...stopRows];
16
+ newFilters.splice(index, 1);
17
+ setStopRows(newFilters);
18
+ };
19
+ return (React.createElement(React.Fragment, null,
20
+ React.createElement("div", { className: "jp-gis-stop-container" },
21
+ React.createElement("div", { className: "jp-gis-stop-labels", style: { display: 'flex', gap: 6 } },
22
+ React.createElement("span", { style: { flex: '0 0 18%' } }, "Value"),
23
+ React.createElement("span", null, "Output Value")),
24
+ stopRows.map((stop, index) => (React.createElement(StopRow, { key: `${index}-${stop.output}`, index: index, value: stop.stop, outputValue: stop.output, stopRows: stopRows, setStopRows: setStopRows, deleteRow: () => deleteStopRow(index), useNumber: selectedMethod === 'radius' ? true : false })))),
25
+ React.createElement("div", { className: "jp-gis-symbology-button-container" },
26
+ React.createElement(Button, { className: "jp-Dialog-button jp-mod-accept jp-mod-styled", onClick: addStopRow }, "Add Stop"))));
27
+ };
28
+ export default StopContainer;
@@ -1,8 +1,15 @@
1
1
  import { faTrash } from '@fortawesome/free-solid-svg-icons';
2
2
  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
3
3
  import { Button } from '@jupyterlab/ui-components';
4
- import React from 'react';
4
+ import React, { useEffect, useRef } from 'react';
5
5
  const StopRow = ({ index, value, outputValue, stopRows, setStopRows, deleteRow, useNumber }) => {
6
+ const inputRef = useRef(null);
7
+ useEffect(() => {
8
+ var _a;
9
+ if (inputRef.current === document.activeElement) {
10
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
11
+ }
12
+ }, [stopRows]);
6
13
  const rgbArrToHex = (rgbArr) => {
7
14
  if (!Array.isArray(rgbArr)) {
8
15
  return;
@@ -56,7 +63,7 @@ const StopRow = ({ index, value, outputValue, stopRows, setStopRows, deleteRow,
56
63
  };
57
64
  return (React.createElement("div", { className: "jp-gis-color-row" },
58
65
  React.createElement("input", { id: `jp-gis-color-value-${index}`, type: "number", value: value, onChange: handleStopChange, onBlur: handleBlur, className: "jp-mod-styled jp-gis-color-row-value-input" }),
59
- useNumber ? (React.createElement("input", { type: "number", value: outputValue, onChange: handleOutputChange, className: "jp-mod-styled jp-gis-color-row-output-input" })) : (React.createElement("input", { id: `jp-gis-color-color-${index}`, value: rgbArrToHex(outputValue), type: "color", onChange: handleOutputChange, className: "jp-mod-styled jp-gis-color-row-output-input" })),
66
+ useNumber ? (React.createElement("input", { type: "number", ref: inputRef, value: outputValue, onChange: handleOutputChange, className: "jp-mod-styled jp-gis-color-row-output-input" })) : (React.createElement("input", { id: `jp-gis-color-color-${index}`, ref: inputRef, value: rgbArrToHex(outputValue), type: "color", onChange: handleOutputChange, className: "jp-mod-styled jp-gis-color-row-output-input" })),
60
67
  React.createElement(Button, { id: `jp-gis-remove-color-${index}`, className: "jp-Button jp-gis-filter-icon" },
61
68
  React.createElement(FontAwesomeIcon, { icon: faTrash, onClick: deleteRow }))));
62
69
  };
@@ -0,0 +1,12 @@
1
+ import { IJupyterGISModel } from '@jupytergis/schema';
2
+ interface IUseGetPropertiesProps {
3
+ layerId?: string;
4
+ model: IJupyterGISModel;
5
+ }
6
+ interface IUseGetPropertiesResult {
7
+ featureProps: Record<string, Set<any>>;
8
+ isLoading: boolean;
9
+ error?: Error;
10
+ }
11
+ export declare const useGetProperties: ({ layerId, model }: IUseGetPropertiesProps) => IUseGetPropertiesResult;
12
+ export {};
@@ -0,0 +1,47 @@
1
+ // import { GeoJSONFeature } from 'geojson';
2
+ import { useEffect, useState } from 'react';
3
+ export const useGetProperties = ({ layerId, model }) => {
4
+ const [featureProps, setFeatureProps] = useState({});
5
+ const [isLoading, setIsLoading] = useState(true);
6
+ const [error, setError] = useState(undefined);
7
+ const getProperties = async () => {
8
+ var _a, _b;
9
+ if (!layerId) {
10
+ return;
11
+ }
12
+ try {
13
+ const layer = model.getLayer(layerId);
14
+ const source = model.getSource((_a = layer === null || layer === void 0 ? void 0 : layer.parameters) === null || _a === void 0 ? void 0 : _a.source);
15
+ if (!source) {
16
+ throw new Error('Source not found');
17
+ }
18
+ const data = await model.readGeoJSON((_b = source.parameters) === null || _b === void 0 ? void 0 : _b.path);
19
+ if (!data) {
20
+ throw new Error('Failed to read GeoJSON data');
21
+ }
22
+ const result = {};
23
+ data.features.forEach((feature) => {
24
+ if (feature.properties) {
25
+ Object.entries(feature.properties).forEach(([key, value]) => {
26
+ if (typeof value !== 'string') {
27
+ if (!(key in result)) {
28
+ result[key] = new Set();
29
+ }
30
+ result[key].add(value);
31
+ }
32
+ });
33
+ }
34
+ });
35
+ setFeatureProps(result);
36
+ setIsLoading(false);
37
+ }
38
+ catch (err) {
39
+ setError(err);
40
+ setIsLoading(false);
41
+ }
42
+ };
43
+ useEffect(() => {
44
+ getProperties();
45
+ }, [model, layerId]);
46
+ return { featureProps, isLoading, error };
47
+ };
@@ -2,8 +2,8 @@ import { Dialog } from '@jupyterlab/apputils';
2
2
  import { PromiseDelegate } from '@lumino/coreutils';
3
3
  import { Signal } from '@lumino/signaling';
4
4
  import React, { useEffect, useState } from 'react';
5
- import BandRendering from './components/symbology/BandRendering';
6
- import VectorRendering from './components/symbology/VectorRendering';
5
+ import TiffRendering from './tiff_layer/TiffRendering';
6
+ import VectorRendering from './vector_layer/VectorRendering';
7
7
  const SymbologyDialog = ({ context, state, okSignalPromise, cancel }) => {
8
8
  const [selectedLayer, setSelectedLayer] = useState(null);
9
9
  const [componentToRender, setComponentToRender] = useState(null);
@@ -39,7 +39,7 @@ const SymbologyDialog = ({ context, state, okSignalPromise, cancel }) => {
39
39
  LayerSymbology = (React.createElement(VectorRendering, { context: context, state: state, okSignalPromise: okSignalPromise, cancel: cancel, layerId: selectedLayer }));
40
40
  break;
41
41
  case 'WebGlLayer':
42
- LayerSymbology = (React.createElement(BandRendering, { context: context, state: state, okSignalPromise: okSignalPromise, cancel: cancel, layerId: selectedLayer }));
42
+ LayerSymbology = (React.createElement(TiffRendering, { context: context, state: state, okSignalPromise: okSignalPromise, cancel: cancel, layerId: selectedLayer }));
43
43
  break;
44
44
  default:
45
45
  LayerSymbology = React.createElement("div", null, "Layer Type Not Supported");
@@ -0,0 +1,9 @@
1
+ import { IJGISLayer } from '@jupytergis/schema';
2
+ import { IStopRow } from './symbologyDialog';
3
+ export declare namespace VectorUtils {
4
+ const buildColorInfo: (layer: IJGISLayer) => IStopRow[];
5
+ const buildRadiusInfo: (layer: IJGISLayer) => IStopRow[];
6
+ }
7
+ export declare namespace Utils {
8
+ const getValueColorPairs: (stops: number[], selectedRamp: string, nClasses: number) => IStopRow[];
9
+ }
@@ -0,0 +1,94 @@
1
+ import colormap from 'colormap';
2
+ export var VectorUtils;
3
+ (function (VectorUtils) {
4
+ VectorUtils.buildColorInfo = (layer) => {
5
+ var _a;
6
+ // This it to parse a color object on the layer
7
+ if (!((_a = layer.parameters) === null || _a === void 0 ? void 0 : _a.color)) {
8
+ return [];
9
+ }
10
+ const color = layer.parameters.color;
11
+ // If color is a string we don't need to parse
12
+ if (typeof color === 'string') {
13
+ return [];
14
+ }
15
+ const prefix = layer.parameters.type === 'circle' ? 'circle-' : '';
16
+ if (!color[`${prefix}fill-color`]) {
17
+ return [];
18
+ }
19
+ const valueColorPairs = [];
20
+ // So if it's not a string then it's an array and we parse
21
+ // Color[0] is the operator used for the color expression
22
+ switch (color[`${prefix}fill-color`][0]) {
23
+ case 'interpolate':
24
+ // First element is interpolate for linear selection
25
+ // Second element is type of interpolation (ie linear)
26
+ // Third is input value that stop values are compared with
27
+ // Fourth and on is value:color pairs
28
+ for (let i = 3; i < color[`${prefix}fill-color`].length; i += 2) {
29
+ const obj = {
30
+ stop: color[`${prefix}fill-color`][i],
31
+ output: color[`${prefix}fill-color`][i + 1]
32
+ };
33
+ valueColorPairs.push(obj);
34
+ }
35
+ break;
36
+ case 'case':
37
+ for (let i = 1; i < color[`${prefix}fill-color`].length - 1; i += 2) {
38
+ const obj = {
39
+ stop: color[`${prefix}fill-color`][i][2],
40
+ output: color[`${prefix}fill-color`][i + 1]
41
+ };
42
+ valueColorPairs.push(obj);
43
+ }
44
+ break;
45
+ }
46
+ return valueColorPairs;
47
+ };
48
+ VectorUtils.buildRadiusInfo = (layer) => {
49
+ var _a;
50
+ if (!((_a = layer.parameters) === null || _a === void 0 ? void 0 : _a.color)) {
51
+ return [];
52
+ }
53
+ const color = layer.parameters.color;
54
+ // If color is a string we don't need to parse
55
+ if (typeof color === 'string') {
56
+ return [];
57
+ }
58
+ const stopOutputPairs = [];
59
+ for (let i = 3; i < color['circle-radius'].length; i += 2) {
60
+ const obj = {
61
+ stop: color['circle-radius'][i],
62
+ output: color['circle-radius'][i + 1]
63
+ };
64
+ stopOutputPairs.push(obj);
65
+ }
66
+ return stopOutputPairs;
67
+ };
68
+ })(VectorUtils || (VectorUtils = {}));
69
+ export var Utils;
70
+ (function (Utils) {
71
+ Utils.getValueColorPairs = (stops, selectedRamp, nClasses) => {
72
+ let colorMap = colormap({
73
+ colormap: selectedRamp,
74
+ nshades: nClasses > 9 ? nClasses : 9,
75
+ format: 'rgba'
76
+ });
77
+ const valueColorPairs = [];
78
+ // colormap requires 9 classes to generate the ramp
79
+ // so we do some tomfoolery to make it work with less than 9 stops
80
+ if (nClasses < 9) {
81
+ const midIndex = Math.floor(nClasses / 2);
82
+ // Get the first n/2 elements from the second array
83
+ const firstPart = colorMap.slice(0, midIndex);
84
+ // Get the last n/2 elements from the second array
85
+ const secondPart = colorMap.slice(colorMap.length - (stops.length - firstPart.length));
86
+ // Create the new array by combining the first and last parts
87
+ colorMap = firstPart.concat(secondPart);
88
+ }
89
+ for (let i = 0; i < nClasses; i++) {
90
+ valueColorPairs.push({ stop: stops[i], output: colorMap[i] });
91
+ }
92
+ return valueColorPairs;
93
+ };
94
+ })(Utils || (Utils = {}));
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { ISymbologyDialogProps } from '../symbologyDialog';
3
+ declare const TiffRendering: ({ context, state, okSignalPromise, cancel, layerId }: ISymbologyDialogProps) => React.JSX.Element;
4
+ export default TiffRendering;
@@ -1,6 +1,6 @@
1
1
  import React, { useEffect, useState } from 'react';
2
- import SingleBandPseudoColor from './SingleBandPseudoColor';
3
- const BandRendering = ({ context, state, okSignalPromise, cancel, layerId }) => {
2
+ import SingleBandPseudoColor from './types/SingleBandPseudoColor';
3
+ const TiffRendering = ({ context, state, okSignalPromise, cancel, layerId }) => {
4
4
  const renderTypes = ['Singleband Pseudocolor', 'Multiband Color'];
5
5
  const [selectedRenderType, setSelectedRenderType] = useState('Singleband Pseudocolor');
6
6
  const [componentToRender, setComponentToRender] = useState(null);
@@ -26,4 +26,4 @@ const BandRendering = ({ context, state, okSignalPromise, cancel, layerId }) =>
26
26
  } }, renderTypes.map((func, funcIndex) => (React.createElement("option", { key: func, value: func }, func))))),
27
27
  componentToRender));
28
28
  };
29
- export default BandRendering;
29
+ export default TiffRendering;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { IBandRow } from './SingleBandPseudoColor';
2
+ import { IBandRow } from '../types/SingleBandPseudoColor';
3
3
  declare const BandRow: ({ index, bandRow, bandRows, setSelectedBand, setBandRows }: {
4
4
  index: number;
5
5
  bandRow: IBandRow;
@@ -11,6 +11,14 @@ export interface IBandRow {
11
11
  stdDev: number;
12
12
  };
13
13
  metadata: IDict;
14
+ histogram: IBandHistogram;
14
15
  }
15
- declare const SingleBandPseudoColor: ({ context, state, okSignalPromise, cancel, layerId }: ISymbologyDialogProps) => React.JSX.Element | undefined;
16
+ export interface IBandHistogram {
17
+ buckets: number[];
18
+ count: number;
19
+ max: number;
20
+ min: number;
21
+ }
22
+ export type InterpolationType = 'discrete' | 'linear' | 'exact';
23
+ declare const SingleBandPseudoColor: ({ context, okSignalPromise, cancel, layerId }: ISymbologyDialogProps) => React.JSX.Element | undefined;
16
24
  export default SingleBandPseudoColor;