@jupytergis/base 0.3.0 → 0.4.0
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.
- package/lib/annotations/components/Annotation.js +1 -1
- package/lib/annotations/model.d.ts +6 -7
- package/lib/annotations/model.js +15 -15
- package/lib/commands.d.ts +2 -3
- package/lib/commands.js +117 -62
- package/lib/constants.d.ts +2 -0
- package/lib/constants.js +4 -1
- package/lib/dialogs/formdialog.js +2 -2
- package/lib/dialogs/layerBrowserDialog.d.ts +4 -5
- package/lib/dialogs/layerBrowserDialog.js +9 -9
- package/lib/dialogs/symbology/hooks/useGetBandInfo.d.ts +1 -2
- package/lib/dialogs/symbology/hooks/useGetBandInfo.js +11 -6
- package/lib/dialogs/symbology/hooks/useGetProperties.d.ts +1 -1
- package/lib/dialogs/symbology/hooks/useGetProperties.js +6 -8
- package/lib/dialogs/symbology/symbologyDialog.d.ts +2 -3
- package/lib/dialogs/symbology/symbologyDialog.js +10 -9
- package/lib/dialogs/symbology/tiff_layer/TiffRendering.d.ts +1 -1
- package/lib/dialogs/symbology/tiff_layer/TiffRendering.js +6 -6
- package/lib/dialogs/symbology/tiff_layer/types/MultibandColor.d.ts +1 -1
- package/lib/dialogs/symbology/tiff_layer/types/MultibandColor.js +5 -4
- package/lib/dialogs/symbology/tiff_layer/types/SingleBandPseudoColor.d.ts +1 -1
- package/lib/dialogs/symbology/tiff_layer/types/SingleBandPseudoColor.js +8 -7
- package/lib/dialogs/symbology/vector_layer/VectorRendering.d.ts +1 -1
- package/lib/dialogs/symbology/vector_layer/VectorRendering.js +18 -13
- package/lib/dialogs/symbology/vector_layer/types/Categorized.d.ts +1 -1
- package/lib/dialogs/symbology/vector_layer/types/Categorized.js +30 -19
- package/lib/dialogs/symbology/vector_layer/types/Graduated.d.ts +1 -1
- package/lib/dialogs/symbology/vector_layer/types/Graduated.js +16 -13
- package/lib/dialogs/symbology/vector_layer/types/Heatmap.d.ts +4 -0
- package/lib/dialogs/symbology/vector_layer/types/Heatmap.js +77 -0
- package/lib/dialogs/symbology/vector_layer/types/SimpleSymbol.d.ts +1 -1
- package/lib/dialogs/symbology/vector_layer/types/SimpleSymbol.js +4 -3
- package/lib/formbuilder/creationform.d.ts +1 -2
- package/lib/formbuilder/creationform.js +4 -4
- package/lib/formbuilder/editform.d.ts +1 -2
- package/lib/formbuilder/editform.js +7 -7
- package/lib/formbuilder/formselectors.js +5 -2
- package/lib/formbuilder/objectform/baseform.d.ts +3 -4
- package/lib/formbuilder/objectform/baseform.js +2 -2
- package/lib/formbuilder/objectform/fileselectorwidget.js +13 -6
- package/lib/formbuilder/objectform/geotiffsource.d.ts +5 -1
- package/lib/formbuilder/objectform/geotiffsource.js +64 -18
- package/lib/formbuilder/objectform/heatmapLayerForm.d.ts +11 -0
- package/lib/formbuilder/objectform/heatmapLayerForm.js +60 -0
- package/lib/formbuilder/objectform/vectorlayerform.d.ts +0 -2
- package/lib/formbuilder/objectform/vectorlayerform.js +0 -59
- package/lib/mainview/TemporalSlider.d.ts +8 -0
- package/lib/mainview/TemporalSlider.js +303 -0
- package/lib/mainview/mainView.d.ts +25 -4
- package/lib/mainview/mainView.js +213 -75
- package/lib/mainview/mainviewmodel.d.ts +4 -0
- package/lib/mainview/mainviewmodel.js +4 -0
- package/lib/mainview/mainviewwidget.d.ts +0 -2
- package/lib/mainview/mainviewwidget.js +0 -2
- package/lib/panelview/annotationPanel.js +5 -5
- package/lib/panelview/components/filter-panel/Filter.js +4 -25
- package/lib/panelview/components/identify-panel/IdentifyPanel.js +1 -1
- package/lib/panelview/components/layers.js +2 -2
- package/lib/panelview/components/sources.js +1 -1
- package/lib/panelview/leftpanel.d.ts +3 -0
- package/lib/panelview/leftpanel.js +5 -1
- package/lib/panelview/model.js +8 -8
- package/lib/panelview/objectproperties.js +10 -10
- package/lib/panelview/rightpanel.d.ts +1 -1
- package/lib/panelview/rightpanel.js +10 -10
- package/lib/toolbar/widget.d.ts +1 -1
- package/lib/toolbar/widget.js +44 -32
- package/lib/tools.d.ts +10 -6
- package/lib/tools.js +89 -15
- package/lib/types.d.ts +2 -0
- package/lib/widget.d.ts +29 -5
- package/lib/widget.js +41 -7
- package/package.json +4 -3
- package/style/base.css +10 -0
- package/style/symbologyDialog.css +7 -1
- package/style/temporalSlider.css +47 -0
|
@@ -2,11 +2,11 @@ import { faCheck, faPlus } from '@fortawesome/free-solid-svg-icons';
|
|
|
2
2
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
3
3
|
import { Dialog } from '@jupyterlab/apputils';
|
|
4
4
|
import { PromiseDelegate, UUID } from '@lumino/coreutils';
|
|
5
|
+
import { Signal } from '@lumino/signaling';
|
|
5
6
|
import React, { useEffect, useState } from 'react';
|
|
6
7
|
import CUSTOM_RASTER_IMAGE from '../../rasterlayer_gallery/custom_raster.png';
|
|
7
8
|
import { CreationFormWrapper } from './formdialog';
|
|
8
|
-
|
|
9
|
-
export const LayerBrowserComponent = ({ context, registry, formSchemaRegistry, okSignalPromise, cancel }) => {
|
|
9
|
+
export const LayerBrowserComponent = ({ model, registry, formSchemaRegistry, okSignalPromise, cancel }) => {
|
|
10
10
|
const [searchTerm, setSearchTerm] = useState('');
|
|
11
11
|
const [activeLayers, setActiveLayers] = useState([]);
|
|
12
12
|
const [selectedCategory, setSelectedCategory] = useState();
|
|
@@ -15,9 +15,9 @@ export const LayerBrowserComponent = ({ context, registry, formSchemaRegistry, o
|
|
|
15
15
|
const providers = [...new Set(registry.map(item => item.source.provider))];
|
|
16
16
|
const filteredGallery = galleryWithCategory.filter(item => item.name.toLowerCase().includes(searchTerm));
|
|
17
17
|
useEffect(() => {
|
|
18
|
-
|
|
18
|
+
model.sharedModel.layersChanged.connect(handleLayerChange);
|
|
19
19
|
return () => {
|
|
20
|
-
|
|
20
|
+
model.sharedModel.layersChanged.disconnect(handleLayerChange);
|
|
21
21
|
};
|
|
22
22
|
}, []);
|
|
23
23
|
/**
|
|
@@ -25,7 +25,7 @@ export const LayerBrowserComponent = ({ context, registry, formSchemaRegistry, o
|
|
|
25
25
|
*/
|
|
26
26
|
const handleLayerChange = (_, change) => {
|
|
27
27
|
// The split is to get rid of the 'Layer' part of the name to match the names in the gallery
|
|
28
|
-
setActiveLayers(Object.values(
|
|
28
|
+
setActiveLayers(Object.values(model.sharedModel.layers).map(layer => layer.name.split(' ')[0]));
|
|
29
29
|
};
|
|
30
30
|
const handleSearchInput = (event) => {
|
|
31
31
|
setSearchTerm(event.target.value.toLowerCase());
|
|
@@ -64,8 +64,8 @@ export const LayerBrowserComponent = ({ context, registry, formSchemaRegistry, o
|
|
|
64
64
|
visible: true,
|
|
65
65
|
name: tile.name + ' Layer'
|
|
66
66
|
};
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
model.sharedModel.addSource(sourceId, sourceModel);
|
|
68
|
+
model.addLayer(UUID.uuid4(), layerModel);
|
|
69
69
|
};
|
|
70
70
|
if (creatingCustomRaster) {
|
|
71
71
|
// Disconnect any previous handler
|
|
@@ -73,7 +73,7 @@ export const LayerBrowserComponent = ({ context, registry, formSchemaRegistry, o
|
|
|
73
73
|
value.disconnect(cancel, this);
|
|
74
74
|
});
|
|
75
75
|
return (React.createElement("div", { className: "jGIS-customlayer-form" },
|
|
76
|
-
React.createElement(CreationFormWrapper, {
|
|
76
|
+
React.createElement(CreationFormWrapper, { model: model, formSchemaRegistry: formSchemaRegistry, createLayer: true, createSource: true, layerType: 'RasterLayer', sourceType: 'RasterSource', layerData: {
|
|
77
77
|
name: 'Custom Raster'
|
|
78
78
|
}, sourceData: {
|
|
79
79
|
url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
|
|
@@ -122,7 +122,7 @@ export class LayerBrowserWidget extends Dialog {
|
|
|
122
122
|
this.resolve(0);
|
|
123
123
|
};
|
|
124
124
|
const okSignalPromise = new PromiseDelegate();
|
|
125
|
-
const body = (React.createElement(LayerBrowserComponent, {
|
|
125
|
+
const body = (React.createElement(LayerBrowserComponent, { model: options.model, registry: options.registry, formSchemaRegistry: options.formSchemaRegistry, okSignalPromise: okSignalPromise, cancel: cancelCallback }));
|
|
126
126
|
super({ body, buttons: [Dialog.cancelButton(), Dialog.okButton()] });
|
|
127
127
|
this.id = 'jupytergis::layerBrowser';
|
|
128
128
|
this.okSignal = new Signal(this);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { IDict, IJGISLayer, IJupyterGISModel } from '@jupytergis/schema';
|
|
2
|
-
import { DocumentRegistry } from '@jupyterlab/docregistry';
|
|
3
2
|
export interface IBandHistogram {
|
|
4
3
|
buckets: number[];
|
|
5
4
|
count: number;
|
|
@@ -18,7 +17,7 @@ export interface IBandRow {
|
|
|
18
17
|
metadata: IDict;
|
|
19
18
|
histogram: IBandHistogram;
|
|
20
19
|
}
|
|
21
|
-
declare const useGetBandInfo: (
|
|
20
|
+
declare const useGetBandInfo: (model: IJupyterGISModel, layer: IJGISLayer) => {
|
|
22
21
|
bandRows: IBandRow[];
|
|
23
22
|
setBandRows: import("react").Dispatch<import("react").SetStateAction<IBandRow[]>>;
|
|
24
23
|
loading: boolean;
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { useEffect, useState } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
const preloadGeoTiffFile = async (sourceInfo) => {
|
|
4
|
-
|
|
2
|
+
import { loadFile } from '../../../tools';
|
|
3
|
+
const preloadGeoTiffFile = async (sourceInfo, model) => {
|
|
4
|
+
var _a;
|
|
5
|
+
return await loadFile({
|
|
6
|
+
filepath: (_a = sourceInfo.url) !== null && _a !== void 0 ? _a : '',
|
|
7
|
+
type: 'GeoTiffSource',
|
|
8
|
+
model: model
|
|
9
|
+
});
|
|
5
10
|
};
|
|
6
|
-
const useGetBandInfo = (
|
|
11
|
+
const useGetBandInfo = (model, layer) => {
|
|
7
12
|
const [bandRows, setBandRows] = useState([]);
|
|
8
13
|
const [loading, setLoading] = useState(false);
|
|
9
14
|
const [error, setError] = useState(null);
|
|
@@ -13,14 +18,14 @@ const useGetBandInfo = (context, layer) => {
|
|
|
13
18
|
setError(null);
|
|
14
19
|
try {
|
|
15
20
|
const bandsArr = [];
|
|
16
|
-
const source =
|
|
21
|
+
const source = model.getSource((_a = layer === null || layer === void 0 ? void 0 : layer.parameters) === null || _a === void 0 ? void 0 : _a.source);
|
|
17
22
|
const sourceInfo = (_b = source === null || source === void 0 ? void 0 : source.parameters) === null || _b === void 0 ? void 0 : _b.urls[0];
|
|
18
23
|
if (!(sourceInfo === null || sourceInfo === void 0 ? void 0 : sourceInfo.url)) {
|
|
19
24
|
setError('No source URL found.');
|
|
20
25
|
setLoading(false);
|
|
21
26
|
return;
|
|
22
27
|
}
|
|
23
|
-
const preloadedFile = await preloadGeoTiffFile(sourceInfo);
|
|
28
|
+
const preloadedFile = await preloadGeoTiffFile(sourceInfo, model);
|
|
24
29
|
const { file, metadata, sourceUrl } = Object.assign({}, preloadedFile);
|
|
25
30
|
if (file && metadata && sourceUrl === sourceInfo.url) {
|
|
26
31
|
metadata['bands'].forEach((bandData) => {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { useEffect, useState } from 'react';
|
|
3
3
|
import { loadFile } from '../../../tools';
|
|
4
4
|
export const useGetProperties = ({ layerId, model }) => {
|
|
5
|
-
const [
|
|
5
|
+
const [featureProperties, setFeatureProperties] = useState({});
|
|
6
6
|
const [isLoading, setIsLoading] = useState(true);
|
|
7
7
|
const [error, setError] = useState(undefined);
|
|
8
8
|
const getProperties = async () => {
|
|
@@ -28,16 +28,14 @@ export const useGetProperties = ({ layerId, model }) => {
|
|
|
28
28
|
data.features.forEach((feature) => {
|
|
29
29
|
if (feature.properties) {
|
|
30
30
|
Object.entries(feature.properties).forEach(([key, value]) => {
|
|
31
|
-
if (
|
|
32
|
-
|
|
33
|
-
result[key] = new Set();
|
|
34
|
-
}
|
|
35
|
-
result[key].add(value);
|
|
31
|
+
if (!(key in result)) {
|
|
32
|
+
result[key] = new Set();
|
|
36
33
|
}
|
|
34
|
+
result[key].add(value);
|
|
37
35
|
});
|
|
38
36
|
}
|
|
39
37
|
});
|
|
40
|
-
|
|
38
|
+
setFeatureProperties(result);
|
|
41
39
|
setIsLoading(false);
|
|
42
40
|
}
|
|
43
41
|
catch (err) {
|
|
@@ -48,5 +46,5 @@ export const useGetProperties = ({ layerId, model }) => {
|
|
|
48
46
|
useEffect(() => {
|
|
49
47
|
getProperties();
|
|
50
48
|
}, [model, layerId]);
|
|
51
|
-
return {
|
|
49
|
+
return { featureProperties, isLoading, error };
|
|
52
50
|
};
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import { IJupyterGISModel } from '@jupytergis/schema';
|
|
2
2
|
import { Dialog } from '@jupyterlab/apputils';
|
|
3
|
-
import { DocumentRegistry } from '@jupyterlab/docregistry';
|
|
4
3
|
import { IStateDB } from '@jupyterlab/statedb';
|
|
5
4
|
import { PromiseDelegate } from '@lumino/coreutils';
|
|
6
5
|
import { Signal } from '@lumino/signaling';
|
|
7
6
|
export interface ISymbologyDialogProps {
|
|
8
|
-
|
|
7
|
+
model: IJupyterGISModel;
|
|
9
8
|
state: IStateDB;
|
|
10
9
|
okSignalPromise: PromiseDelegate<Signal<SymbologyWidget, null>>;
|
|
11
10
|
cancel: () => void;
|
|
12
11
|
layerId?: string;
|
|
13
12
|
}
|
|
14
13
|
export interface ISymbologyWidgetOptions {
|
|
15
|
-
|
|
14
|
+
model: IJupyterGISModel;
|
|
16
15
|
state: IStateDB;
|
|
17
16
|
}
|
|
18
17
|
export interface IStopRow {
|
|
@@ -4,31 +4,31 @@ import { Signal } from '@lumino/signaling';
|
|
|
4
4
|
import React, { useEffect, useState } from 'react';
|
|
5
5
|
import TiffRendering from './tiff_layer/TiffRendering';
|
|
6
6
|
import VectorRendering from './vector_layer/VectorRendering';
|
|
7
|
-
const SymbologyDialog = ({
|
|
7
|
+
const SymbologyDialog = ({ model, state, okSignalPromise, cancel }) => {
|
|
8
8
|
const [selectedLayer, setSelectedLayer] = useState(null);
|
|
9
9
|
const [componentToRender, setComponentToRender] = useState(null);
|
|
10
10
|
let LayerSymbology;
|
|
11
11
|
useEffect(() => {
|
|
12
12
|
const handleClientStateChanged = () => {
|
|
13
13
|
var _a, _b;
|
|
14
|
-
if (!((_b = (_a =
|
|
14
|
+
if (!((_b = (_a = model.localState) === null || _a === void 0 ? void 0 : _a.selected) === null || _b === void 0 ? void 0 : _b.value)) {
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
|
-
const currentLayer = Object.keys(
|
|
17
|
+
const currentLayer = Object.keys(model.localState.selected.value)[0];
|
|
18
18
|
setSelectedLayer(currentLayer);
|
|
19
19
|
};
|
|
20
20
|
// Initial state
|
|
21
21
|
handleClientStateChanged();
|
|
22
|
-
|
|
22
|
+
model.clientStateChanged.connect(handleClientStateChanged);
|
|
23
23
|
return () => {
|
|
24
|
-
|
|
24
|
+
model.clientStateChanged.disconnect(handleClientStateChanged);
|
|
25
25
|
};
|
|
26
26
|
}, []);
|
|
27
27
|
useEffect(() => {
|
|
28
28
|
if (!selectedLayer) {
|
|
29
29
|
return;
|
|
30
30
|
}
|
|
31
|
-
const layer =
|
|
31
|
+
const layer = model.getLayer(selectedLayer);
|
|
32
32
|
if (!layer) {
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
@@ -36,10 +36,11 @@ const SymbologyDialog = ({ context, state, okSignalPromise, cancel }) => {
|
|
|
36
36
|
switch (layer.type) {
|
|
37
37
|
case 'VectorLayer':
|
|
38
38
|
case 'VectorTileLayer':
|
|
39
|
-
|
|
39
|
+
case 'HeatmapLayer':
|
|
40
|
+
LayerSymbology = (React.createElement(VectorRendering, { model: model, state: state, okSignalPromise: okSignalPromise, cancel: cancel, layerId: selectedLayer }));
|
|
40
41
|
break;
|
|
41
42
|
case 'WebGlLayer':
|
|
42
|
-
LayerSymbology = (React.createElement(TiffRendering, {
|
|
43
|
+
LayerSymbology = (React.createElement(TiffRendering, { model: model, state: state, okSignalPromise: okSignalPromise, cancel: cancel, layerId: selectedLayer }));
|
|
43
44
|
break;
|
|
44
45
|
default:
|
|
45
46
|
LayerSymbology = React.createElement("div", null, "Layer Type Not Supported");
|
|
@@ -54,7 +55,7 @@ export class SymbologyWidget extends Dialog {
|
|
|
54
55
|
this.resolve(0);
|
|
55
56
|
};
|
|
56
57
|
const okSignalPromise = new PromiseDelegate();
|
|
57
|
-
const body = (React.createElement(SymbologyDialog, {
|
|
58
|
+
const body = (React.createElement(SymbologyDialog, { model: options.model, okSignalPromise: okSignalPromise, cancel: cancelCallback, state: options.state }));
|
|
58
59
|
super({ title: 'Symbology', body });
|
|
59
60
|
this.id = 'jupytergis::symbologyWidget';
|
|
60
61
|
this.okSignal = new Signal(this);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ISymbologyDialogProps } from '../symbologyDialog';
|
|
3
|
-
declare const TiffRendering: ({
|
|
3
|
+
declare const TiffRendering: ({ model, state, okSignalPromise, cancel, layerId }: ISymbologyDialogProps) => React.JSX.Element | undefined;
|
|
4
4
|
export default TiffRendering;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
2
|
import SingleBandPseudoColor from './types/SingleBandPseudoColor';
|
|
3
3
|
import MultibandColor from './types/MultibandColor';
|
|
4
|
-
const TiffRendering = ({
|
|
4
|
+
const TiffRendering = ({ model, state, okSignalPromise, cancel, layerId }) => {
|
|
5
5
|
const renderTypes = ['Singleband Pseudocolor', 'Multiband Color'];
|
|
6
6
|
const [selectedRenderType, setSelectedRenderType] = useState();
|
|
7
7
|
const [componentToRender, setComponentToRender] = useState(null);
|
|
@@ -10,9 +10,9 @@ const TiffRendering = ({ context, state, okSignalPromise, cancel, layerId }) =>
|
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
12
|
useEffect(() => {
|
|
13
|
-
var _a;
|
|
14
|
-
const layer =
|
|
15
|
-
const renderType = (_a = layer === null || layer === void 0 ? void 0 : layer.parameters) === null || _a === void 0 ? void 0 : _a.symbologyState.renderType;
|
|
13
|
+
var _a, _b;
|
|
14
|
+
const layer = model.getLayer(layerId);
|
|
15
|
+
const renderType = (_b = (_a = layer === null || layer === void 0 ? void 0 : layer.parameters) === null || _a === void 0 ? void 0 : _a.symbologyState) === null || _b === void 0 ? void 0 : _b.renderType;
|
|
16
16
|
setSelectedRenderType(renderType !== null && renderType !== void 0 ? renderType : 'Singleband Pseudocolor');
|
|
17
17
|
}, []);
|
|
18
18
|
useEffect(() => {
|
|
@@ -21,10 +21,10 @@ const TiffRendering = ({ context, state, okSignalPromise, cancel, layerId }) =>
|
|
|
21
21
|
}
|
|
22
22
|
switch (selectedRenderType) {
|
|
23
23
|
case 'Singleband Pseudocolor':
|
|
24
|
-
RenderComponent = (React.createElement(SingleBandPseudoColor, {
|
|
24
|
+
RenderComponent = (React.createElement(SingleBandPseudoColor, { model: model, state: state, okSignalPromise: okSignalPromise, cancel: cancel, layerId: layerId }));
|
|
25
25
|
break;
|
|
26
26
|
case 'Multiband Color':
|
|
27
|
-
RenderComponent = (React.createElement(MultibandColor, {
|
|
27
|
+
RenderComponent = (React.createElement(MultibandColor, { model: model, state: state, okSignalPromise: okSignalPromise, cancel: cancel, layerId: layerId }));
|
|
28
28
|
break;
|
|
29
29
|
default:
|
|
30
30
|
RenderComponent = React.createElement("div", null, "Render Type Not Implemented (yet)");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ISymbologyDialogProps } from '../../symbologyDialog';
|
|
3
|
-
declare const MultibandColor: ({
|
|
3
|
+
declare const MultibandColor: ({ model, okSignalPromise, cancel, layerId }: ISymbologyDialogProps) => React.JSX.Element | undefined;
|
|
4
4
|
export default MultibandColor;
|
|
@@ -2,15 +2,15 @@ import React, { useEffect, useRef, useState } from 'react';
|
|
|
2
2
|
import { Spinner } from '../../../../mainview/spinner';
|
|
3
3
|
import useGetBandInfo from '../../hooks/useGetBandInfo';
|
|
4
4
|
import BandRow from '../components/BandRow';
|
|
5
|
-
const MultibandColor = ({
|
|
5
|
+
const MultibandColor = ({ model, okSignalPromise, cancel, layerId }) => {
|
|
6
6
|
if (!layerId) {
|
|
7
7
|
return;
|
|
8
8
|
}
|
|
9
|
-
const layer =
|
|
9
|
+
const layer = model.getLayer(layerId);
|
|
10
10
|
if (!(layer === null || layer === void 0 ? void 0 : layer.parameters)) {
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
13
|
-
const { bandRows, setBandRows, loading } = useGetBandInfo(
|
|
13
|
+
const { bandRows, setBandRows, loading } = useGetBandInfo(model, layer);
|
|
14
14
|
const [selectedBands, setSelectedBands] = useState({
|
|
15
15
|
red: 1,
|
|
16
16
|
green: 2,
|
|
@@ -72,7 +72,8 @@ const MultibandColor = ({ context, okSignalPromise, cancel, layerId }) => {
|
|
|
72
72
|
};
|
|
73
73
|
layer.parameters.symbologyState = symbologyState;
|
|
74
74
|
layer.parameters.color = colorExpr;
|
|
75
|
-
|
|
75
|
+
layer.type = 'WebGlLayer';
|
|
76
|
+
model.sharedModel.updateLayer(layerId, layer);
|
|
76
77
|
cancel();
|
|
77
78
|
};
|
|
78
79
|
return (React.createElement("div", { className: "jp-gis-layer-symbology-container" },
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ISymbologyDialogProps } from '../../symbologyDialog';
|
|
3
3
|
export type InterpolationType = 'discrete' | 'linear' | 'exact';
|
|
4
|
-
declare const SingleBandPseudoColor: ({
|
|
4
|
+
declare const SingleBandPseudoColor: ({ model, okSignalPromise, cancel, layerId }: ISymbologyDialogProps) => React.JSX.Element | undefined;
|
|
5
5
|
export default SingleBandPseudoColor;
|
|
@@ -8,18 +8,18 @@ import StopRow from '../../components/color_stops/StopRow';
|
|
|
8
8
|
import useGetBandInfo from '../../hooks/useGetBandInfo';
|
|
9
9
|
import { Utils } from '../../symbologyUtils';
|
|
10
10
|
import BandRow from '../components/BandRow';
|
|
11
|
-
const SingleBandPseudoColor = ({
|
|
11
|
+
const SingleBandPseudoColor = ({ model, okSignalPromise, cancel, layerId }) => {
|
|
12
12
|
if (!layerId) {
|
|
13
13
|
return;
|
|
14
14
|
}
|
|
15
|
-
const layer =
|
|
15
|
+
const layer = model.getLayer(layerId);
|
|
16
16
|
if (!(layer === null || layer === void 0 ? void 0 : layer.parameters)) {
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
19
|
const functions = ['discrete', 'linear', 'exact'];
|
|
20
20
|
const modeOptions = ['continuous', 'equal interval', 'quantile'];
|
|
21
21
|
const stateDb = GlobalStateDbManager.getInstance().getStateDb();
|
|
22
|
-
const { bandRows, setBandRows, loading } = useGetBandInfo(
|
|
22
|
+
const { bandRows, setBandRows, loading } = useGetBandInfo(model, layer);
|
|
23
23
|
const [layerState, setLayerState] = useState();
|
|
24
24
|
const [selectedBand, setSelectedBand] = useState(1);
|
|
25
25
|
const [stopRows, setStopRows] = useState([]);
|
|
@@ -120,7 +120,7 @@ const SingleBandPseudoColor = ({ context, okSignalPromise, cancel, layerId }) =>
|
|
|
120
120
|
return;
|
|
121
121
|
}
|
|
122
122
|
const sourceId = (_a = layer.parameters) === null || _a === void 0 ? void 0 : _a.source;
|
|
123
|
-
const source =
|
|
123
|
+
const source = model.getSource(sourceId);
|
|
124
124
|
if (!source || !source.parameters) {
|
|
125
125
|
return;
|
|
126
126
|
}
|
|
@@ -129,7 +129,7 @@ const SingleBandPseudoColor = ({ context, okSignalPromise, cancel, layerId }) =>
|
|
|
129
129
|
sourceInfo.min = bandRow.stats.minimum;
|
|
130
130
|
sourceInfo.max = bandRow.stats.maximum;
|
|
131
131
|
source.parameters.urls[0] = sourceInfo;
|
|
132
|
-
|
|
132
|
+
model.sharedModel.updateSource(sourceId, source);
|
|
133
133
|
// Update layer
|
|
134
134
|
if (!layer.parameters) {
|
|
135
135
|
return;
|
|
@@ -193,7 +193,8 @@ const SingleBandPseudoColor = ({ context, okSignalPromise, cancel, layerId }) =>
|
|
|
193
193
|
};
|
|
194
194
|
layer.parameters.symbologyState = symbologyState;
|
|
195
195
|
layer.parameters.color = colorExpr;
|
|
196
|
-
|
|
196
|
+
layer.type = 'WebGlLayer';
|
|
197
|
+
model.sharedModel.updateLayer(layerId, layer);
|
|
197
198
|
cancel();
|
|
198
199
|
};
|
|
199
200
|
const addStopRow = () => {
|
|
@@ -220,7 +221,7 @@ const SingleBandPseudoColor = ({ context, okSignalPromise, cancel, layerId }) =>
|
|
|
220
221
|
});
|
|
221
222
|
let stops = [];
|
|
222
223
|
const currentBand = bandRows[selectedBand - 1];
|
|
223
|
-
const source =
|
|
224
|
+
const source = model.getSource((_a = layer === null || layer === void 0 ? void 0 : layer.parameters) === null || _a === void 0 ? void 0 : _a.source);
|
|
224
225
|
const sourceInfo = (_b = source === null || source === void 0 ? void 0 : source.parameters) === null || _b === void 0 ? void 0 : _b.urls[0];
|
|
225
226
|
const nClasses = selectedMode === 'continuous' ? 52 : +numberOfShades;
|
|
226
227
|
setIsLoading(true);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ISymbologyDialogProps } from '../symbologyDialog';
|
|
3
|
-
declare const VectorRendering: ({
|
|
3
|
+
declare const VectorRendering: ({ model, state, okSignalPromise, cancel, layerId }: ISymbologyDialogProps) => React.JSX.Element | undefined;
|
|
4
4
|
export default VectorRendering;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import Categorized from './types/Categorized';
|
|
2
3
|
import Graduated from './types/Graduated';
|
|
4
|
+
import Heatmap from './types/Heatmap';
|
|
3
5
|
import SimpleSymbol from './types/SimpleSymbol';
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const [selectedRenderType, setSelectedRenderType] = useState('Single Symbol');
|
|
6
|
+
const VectorRendering = ({ model, state, okSignalPromise, cancel, layerId }) => {
|
|
7
|
+
const [selectedRenderType, setSelectedRenderType] = useState('');
|
|
7
8
|
const [componentToRender, setComponentToRender] = useState(null);
|
|
8
9
|
const [renderTypeOptions, setRenderTypeOptions] = useState([
|
|
9
10
|
'Single Symbol'
|
|
@@ -12,32 +13,36 @@ const VectorRendering = ({ context, state, okSignalPromise, cancel, layerId }) =
|
|
|
12
13
|
if (!layerId) {
|
|
13
14
|
return;
|
|
14
15
|
}
|
|
15
|
-
const layer =
|
|
16
|
+
const layer = model.getLayer(layerId);
|
|
16
17
|
if (!(layer === null || layer === void 0 ? void 0 : layer.parameters)) {
|
|
17
18
|
return;
|
|
18
19
|
}
|
|
19
20
|
useEffect(() => {
|
|
20
21
|
var _a, _b;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const options = ['Single Symbol', 'Graduated', 'Categorized'];
|
|
25
|
-
setRenderTypeOptions(options);
|
|
22
|
+
let renderType = (_b = (_a = layer.parameters) === null || _a === void 0 ? void 0 : _a.symbologyState) === null || _b === void 0 ? void 0 : _b.renderType;
|
|
23
|
+
if (!renderType) {
|
|
24
|
+
renderType = layer.type === 'HeatmapLayer' ? 'Heatmap' : 'Single Symbol';
|
|
26
25
|
}
|
|
26
|
+
setSelectedRenderType(renderType);
|
|
27
|
+
const options = ['Single Symbol', 'Graduated', 'Categorized', 'Heatmap'];
|
|
28
|
+
setRenderTypeOptions(options);
|
|
27
29
|
}, []);
|
|
28
30
|
useEffect(() => {
|
|
29
31
|
switch (selectedRenderType) {
|
|
30
32
|
case 'Single Symbol':
|
|
31
|
-
RenderComponent = (React.createElement(SimpleSymbol, {
|
|
33
|
+
RenderComponent = (React.createElement(SimpleSymbol, { model: model, state: state, okSignalPromise: okSignalPromise, cancel: cancel, layerId: layerId }));
|
|
32
34
|
break;
|
|
33
35
|
case 'Graduated':
|
|
34
|
-
RenderComponent = (React.createElement(Graduated, {
|
|
36
|
+
RenderComponent = (React.createElement(Graduated, { model: model, state: state, okSignalPromise: okSignalPromise, cancel: cancel, layerId: layerId }));
|
|
35
37
|
break;
|
|
36
38
|
case 'Categorized':
|
|
37
|
-
RenderComponent = (React.createElement(Categorized, {
|
|
39
|
+
RenderComponent = (React.createElement(Categorized, { model: model, state: state, okSignalPromise: okSignalPromise, cancel: cancel, layerId: layerId }));
|
|
40
|
+
break;
|
|
41
|
+
case 'Heatmap':
|
|
42
|
+
RenderComponent = (React.createElement(Heatmap, { model: model, state: state, okSignalPromise: okSignalPromise, cancel: cancel, layerId: layerId }));
|
|
38
43
|
break;
|
|
39
44
|
default:
|
|
40
|
-
RenderComponent = React.createElement("div", null, "
|
|
45
|
+
RenderComponent = React.createElement("div", null, "Select a render type");
|
|
41
46
|
}
|
|
42
47
|
setComponentToRender(RenderComponent);
|
|
43
48
|
}, [selectedRenderType]);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ISymbologyDialogProps } from '../../symbologyDialog';
|
|
3
|
-
declare const Categorized: ({
|
|
3
|
+
declare const Categorized: ({ model, state, okSignalPromise, cancel, layerId }: ISymbologyDialogProps) => React.JSX.Element | undefined;
|
|
4
4
|
export default Categorized;
|
|
@@ -1,26 +1,28 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useState } from 'react';
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import { getNumericFeatureAttributes } from '../../../../tools';
|
|
3
|
+
import ColorRamp from '../../components/color_ramp/ColorRamp';
|
|
4
4
|
import StopContainer from '../../components/color_stops/StopContainer';
|
|
5
|
+
import { useGetProperties } from '../../hooks/useGetProperties';
|
|
5
6
|
import { Utils, VectorUtils } from '../../symbologyUtils';
|
|
6
|
-
import
|
|
7
|
-
const Categorized = ({
|
|
7
|
+
import ValueSelect from '../components/ValueSelect';
|
|
8
|
+
const Categorized = ({ model, state, okSignalPromise, cancel, layerId }) => {
|
|
8
9
|
const selectedValueRef = useRef();
|
|
9
10
|
const stopRowsRef = useRef();
|
|
10
11
|
const colorRampOptionsRef = useRef();
|
|
11
12
|
const [selectedValue, setSelectedValue] = useState('');
|
|
12
13
|
const [stopRows, setStopRows] = useState([]);
|
|
13
14
|
const [colorRampOptions, setColorRampOptions] = useState();
|
|
15
|
+
const [features, setFeatures] = useState({});
|
|
14
16
|
if (!layerId) {
|
|
15
17
|
return;
|
|
16
18
|
}
|
|
17
|
-
const layer =
|
|
19
|
+
const layer = model.getLayer(layerId);
|
|
18
20
|
if (!(layer === null || layer === void 0 ? void 0 : layer.parameters)) {
|
|
19
21
|
return;
|
|
20
22
|
}
|
|
21
|
-
const {
|
|
23
|
+
const { featureProperties } = useGetProperties({
|
|
22
24
|
layerId,
|
|
23
|
-
model:
|
|
25
|
+
model: model
|
|
24
26
|
});
|
|
25
27
|
useEffect(() => {
|
|
26
28
|
const valueColorPairs = VectorUtils.buildColorInfo(layer);
|
|
@@ -35,19 +37,19 @@ const Categorized = ({ context, state, okSignalPromise, cancel, layerId }) => {
|
|
|
35
37
|
};
|
|
36
38
|
}, []);
|
|
37
39
|
useEffect(() => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
var _a, _b;
|
|
41
|
+
// We only want number values here
|
|
42
|
+
const numericFeatures = getNumericFeatureAttributes(featureProperties);
|
|
43
|
+
setFeatures(numericFeatures);
|
|
44
|
+
const layerParams = layer.parameters;
|
|
45
|
+
const value = (_b = (_a = layerParams.symbologyState) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : Object.keys(numericFeatures)[0];
|
|
46
|
+
setSelectedValue(value);
|
|
47
|
+
}, [featureProperties]);
|
|
40
48
|
useEffect(() => {
|
|
41
49
|
selectedValueRef.current = selectedValue;
|
|
42
50
|
stopRowsRef.current = stopRows;
|
|
43
51
|
colorRampOptionsRef.current = colorRampOptions;
|
|
44
52
|
}, [selectedValue, stopRows, colorRampOptions]);
|
|
45
|
-
const populateOptions = async () => {
|
|
46
|
-
var _a, _b;
|
|
47
|
-
const layerParams = layer.parameters;
|
|
48
|
-
const value = (_b = (_a = layerParams.symbologyState) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : Object.keys(featureProps)[0];
|
|
49
|
-
setSelectedValue(value);
|
|
50
|
-
};
|
|
51
53
|
const buildColorInfoFromClassification = (selectedMode, numberOfShades, selectedRamp, setIsLoading) => {
|
|
52
54
|
setColorRampOptions({
|
|
53
55
|
selectedFunction: '',
|
|
@@ -55,7 +57,7 @@ const Categorized = ({ context, state, okSignalPromise, cancel, layerId }) => {
|
|
|
55
57
|
numberOfShades: '',
|
|
56
58
|
selectedMode: ''
|
|
57
59
|
});
|
|
58
|
-
const stops = Array.from(
|
|
60
|
+
const stops = Array.from(features[selectedValue]).sort((a, b) => a - b);
|
|
59
61
|
const valueColorPairs = Utils.getValueColorPairs(stops, selectedRamp, stops.length);
|
|
60
62
|
setStopRows(valueColorPairs);
|
|
61
63
|
};
|
|
@@ -73,7 +75,15 @@ const Categorized = ({ context, state, okSignalPromise, cancel, layerId }) => {
|
|
|
73
75
|
// fallback value
|
|
74
76
|
colorExpr.push([0, 0, 0, 0.0]);
|
|
75
77
|
const newStyle = Object.assign({}, layer.parameters.color);
|
|
76
|
-
|
|
78
|
+
if (layer.parameters.type === 'fill') {
|
|
79
|
+
newStyle['fill-color'] = colorExpr;
|
|
80
|
+
}
|
|
81
|
+
if (layer.parameters.type === 'line') {
|
|
82
|
+
newStyle['stroke-color'] = colorExpr;
|
|
83
|
+
}
|
|
84
|
+
if (layer.parameters.type === 'circle') {
|
|
85
|
+
newStyle['circle-fill-color'] = colorExpr;
|
|
86
|
+
}
|
|
77
87
|
const symbologyState = {
|
|
78
88
|
renderType: 'Categorized',
|
|
79
89
|
value: selectedValueRef.current,
|
|
@@ -83,11 +93,12 @@ const Categorized = ({ context, state, okSignalPromise, cancel, layerId }) => {
|
|
|
83
93
|
};
|
|
84
94
|
layer.parameters.symbologyState = symbologyState;
|
|
85
95
|
layer.parameters.color = newStyle;
|
|
86
|
-
|
|
96
|
+
layer.type = 'VectorLayer';
|
|
97
|
+
model.sharedModel.updateLayer(layerId, layer);
|
|
87
98
|
cancel();
|
|
88
99
|
};
|
|
89
100
|
return (React.createElement("div", { className: "jp-gis-layer-symbology-container" },
|
|
90
|
-
React.createElement(ValueSelect, { featureProperties:
|
|
101
|
+
React.createElement(ValueSelect, { featureProperties: features, selectedValue: selectedValue, setSelectedValue: setSelectedValue }),
|
|
91
102
|
React.createElement(ColorRamp, { layerParams: layer.parameters, modeOptions: [], classifyFunc: buildColorInfoFromClassification, showModeRow: false }),
|
|
92
103
|
React.createElement(StopContainer, { selectedMethod: '', stopRows: stopRows, setStopRows: setStopRows })));
|
|
93
104
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ISymbologyDialogProps } from '../../symbologyDialog';
|
|
3
|
-
declare const Graduated: ({
|
|
3
|
+
declare const Graduated: ({ model, state, okSignalPromise, cancel, layerId }: ISymbologyDialogProps) => React.JSX.Element | undefined;
|
|
4
4
|
export default Graduated;
|