@jupytergis/base 0.4.4 → 0.4.5
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/AnnotationFloater.d.ts +1 -4
- package/lib/annotations/components/AnnotationFloater.js +11 -6
- package/lib/annotations/model.d.ts +1 -0
- package/lib/annotations/model.js +9 -0
- package/lib/commands.js +32 -0
- package/lib/constants.d.ts +1 -0
- package/lib/constants.js +7 -5
- package/lib/icons.d.ts +8 -0
- package/lib/icons.js +40 -0
- package/lib/mainview/mainView.d.ts +6 -1
- package/lib/mainview/mainView.js +127 -11
- package/lib/panelview/annotationPanel.js +2 -2
- package/lib/panelview/components/identify-panel/IdentifyPanel.js +29 -7
- package/lib/panelview/components/layers.js +1 -0
- package/lib/panelview/rightpanel.js +1 -0
- package/lib/toolbar/widget.js +42 -19
- package/package.json +2 -2
- package/style/icons/book_open.svg +19 -0
- package/style/icons/clock-solid.svg +17 -0
- package/style/icons/geolocation.svg +15 -0
- package/style/icons/info-solid.svg +20 -0
- package/style/icons/raster.svg +3 -2
- package/style/icons/target_with_center.svg +9 -0
- package/style/icons/target_without_center.svg +17 -0
- package/style/icons/terminal_toolbar.svg +12 -0
- package/style/icons/vector_square.svg +21 -0
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { IAnnotationProps } from './Annotation';
|
|
3
|
-
|
|
4
|
-
open: boolean;
|
|
5
|
-
}
|
|
6
|
-
declare const AnnotationFloater: ({ itemId, annotationModel: model, open }: IAnnotationFloaterProps) => React.JSX.Element;
|
|
3
|
+
declare const AnnotationFloater: ({ itemId, annotationModel: model }: IAnnotationProps) => React.JSX.Element;
|
|
7
4
|
export default AnnotationFloater;
|
|
@@ -2,21 +2,26 @@ import React, { useState } from 'react';
|
|
|
2
2
|
import { faWindowMinimize } from '@fortawesome/free-solid-svg-icons';
|
|
3
3
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
4
4
|
import Annotation from './Annotation';
|
|
5
|
-
const AnnotationFloater = ({ itemId, annotationModel: model
|
|
6
|
-
const
|
|
5
|
+
const AnnotationFloater = ({ itemId, annotationModel: model }) => {
|
|
6
|
+
const annotation = model.getAnnotation(itemId);
|
|
7
|
+
const [isOpen, setIsOpen] = useState(annotation === null || annotation === void 0 ? void 0 : annotation.open);
|
|
7
8
|
// Function that either
|
|
8
9
|
// - opens the annotation if `open`
|
|
9
10
|
// - removes the annotation if `!open` and the annotation is empty
|
|
10
11
|
// - closes the annotation if `!open` and the annotation is not empty
|
|
11
12
|
const setOpenOrDelete = (open) => {
|
|
12
|
-
var _a;
|
|
13
13
|
if (open) {
|
|
14
|
+
model.updateAnnotation(itemId, { open: true });
|
|
14
15
|
return setIsOpen(true);
|
|
15
16
|
}
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
const current = model.getAnnotation(itemId);
|
|
18
|
+
if (!(current === null || current === void 0 ? void 0 : current.contents.length)) {
|
|
19
|
+
model.removeAnnotation(itemId);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
model.updateAnnotation(itemId, { open: false });
|
|
23
|
+
setIsOpen(false);
|
|
18
24
|
}
|
|
19
|
-
setIsOpen(false);
|
|
20
25
|
};
|
|
21
26
|
return (React.createElement(React.Fragment, null,
|
|
22
27
|
React.createElement("div", { className: "jGIS-Annotation-Handler", onClick: () => setOpenOrDelete(!isOpen) }),
|
|
@@ -12,6 +12,7 @@ export declare class AnnotationModel implements IAnnotationModel {
|
|
|
12
12
|
getAnnotation(id: string): IAnnotation | undefined;
|
|
13
13
|
getAnnotationIds(): string[];
|
|
14
14
|
addAnnotation(key: string, value: IAnnotation): void;
|
|
15
|
+
updateAnnotation(id: string, updates: Partial<IAnnotation>): void;
|
|
15
16
|
removeAnnotation(key: string): void;
|
|
16
17
|
addContent(id: string, value: string): void;
|
|
17
18
|
private _model;
|
package/lib/annotations/model.js
CHANGED
|
@@ -48,6 +48,15 @@ export class AnnotationModel {
|
|
|
48
48
|
var _a;
|
|
49
49
|
(_a = this._model) === null || _a === void 0 ? void 0 : _a.sharedModel.setMetadata(`annotation_${key}`, JSON.stringify(value));
|
|
50
50
|
}
|
|
51
|
+
updateAnnotation(id, updates) {
|
|
52
|
+
var _a;
|
|
53
|
+
const existing = this.getAnnotation(id);
|
|
54
|
+
if (!existing) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
(_a = this._model) === null || _a === void 0 ? void 0 : _a.sharedModel.setMetadata(id, JSON.stringify(Object.assign(Object.assign({}, existing), updates)));
|
|
58
|
+
this._updateSignal.emit(null);
|
|
59
|
+
}
|
|
51
60
|
removeAnnotation(key) {
|
|
52
61
|
var _a;
|
|
53
62
|
(_a = this._model) === null || _a === void 0 ? void 0 : _a.removeMetadata(key);
|
package/lib/commands.js
CHANGED
|
@@ -8,6 +8,8 @@ import { JupyterGISDocumentWidget } from './widget';
|
|
|
8
8
|
import { getGeoJSONDataFromLayerSource, downloadFile } from './tools';
|
|
9
9
|
import { ProcessingFormDialog } from './dialogs/ProcessingFormDialog';
|
|
10
10
|
import { getSingleSelectedLayer, selectedLayerIsOfType, processSelectedLayer } from './processing';
|
|
11
|
+
import { fromLonLat } from 'ol/proj';
|
|
12
|
+
import { targetWithCenterIcon } from './icons';
|
|
11
13
|
function loadKeybindings(commands, keybindings) {
|
|
12
14
|
keybindings.forEach(binding => {
|
|
13
15
|
commands.addKeyBinding({
|
|
@@ -842,6 +844,36 @@ export function addCommands(app, tracker, translator, formSchemaRegistry, layerB
|
|
|
842
844
|
downloadFile(geojsonString, `${exportFileName}.geojson`, 'application/geo+json');
|
|
843
845
|
}
|
|
844
846
|
});
|
|
847
|
+
commands.addCommand(CommandIDs.getGeolocation, {
|
|
848
|
+
label: trans.__('Center on Geolocation'),
|
|
849
|
+
execute: async () => {
|
|
850
|
+
var _a;
|
|
851
|
+
const viewModel = (_a = tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.model;
|
|
852
|
+
const options = {
|
|
853
|
+
enableHighAccuracy: true,
|
|
854
|
+
timeout: 5000,
|
|
855
|
+
maximumAge: 0
|
|
856
|
+
};
|
|
857
|
+
const success = (pos) => {
|
|
858
|
+
const location = fromLonLat([
|
|
859
|
+
pos.coords.longitude,
|
|
860
|
+
pos.coords.latitude
|
|
861
|
+
]);
|
|
862
|
+
const Jgislocation = {
|
|
863
|
+
x: location[0],
|
|
864
|
+
y: location[1]
|
|
865
|
+
};
|
|
866
|
+
if (viewModel) {
|
|
867
|
+
viewModel.geolocationChanged.emit(Jgislocation);
|
|
868
|
+
}
|
|
869
|
+
};
|
|
870
|
+
const error = (err) => {
|
|
871
|
+
console.warn(`ERROR(${err.code}): ${err.message}`);
|
|
872
|
+
};
|
|
873
|
+
navigator.geolocation.getCurrentPosition(success, error, options);
|
|
874
|
+
},
|
|
875
|
+
icon: targetWithCenterIcon
|
|
876
|
+
});
|
|
845
877
|
loadKeybindings(commands, keybindings);
|
|
846
878
|
}
|
|
847
879
|
var Private;
|
package/lib/constants.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export declare namespace CommandIDs {
|
|
|
9
9
|
const symbology = "jupytergis:symbology";
|
|
10
10
|
const identify = "jupytergis:identify";
|
|
11
11
|
const temporalController = "jupytergis:temporalController";
|
|
12
|
+
const getGeolocation = "jupytergis:getGeolocation";
|
|
12
13
|
const openLayerBrowser = "jupytergis:openLayerBrowser";
|
|
13
14
|
const newRasterEntry = "jupytergis:newRasterEntry";
|
|
14
15
|
const newVectorTileEntry = "jupytergis:newVectorTileEntry";
|
package/lib/constants.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { redoIcon, undoIcon } from '@jupyterlab/ui-components';
|
|
2
|
-
import { geoJSONIcon, moundIcon, rasterIcon } from './icons';
|
|
2
|
+
import { bookOpenIcon, clockIcon, geoJSONIcon, infoIcon, moundIcon, rasterIcon, vectorSquareIcon } from './icons';
|
|
3
3
|
/**
|
|
4
4
|
* The command IDs.
|
|
5
5
|
*/
|
|
@@ -11,6 +11,8 @@ export var CommandIDs;
|
|
|
11
11
|
CommandIDs.symbology = 'jupytergis:symbology';
|
|
12
12
|
CommandIDs.identify = 'jupytergis:identify';
|
|
13
13
|
CommandIDs.temporalController = 'jupytergis:temporalController';
|
|
14
|
+
// geolocation
|
|
15
|
+
CommandIDs.getGeolocation = 'jupytergis:getGeolocation';
|
|
14
16
|
// Layers and sources creation commands
|
|
15
17
|
CommandIDs.openLayerBrowser = 'jupytergis:openLayerBrowser';
|
|
16
18
|
// Layer and source
|
|
@@ -78,9 +80,9 @@ const iconObject = {
|
|
|
78
80
|
VideoLayer: { iconClass: 'fa fa-video' },
|
|
79
81
|
[CommandIDs.redo]: { icon: redoIcon },
|
|
80
82
|
[CommandIDs.undo]: { icon: undoIcon },
|
|
81
|
-
[CommandIDs.openLayerBrowser]: {
|
|
83
|
+
[CommandIDs.openLayerBrowser]: { icon: bookOpenIcon },
|
|
82
84
|
[CommandIDs.newRasterEntry]: { icon: rasterIcon },
|
|
83
|
-
[CommandIDs.newVectorTileEntry]: {
|
|
85
|
+
[CommandIDs.newVectorTileEntry]: { icon: vectorSquareIcon },
|
|
84
86
|
[CommandIDs.newGeoJSONEntry]: { icon: geoJSONIcon },
|
|
85
87
|
[CommandIDs.newHillshadeEntry]: { icon: moundIcon },
|
|
86
88
|
[CommandIDs.newImageEntry]: { iconClass: 'fa fa-image' },
|
|
@@ -88,8 +90,8 @@ const iconObject = {
|
|
|
88
90
|
[CommandIDs.newShapefileLayer]: { iconClass: 'fa fa-file' },
|
|
89
91
|
[CommandIDs.newGeoTiffEntry]: { iconClass: 'fa fa-image' },
|
|
90
92
|
[CommandIDs.symbology]: { iconClass: 'fa fa-brush' },
|
|
91
|
-
[CommandIDs.identify]: {
|
|
92
|
-
[CommandIDs.temporalController]: {
|
|
93
|
+
[CommandIDs.identify]: { icon: infoIcon },
|
|
94
|
+
[CommandIDs.temporalController]: { icon: clockIcon }
|
|
93
95
|
};
|
|
94
96
|
/**
|
|
95
97
|
* The registered icons
|
package/lib/icons.d.ts
CHANGED
|
@@ -8,3 +8,11 @@ export declare const nonVisibilityIcon: LabIcon;
|
|
|
8
8
|
export declare const geoJSONIcon: LabIcon;
|
|
9
9
|
export declare const moundIcon: LabIcon;
|
|
10
10
|
export declare const logoMiniIconQGZ: LabIcon;
|
|
11
|
+
export declare const bookOpenIcon: LabIcon;
|
|
12
|
+
export declare const vectorSquareIcon: LabIcon;
|
|
13
|
+
export declare const infoIcon: LabIcon;
|
|
14
|
+
export declare const clockIcon: LabIcon;
|
|
15
|
+
export declare const terminalToolbarIcon: LabIcon;
|
|
16
|
+
export declare const geolocationIcon: LabIcon;
|
|
17
|
+
export declare const targetWithoutCenterIcon: LabIcon;
|
|
18
|
+
export declare const targetWithCenterIcon: LabIcon;
|
package/lib/icons.js
CHANGED
|
@@ -13,6 +13,14 @@ import nonVisibilitySvgStr from '../style/icons/nonvisibility.svg';
|
|
|
13
13
|
import geoJsonSvgStr from '../style/icons/geojson.svg';
|
|
14
14
|
import moundSvgStr from '../style/icons/mound.svg';
|
|
15
15
|
import logoMiniQGZ from '../style/icons/logo_mini_qgz.svg';
|
|
16
|
+
import bookOpenSvgStr from '../style/icons/book_open.svg';
|
|
17
|
+
import vectorSquareSvgStr from '../style/icons/vector_square.svg';
|
|
18
|
+
import infoSvgStr from '../style/icons/info-solid.svg';
|
|
19
|
+
import clockSvgStr from '../style/icons/clock-solid.svg';
|
|
20
|
+
import terminalToolbarSvgStr from '../style/icons/terminal_toolbar.svg';
|
|
21
|
+
import geolocationSvgStr from '../style/icons/geolocation.svg';
|
|
22
|
+
import targetWithoutCenterSvgStr from '../style/icons/target_without_center.svg';
|
|
23
|
+
import targetWithCenterSvgStr from '../style/icons/target_with_center.svg';
|
|
16
24
|
export const logoIcon = new LabIcon({
|
|
17
25
|
name: 'jupytergis::logo',
|
|
18
26
|
svgstr: logoSvgStr
|
|
@@ -49,3 +57,35 @@ export const logoMiniIconQGZ = new LabIcon({
|
|
|
49
57
|
name: 'jupytergis::logoQGZ',
|
|
50
58
|
svgstr: logoMiniQGZ
|
|
51
59
|
});
|
|
60
|
+
export const bookOpenIcon = new LabIcon({
|
|
61
|
+
name: 'jupytergis::bookOpen',
|
|
62
|
+
svgstr: bookOpenSvgStr
|
|
63
|
+
});
|
|
64
|
+
export const vectorSquareIcon = new LabIcon({
|
|
65
|
+
name: 'jupytergis::vectorSquare',
|
|
66
|
+
svgstr: vectorSquareSvgStr
|
|
67
|
+
});
|
|
68
|
+
export const infoIcon = new LabIcon({
|
|
69
|
+
name: 'jupytergis::info',
|
|
70
|
+
svgstr: infoSvgStr
|
|
71
|
+
});
|
|
72
|
+
export const clockIcon = new LabIcon({
|
|
73
|
+
name: 'jupytergis::clock',
|
|
74
|
+
svgstr: clockSvgStr
|
|
75
|
+
});
|
|
76
|
+
export const terminalToolbarIcon = new LabIcon({
|
|
77
|
+
name: 'jupytergis::terminalToolbar',
|
|
78
|
+
svgstr: terminalToolbarSvgStr
|
|
79
|
+
});
|
|
80
|
+
export const geolocationIcon = new LabIcon({
|
|
81
|
+
name: 'jupytergis::geolocation',
|
|
82
|
+
svgstr: geolocationSvgStr
|
|
83
|
+
});
|
|
84
|
+
export const targetWithoutCenterIcon = new LabIcon({
|
|
85
|
+
name: 'jupytergis::targetWithCenter',
|
|
86
|
+
svgstr: targetWithCenterSvgStr
|
|
87
|
+
});
|
|
88
|
+
export const targetWithCenterIcon = new LabIcon({
|
|
89
|
+
name: 'jupytergis::targetWithoutCenter',
|
|
90
|
+
svgstr: targetWithoutCenterSvgStr
|
|
91
|
+
});
|
|
@@ -33,7 +33,7 @@ export declare class MainView extends React.Component<IProps, IStates> {
|
|
|
33
33
|
constructor(props: IProps);
|
|
34
34
|
componentDidMount(): Promise<void>;
|
|
35
35
|
componentWillUnmount(): void;
|
|
36
|
-
generateScene(): Promise<void>;
|
|
36
|
+
generateScene(center: number[], zoom: number): Promise<void>;
|
|
37
37
|
createSelectInteraction: () => void;
|
|
38
38
|
addContextMenu: () => void;
|
|
39
39
|
/**
|
|
@@ -110,6 +110,8 @@ export declare class MainView extends React.Component<IProps, IStates> {
|
|
|
110
110
|
* to work with the temporal controller
|
|
111
111
|
*/
|
|
112
112
|
handleTemporalController: (id: string, layer: IJGISLayer) => void;
|
|
113
|
+
private flyToGeometry;
|
|
114
|
+
private highlightFeatureOnMap;
|
|
113
115
|
/**
|
|
114
116
|
* Wait for all layers to be loaded.
|
|
115
117
|
*/
|
|
@@ -165,11 +167,13 @@ export declare class MainView extends React.Component<IProps, IStates> {
|
|
|
165
167
|
private _updateAnnotation;
|
|
166
168
|
private _onZoomToPosition;
|
|
167
169
|
private _moveToPosition;
|
|
170
|
+
private _flyToPosition;
|
|
168
171
|
private _onPointerMove;
|
|
169
172
|
private _syncPointer;
|
|
170
173
|
private _identifyFeature;
|
|
171
174
|
private _triggerLayerUpdate;
|
|
172
175
|
private _convertFeatureToMs;
|
|
176
|
+
private _handleGeolocationChanged;
|
|
173
177
|
private _handleThemeChange;
|
|
174
178
|
private _handleWindowResize;
|
|
175
179
|
render(): JSX.Element;
|
|
@@ -187,5 +191,6 @@ export declare class MainView extends React.Component<IProps, IStates> {
|
|
|
187
191
|
private _contextMenu;
|
|
188
192
|
private _loadingLayers;
|
|
189
193
|
private _originalFeatures;
|
|
194
|
+
private _highlightLayer;
|
|
190
195
|
}
|
|
191
196
|
export {};
|
package/lib/mainview/mainView.js
CHANGED
|
@@ -6,6 +6,7 @@ import { ContextMenu } from '@lumino/widgets';
|
|
|
6
6
|
import { Collection, Map as OlMap, View, getUid } from 'ol';
|
|
7
7
|
//@ts-expect-error no types for ol-pmtiles
|
|
8
8
|
import { PMTilesRasterSource, PMTilesVectorSource } from 'ol-pmtiles';
|
|
9
|
+
import Feature from 'ol/Feature';
|
|
9
10
|
import { ScaleLine } from 'ol/control';
|
|
10
11
|
import { singleClick } from 'ol/events/condition';
|
|
11
12
|
import { GeoJSON, MVT } from 'ol/format';
|
|
@@ -31,6 +32,7 @@ import CollaboratorPointers from './CollaboratorPointers';
|
|
|
31
32
|
import { FollowIndicator } from './FollowIndicator';
|
|
32
33
|
import TemporalSlider from './TemporalSlider';
|
|
33
34
|
import { Spinner } from './spinner';
|
|
35
|
+
import { Point } from 'ol/geom';
|
|
34
36
|
export class MainView extends React.Component {
|
|
35
37
|
constructor(props) {
|
|
36
38
|
super(props);
|
|
@@ -114,7 +116,8 @@ export class MainView extends React.Component {
|
|
|
114
116
|
zoom: (_a = this._Map.getView().getZoom()) !== null && _a !== void 0 ? _a : 0,
|
|
115
117
|
label: 'New annotation',
|
|
116
118
|
contents: [],
|
|
117
|
-
parent: this._Map.getViewport().id
|
|
119
|
+
parent: this._Map.getViewport().id,
|
|
120
|
+
open: true
|
|
118
121
|
});
|
|
119
122
|
},
|
|
120
123
|
label: 'Add annotation',
|
|
@@ -418,6 +421,17 @@ export class MainView extends React.Component {
|
|
|
418
421
|
this._model.zoomToPositionSignal.connect(this._onZoomToPosition, this);
|
|
419
422
|
this._model.updateLayerSignal.connect(this._triggerLayerUpdate, this);
|
|
420
423
|
this._model.addFeatureAsMsSignal.connect(this._convertFeatureToMs, this);
|
|
424
|
+
this._model.geolocationChanged.connect(this._handleGeolocationChanged, this);
|
|
425
|
+
this._model.flyToGeometrySignal.connect(this.flyToGeometry, this);
|
|
426
|
+
this._model.highlightFeatureSignal.connect(this.highlightFeatureOnMap, this);
|
|
427
|
+
// Watch isIdentifying and clear the highlight when Identify Tool is turned off
|
|
428
|
+
this._model.sharedModel.awareness.on('change', () => {
|
|
429
|
+
var _a;
|
|
430
|
+
const isIdentifying = this._model.isIdentifying;
|
|
431
|
+
if (!isIdentifying && this._highlightLayer) {
|
|
432
|
+
(_a = this._highlightLayer.getSource()) === null || _a === void 0 ? void 0 : _a.clear();
|
|
433
|
+
}
|
|
434
|
+
});
|
|
421
435
|
this.state = {
|
|
422
436
|
id: this._mainViewModel.id,
|
|
423
437
|
lightTheme: isLightTheme(),
|
|
@@ -439,7 +453,12 @@ export class MainView extends React.Component {
|
|
|
439
453
|
}
|
|
440
454
|
async componentDidMount() {
|
|
441
455
|
window.addEventListener('resize', this._handleWindowResize);
|
|
442
|
-
|
|
456
|
+
const options = this._model.getOptions();
|
|
457
|
+
const center = options.longitude !== undefined && options.latitude !== undefined
|
|
458
|
+
? fromLonLat([options.longitude, options.latitude])
|
|
459
|
+
: [0, 0];
|
|
460
|
+
const zoom = options.zoom !== undefined ? options.zoom : 1;
|
|
461
|
+
await this.generateScene(center, zoom);
|
|
443
462
|
this.addContextMenu();
|
|
444
463
|
this._mainViewModel.initSignal();
|
|
445
464
|
if (window.jupytergisMaps !== undefined && this._documentPath) {
|
|
@@ -457,14 +476,14 @@ export class MainView extends React.Component {
|
|
|
457
476
|
this._model.clientStateChanged.disconnect(this._onClientSharedStateChanged, this);
|
|
458
477
|
this._mainViewModel.dispose();
|
|
459
478
|
}
|
|
460
|
-
async generateScene() {
|
|
479
|
+
async generateScene(center, zoom) {
|
|
461
480
|
if (this.divRef.current) {
|
|
462
481
|
this._Map = new OlMap({
|
|
463
482
|
target: this.divRef.current,
|
|
464
483
|
layers: [],
|
|
465
484
|
view: new View({
|
|
466
|
-
center
|
|
467
|
-
zoom
|
|
485
|
+
center,
|
|
486
|
+
zoom
|
|
468
487
|
}),
|
|
469
488
|
controls: [new ScaleLine()]
|
|
470
489
|
});
|
|
@@ -1064,6 +1083,86 @@ export class MainView extends React.Component {
|
|
|
1064
1083
|
}
|
|
1065
1084
|
}
|
|
1066
1085
|
}
|
|
1086
|
+
flyToGeometry(sender, geometry) {
|
|
1087
|
+
if (!geometry || typeof geometry.getExtent !== 'function') {
|
|
1088
|
+
console.warn('Invalid geometry for flyToGeometry:', geometry);
|
|
1089
|
+
return;
|
|
1090
|
+
}
|
|
1091
|
+
const view = this._Map.getView();
|
|
1092
|
+
const extent = geometry.getExtent();
|
|
1093
|
+
view.fit(extent, {
|
|
1094
|
+
padding: [50, 50, 50, 50],
|
|
1095
|
+
duration: 1000,
|
|
1096
|
+
maxZoom: 16
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
1099
|
+
highlightFeatureOnMap(sender, featureOrGeometry) {
|
|
1100
|
+
const geometry = (featureOrGeometry === null || featureOrGeometry === void 0 ? void 0 : featureOrGeometry.geometry) ||
|
|
1101
|
+
(featureOrGeometry === null || featureOrGeometry === void 0 ? void 0 : featureOrGeometry._geometry) ||
|
|
1102
|
+
featureOrGeometry;
|
|
1103
|
+
if (!geometry) {
|
|
1104
|
+
console.warn('No geometry found in feature:', featureOrGeometry);
|
|
1105
|
+
return;
|
|
1106
|
+
}
|
|
1107
|
+
const isOlGeometry = typeof geometry.getCoordinates === 'function';
|
|
1108
|
+
const parsedGeometry = isOlGeometry
|
|
1109
|
+
? geometry
|
|
1110
|
+
: new GeoJSON().readGeometry(geometry, {
|
|
1111
|
+
featureProjection: this._Map.getView().getProjection()
|
|
1112
|
+
});
|
|
1113
|
+
const olFeature = new Feature(Object.assign({ geometry: parsedGeometry }, (geometry !== featureOrGeometry ? featureOrGeometry : {})));
|
|
1114
|
+
if (!this._highlightLayer) {
|
|
1115
|
+
this._highlightLayer = new VectorLayer({
|
|
1116
|
+
source: new VectorSource(),
|
|
1117
|
+
style: feature => {
|
|
1118
|
+
var _a;
|
|
1119
|
+
const geomType = (_a = feature.getGeometry()) === null || _a === void 0 ? void 0 : _a.getType();
|
|
1120
|
+
switch (geomType) {
|
|
1121
|
+
case 'Point':
|
|
1122
|
+
case 'MultiPoint':
|
|
1123
|
+
return new Style({
|
|
1124
|
+
image: new Circle({
|
|
1125
|
+
radius: 6,
|
|
1126
|
+
fill: new Fill({ color: 'rgba(255, 255, 0, 0.8)' }),
|
|
1127
|
+
stroke: new Stroke({ color: '#ff0', width: 2 })
|
|
1128
|
+
})
|
|
1129
|
+
});
|
|
1130
|
+
case 'LineString':
|
|
1131
|
+
case 'MultiLineString':
|
|
1132
|
+
return new Style({
|
|
1133
|
+
stroke: new Stroke({
|
|
1134
|
+
color: 'rgba(255, 255, 0, 0.8)',
|
|
1135
|
+
width: 3
|
|
1136
|
+
})
|
|
1137
|
+
});
|
|
1138
|
+
case 'Polygon':
|
|
1139
|
+
case 'MultiPolygon':
|
|
1140
|
+
return new Style({
|
|
1141
|
+
stroke: new Stroke({
|
|
1142
|
+
color: '#f00',
|
|
1143
|
+
width: 2
|
|
1144
|
+
}),
|
|
1145
|
+
fill: new Fill({
|
|
1146
|
+
color: 'rgba(255, 255, 0, 0.8)'
|
|
1147
|
+
})
|
|
1148
|
+
});
|
|
1149
|
+
default:
|
|
1150
|
+
return new Style({
|
|
1151
|
+
stroke: new Stroke({
|
|
1152
|
+
color: '#000',
|
|
1153
|
+
width: 2
|
|
1154
|
+
})
|
|
1155
|
+
});
|
|
1156
|
+
}
|
|
1157
|
+
},
|
|
1158
|
+
zIndex: 999
|
|
1159
|
+
});
|
|
1160
|
+
this._Map.addLayer(this._highlightLayer);
|
|
1161
|
+
}
|
|
1162
|
+
const source = this._highlightLayer.getSource();
|
|
1163
|
+
source === null || source === void 0 ? void 0 : source.clear();
|
|
1164
|
+
source === null || source === void 0 ? void 0 : source.addFeature(olFeature);
|
|
1165
|
+
}
|
|
1067
1166
|
/**
|
|
1068
1167
|
* Wait for all layers to be loaded.
|
|
1069
1168
|
*/
|
|
@@ -1302,7 +1401,7 @@ export class MainView extends React.Component {
|
|
|
1302
1401
|
// Check if the id is an annotation
|
|
1303
1402
|
const annotation = (_a = this._model.annotationModel) === null || _a === void 0 ? void 0 : _a.getAnnotation(id);
|
|
1304
1403
|
if (annotation) {
|
|
1305
|
-
this.
|
|
1404
|
+
this._flyToPosition(annotation.position, annotation.zoom);
|
|
1306
1405
|
return;
|
|
1307
1406
|
}
|
|
1308
1407
|
// The id is a layer
|
|
@@ -1334,15 +1433,18 @@ export class MainView extends React.Component {
|
|
|
1334
1433
|
}
|
|
1335
1434
|
_moveToPosition(center, zoom, duration = 1000) {
|
|
1336
1435
|
const view = this._Map.getView();
|
|
1436
|
+
view.setZoom(zoom);
|
|
1437
|
+
view.setCenter([center.x, center.y]);
|
|
1337
1438
|
// Zoom needs to be set before changing center
|
|
1338
1439
|
if (!view.animate === undefined) {
|
|
1339
1440
|
view.animate({ zoom, duration });
|
|
1340
1441
|
view.animate({ center: [center.x, center.y], duration });
|
|
1341
1442
|
}
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
}
|
|
1443
|
+
}
|
|
1444
|
+
_flyToPosition(center, zoom, duration = 1000) {
|
|
1445
|
+
const view = this._Map.getView();
|
|
1446
|
+
view.animate({ zoom, duration });
|
|
1447
|
+
view.animate({ center: [center.x, center.y], duration });
|
|
1346
1448
|
}
|
|
1347
1449
|
_onPointerMove(e) {
|
|
1348
1450
|
const pixel = this._Map.getEventPixel(e);
|
|
@@ -1378,6 +1480,10 @@ export class MainView extends React.Component {
|
|
|
1378
1480
|
// last element is alpha
|
|
1379
1481
|
bandValues['Alpha'] = data[data.length - 1];
|
|
1380
1482
|
this._model.syncIdentifiedFeatures([bandValues], this._mainViewModel.id);
|
|
1483
|
+
const coordinate = this._Map.getCoordinateFromPixel(e.pixel);
|
|
1484
|
+
const point = new Point(coordinate);
|
|
1485
|
+
// trigger highlight via signal
|
|
1486
|
+
this._model.highlightFeatureSignal.emit(point);
|
|
1381
1487
|
break;
|
|
1382
1488
|
}
|
|
1383
1489
|
}
|
|
@@ -1404,6 +1510,16 @@ export class MainView extends React.Component {
|
|
|
1404
1510
|
feature.set(`${selectedFeature}ms`, parsedTime);
|
|
1405
1511
|
});
|
|
1406
1512
|
}
|
|
1513
|
+
_handleGeolocationChanged(sender, newPosition) {
|
|
1514
|
+
const view = this._Map.getView();
|
|
1515
|
+
const zoom = view.getZoom();
|
|
1516
|
+
if (zoom) {
|
|
1517
|
+
this._flyToPosition(newPosition, zoom);
|
|
1518
|
+
}
|
|
1519
|
+
else {
|
|
1520
|
+
throw new Error('Could not move to geolocation, because current zoom is not defined.');
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1407
1523
|
render() {
|
|
1408
1524
|
return (React.createElement(React.Fragment, null,
|
|
1409
1525
|
Object.entries(this.state.annotations).map(([key, annotation]) => {
|
|
@@ -1415,7 +1531,7 @@ export class MainView extends React.Component {
|
|
|
1415
1531
|
left: screenPosition.x,
|
|
1416
1532
|
top: screenPosition.y
|
|
1417
1533
|
}, className: 'jGIS-Popup-Wrapper' },
|
|
1418
|
-
React.createElement(AnnotationFloater, { itemId: key, annotationModel: this._model.annotationModel
|
|
1534
|
+
React.createElement(AnnotationFloater, { itemId: key, annotationModel: this._model.annotationModel }))));
|
|
1419
1535
|
}),
|
|
1420
1536
|
React.createElement("div", { className: "jGIS-Mainview-Container" },
|
|
1421
1537
|
this.state.displayTemporalController && (React.createElement(TemporalSlider, { model: this._model, filterStates: this.state.filterStates })),
|
|
@@ -29,14 +29,14 @@ export class AnnotationsPanel extends Component {
|
|
|
29
29
|
React.createElement(Annotation, { rightPanelModel: this._rightPanelModel, annotationModel: this._annotationModel, itemId: id }),
|
|
30
30
|
React.createElement("hr", { className: "jGIS-Annotations-Separator" })));
|
|
31
31
|
});
|
|
32
|
-
return React.createElement("div",
|
|
32
|
+
return React.createElement("div", { className: "jgis-scrollable" }, annotations);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
export class Annotations extends PanelWithToolbar {
|
|
36
36
|
constructor(options) {
|
|
37
37
|
super({});
|
|
38
38
|
this.title.label = 'Annotations';
|
|
39
|
-
this.addClass('
|
|
39
|
+
this.addClass('jgis-scrollable');
|
|
40
40
|
this._annotationModel = options.annotationModel;
|
|
41
41
|
this._rightPanelModel = options.rightPanelModel;
|
|
42
42
|
this._widget = ReactWidget.create(React.createElement(AnnotationsPanel, { rightPanelModel: this._rightPanelModel, annotationModel: this._annotationModel }));
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { LabIcon, ReactWidget, caretDownIcon } from '@jupyterlab/ui-components';
|
|
2
2
|
import { Panel } from '@lumino/widgets';
|
|
3
3
|
import React, { useEffect, useRef, useState } from 'react';
|
|
4
|
+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
5
|
+
import { faMagnifyingGlass } from '@fortawesome/free-solid-svg-icons';
|
|
4
6
|
export class IdentifyPanel extends Panel {
|
|
5
7
|
constructor(options) {
|
|
6
8
|
super();
|
|
@@ -9,6 +11,7 @@ export class IdentifyPanel extends Panel {
|
|
|
9
11
|
this.id = 'jupytergis::identifyPanel';
|
|
10
12
|
this.title.caption = 'Identify';
|
|
11
13
|
this.title.label = 'Identify';
|
|
14
|
+
this.addClass('jgis-scrollable');
|
|
12
15
|
this.addWidget(ReactWidget.create(React.createElement(IdentifyPanelComponent, { controlPanelModel: this._model, tracker: this._tracker })));
|
|
13
16
|
}
|
|
14
17
|
}
|
|
@@ -80,8 +83,13 @@ const IdentifyPanelComponent = ({ controlPanelModel, tracker }) => {
|
|
|
80
83
|
jgisModel === null || jgisModel === void 0 ? void 0 : jgisModel.clientStateChanged.disconnect(handleClientStateChanged);
|
|
81
84
|
};
|
|
82
85
|
}, [jgisModel]);
|
|
86
|
+
const highlightFeatureOnMap = (feature) => {
|
|
87
|
+
var _a, _b;
|
|
88
|
+
(_a = jgisModel === null || jgisModel === void 0 ? void 0 : jgisModel.highlightFeatureSignal) === null || _a === void 0 ? void 0 : _a.emit(feature);
|
|
89
|
+
const geometry = feature.geometry || feature._geometry;
|
|
90
|
+
(_b = jgisModel === null || jgisModel === void 0 ? void 0 : jgisModel.flyToGeometrySignal) === null || _b === void 0 ? void 0 : _b.emit(geometry);
|
|
91
|
+
};
|
|
83
92
|
const toggleFeatureVisibility = (index) => {
|
|
84
|
-
console.log('visibleFeatures', visibleFeatures);
|
|
85
93
|
setVisibleFeatures(prev => (Object.assign(Object.assign({}, prev), { [index]: !prev[index] })));
|
|
86
94
|
};
|
|
87
95
|
return (React.createElement("div", { className: "jgis-identify-wrapper", style: {
|
|
@@ -90,14 +98,28 @@ const IdentifyPanelComponent = ({ controlPanelModel, tracker }) => {
|
|
|
90
98
|
: 'unset'
|
|
91
99
|
} }, features &&
|
|
92
100
|
Object.values(features).map((feature, featureIndex) => (React.createElement("div", { key: featureIndex, className: "jgis-identify-grid-item" },
|
|
93
|
-
React.createElement("div", { className: "jgis-identify-grid-item-header"
|
|
94
|
-
React.createElement(
|
|
95
|
-
|
|
96
|
-
"
|
|
97
|
-
|
|
98
|
-
|
|
101
|
+
React.createElement("div", { className: "jgis-identify-grid-item-header" },
|
|
102
|
+
React.createElement("span", { onClick: () => toggleFeatureVisibility(featureIndex) },
|
|
103
|
+
React.createElement(LabIcon.resolveReact, { icon: caretDownIcon, className: `jp-gis-layerGroupCollapser${visibleFeatures[featureIndex] ? ' jp-mod-expanded' : ''}`, tag: 'span' }),
|
|
104
|
+
React.createElement("span", null,
|
|
105
|
+
"Feature ",
|
|
106
|
+
featureIndex + 1)),
|
|
107
|
+
(() => {
|
|
108
|
+
const isRasterFeature = !feature.geometry &&
|
|
109
|
+
!feature._geometry &&
|
|
110
|
+
typeof (feature === null || feature === void 0 ? void 0 : feature.x) !== 'number' &&
|
|
111
|
+
typeof (feature === null || feature === void 0 ? void 0 : feature.y) !== 'number';
|
|
112
|
+
return (React.createElement("button", { className: "jgis-highlight-button", onClick: e => {
|
|
113
|
+
e.stopPropagation();
|
|
114
|
+
highlightFeatureOnMap(feature);
|
|
115
|
+
}, title: isRasterFeature
|
|
116
|
+
? 'Highlight not available for raster features'
|
|
117
|
+
: 'Highlight feature on map', disabled: isRasterFeature },
|
|
118
|
+
React.createElement(FontAwesomeIcon, { icon: faMagnifyingGlass })));
|
|
119
|
+
})()),
|
|
99
120
|
visibleFeatures[featureIndex] && (React.createElement(React.Fragment, null, Object.entries(feature)
|
|
100
121
|
.filter(([key, value]) => typeof value !== 'object' || value === null)
|
|
122
|
+
.sort(([keyA], [keyB]) => keyA.localeCompare(keyB))
|
|
101
123
|
.map(([key, value]) => (React.createElement("div", { key: key, className: "jgis-identify-grid-body" },
|
|
102
124
|
React.createElement("strong", null,
|
|
103
125
|
key,
|
|
@@ -94,6 +94,7 @@ function LayersBodyComponent(props) {
|
|
|
94
94
|
};
|
|
95
95
|
model === null || model === void 0 ? void 0 : model.sharedModel.layersChanged.connect(updateLayers);
|
|
96
96
|
model === null || model === void 0 ? void 0 : model.sharedModel.layerTreeChanged.connect(updateLayers);
|
|
97
|
+
updateLayers();
|
|
97
98
|
return () => {
|
|
98
99
|
model === null || model === void 0 ? void 0 : model.sharedModel.layersChanged.disconnect(updateLayers);
|
|
99
100
|
model === null || model === void 0 ? void 0 : model.sharedModel.layerTreeChanged.disconnect(updateLayers);
|
|
@@ -30,6 +30,7 @@ export class RightPanelWidget extends SidePanel {
|
|
|
30
30
|
});
|
|
31
31
|
identifyPanel.title.caption = 'Identify';
|
|
32
32
|
identifyPanel.title.label = 'Identify';
|
|
33
|
+
identifyPanel.addClass('jgis-scrollable');
|
|
33
34
|
this.addWidget(identifyPanel);
|
|
34
35
|
this._model.documentChanged.connect((_, changed) => {
|
|
35
36
|
if (changed) {
|
package/lib/toolbar/widget.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { CommandToolbarButton } from '@jupyterlab/apputils';
|
|
2
|
-
import { MenuSvg, ReactWidget, ReactiveToolbar, ToolbarButton, addIcon, redoIcon,
|
|
2
|
+
import { MenuSvg, ReactWidget, ReactiveToolbar, ToolbarButton, addIcon, redoIcon, 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
|
+
import { rasterIcon, terminalToolbarIcon } from '../icons';
|
|
7
7
|
import { UsersItem } from './usertoolbaritem';
|
|
8
8
|
export const TOOLBAR_SEPARATOR_CLASS = 'jGIS-Toolbar-Separator';
|
|
9
9
|
export const TOOLBAR_GROUPNAME_CLASS = 'jGIS-Toolbar-GroupName';
|
|
@@ -21,41 +21,58 @@ export class ToolbarWidget extends ReactiveToolbar {
|
|
|
21
21
|
super();
|
|
22
22
|
this.addClass('jGIS-toolbar-widget');
|
|
23
23
|
if (options.commands) {
|
|
24
|
-
|
|
24
|
+
const undoButton = new CommandToolbarButton({
|
|
25
25
|
id: CommandIDs.undo,
|
|
26
26
|
label: '',
|
|
27
27
|
icon: undoIcon,
|
|
28
28
|
commands: options.commands
|
|
29
|
-
})
|
|
30
|
-
this.addItem('
|
|
29
|
+
});
|
|
30
|
+
this.addItem('undo', undoButton);
|
|
31
|
+
undoButton.node.dataset.testid = 'undo-button';
|
|
32
|
+
const redoButton = new CommandToolbarButton({
|
|
31
33
|
id: CommandIDs.redo,
|
|
32
34
|
label: '',
|
|
33
35
|
icon: redoIcon,
|
|
34
36
|
commands: options.commands
|
|
35
|
-
})
|
|
37
|
+
});
|
|
38
|
+
this.addItem('redo', redoButton);
|
|
36
39
|
this.addItem('separator0', new Separator());
|
|
37
|
-
|
|
40
|
+
const toggleConsoleButton = new CommandToolbarButton({
|
|
38
41
|
id: CommandIDs.toggleConsole,
|
|
39
42
|
commands: options.commands,
|
|
40
43
|
label: '',
|
|
41
|
-
icon:
|
|
42
|
-
})
|
|
44
|
+
icon: terminalToolbarIcon
|
|
45
|
+
});
|
|
46
|
+
this.addItem('Toggle console', toggleConsoleButton);
|
|
47
|
+
toggleConsoleButton.node.dataset.testid = 'toggle-console-button';
|
|
43
48
|
this.addItem('separator1', new Separator());
|
|
44
|
-
|
|
49
|
+
const openLayersBrowserButton = new CommandToolbarButton({
|
|
45
50
|
id: CommandIDs.openLayerBrowser,
|
|
46
51
|
label: '',
|
|
47
52
|
commands: options.commands
|
|
48
|
-
})
|
|
49
|
-
this.addItem('
|
|
53
|
+
});
|
|
54
|
+
this.addItem('openLayerBrowser', openLayersBrowserButton);
|
|
55
|
+
openLayersBrowserButton.node.dataset.testid = 'open-layers-browser';
|
|
56
|
+
const newRasterEntryButton = new CommandToolbarButton({
|
|
50
57
|
id: CommandIDs.newRasterEntry,
|
|
51
58
|
label: '',
|
|
52
59
|
commands: options.commands
|
|
53
|
-
})
|
|
54
|
-
this.addItem('
|
|
60
|
+
});
|
|
61
|
+
this.addItem('newRasterEntry', newRasterEntryButton);
|
|
62
|
+
const newVectorTileEntryButton = new CommandToolbarButton({
|
|
55
63
|
id: CommandIDs.newVectorTileEntry,
|
|
56
64
|
label: '',
|
|
57
65
|
commands: options.commands
|
|
58
|
-
})
|
|
66
|
+
});
|
|
67
|
+
this.addItem('newVectorTileEntry', newVectorTileEntryButton);
|
|
68
|
+
newRasterEntryButton.node.dataset.testid = 'new-raster-entry-button';
|
|
69
|
+
const geolocationButton = new CommandToolbarButton({
|
|
70
|
+
id: CommandIDs.getGeolocation,
|
|
71
|
+
commands: options.commands,
|
|
72
|
+
label: ''
|
|
73
|
+
});
|
|
74
|
+
this.addItem('Geolocation', geolocationButton);
|
|
75
|
+
geolocationButton.node.dataset.testid = 'geolocation-button';
|
|
59
76
|
// vector sub menu
|
|
60
77
|
const vectorSubMenu = new Menu({ commands: options.commands });
|
|
61
78
|
vectorSubMenu.title.label = 'Add Vector Layer';
|
|
@@ -101,18 +118,24 @@ export class ToolbarWidget extends ReactiveToolbar {
|
|
|
101
118
|
NewSubMenu.open(bbox.x, bbox.bottom);
|
|
102
119
|
}
|
|
103
120
|
});
|
|
121
|
+
NewEntryButton.node.dataset.testid = 'new-entry-button';
|
|
104
122
|
this.addItem('New', NewEntryButton);
|
|
105
123
|
this.addItem('separator2', new Separator());
|
|
106
|
-
|
|
124
|
+
const identifyButton = new CommandToolbarButton({
|
|
107
125
|
id: CommandIDs.identify,
|
|
108
126
|
label: '',
|
|
109
127
|
commands: options.commands
|
|
110
|
-
})
|
|
111
|
-
this.addItem('
|
|
128
|
+
});
|
|
129
|
+
this.addItem('identify', identifyButton);
|
|
130
|
+
identifyButton.node.dataset.testid = 'identify-button';
|
|
131
|
+
const temporalControllerButton = new CommandToolbarButton({
|
|
112
132
|
id: CommandIDs.temporalController,
|
|
113
133
|
label: '',
|
|
114
134
|
commands: options.commands
|
|
115
|
-
})
|
|
135
|
+
});
|
|
136
|
+
this.addItem('temporalController', temporalControllerButton);
|
|
137
|
+
temporalControllerButton.node.dataset.testid =
|
|
138
|
+
'temporal-controller-button';
|
|
116
139
|
this.addItem('spacer', ReactiveToolbar.createSpacerItem());
|
|
117
140
|
// Users
|
|
118
141
|
this.addItem('users', ReactWidget.create(React.createElement(UsersItem, { model: options.model })));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jupytergis/base",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.5",
|
|
4
4
|
"description": "A JupyterLab extension for 3D modelling.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jupyter",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"@fortawesome/react-fontawesome": "latest",
|
|
44
44
|
"@jupyter/react-components": "^0.16.6",
|
|
45
45
|
"@jupyter/ydoc": "^2.0.0 || ^3.0.0",
|
|
46
|
-
"@jupytergis/schema": "^0.4.
|
|
46
|
+
"@jupytergis/schema": "^0.4.5",
|
|
47
47
|
"@jupyterlab/application": "^4.3.0",
|
|
48
48
|
"@jupyterlab/apputils": "^4.3.0",
|
|
49
49
|
"@jupyterlab/completer": "^4.3.0",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<svg
|
|
3
|
+
viewBox="0 0 576 512"
|
|
4
|
+
version="1.1"
|
|
5
|
+
id="svg1"
|
|
6
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
7
|
+
xmlns:svg="http://www.w3.org/2000/svg">
|
|
8
|
+
<defs
|
|
9
|
+
id="defs1" />
|
|
10
|
+
<!--!Font
|
|
11
|
+
Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License -
|
|
12
|
+
https://fontawesome.com/license/free -->
|
|
13
|
+
<path
|
|
14
|
+
id="path1"
|
|
15
|
+
d="M542.2 32.1c-54.8 3.1-163.7 14.4-231 55.6-4.6 2.8-7.3 7.9-7.3 13.2v363.9c0 11.6 12.6 18.9 23.3 13.5 69.2-34.8 169.2-44.3 218.7-46.9 16.9-.9 30-14.4 30-30.7V62.8c0-17.7-15.4-31.7-33.8-30.7zM264.7 87.6C197.5 46.5 88.6 35.2 33.8 32.1 15.4 31 0 45 0 62.8V400.6c0 16.2 13.1 29.8 30 30.7 49.5 2.6 149.6 12.1 218.8 47 10.6 5.4 23.2-1.9 23.2-13.5V100.6c0-5.3-2.6-10.1-7.3-13z"
|
|
16
|
+
fill="#616161"
|
|
17
|
+
class="jp-icon3"
|
|
18
|
+
/>
|
|
19
|
+
</svg>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<svg
|
|
3
|
+
viewBox="0 0 512 512"
|
|
4
|
+
version="1.1"
|
|
5
|
+
id="svg1"
|
|
6
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
7
|
+
xmlns:svg="http://www.w3.org/2000/svg">
|
|
8
|
+
<defs
|
|
9
|
+
id="defs1" />
|
|
10
|
+
<!--!FontAwesome Free 6.7.2 by @fontawesome - https://fontawesome.com License -https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
|
|
11
|
+
<path
|
|
12
|
+
d="M 256,47.68 C 140.92,47.68 47.68,140.92 47.68,256 47.68,371.08 140.92,464.32 256,464.32 371.08,464.32 464.32,371.08 464.32,256 464.32,140.92 371.08,47.68 256,47.68 Z m 77.7,262.92 v 0 l -16.8,21 a 13.44,13.44 0 0 1 -18.9,2.1 v 0 l -56.28,-41.748 a 33.6,33.6 0 0 1 -12.6,-26.208 V 135.04 a 13.44,13.44 0 0 1 13.44,-13.44 h 26.88 a 13.44,13.44 0 0 1 13.44,13.44 V 256 l 48.72,35.7 a 13.44,13.44 0 0 1 2.1,18.9 z"
|
|
13
|
+
id="path1"
|
|
14
|
+
style="stroke-width:0.84"
|
|
15
|
+
fill="#616161"
|
|
16
|
+
class="jp-icon3" />
|
|
17
|
+
</svg>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<svg
|
|
3
|
+
viewBox="0 0 384 512"
|
|
4
|
+
version="1.1"
|
|
5
|
+
id="svg1"
|
|
6
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
7
|
+
xmlns:svg="http://www.w3.org/2000/svg">
|
|
8
|
+
<defs
|
|
9
|
+
id="defs1" />
|
|
10
|
+
<!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
|
|
11
|
+
<path
|
|
12
|
+
d="M172.3 501.7C27 291 0 269.4 0 192 0 86 86 0 192 0s192 86 192 192c0 77.4-27 99-172.3 309.7-9.5 13.8-29.9 13.8-39.5 0zM192 272c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80z"
|
|
13
|
+
id="path1"
|
|
14
|
+
style="fill:#616161;fill-opacity:1" />
|
|
15
|
+
</svg>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<svg
|
|
3
|
+
viewBox="0 0 192 512"
|
|
4
|
+
version="1.1"
|
|
5
|
+
id="svg1"
|
|
6
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
7
|
+
xmlns:svg="http://www.w3.org/2000/svg">
|
|
8
|
+
<defs
|
|
9
|
+
id="defs1" />
|
|
10
|
+
<!--!Font
|
|
11
|
+
Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License -
|
|
12
|
+
https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
|
|
13
|
+
<path
|
|
14
|
+
d="m 35.2,390.56 h 16 V 275.04 h -16 c -8.8,0 -16,-7.2 -16,-16 V 220.8 c 0,-8.8 7.2,-16 16,-16 h 89.6 c 8.8,0 16,7.2 16,16 v 169.76 h 16 c 8.8,0 16,7.2 16,16 v 38.24 c 0,8.8 -7.2,16 -16,16 H 35.2 c -8.8,0 -16,-7.2 -16,-16 v -38.24 c 0,-8.8 7.2,-16 16,-16 z M 96,51.2 c -31.84,0 -57.6,25.76 -57.6,57.6 0,31.84 25.76,57.6 57.6,57.6 31.84,0 57.6,-25.76 57.6,-57.6 0,-31.84 -25.76,-57.6 -57.6,-57.6 z"
|
|
15
|
+
id="path1"
|
|
16
|
+
style="stroke-width:0.8"
|
|
17
|
+
fill="#616161"
|
|
18
|
+
class="jp-icon3"
|
|
19
|
+
/>
|
|
20
|
+
</svg>
|
package/style/icons/raster.svg
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<svg height="16" viewBox="0 0 24 24" width="16" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
-
<g class="jp-
|
|
3
|
-
<path
|
|
2
|
+
<g class="jp-icon3 jp-icon-selectable" fill="#616161">
|
|
3
|
+
<path
|
|
4
|
+
d="M 22,8 H 2 v 1 h 20 z m 0,10.5 H 2 v 1 H 22 Z M 22,15 H 2 v 1 h 20 z m 0,-3.5 H 2 v 1 h 20 z m 0,-7 H 2 v 1 H 22 Z M 5.5,2 h -1 v 20 h 1 z M 9,2 H 8 v 20 h 1 z m 3.5,0 h -1 v 20 h 1 z M 16,2 h -1 v 20 h 1 z m 3.5,0 h -1 v 20 h 1 z" />
|
|
4
5
|
</g>
|
|
5
6
|
</svg>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font
|
|
2
|
+
Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License -
|
|
3
|
+
https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
|
|
4
|
+
<path
|
|
5
|
+
d="M256 0c17.7 0 32 14.3 32 32l0 34.7C368.4 80.1 431.9 143.6 445.3 224l34.7 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-34.7 0C431.9 368.4 368.4 431.9 288 445.3l0 34.7c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-34.7C143.6 431.9 80.1 368.4 66.7 288L32 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l34.7 0C80.1 143.6 143.6 80.1 224 66.7L224 32c0-17.7 14.3-32 32-32zM128 256a128 128 0 1 0 256 0 128 128 0 1 0 -256 0zm128-80a80 80 0 1 1 0 160 80 80 0 1 1 0-160z"
|
|
6
|
+
fill="#616161"
|
|
7
|
+
class="jp-icon3"
|
|
8
|
+
/>
|
|
9
|
+
</svg>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<svg
|
|
3
|
+
viewBox="0 0 512 512"
|
|
4
|
+
version="1.1"
|
|
5
|
+
id="svg1"
|
|
6
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
7
|
+
xmlns:svg="http://www.w3.org/2000/svg">
|
|
8
|
+
<defs
|
|
9
|
+
id="defs1" />
|
|
10
|
+
<!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
|
|
11
|
+
<path
|
|
12
|
+
d="m 256,0 c 17.7,0 32,14.3 32,32 V 66.7 C 368.4,80.1 431.9,143.6 445.3,224 H 480 c 17.7,0 32,14.3 32,32 0,17.7 -14.3,32 -32,32 H 445.3 C 431.9,368.4 368.4,431.9 288,445.3 V 480 c 0,17.7 -14.3,32 -32,32 -17.7,0 -32,-14.3 -32,-32 V 445.3 C 143.6,431.9 80.1,368.4 66.7,288 H 32 C 14.3,288 0,273.7 0,256 0,238.3 14.3,224 32,224 H 66.7 C 80.1,143.6 143.6,80.1 224,66.7 V 32 C 224,14.3 238.3,0 256,0 Z M 128,256 c 0,70.6925 57.30755,127.99994 128,127.99994 70.69245,0 128,-57.30744 128,-127.99994 0,-70.6925 -57.30755,-127.99994 -128,-127.99994 -70.69245,0 -128,57.30744 -128,127.99994 z"
|
|
13
|
+
id="path1"
|
|
14
|
+
fill="#616161"
|
|
15
|
+
class="jp-icon3"
|
|
16
|
+
/>
|
|
17
|
+
</svg>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" viewBox="0 0 24 24">
|
|
2
|
+
<path
|
|
3
|
+
d="M2 2h20v20H2z"
|
|
4
|
+
fill="#616161"
|
|
5
|
+
class="jp-icon3"
|
|
6
|
+
/>
|
|
7
|
+
<path
|
|
8
|
+
d="M9.01 14.762q0-.246-.077-.434a.9.9 0 0 0-.234-.351 1.6 1.6 0 0 0-.422-.288 5 5 0 0 0-.627-.263q-.592-.211-1.078-.446a3.5 3.5 0 0 1-.832-.544 2.2 2.2 0 0 1-.528-.721 2.4 2.4 0 0 1-.187-.985q0-.498.17-.908a2.1 2.1 0 0 1 .48-.72q.31-.306.75-.493.44-.188.979-.24V7.11h.937v1.272q.527.07.95.287.421.217.714.568.3.345.457.82.165.47.164 1.055H8.998q0-.709-.323-1.072-.322-.37-.873-.37-.299 0-.521.083a.9.9 0 0 0-.358.223.9.9 0 0 0-.21.334q-.066.194-.065.421 0 .23.064.41a.9.9 0 0 0 .229.329q.165.152.428.293.263.134.656.275.591.223 1.072.463.48.235.82.55.346.312.528.727.187.41.187.973 0 .515-.17.932-.17.41-.486.709t-.762.48a3.7 3.7 0 0 1-.996.229v1.148h-.931V17.1a4 4 0 0 1-.967-.217 2.6 2.6 0 0 1-.832-.504 2.4 2.4 0 0 1-.574-.826q-.217-.505-.217-1.207h1.635q0 .421.123.709.123.281.316.45.2.165.451.235.252.07.516.07.627 0 .949-.292a.98.98 0 0 0 .322-.756m8.36 3.51h-5.343V17h5.344z"
|
|
9
|
+
fill="#bdbdbd"
|
|
10
|
+
class="jp-icon-accent1"
|
|
11
|
+
/>
|
|
12
|
+
</svg>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<svg
|
|
3
|
+
class="jp-icon3"
|
|
4
|
+
viewBox="0 0 512 512"
|
|
5
|
+
version="1.1"
|
|
6
|
+
id="svg1"
|
|
7
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
8
|
+
xmlns:svg="http://www.w3.org/2000/svg">
|
|
9
|
+
<defs
|
|
10
|
+
id="defs1" />
|
|
11
|
+
<!--!Font
|
|
12
|
+
Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License -
|
|
13
|
+
https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
|
|
14
|
+
<path
|
|
15
|
+
d="M 486.4,140.8 V 54.4 c 0,-15.93 -12.87,-28.8 -28.8,-28.8 h -86.4 c -15.93,0 -28.8,12.87 -28.8,28.8 H 169.6 c 0,-15.93 -12.87,-28.8 -28.8,-28.8 H 54.4 c -15.93,0 -28.8,12.87 -28.8,28.8 v 86.4 c 0,15.93 12.87,28.8 28.8,28.8 v 172.8 c -15.93,0 -28.8,12.87 -28.8,28.8 v 86.4 c 0,15.93 12.87,28.8 28.8,28.8 h 86.4 c 15.93,0 28.8,-12.87 28.8,-28.8 h 172.8 c 0,15.93 12.87,28.8 28.8,28.8 h 86.4 c 15.93,0 28.8,-12.87 28.8,-28.8 v -86.4 c 0,-15.93 -12.87,-28.8 -28.8,-28.8 V 169.6 c 15.93,0 28.8,-12.87 28.8,-28.8 z M 400,83.2 h 28.8 V 112 H 400 Z m -316.8,0 H 112 V 112 H 83.2 Z M 112,428.8 H 83.2 V 400 H 112 Z m 316.8,0 H 400 V 400 h 28.8 z M 400,342.4 h -28.8 c -15.93,0 -28.8,12.87 -28.8,28.8 V 400 H 169.6 v -28.8 c 0,-15.93 -12.87,-28.8 -28.8,-28.8 H 112 V 169.6 h 28.8 c 15.93,0 28.8,-12.87 28.8,-28.8 V 112 h 172.8 v 28.8 c 0,15.93 12.87,28.8 28.8,28.8 H 400 Z"
|
|
16
|
+
id="path1"
|
|
17
|
+
style="stroke-width:0.9"
|
|
18
|
+
fill="#616161"
|
|
19
|
+
class="jp-icon3"
|
|
20
|
+
/>
|
|
21
|
+
</svg>
|