@jupytergis/base 0.2.1 → 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 +2 -2
- 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 +146 -62
- package/lib/constants.d.ts +3 -0
- package/lib/constants.js +5 -1
- package/lib/dialogs/formdialog.d.ts +5 -0
- 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/components/color_ramp/ModeSelectRow.js +2 -1
- package/lib/dialogs/symbology/hooks/useGetBandInfo.d.ts +26 -0
- package/lib/dialogs/symbology/hooks/useGetBandInfo.js +64 -0
- package/lib/dialogs/symbology/hooks/useGetProperties.d.ts +1 -1
- package/lib/dialogs/symbology/hooks/useGetProperties.js +12 -9
- 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 +16 -3
- package/lib/dialogs/symbology/tiff_layer/components/BandRow.d.ts +16 -3
- package/lib/dialogs/symbology/tiff_layer/components/BandRow.js +21 -7
- package/lib/dialogs/symbology/tiff_layer/types/MultibandColor.d.ts +4 -0
- package/lib/dialogs/symbology/tiff_layer/types/MultibandColor.js +85 -0
- package/lib/dialogs/symbology/tiff_layer/types/SingleBandPseudoColor.d.ts +1 -20
- package/lib/dialogs/symbology/tiff_layer/types/SingleBandPseudoColor.js +25 -65
- 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 +6 -2
- package/lib/formbuilder/creationform.js +6 -6
- package/lib/formbuilder/editform.d.ts +2 -2
- package/lib/formbuilder/editform.js +14 -9
- package/lib/formbuilder/formselectors.js +11 -1
- package/lib/formbuilder/objectform/baseform.d.ts +12 -3
- package/lib/formbuilder/objectform/baseform.js +39 -0
- package/lib/formbuilder/objectform/fileselectorwidget.d.ts +2 -0
- package/lib/formbuilder/objectform/fileselectorwidget.js +88 -0
- package/lib/formbuilder/objectform/geojsonsource.d.ts +5 -7
- package/lib/formbuilder/objectform/geojsonsource.js +8 -24
- 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/layerform.d.ts +2 -0
- package/lib/formbuilder/objectform/layerform.js +6 -0
- package/lib/formbuilder/objectform/pathbasedsource.d.ts +19 -0
- package/lib/formbuilder/objectform/pathbasedsource.js +98 -0
- package/lib/formbuilder/objectform/vectorlayerform.d.ts +0 -2
- package/lib/formbuilder/objectform/vectorlayerform.js +0 -59
- package/lib/icons.d.ts +1 -0
- package/lib/icons.js +5 -0
- package/lib/keybindings.json +62 -0
- package/lib/mainview/TemporalSlider.d.ts +8 -0
- package/lib/mainview/TemporalSlider.js +303 -0
- package/lib/mainview/mainView.d.ts +46 -8
- package/lib/mainview/mainView.js +431 -144
- 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 +8 -24
- 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/statusbar/StatusBar.d.ts +13 -0
- package/lib/statusbar/StatusBar.js +52 -0
- package/lib/toolbar/widget.d.ts +1 -1
- package/lib/toolbar/widget.js +44 -37
- package/lib/tools.d.ts +50 -7
- package/lib/tools.js +394 -12
- package/lib/types.d.ts +2 -0
- package/lib/widget.d.ts +29 -5
- package/lib/widget.js +41 -7
- package/package.json +17 -5
- package/style/base.css +11 -0
- package/style/icons/logo_mini_qgz.svg +31 -0
- package/style/leftPanel.css +8 -0
- package/style/statusBar.css +16 -0
- package/style/symbologyDialog.css +7 -1
- package/style/temporalSlider.css +47 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { IAnnotation, IJupyterGISModel } from '@jupytergis/schema';
|
|
2
2
|
import { ObservableMap } from '@jupyterlab/observables';
|
|
3
|
+
import { CommandRegistry } from '@lumino/commands';
|
|
3
4
|
import { JSONValue } from '@lumino/coreutils';
|
|
4
5
|
import { IDisposable } from '@lumino/disposable';
|
|
5
6
|
export declare class MainViewModel implements IDisposable {
|
|
@@ -8,12 +9,14 @@ export declare class MainViewModel implements IDisposable {
|
|
|
8
9
|
get id(): string;
|
|
9
10
|
get jGISModel(): IJupyterGISModel;
|
|
10
11
|
get viewSettingChanged(): import("@lumino/signaling").ISignal<ObservableMap<JSONValue>, import("@jupyterlab/observables").IObservableMap.IChangedArgs<JSONValue>>;
|
|
12
|
+
get commands(): CommandRegistry;
|
|
11
13
|
dispose(): void;
|
|
12
14
|
initSignal(): void;
|
|
13
15
|
addAnnotation(value: IAnnotation): void;
|
|
14
16
|
private _onsharedLayersChanged;
|
|
15
17
|
private _jGISModel;
|
|
16
18
|
private _viewSetting;
|
|
19
|
+
private _commands;
|
|
17
20
|
private _id;
|
|
18
21
|
private _isDisposed;
|
|
19
22
|
}
|
|
@@ -21,5 +24,6 @@ export declare namespace MainViewModel {
|
|
|
21
24
|
interface IOptions {
|
|
22
25
|
jGISModel: IJupyterGISModel;
|
|
23
26
|
viewSetting: ObservableMap<JSONValue>;
|
|
27
|
+
commands: CommandRegistry;
|
|
24
28
|
}
|
|
25
29
|
}
|
|
@@ -4,6 +4,7 @@ export class MainViewModel {
|
|
|
4
4
|
this._isDisposed = false;
|
|
5
5
|
this._jGISModel = options.jGISModel;
|
|
6
6
|
this._viewSetting = options.viewSetting;
|
|
7
|
+
this._commands = options.commands;
|
|
7
8
|
}
|
|
8
9
|
get isDisposed() {
|
|
9
10
|
return this._isDisposed;
|
|
@@ -17,6 +18,9 @@ export class MainViewModel {
|
|
|
17
18
|
get viewSettingChanged() {
|
|
18
19
|
return this._viewSetting.changed;
|
|
19
20
|
}
|
|
21
|
+
get commands() {
|
|
22
|
+
return this._commands;
|
|
23
|
+
}
|
|
20
24
|
dispose() {
|
|
21
25
|
if (this._isDisposed) {
|
|
22
26
|
return;
|
|
@@ -3,8 +3,6 @@ import { MainViewModel } from './mainviewmodel';
|
|
|
3
3
|
export declare class JupyterGISMainViewPanel extends ReactWidget {
|
|
4
4
|
/**
|
|
5
5
|
* Construct a `JupyterGISPanel`.
|
|
6
|
-
*
|
|
7
|
-
* @param context - The documents context.
|
|
8
6
|
*/
|
|
9
7
|
constructor(options: {
|
|
10
8
|
mainViewModel: MainViewModel;
|
|
@@ -9,12 +9,12 @@ export class AnnotationsPanel extends Component {
|
|
|
9
9
|
};
|
|
10
10
|
this._annotationModel = props.annotationModel;
|
|
11
11
|
this._rightPanelModel = props.rightPanelModel;
|
|
12
|
-
this._annotationModel.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
(
|
|
12
|
+
this._annotationModel.modelChanged.connect(async () => {
|
|
13
|
+
// await this._annotationModel?.context?.ready;
|
|
14
|
+
var _a, _b, _c, _d;
|
|
15
|
+
(_b = (_a = this._annotationModel) === null || _a === void 0 ? void 0 : _a.model) === null || _b === void 0 ? void 0 : _b.sharedMetadataChanged.disconnect(updateCallback);
|
|
16
16
|
this._annotationModel = props.annotationModel;
|
|
17
|
-
(
|
|
17
|
+
(_d = (_c = this._annotationModel) === null || _c === void 0 ? void 0 : _c.model) === null || _d === void 0 ? void 0 : _d.sharedMetadataChanged.connect(updateCallback);
|
|
18
18
|
this.forceUpdate();
|
|
19
19
|
});
|
|
20
20
|
}
|
|
@@ -2,7 +2,7 @@ import { Button, ReactWidget } from '@jupyterlab/ui-components';
|
|
|
2
2
|
import { Panel } from '@lumino/widgets';
|
|
3
3
|
import { cloneDeep } from 'lodash';
|
|
4
4
|
import React, { useEffect, useRef, useState } from 'react';
|
|
5
|
-
import { debounce,
|
|
5
|
+
import { debounce, loadFile } from '../../../tools';
|
|
6
6
|
import FilterRow from './FilterRow';
|
|
7
7
|
/**
|
|
8
8
|
* The filters panel widget.
|
|
@@ -28,7 +28,7 @@ const FilterComponent = (props) => {
|
|
|
28
28
|
const [featuresInLayer, setFeaturesInLayer] = useState({});
|
|
29
29
|
const [model, setModel] = useState(props.model.jGISModel);
|
|
30
30
|
(_a = props.model) === null || _a === void 0 ? void 0 : _a.documentChanged.connect((_, widget) => {
|
|
31
|
-
setModel(widget === null || widget === void 0 ? void 0 : widget.
|
|
31
|
+
setModel(widget === null || widget === void 0 ? void 0 : widget.model);
|
|
32
32
|
});
|
|
33
33
|
// Reset state values when current widget changes
|
|
34
34
|
useEffect(() => {
|
|
@@ -107,13 +107,12 @@ const FilterComponent = (props) => {
|
|
|
107
107
|
featuresInLayerRef.current = featuresInLayer;
|
|
108
108
|
}, [featuresInLayer]);
|
|
109
109
|
const buildFilterObject = async (currentLayer) => {
|
|
110
|
-
var _a, _b
|
|
110
|
+
var _a, _b;
|
|
111
111
|
if (!model) {
|
|
112
112
|
return;
|
|
113
113
|
}
|
|
114
114
|
const layer = model.getLayer(currentLayer !== null && currentLayer !== void 0 ? currentLayer : selectedLayer);
|
|
115
115
|
const source = model.getSource((_a = layer === null || layer === void 0 ? void 0 : layer.parameters) === null || _a === void 0 ? void 0 : _a.source);
|
|
116
|
-
const { latitude, longitude, extent, zoom } = model.getOptions();
|
|
117
116
|
if (!source || !layer) {
|
|
118
117
|
return;
|
|
119
118
|
}
|
|
@@ -130,27 +129,12 @@ const FilterComponent = (props) => {
|
|
|
130
129
|
});
|
|
131
130
|
}
|
|
132
131
|
switch (source.type) {
|
|
133
|
-
case 'VectorTileSource': {
|
|
134
|
-
try {
|
|
135
|
-
const tile = await getLayerTileInfo((_b = source === null || source === void 0 ? void 0 : source.parameters) === null || _b === void 0 ? void 0 : _b.url, {
|
|
136
|
-
latitude,
|
|
137
|
-
longitude,
|
|
138
|
-
extent,
|
|
139
|
-
zoom
|
|
140
|
-
});
|
|
141
|
-
const layerValue = tile.layers[(_c = layer.parameters) === null || _c === void 0 ? void 0 : _c.sourceLayer];
|
|
142
|
-
for (let i = 0; i < layerValue.length; i++) {
|
|
143
|
-
const feature = layerValue.feature(i);
|
|
144
|
-
addFeatureValue(feature.properties, aggregatedProperties);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
catch (error) {
|
|
148
|
-
console.warn(`Error fetching tile info: ${error}`);
|
|
149
|
-
}
|
|
150
|
-
break;
|
|
151
|
-
}
|
|
152
132
|
case 'GeoJSONSource': {
|
|
153
|
-
const data = await (
|
|
133
|
+
const data = await loadFile({
|
|
134
|
+
filepath: (_b = source.parameters) === null || _b === void 0 ? void 0 : _b.path,
|
|
135
|
+
type: 'GeoJSONSource',
|
|
136
|
+
model: model
|
|
137
|
+
});
|
|
154
138
|
data === null || data === void 0 ? void 0 : data.features.forEach((feature) => {
|
|
155
139
|
feature.properties &&
|
|
156
140
|
addFeatureValue(feature.properties, aggregatedProperties);
|
|
@@ -26,7 +26,7 @@ const IdentifyPanelComponent = ({ controlPanelModel, tracker }) => {
|
|
|
26
26
|
* Update the model when it changes.
|
|
27
27
|
*/
|
|
28
28
|
controlPanelModel === null || controlPanelModel === void 0 ? void 0 : controlPanelModel.documentChanged.connect((_, widget) => {
|
|
29
|
-
setJgisModel(widget === null || widget === void 0 ? void 0 : widget.
|
|
29
|
+
setJgisModel(widget === null || widget === void 0 ? void 0 : widget.model);
|
|
30
30
|
});
|
|
31
31
|
// Reset state values when current widget changes
|
|
32
32
|
useEffect(() => {
|
|
@@ -104,8 +104,8 @@ function LayersBodyComponent(props) {
|
|
|
104
104
|
*/
|
|
105
105
|
(_b = props.model) === null || _b === void 0 ? void 0 : _b.documentChanged.connect((_, widget) => {
|
|
106
106
|
var _a;
|
|
107
|
-
setModel(widget === null || widget === void 0 ? void 0 : widget.
|
|
108
|
-
setLayerTree(((_a = widget === null || widget === void 0 ? void 0 : widget.
|
|
107
|
+
setModel(widget === null || widget === void 0 ? void 0 : widget.model);
|
|
108
|
+
setLayerTree(((_a = widget === null || widget === void 0 ? void 0 : widget.model) === null || _a === void 0 ? void 0 : _a.getLayerTree()) || []);
|
|
109
109
|
});
|
|
110
110
|
return (React.createElement("div", { id: "jp-gis-layer-tree" }, layerTree
|
|
111
111
|
.slice()
|
|
@@ -55,7 +55,7 @@ function SourcesBodyComponent(props) {
|
|
|
55
55
|
* Update the model when it changes.
|
|
56
56
|
*/
|
|
57
57
|
(_b = props.model) === null || _b === void 0 ? void 0 : _b.documentChanged.connect((_, widget) => {
|
|
58
|
-
setModel(widget === null || widget === void 0 ? void 0 : widget.
|
|
58
|
+
setModel(widget === null || widget === void 0 ? void 0 : widget.model);
|
|
59
59
|
});
|
|
60
60
|
return (React.createElement("div", { id: "jp-gis-sources" }, sourceIds.map(sourceId => {
|
|
61
61
|
return (React.createElement(SourceComponent, { key: `source-${sourceId}`, gisModel: model, sourceId: sourceId, onClick: onItemClick }));
|
|
@@ -4,6 +4,7 @@ import { SidePanel } from '@jupyterlab/ui-components';
|
|
|
4
4
|
import { Message } from '@lumino/messaging';
|
|
5
5
|
import { MouseEvent as ReactMouseEvent } from 'react';
|
|
6
6
|
import { IControlPanelModel } from '../types';
|
|
7
|
+
import { CommandRegistry } from '@lumino/commands';
|
|
7
8
|
/**
|
|
8
9
|
* Options of the left panel widget.
|
|
9
10
|
*/
|
|
@@ -37,12 +38,14 @@ export declare class LeftPanelWidget extends SidePanel {
|
|
|
37
38
|
private _lastSelectedNodeId;
|
|
38
39
|
private _model;
|
|
39
40
|
private _state;
|
|
41
|
+
private _commands;
|
|
40
42
|
}
|
|
41
43
|
export declare namespace LeftPanelWidget {
|
|
42
44
|
interface IOptions {
|
|
43
45
|
model: IControlPanelModel;
|
|
44
46
|
tracker: IJupyterGISTracker;
|
|
45
47
|
state: IStateDB;
|
|
48
|
+
commands: CommandRegistry;
|
|
46
49
|
}
|
|
47
50
|
interface IProps {
|
|
48
51
|
filePath?: string;
|
|
@@ -3,6 +3,7 @@ import { LayersPanel } from './components/layers';
|
|
|
3
3
|
import { SourcesPanel } from './components/sources';
|
|
4
4
|
import { ControlPanelHeader } from './header';
|
|
5
5
|
import { FilterPanel } from './components/filter-panel/Filter';
|
|
6
|
+
import { CommandIDs } from '../constants';
|
|
6
7
|
export class LeftPanelWidget extends SidePanel {
|
|
7
8
|
constructor(options) {
|
|
8
9
|
super();
|
|
@@ -50,11 +51,13 @@ export class LeftPanelWidget extends SidePanel {
|
|
|
50
51
|
const updatedSelectedValue = Object.assign(Object.assign({}, selectedValue), { [item]: { type, selectedNodeId: nodeId } });
|
|
51
52
|
this._lastSelectedNodeId = nodeId;
|
|
52
53
|
jGISModel.syncSelected(updatedSelectedValue, this.id);
|
|
54
|
+
this._commands.notifyCommandChanged(CommandIDs.temporalController);
|
|
53
55
|
}
|
|
54
56
|
};
|
|
55
57
|
this.addClass('jGIS-sidepanel-widget');
|
|
56
58
|
this._model = options.model;
|
|
57
59
|
this._state = options.state;
|
|
60
|
+
this._commands = options.commands;
|
|
58
61
|
const header = new ControlPanelHeader();
|
|
59
62
|
this.header.addWidget(header);
|
|
60
63
|
const sourcesPanel = new SourcesPanel({
|
|
@@ -81,7 +84,7 @@ export class LeftPanelWidget extends SidePanel {
|
|
|
81
84
|
this.addWidget(filterPanel);
|
|
82
85
|
options.tracker.currentChanged.connect((_, changed) => {
|
|
83
86
|
if (changed) {
|
|
84
|
-
header.title.label = changed.
|
|
87
|
+
header.title.label = changed.model.filePath;
|
|
85
88
|
}
|
|
86
89
|
else {
|
|
87
90
|
header.title.label = '-';
|
|
@@ -129,5 +132,6 @@ export class LeftPanelWidget extends SidePanel {
|
|
|
129
132
|
this._lastSelectedNodeId = nodeId;
|
|
130
133
|
}
|
|
131
134
|
(_b = (_a = this._model) === null || _a === void 0 ? void 0 : _a.jGISModel) === null || _b === void 0 ? void 0 : _b.syncSelected(selection, this.id);
|
|
135
|
+
this._commands.notifyCommandChanged(CommandIDs.temporalController);
|
|
132
136
|
}
|
|
133
137
|
}
|
package/lib/panelview/model.js
CHANGED
|
@@ -8,23 +8,23 @@ export class ControlPanelModel {
|
|
|
8
8
|
}
|
|
9
9
|
get filePath() {
|
|
10
10
|
var _a;
|
|
11
|
-
return (_a = this._tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.
|
|
11
|
+
return (_a = this._tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.model.filePath;
|
|
12
12
|
}
|
|
13
13
|
get jGISModel() {
|
|
14
14
|
var _a;
|
|
15
|
-
return (_a = this._tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.
|
|
15
|
+
return (_a = this._tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.model;
|
|
16
16
|
}
|
|
17
17
|
get sharedModel() {
|
|
18
18
|
var _a;
|
|
19
|
-
return (_a = this._tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.
|
|
19
|
+
return (_a = this._tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.model.sharedModel;
|
|
20
20
|
}
|
|
21
21
|
disconnect(f) {
|
|
22
22
|
this._tracker.forEach(w => {
|
|
23
|
-
w.
|
|
24
|
-
w.
|
|
25
|
-
w.
|
|
23
|
+
w.model.sharedLayersChanged.disconnect(f);
|
|
24
|
+
w.model.sharedSourcesChanged.disconnect(f);
|
|
25
|
+
w.model.sharedOptionsChanged.disconnect(f);
|
|
26
26
|
});
|
|
27
|
-
this._tracker.forEach(w => w.
|
|
28
|
-
this._tracker.forEach(w => w.
|
|
27
|
+
this._tracker.forEach(w => w.model.themeChanged.disconnect(f));
|
|
28
|
+
this._tracker.forEach(w => w.model.clientStateChanged.disconnect(f));
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -45,7 +45,7 @@ class ObjectPropertiesReact extends React.Component {
|
|
|
45
45
|
}
|
|
46
46
|
};
|
|
47
47
|
this.state = {
|
|
48
|
-
|
|
48
|
+
model: (_a = props.tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.model,
|
|
49
49
|
clientId: null,
|
|
50
50
|
id: uuid()
|
|
51
51
|
};
|
|
@@ -55,14 +55,14 @@ class ObjectPropertiesReact extends React.Component {
|
|
|
55
55
|
if (changed) {
|
|
56
56
|
this.props.cpModel.disconnect(this._sharedJGISModelChanged);
|
|
57
57
|
this.props.cpModel.disconnect(this._onClientSharedStateChanged);
|
|
58
|
-
changed.
|
|
59
|
-
changed.
|
|
60
|
-
changed.
|
|
61
|
-
this.setState(old => (Object.assign(Object.assign({}, old), {
|
|
58
|
+
changed.model.sharedLayersChanged.connect(this._sharedJGISModelChanged);
|
|
59
|
+
changed.model.sharedSourcesChanged.connect(this._sharedJGISModelChanged);
|
|
60
|
+
changed.model.clientStateChanged.connect(this._onClientSharedStateChanged);
|
|
61
|
+
this.setState(old => (Object.assign(Object.assign({}, old), { model: changed.model, filePath: changed.model.filePath, clientId: changed.model.getClientId() })));
|
|
62
62
|
}
|
|
63
63
|
else {
|
|
64
64
|
this.setState({
|
|
65
|
-
|
|
65
|
+
model: undefined,
|
|
66
66
|
selectedObject: undefined
|
|
67
67
|
});
|
|
68
68
|
}
|
|
@@ -71,22 +71,22 @@ class ObjectPropertiesReact extends React.Component {
|
|
|
71
71
|
render() {
|
|
72
72
|
var _a;
|
|
73
73
|
const selectedObject = this.state.selectedObject;
|
|
74
|
-
if (!selectedObject || !this.state.
|
|
74
|
+
if (!selectedObject || !this.state.model) {
|
|
75
75
|
return React.createElement("div", null);
|
|
76
76
|
}
|
|
77
77
|
let layerId = undefined;
|
|
78
78
|
let sourceId = undefined;
|
|
79
|
-
const layer = this.state.
|
|
79
|
+
const layer = this.state.model.getLayer(selectedObject);
|
|
80
80
|
if (layer) {
|
|
81
81
|
layerId = selectedObject;
|
|
82
82
|
sourceId = (_a = layer.parameters) === null || _a === void 0 ? void 0 : _a.source;
|
|
83
83
|
}
|
|
84
84
|
else {
|
|
85
|
-
const source = this.state.
|
|
85
|
+
const source = this.state.model.getSource(selectedObject);
|
|
86
86
|
if (source) {
|
|
87
87
|
sourceId = selectedObject;
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
|
-
return (React.createElement(EditForm, { layer: layerId, source: sourceId, formSchemaRegistry: this.props.formSchemaRegistry,
|
|
90
|
+
return (React.createElement(EditForm, { layer: layerId, source: sourceId, formSchemaRegistry: this.props.formSchemaRegistry, model: this.state.model }));
|
|
91
91
|
}
|
|
92
92
|
}
|
|
@@ -4,7 +4,7 @@ import { IControlPanelModel } from '../types';
|
|
|
4
4
|
export declare class RightPanelWidget extends SidePanel {
|
|
5
5
|
constructor(options: RightPanelWidget.IOptions);
|
|
6
6
|
dispose(): void;
|
|
7
|
-
private
|
|
7
|
+
private _currentModel;
|
|
8
8
|
private _model;
|
|
9
9
|
private _annotationModel;
|
|
10
10
|
}
|
|
@@ -31,12 +31,12 @@ export class RightPanelWidget extends SidePanel {
|
|
|
31
31
|
this.addWidget(identifyPanel);
|
|
32
32
|
this._model.documentChanged.connect((_, changed) => {
|
|
33
33
|
if (changed) {
|
|
34
|
-
if (changed.
|
|
35
|
-
header.title.label = changed.
|
|
34
|
+
if (changed.model.sharedModel.editable) {
|
|
35
|
+
header.title.label = changed.model.filePath;
|
|
36
36
|
properties.show();
|
|
37
37
|
}
|
|
38
38
|
else {
|
|
39
|
-
header.title.label = `${changed.
|
|
39
|
+
header.title.label = `${changed.model.filePath} - Read Only`;
|
|
40
40
|
properties.hide();
|
|
41
41
|
}
|
|
42
42
|
}
|
|
@@ -47,16 +47,16 @@ export class RightPanelWidget extends SidePanel {
|
|
|
47
47
|
options.tracker.currentChanged.connect(async (_, changed) => {
|
|
48
48
|
var _a;
|
|
49
49
|
if (changed) {
|
|
50
|
-
this.
|
|
51
|
-
header.title.label = this.
|
|
52
|
-
this._annotationModel.
|
|
53
|
-
((_a = options.tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.
|
|
54
|
-
await changed.context.ready;
|
|
50
|
+
this._currentModel = changed.model;
|
|
51
|
+
header.title.label = this._currentModel.filePath;
|
|
52
|
+
this._annotationModel.model =
|
|
53
|
+
((_a = options.tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.model) || undefined;
|
|
54
|
+
// await changed.context.ready;
|
|
55
55
|
}
|
|
56
56
|
else {
|
|
57
57
|
header.title.label = '-';
|
|
58
|
-
this.
|
|
59
|
-
this._annotationModel.
|
|
58
|
+
this._currentModel = null;
|
|
59
|
+
this._annotationModel.model = undefined;
|
|
60
60
|
}
|
|
61
61
|
});
|
|
62
62
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { IJupyterGISModel } from '@jupytergis/schema';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
interface IStatusBarProps {
|
|
4
|
+
jgisModel: IJupyterGISModel;
|
|
5
|
+
loading?: boolean;
|
|
6
|
+
projection?: {
|
|
7
|
+
code: string;
|
|
8
|
+
units: string;
|
|
9
|
+
};
|
|
10
|
+
scale: number;
|
|
11
|
+
}
|
|
12
|
+
declare const StatusBar: ({ jgisModel, loading, projection, scale }: IStatusBarProps) => React.JSX.Element;
|
|
13
|
+
export default StatusBar;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { faGlobe, faLocationDot, faRuler } from '@fortawesome/free-solid-svg-icons';
|
|
2
|
+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
3
|
+
import { Progress } from '@jupyter/react-components';
|
|
4
|
+
import React, { useEffect, useState } from 'react';
|
|
5
|
+
import { version } from '../../package.json'; // Adjust the path as necessary
|
|
6
|
+
const StatusBar = ({ jgisModel, loading, projection, scale }) => {
|
|
7
|
+
var _a;
|
|
8
|
+
const [coords, setCoords] = useState({ x: 0, y: 0 });
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
const handleClientStateChanged = () => {
|
|
11
|
+
var _a, _b;
|
|
12
|
+
const pointer = (_b = (_a = jgisModel === null || jgisModel === void 0 ? void 0 : jgisModel.localState) === null || _a === void 0 ? void 0 : _a.pointer) === null || _b === void 0 ? void 0 : _b.value;
|
|
13
|
+
if (!pointer) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
setCoords({ x: pointer === null || pointer === void 0 ? void 0 : pointer.coordinates.x, y: pointer === null || pointer === void 0 ? void 0 : pointer.coordinates.y });
|
|
17
|
+
};
|
|
18
|
+
jgisModel.clientStateChanged.connect(handleClientStateChanged);
|
|
19
|
+
return () => {
|
|
20
|
+
jgisModel.clientStateChanged.disconnect(handleClientStateChanged);
|
|
21
|
+
};
|
|
22
|
+
}, [jgisModel]);
|
|
23
|
+
return (React.createElement("div", { className: "jgis-status-bar" },
|
|
24
|
+
loading && (React.createElement("div", { style: { width: '16%', padding: '0 6px' } },
|
|
25
|
+
React.createElement(Progress, { height: 14 }))),
|
|
26
|
+
React.createElement("div", { className: "jgis-status-bar-item" },
|
|
27
|
+
React.createElement("span", null,
|
|
28
|
+
"jgis: ",
|
|
29
|
+
version)),
|
|
30
|
+
React.createElement("div", { className: "jgis-status-bar-item jgis-status-bar-coords" },
|
|
31
|
+
React.createElement(FontAwesomeIcon, { icon: faLocationDot }),
|
|
32
|
+
React.createElement("span", null,
|
|
33
|
+
' ',
|
|
34
|
+
"x: ",
|
|
35
|
+
Math.trunc(coords.x),
|
|
36
|
+
" y: ",
|
|
37
|
+
Math.trunc(coords.y))),
|
|
38
|
+
React.createElement("div", { className: "jgis-status-bar-item" },
|
|
39
|
+
React.createElement(FontAwesomeIcon, { icon: faRuler }),
|
|
40
|
+
' ',
|
|
41
|
+
React.createElement("span", null,
|
|
42
|
+
"Scale: 1: ",
|
|
43
|
+
Math.trunc(scale))),
|
|
44
|
+
React.createElement("div", { className: "jgis-status-bar-item" },
|
|
45
|
+
React.createElement(FontAwesomeIcon, { icon: faGlobe }),
|
|
46
|
+
' ',
|
|
47
|
+
React.createElement("span", null, (_a = projection === null || projection === void 0 ? void 0 : projection.code) !== null && _a !== void 0 ? _a : null)),
|
|
48
|
+
React.createElement("div", { className: "jgis-status-bar-item" },
|
|
49
|
+
"Units: ", projection === null || projection === void 0 ? void 0 :
|
|
50
|
+
projection.units)));
|
|
51
|
+
};
|
|
52
|
+
export default StatusBar;
|
package/lib/toolbar/widget.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IJGISExternalCommand, JupyterGISModel } from '@jupytergis/schema';
|
|
2
|
-
import {
|
|
2
|
+
import { ReactiveToolbar, Toolbar } from '@jupyterlab/ui-components';
|
|
3
3
|
import { CommandRegistry } from '@lumino/commands';
|
|
4
4
|
import { Widget } from '@lumino/widgets';
|
|
5
5
|
export declare const TOOLBAR_SEPARATOR_CLASS = "jGIS-Toolbar-Separator";
|
package/lib/toolbar/widget.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { CommandToolbarButton } from '@jupyterlab/apputils';
|
|
2
|
-
import { ReactWidget, ReactiveToolbar, ToolbarButton, addIcon, redoIcon,
|
|
2
|
+
import { MenuSvg, ReactWidget, ReactiveToolbar, ToolbarButton, addIcon, redoIcon, terminalIcon, undoIcon } from '@jupyterlab/ui-components';
|
|
3
3
|
import { Menu, Widget } from '@lumino/widgets';
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import { CommandIDs } from '../constants';
|
|
6
|
+
import { rasterIcon } from '../icons';
|
|
6
7
|
import { UsersItem } from './usertoolbaritem';
|
|
7
8
|
export const TOOLBAR_SEPARATOR_CLASS = 'jGIS-Toolbar-Separator';
|
|
8
9
|
export const TOOLBAR_GROUPNAME_CLASS = 'jGIS-Toolbar-GroupName';
|
|
@@ -55,57 +56,63 @@ export class ToolbarWidget extends ReactiveToolbar {
|
|
|
55
56
|
label: '',
|
|
56
57
|
commands: options.commands
|
|
57
58
|
}));
|
|
58
|
-
|
|
59
|
+
// vector sub menu
|
|
60
|
+
const vectorSubMenu = new Menu({ commands: options.commands });
|
|
61
|
+
vectorSubMenu.title.label = 'Add Vector Layer';
|
|
62
|
+
vectorSubMenu.title.iconClass = 'fa fa-vector-square';
|
|
63
|
+
vectorSubMenu.id = 'jp-gis-toolbar-vector-menu';
|
|
64
|
+
vectorSubMenu.addItem({
|
|
65
|
+
type: 'command',
|
|
66
|
+
command: CommandIDs.newGeoJSONEntry
|
|
67
|
+
});
|
|
68
|
+
vectorSubMenu.addItem({
|
|
69
|
+
type: 'command',
|
|
70
|
+
command: CommandIDs.newShapefileLayer
|
|
71
|
+
});
|
|
72
|
+
//raster submenu
|
|
73
|
+
const rasterSubMenu = new Menu({ commands: options.commands });
|
|
74
|
+
rasterSubMenu.title.label = 'Add Raster Layer';
|
|
75
|
+
rasterSubMenu.title.icon = rasterIcon;
|
|
76
|
+
rasterSubMenu.id = 'jp-gis-toolbar-raster-menu';
|
|
77
|
+
rasterSubMenu.addItem({
|
|
78
|
+
type: 'command',
|
|
79
|
+
command: CommandIDs.newHillshadeEntry
|
|
80
|
+
});
|
|
81
|
+
rasterSubMenu.addItem({
|
|
82
|
+
type: 'command',
|
|
83
|
+
command: CommandIDs.newImageEntry
|
|
84
|
+
});
|
|
85
|
+
rasterSubMenu.addItem({
|
|
86
|
+
type: 'command',
|
|
87
|
+
command: CommandIDs.newGeoTiffEntry
|
|
88
|
+
});
|
|
89
|
+
const NewSubMenu = new MenuSvg({ commands: options.commands });
|
|
90
|
+
NewSubMenu.title.label = 'Add Layer';
|
|
91
|
+
NewSubMenu.addItem({ type: 'submenu', submenu: rasterSubMenu });
|
|
92
|
+
NewSubMenu.addItem({ type: 'submenu', submenu: vectorSubMenu });
|
|
93
|
+
const NewEntryButton = new ToolbarButton({
|
|
59
94
|
icon: addIcon,
|
|
60
95
|
noFocusOnClick: false,
|
|
61
96
|
onClick: () => {
|
|
62
97
|
if (!options.commands) {
|
|
63
98
|
return;
|
|
64
99
|
}
|
|
65
|
-
const bbox =
|
|
66
|
-
const NewSubMenu = new Menu({ commands: options.commands });
|
|
67
|
-
NewSubMenu.title.label = 'New Layer';
|
|
68
|
-
NewSubMenu.addItem({
|
|
69
|
-
type: 'command',
|
|
70
|
-
command: CommandIDs.newHillshadeEntry
|
|
71
|
-
});
|
|
72
|
-
NewSubMenu.addItem({
|
|
73
|
-
type: 'separator'
|
|
74
|
-
});
|
|
75
|
-
NewSubMenu.addItem({
|
|
76
|
-
type: 'command',
|
|
77
|
-
command: CommandIDs.newImageEntry
|
|
78
|
-
});
|
|
79
|
-
NewSubMenu.addItem({
|
|
80
|
-
type: 'separator'
|
|
81
|
-
});
|
|
82
|
-
NewSubMenu.addItem({
|
|
83
|
-
type: 'command',
|
|
84
|
-
command: CommandIDs.newShapefileLayer
|
|
85
|
-
});
|
|
86
|
-
NewSubMenu.addItem({
|
|
87
|
-
type: 'command',
|
|
88
|
-
command: CommandIDs.newGeoTiffEntry
|
|
89
|
-
});
|
|
90
|
-
NewSubMenu.addItem({
|
|
91
|
-
type: 'command',
|
|
92
|
-
command: CommandIDs.newGeoJSONEntry
|
|
93
|
-
});
|
|
100
|
+
const bbox = NewEntryButton.node.getBoundingClientRect();
|
|
94
101
|
NewSubMenu.open(bbox.x, bbox.bottom);
|
|
95
102
|
}
|
|
96
103
|
});
|
|
97
|
-
this.addItem('New',
|
|
104
|
+
this.addItem('New', NewEntryButton);
|
|
98
105
|
this.addItem('separator2', new Separator());
|
|
99
106
|
this.addItem('identify', new CommandToolbarButton({
|
|
100
107
|
id: CommandIDs.identify,
|
|
101
108
|
label: '',
|
|
102
109
|
commands: options.commands
|
|
103
110
|
}));
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
});
|
|
111
|
+
this.addItem('temporalController', new CommandToolbarButton({
|
|
112
|
+
id: CommandIDs.temporalController,
|
|
113
|
+
label: '',
|
|
114
|
+
commands: options.commands
|
|
115
|
+
}));
|
|
109
116
|
this.addItem('spacer', ReactiveToolbar.createSpacerItem());
|
|
110
117
|
// Users
|
|
111
118
|
this.addItem('users', ReactWidget.create(React.createElement(UsersItem, { model: options.model })));
|