@jupytergis/base 0.5.0 → 0.6.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.d.ts +2 -2
- package/lib/annotations/components/Annotation.js +3 -3
- package/lib/annotations/components/AnnotationFloater.d.ts +1 -1
- package/lib/annotations/components/AnnotationFloater.js +2 -2
- package/lib/annotations/components/Message.d.ts +2 -1
- package/lib/annotations/components/Message.js +3 -3
- package/lib/annotations/model.js +5 -5
- package/lib/commands/BaseCommandIDs.d.ts +32 -0
- package/lib/commands/BaseCommandIDs.js +43 -0
- package/lib/{commands.d.ts → commands/index.d.ts} +1 -1
- package/lib/{commands.js → commands/index.js} +59 -99
- package/lib/console/consoleview.d.ts +3 -3
- package/lib/console/consoleview.js +5 -5
- package/lib/constants.d.ts +2 -36
- package/lib/constants.js +5 -47
- package/lib/dialogs/ProcessingFormDialog.d.ts +4 -4
- package/lib/dialogs/ProcessingFormDialog.js +9 -11
- package/lib/dialogs/layerBrowserDialog.d.ts +1 -1
- package/lib/dialogs/layerBrowserDialog.js +7 -7
- package/lib/dialogs/layerCreationFormDialog.d.ts +4 -4
- package/lib/dialogs/layerCreationFormDialog.js +6 -6
- package/lib/dialogs/symbology/components/color_ramp/CanvasSelectComponent.d.ts +1 -1
- package/lib/dialogs/symbology/components/color_ramp/CanvasSelectComponent.js +3 -3
- package/lib/dialogs/symbology/components/color_ramp/ColorRamp.d.ts +3 -2
- package/lib/dialogs/symbology/components/color_ramp/ColorRamp.js +6 -7
- package/lib/dialogs/symbology/components/color_ramp/ColorRampEntry.d.ts +1 -1
- package/lib/dialogs/symbology/components/color_ramp/ColorRampEntry.js +1 -1
- package/lib/dialogs/symbology/components/color_ramp/ModeSelectRow.d.ts +1 -1
- package/lib/dialogs/symbology/components/color_ramp/ModeSelectRow.js +1 -1
- package/lib/dialogs/symbology/components/color_stops/StopContainer.d.ts +2 -2
- package/lib/dialogs/symbology/components/color_stops/StopContainer.js +4 -4
- package/lib/dialogs/symbology/components/color_stops/StopRow.d.ts +3 -3
- package/lib/dialogs/symbology/components/color_stops/StopRow.js +2 -2
- package/lib/dialogs/symbology/hooks/useGetBandInfo.js +5 -5
- package/lib/dialogs/symbology/hooks/useGetProperties.d.ts +1 -1
- package/lib/dialogs/symbology/hooks/useGetProperties.js +4 -4
- package/lib/dialogs/symbology/symbologyDialog.d.ts +8 -0
- package/lib/dialogs/symbology/symbologyDialog.js +1 -1
- package/lib/dialogs/symbology/symbologyUtils.js +38 -31
- package/lib/dialogs/symbology/tiff_layer/TiffRendering.d.ts +2 -2
- package/lib/dialogs/symbology/tiff_layer/TiffRendering.js +2 -2
- package/lib/dialogs/symbology/tiff_layer/components/BandRow.d.ts +2 -2
- package/lib/dialogs/symbology/tiff_layer/components/BandRow.js +4 -4
- package/lib/dialogs/symbology/tiff_layer/types/MultibandColor.d.ts +2 -2
- package/lib/dialogs/symbology/tiff_layer/types/MultibandColor.js +30 -20
- package/lib/dialogs/symbology/tiff_layer/types/SingleBandPseudoColor.d.ts +2 -2
- package/lib/dialogs/symbology/tiff_layer/types/SingleBandPseudoColor.js +23 -21
- package/lib/dialogs/symbology/vector_layer/VectorRendering.d.ts +2 -2
- package/lib/dialogs/symbology/vector_layer/VectorRendering.js +81 -39
- package/lib/dialogs/symbology/vector_layer/components/ValueSelect.d.ts +1 -1
- package/lib/dialogs/symbology/vector_layer/components/ValueSelect.js +1 -1
- package/lib/dialogs/symbology/vector_layer/types/Canonical.d.ts +4 -0
- package/lib/dialogs/symbology/vector_layer/types/Canonical.js +66 -0
- package/lib/dialogs/symbology/vector_layer/types/Categorized.d.ts +2 -2
- package/lib/dialogs/symbology/vector_layer/types/Categorized.js +142 -47
- package/lib/dialogs/symbology/vector_layer/types/Graduated.d.ts +2 -2
- package/lib/dialogs/symbology/vector_layer/types/Graduated.js +193 -99
- package/lib/dialogs/symbology/vector_layer/types/Heatmap.d.ts +2 -2
- package/lib/dialogs/symbology/vector_layer/types/Heatmap.js +7 -6
- package/lib/dialogs/symbology/vector_layer/types/SimpleSymbol.d.ts +2 -2
- package/lib/dialogs/symbology/vector_layer/types/SimpleSymbol.js +33 -30
- package/lib/formbuilder/creationform.js +3 -3
- package/lib/formbuilder/editform.js +3 -3
- package/lib/formbuilder/formselectors.d.ts +1 -1
- package/lib/formbuilder/formselectors.js +2 -2
- package/lib/formbuilder/objectform/baseform.d.ts +5 -4
- package/lib/formbuilder/objectform/baseform.js +16 -14
- package/lib/formbuilder/objectform/fileselectorwidget.d.ts +1 -1
- package/lib/formbuilder/objectform/fileselectorwidget.js +5 -5
- package/lib/formbuilder/objectform/layer/heatmapLayerForm.js +2 -2
- package/lib/formbuilder/objectform/layer/hillshadeLayerForm.js +1 -1
- package/lib/formbuilder/objectform/layer/layerform.d.ts +1 -1
- package/lib/formbuilder/objectform/layer/layerform.js +3 -2
- package/lib/formbuilder/objectform/process/dissolveProcessForm.d.ts +1 -1
- package/lib/formbuilder/objectform/process/dissolveProcessForm.js +5 -5
- package/lib/formbuilder/objectform/source/geojsonsource.js +4 -4
- package/lib/formbuilder/objectform/source/geotiffsource.js +4 -4
- package/lib/formbuilder/objectform/source/pathbasedsource.js +6 -6
- package/lib/formbuilder/objectform/source/sourceform.d.ts +1 -1
- package/lib/formbuilder/objectform/source/sourceform.js +1 -1
- package/lib/formbuilder/objectform/source/tilesourceform.js +3 -3
- package/lib/gdal.js +2 -2
- package/lib/icons.js +29 -29
- package/lib/index.d.ts +4 -3
- package/lib/index.js +4 -3
- package/lib/mainview/CollaboratorPointers.d.ts +1 -1
- package/lib/mainview/CollaboratorPointers.js +5 -5
- package/lib/mainview/FollowIndicator.d.ts +2 -2
- package/lib/mainview/FollowIndicator.js +3 -3
- package/lib/mainview/TemporalSlider.d.ts +1 -1
- package/lib/mainview/TemporalSlider.js +7 -7
- package/lib/mainview/mainView.d.ts +4 -2
- package/lib/mainview/mainView.js +232 -137
- package/lib/menus.d.ts +1 -1
- package/lib/menus.js +7 -7
- package/lib/panelview/annotationPanel.d.ts +2 -2
- package/lib/panelview/annotationPanel.js +1 -1
- package/lib/panelview/components/filter-panel/Filter.d.ts +2 -2
- package/lib/panelview/components/filter-panel/Filter.js +5 -5
- package/lib/panelview/components/filter-panel/FilterRow.d.ts +2 -2
- package/lib/panelview/components/identify-panel/IdentifyPanel.d.ts +1 -1
- package/lib/panelview/components/identify-panel/IdentifyPanel.js +5 -5
- package/lib/panelview/components/layers.d.ts +1 -1
- package/lib/panelview/components/layers.js +12 -12
- package/lib/panelview/leftpanel.d.ts +4 -2
- package/lib/panelview/leftpanel.js +24 -6
- package/lib/panelview/model.d.ts +1 -1
- package/lib/panelview/objectproperties.d.ts +1 -1
- package/lib/panelview/objectproperties.js +3 -3
- package/lib/panelview/rightpanel.d.ts +2 -1
- package/lib/panelview/rightpanel.js +13 -5
- package/lib/{processing.d.ts → processing/index.d.ts} +4 -4
- package/lib/{processing.js → processing/index.js} +19 -24
- package/lib/processing/processingCommands.d.ts +6 -0
- package/lib/processing/processingCommands.js +47 -0
- package/lib/processing/processingFormToParam.d.ts +2 -0
- package/lib/processing/processingFormToParam.js +15 -0
- package/lib/shared/components/Badge.d.ts +7 -0
- package/lib/shared/components/Badge.js +19 -0
- package/lib/shared/components/Button.d.ts +9 -0
- package/lib/shared/components/Button.js +20 -0
- package/lib/shared/components/Calendar.d.ts +47 -0
- package/lib/shared/components/Calendar.js +184 -0
- package/lib/shared/components/Checkbox.d.ts +4 -0
- package/lib/shared/components/Checkbox.js +25 -0
- package/lib/shared/components/DropdownMenu.d.ts +27 -0
- package/lib/shared/components/DropdownMenu.js +92 -0
- package/lib/shared/components/Pagination.d.ts +25 -0
- package/lib/shared/components/Pagination.js +68 -0
- package/lib/shared/components/Popover.d.ts +7 -0
- package/lib/shared/components/Popover.js +32 -0
- package/lib/shared/components/Tabs.d.ts +7 -0
- package/lib/shared/components/Tabs.js +31 -0
- package/lib/shared/components/ToggleGroup.d.ts +12 -0
- package/lib/shared/components/ToggleGroup.js +52 -0
- package/lib/shared/components/loading.d.ts +12 -0
- package/lib/shared/components/loading.js +6 -0
- package/lib/shared/components/utils.d.ts +2 -0
- package/lib/shared/components/utils.js +4 -0
- package/lib/shared/hooks/useIsFirstRender.d.ts +2 -0
- package/lib/shared/hooks/useIsFirstRender.js +10 -0
- package/lib/stacBrowser/StacBrowser.d.ts +7 -0
- package/lib/stacBrowser/StacBrowser.js +16 -0
- package/lib/stacBrowser/StacPanel.d.ts +14 -0
- package/lib/stacBrowser/StacPanel.js +16 -0
- package/lib/stacBrowser/components/StacFilterSection.d.ts +23 -0
- package/lib/stacBrowser/components/StacFilterSection.js +49 -0
- package/lib/stacBrowser/components/StacPanelFilters.d.ts +14 -0
- package/lib/stacBrowser/components/StacPanelFilters.js +65 -0
- package/lib/stacBrowser/components/StacPanelResults.d.ts +13 -0
- package/lib/stacBrowser/components/StacPanelResults.js +48 -0
- package/lib/stacBrowser/components/StacPanelView.d.ts +7 -0
- package/lib/stacBrowser/components/StacPanelView.js +20 -0
- package/lib/stacBrowser/constants.d.ts +25 -0
- package/lib/stacBrowser/constants.js +197 -0
- package/lib/stacBrowser/hooks/useStacSearch.d.ts +30 -0
- package/lib/stacBrowser/hooks/useStacSearch.js +221 -0
- package/lib/stacBrowser/index.d.ts +1 -0
- package/lib/stacBrowser/index.js +1 -0
- package/lib/stacBrowser/types/types.d.ts +124 -0
- package/lib/stacBrowser/types/types.js +1 -0
- package/lib/statusbar/StatusBar.d.ts +1 -1
- package/lib/statusbar/StatusBar.js +3 -3
- package/lib/toolbar/index.d.ts +0 -1
- package/lib/toolbar/index.js +0 -1
- package/lib/toolbar/widget.js +15 -15
- package/lib/tools.d.ts +29 -4
- package/lib/tools.js +74 -69
- package/lib/types.d.ts +2 -0
- package/lib/widget.d.ts +1 -1
- package/lib/widget.js +5 -5
- package/package.json +22 -8
- package/style/base.css +26 -0
- package/style/layerBrowser.css +10 -0
- package/style/shared/badge.css +61 -0
- package/style/shared/button.css +164 -0
- package/style/shared/calendar.css +274 -0
- package/style/shared/checkbox.css +28 -0
- package/style/shared/dropdownMenu.css +240 -0
- package/style/shared/pagination.css +167 -0
- package/style/shared/popover.css +53 -0
- package/style/shared/tabs.css +57 -0
- package/style/shared/toggle.css +85 -0
- package/style/stacBrowser.css +74 -0
- package/style/symbologyDialog.css +0 -7
- package/lib/mainview/spinner.d.ts +0 -6
- package/lib/mainview/spinner.js +0 -5
- package/lib/toolbar/usertoolbaritem.d.ts +0 -19
- package/lib/toolbar/usertoolbaritem.js +0 -59
package/lib/mainview/mainView.js
CHANGED
|
@@ -1,66 +1,78 @@
|
|
|
1
|
-
import { JupyterGISModel } from '@jupytergis/schema';
|
|
1
|
+
import { JupyterGISModel, } from '@jupytergis/schema';
|
|
2
2
|
import { showErrorMessage } from '@jupyterlab/apputils';
|
|
3
3
|
import { CommandRegistry } from '@lumino/commands';
|
|
4
4
|
import { UUID } from '@lumino/coreutils';
|
|
5
5
|
import { ContextMenu } from '@lumino/widgets';
|
|
6
6
|
import { Collection, Map as OlMap, View, getUid } from 'ol';
|
|
7
|
-
//@ts-expect-error no types for ol-pmtiles
|
|
8
|
-
import { PMTilesRasterSource, PMTilesVectorSource } from 'ol-pmtiles';
|
|
9
7
|
import Feature from 'ol/Feature';
|
|
10
|
-
import { ScaleLine } from 'ol/control';
|
|
8
|
+
import { FullScreen, ScaleLine } from 'ol/control';
|
|
11
9
|
import { singleClick } from 'ol/events/condition';
|
|
12
10
|
import { GeoJSON, MVT } from 'ol/format';
|
|
11
|
+
import { Point } from 'ol/geom';
|
|
13
12
|
import { DragAndDrop, Select } from 'ol/interaction';
|
|
14
|
-
import { Heatmap as HeatmapLayer, Image as ImageLayer, Vector as VectorLayer, VectorTile as VectorTileLayer, WebGLTile as WebGlTileLayer } from 'ol/layer';
|
|
13
|
+
import { Heatmap as HeatmapLayer, Image as ImageLayer, Layer, Vector as VectorLayer, VectorTile as VectorTileLayer, WebGLTile as WebGlTileLayer, } from 'ol/layer';
|
|
15
14
|
import TileLayer from 'ol/layer/Tile';
|
|
16
|
-
import { fromLonLat, get as
|
|
17
|
-
import { get as getProjection } from 'ol/proj.js';
|
|
15
|
+
import { fromLonLat, get as getProjection, toLonLat, transformExtent, } from 'ol/proj';
|
|
18
16
|
import { register } from 'ol/proj/proj4.js';
|
|
19
17
|
import RenderFeature from 'ol/render/Feature';
|
|
20
|
-
import { GeoTIFF as GeoTIFFSource, ImageTile as ImageTileSource, Vector as VectorSource, VectorTile as VectorTileSource, XYZ as XYZSource } from 'ol/source';
|
|
18
|
+
import { GeoTIFF as GeoTIFFSource, ImageTile as ImageTileSource, Vector as VectorSource, VectorTile as VectorTileSource, XYZ as XYZSource, } from 'ol/source';
|
|
21
19
|
import Static from 'ol/source/ImageStatic';
|
|
22
20
|
import TileSource from 'ol/source/Tile';
|
|
23
21
|
import { Circle, Fill, Stroke, Style } from 'ol/style';
|
|
22
|
+
//@ts-expect-error no types for ol-pmtiles
|
|
23
|
+
import { PMTilesRasterSource, PMTilesVectorSource } from 'ol-pmtiles';
|
|
24
|
+
import StacLayer from 'ol-stac';
|
|
24
25
|
import proj4 from 'proj4';
|
|
25
26
|
import proj4list from 'proj4-list';
|
|
26
27
|
import * as React from 'react';
|
|
27
|
-
import AnnotationFloater from
|
|
28
|
-
import { CommandIDs } from
|
|
29
|
-
import
|
|
30
|
-
import
|
|
28
|
+
import AnnotationFloater from "../annotations/components/AnnotationFloater";
|
|
29
|
+
import { CommandIDs } from "../constants";
|
|
30
|
+
import { LoadingOverlay } from "../shared/components/loading";
|
|
31
|
+
import StatusBar from "../statusbar/StatusBar";
|
|
32
|
+
import { debounce, isLightTheme, loadFile, throttle } from "../tools";
|
|
31
33
|
import CollaboratorPointers from './CollaboratorPointers';
|
|
32
34
|
import { FollowIndicator } from './FollowIndicator';
|
|
33
35
|
import TemporalSlider from './TemporalSlider';
|
|
34
|
-
import { Spinner } from './spinner';
|
|
35
|
-
import { Point } from 'ol/geom';
|
|
36
36
|
export class MainView extends React.Component {
|
|
37
37
|
constructor(props) {
|
|
38
38
|
super(props);
|
|
39
|
+
this.updateCenter = () => {
|
|
40
|
+
const extentIn4326 = this.getViewBbox();
|
|
41
|
+
this._model.updateBboxSignal.emit(extentIn4326);
|
|
42
|
+
};
|
|
43
|
+
this.getViewBbox = (targetProjection = 'EPSG:4326') => {
|
|
44
|
+
const view = this._Map.getView();
|
|
45
|
+
const extent = view.calculateExtent(this._Map.getSize());
|
|
46
|
+
if (view.getProjection().getCode() === targetProjection) {
|
|
47
|
+
return extent;
|
|
48
|
+
}
|
|
49
|
+
return transformExtent(extent, view.getProjection(), targetProjection);
|
|
50
|
+
};
|
|
39
51
|
this.createSelectInteraction = () => {
|
|
40
52
|
const pointStyle = new Style({
|
|
41
53
|
image: new Circle({
|
|
42
54
|
radius: 5,
|
|
43
55
|
fill: new Fill({
|
|
44
|
-
color: '#C52707'
|
|
56
|
+
color: '#C52707',
|
|
45
57
|
}),
|
|
46
58
|
stroke: new Stroke({
|
|
47
59
|
color: '#171717',
|
|
48
|
-
width: 2
|
|
49
|
-
})
|
|
50
|
-
})
|
|
60
|
+
width: 2,
|
|
61
|
+
}),
|
|
62
|
+
}),
|
|
51
63
|
});
|
|
52
64
|
const lineStyle = new Style({
|
|
53
65
|
stroke: new Stroke({
|
|
54
66
|
color: '#171717',
|
|
55
|
-
width: 2
|
|
56
|
-
})
|
|
67
|
+
width: 2,
|
|
68
|
+
}),
|
|
57
69
|
});
|
|
58
70
|
const polygonStyle = new Style({
|
|
59
71
|
fill: new Fill({ color: '#C5270780' }),
|
|
60
72
|
stroke: new Stroke({
|
|
61
73
|
color: '#171717',
|
|
62
|
-
width: 2
|
|
63
|
-
})
|
|
74
|
+
width: 2,
|
|
75
|
+
}),
|
|
64
76
|
});
|
|
65
77
|
const styleFunction = (feature) => {
|
|
66
78
|
var _a;
|
|
@@ -93,7 +105,7 @@ export class MainView extends React.Component {
|
|
|
93
105
|
condition: (event) => {
|
|
94
106
|
return singleClick(event) && this._model.isIdentifying;
|
|
95
107
|
},
|
|
96
|
-
style: styleFunction
|
|
108
|
+
style: styleFunction,
|
|
97
109
|
});
|
|
98
110
|
selectInteraction.on('select', event => {
|
|
99
111
|
const identifiedFeatures = [];
|
|
@@ -112,23 +124,26 @@ export class MainView extends React.Component {
|
|
|
112
124
|
return;
|
|
113
125
|
}
|
|
114
126
|
this._mainViewModel.addAnnotation({
|
|
115
|
-
position: {
|
|
127
|
+
position: {
|
|
128
|
+
x: this._clickCoords[0],
|
|
129
|
+
y: this._clickCoords[1],
|
|
130
|
+
},
|
|
116
131
|
zoom: (_a = this._Map.getView().getZoom()) !== null && _a !== void 0 ? _a : 0,
|
|
117
132
|
label: 'New annotation',
|
|
118
133
|
contents: [],
|
|
119
134
|
parent: this._Map.getViewport().id,
|
|
120
|
-
open: true
|
|
135
|
+
open: true,
|
|
121
136
|
});
|
|
122
137
|
},
|
|
123
138
|
label: 'Add annotation',
|
|
124
139
|
isEnabled: () => {
|
|
125
140
|
return !!this._Map;
|
|
126
|
-
}
|
|
141
|
+
},
|
|
127
142
|
});
|
|
128
143
|
this._contextMenu.addItem({
|
|
129
144
|
command: CommandIDs.addAnnotation,
|
|
130
145
|
selector: '.ol-viewport',
|
|
131
|
-
rank: 1
|
|
146
|
+
rank: 1,
|
|
132
147
|
});
|
|
133
148
|
};
|
|
134
149
|
this.vectorLayerStyleRuleBuilder = (layer) => {
|
|
@@ -144,10 +159,10 @@ export class MainView extends React.Component {
|
|
|
144
159
|
'circle-radius': 5,
|
|
145
160
|
'circle-fill-color': 'rgba(255,255,255,0.4)',
|
|
146
161
|
'circle-stroke-width': 1.25,
|
|
147
|
-
'circle-stroke-color': '#3399CC'
|
|
162
|
+
'circle-stroke-color': '#3399CC',
|
|
148
163
|
};
|
|
149
164
|
const defaultRules = {
|
|
150
|
-
style: defaultStyle
|
|
165
|
+
style: defaultStyle,
|
|
151
166
|
};
|
|
152
167
|
const layerStyle = Object.assign({}, defaultRules);
|
|
153
168
|
if (((_a = layer.filters) === null || _a === void 0 ? void 0 : _a.logicalOp) && ((_b = layer.filters.appliedFilters) === null || _b === void 0 ? void 0 : _b.length) > 0) {
|
|
@@ -167,7 +182,7 @@ export class MainView extends React.Component {
|
|
|
167
182
|
// Arguments for "Any" and 'All' need to be wrapped in brackets
|
|
168
183
|
filterExpr = [
|
|
169
184
|
layer.filters.logicalOp,
|
|
170
|
-
...layer.filters.appliedFilters.map(buildCondition)
|
|
185
|
+
...layer.filters.appliedFilters.map(buildCondition),
|
|
171
186
|
];
|
|
172
187
|
}
|
|
173
188
|
layerStyle.filter = filterExpr;
|
|
@@ -202,7 +217,7 @@ export class MainView extends React.Component {
|
|
|
202
217
|
['*', 255 * 256, red],
|
|
203
218
|
['*', 255, green],
|
|
204
219
|
['*', 255 / 256, blue],
|
|
205
|
-
-32768
|
|
220
|
+
-32768,
|
|
206
221
|
];
|
|
207
222
|
}
|
|
208
223
|
// Generates a shaded relief image given elevation data. Uses a 3x3
|
|
@@ -221,7 +236,7 @@ export class MainView extends React.Component {
|
|
|
221
236
|
const cosIncidence = [
|
|
222
237
|
'+',
|
|
223
238
|
['*', ['sin', sunEl], ['cos', slope]],
|
|
224
|
-
['*', ['cos', sunEl], ['sin', slope], ['cos', ['-', sunAz, aspect]]]
|
|
239
|
+
['*', ['cos', sunEl], ['sin', slope], ['cos', ['-', sunAz, aspect]]],
|
|
225
240
|
];
|
|
226
241
|
const scaled = ['*', 255, cosIncidence];
|
|
227
242
|
return scaled;
|
|
@@ -319,7 +334,7 @@ export class MainView extends React.Component {
|
|
|
319
334
|
if (pointer) {
|
|
320
335
|
const pixel = this._Map.getPixelFromCoordinate([
|
|
321
336
|
pointer.coordinates.x,
|
|
322
|
-
pointer.coordinates.y
|
|
337
|
+
pointer.coordinates.y,
|
|
323
338
|
]);
|
|
324
339
|
const lonLat = toLonLat([pointer.coordinates.x, pointer.coordinates.y]);
|
|
325
340
|
if (!currentClientPointer) {
|
|
@@ -327,12 +342,24 @@ export class MainView extends React.Component {
|
|
|
327
342
|
username: client.user.username,
|
|
328
343
|
displayName: client.user.display_name,
|
|
329
344
|
color: client.user.color,
|
|
330
|
-
coordinates: {
|
|
331
|
-
|
|
345
|
+
coordinates: {
|
|
346
|
+
x: pixel[0],
|
|
347
|
+
y: pixel[1],
|
|
348
|
+
},
|
|
349
|
+
lonLat: {
|
|
350
|
+
longitude: lonLat[0],
|
|
351
|
+
latitude: lonLat[1],
|
|
352
|
+
},
|
|
332
353
|
};
|
|
333
354
|
}
|
|
334
355
|
else {
|
|
335
|
-
currentClientPointer = Object.assign(Object.assign({}, currentClientPointer), { coordinates: {
|
|
356
|
+
currentClientPointer = Object.assign(Object.assign({}, currentClientPointer), { coordinates: {
|
|
357
|
+
x: pixel[0],
|
|
358
|
+
y: pixel[1],
|
|
359
|
+
}, lonLat: {
|
|
360
|
+
longitude: lonLat[0],
|
|
361
|
+
latitude: lonLat[1],
|
|
362
|
+
} });
|
|
336
363
|
}
|
|
337
364
|
clientPointers[clientId] = currentClientPointer;
|
|
338
365
|
}
|
|
@@ -373,24 +400,31 @@ export class MainView extends React.Component {
|
|
|
373
400
|
return;
|
|
374
401
|
}
|
|
375
402
|
const data = this._model.sharedModel.getMetadata(key);
|
|
376
|
-
let open = true;
|
|
377
|
-
if (this.state.firstLoad) {
|
|
378
|
-
open = false;
|
|
379
|
-
}
|
|
380
403
|
if (data && (val.action === 'add' || val.action === 'update')) {
|
|
381
|
-
|
|
382
|
-
|
|
404
|
+
let jsonData;
|
|
405
|
+
if (typeof data === 'string') {
|
|
406
|
+
try {
|
|
407
|
+
jsonData = JSON.parse(data);
|
|
408
|
+
}
|
|
409
|
+
catch (e) {
|
|
410
|
+
console.warn(`Failed to parse annotation data for ${key}:`, e);
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
jsonData = data;
|
|
416
|
+
}
|
|
383
417
|
newState[key] = jsonData;
|
|
384
418
|
}
|
|
385
419
|
else if (val.action === 'delete') {
|
|
386
420
|
delete newState[key];
|
|
387
421
|
}
|
|
388
422
|
});
|
|
389
|
-
this.setState(old => (Object.assign(Object.assign({}, old), { annotations: newState
|
|
423
|
+
this.setState(old => (Object.assign(Object.assign({}, old), { annotations: newState })));
|
|
390
424
|
};
|
|
391
425
|
this._syncPointer = throttle((coordinates) => {
|
|
392
426
|
const pointer = {
|
|
393
|
-
coordinates: { x: coordinates[0], y: coordinates[1] }
|
|
427
|
+
coordinates: { x: coordinates[0], y: coordinates[1] },
|
|
394
428
|
};
|
|
395
429
|
this._model.syncPointer(pointer);
|
|
396
430
|
});
|
|
@@ -407,6 +441,25 @@ export class MainView extends React.Component {
|
|
|
407
441
|
this._ready = false;
|
|
408
442
|
this._sourceToLayerMap = new Map();
|
|
409
443
|
this._originalFeatures = {};
|
|
444
|
+
// Enforce the map to take the full available width in the case of Jupyter Notebook viewer
|
|
445
|
+
const el = document.getElementById('main-panel');
|
|
446
|
+
if (el) {
|
|
447
|
+
const setWidthOneHundred = (selector) => {
|
|
448
|
+
document.querySelector(selector).style.setProperty('width', '100%');
|
|
449
|
+
};
|
|
450
|
+
//We need to observe the size to counteract
|
|
451
|
+
//What the default jupyter plugin will try
|
|
452
|
+
//To do dynamically with the width
|
|
453
|
+
const resizeObserver = new ResizeObserver(_ => {
|
|
454
|
+
el.style.setProperty('width', '100%');
|
|
455
|
+
el.style.setProperty('max-width', '100%');
|
|
456
|
+
el === null || el === void 0 ? void 0 : el.style.setProperty('left', '0px');
|
|
457
|
+
setWidthOneHundred('#main-panel jp-toolbar');
|
|
458
|
+
setWidthOneHundred('#main-panel .lm-SplitPanel ');
|
|
459
|
+
setWidthOneHundred('#main-panel .lm-SplitPanel .lm-SplitPanel-child ');
|
|
460
|
+
});
|
|
461
|
+
resizeObserver.observe(el);
|
|
462
|
+
}
|
|
410
463
|
this._mainViewModel = this.props.viewModel;
|
|
411
464
|
this._mainViewModel.viewSettingChanged.connect(this._onViewChanged, this);
|
|
412
465
|
this._model = this._mainViewModel.jGISModel;
|
|
@@ -436,7 +489,6 @@ export class MainView extends React.Component {
|
|
|
436
489
|
id: this._mainViewModel.id,
|
|
437
490
|
lightTheme: isLightTheme(),
|
|
438
491
|
loading: true,
|
|
439
|
-
firstLoad: true,
|
|
440
492
|
annotations: {},
|
|
441
493
|
clientPointers: {},
|
|
442
494
|
viewProjection: { code: '', units: '' },
|
|
@@ -444,12 +496,15 @@ export class MainView extends React.Component {
|
|
|
444
496
|
scale: 0,
|
|
445
497
|
loadingErrors: [],
|
|
446
498
|
displayTemporalController: false,
|
|
447
|
-
filterStates: {}
|
|
499
|
+
filterStates: {},
|
|
448
500
|
};
|
|
449
501
|
this._sources = [];
|
|
450
502
|
this._loadingLayers = new Set();
|
|
451
503
|
this._commands = new CommandRegistry();
|
|
452
|
-
this._contextMenu = new ContextMenu({
|
|
504
|
+
this._contextMenu = new ContextMenu({
|
|
505
|
+
commands: this._commands,
|
|
506
|
+
});
|
|
507
|
+
this._updateCenter = debounce(this.updateCenter, 100);
|
|
453
508
|
}
|
|
454
509
|
async componentDidMount() {
|
|
455
510
|
window.addEventListener('resize', this._handleWindowResize);
|
|
@@ -458,7 +513,7 @@ export class MainView extends React.Component {
|
|
|
458
513
|
? fromLonLat([options.longitude, options.latitude])
|
|
459
514
|
: [0, 0];
|
|
460
515
|
const zoom = options.zoom !== undefined ? options.zoom : 1;
|
|
461
|
-
await this.
|
|
516
|
+
await this.generateMap(center, zoom);
|
|
462
517
|
this.addContextMenu();
|
|
463
518
|
this._mainViewModel.initSignal();
|
|
464
519
|
if (window.jupytergisMaps !== undefined && this._documentPath) {
|
|
@@ -476,27 +531,27 @@ export class MainView extends React.Component {
|
|
|
476
531
|
this._model.clientStateChanged.disconnect(this._onClientSharedStateChanged, this);
|
|
477
532
|
this._mainViewModel.dispose();
|
|
478
533
|
}
|
|
479
|
-
async
|
|
534
|
+
async generateMap(center, zoom) {
|
|
480
535
|
if (this.divRef.current) {
|
|
481
536
|
this._Map = new OlMap({
|
|
482
537
|
target: this.divRef.current,
|
|
483
538
|
layers: [],
|
|
484
539
|
view: new View({
|
|
485
540
|
center,
|
|
486
|
-
zoom
|
|
541
|
+
zoom,
|
|
487
542
|
}),
|
|
488
|
-
controls: [new ScaleLine()]
|
|
543
|
+
controls: [new ScaleLine(), new FullScreen()],
|
|
489
544
|
});
|
|
490
545
|
// Add map interactions
|
|
491
546
|
const dragAndDropInteraction = new DragAndDrop({
|
|
492
|
-
formatConstructors: [GeoJSON]
|
|
547
|
+
formatConstructors: [GeoJSON],
|
|
493
548
|
});
|
|
494
549
|
dragAndDropInteraction.on('addfeatures', event => {
|
|
495
550
|
const sourceId = UUID.uuid4();
|
|
496
551
|
const sourceModel = {
|
|
497
552
|
type: 'GeoJSONSource',
|
|
498
553
|
name: 'Drag and Drop source',
|
|
499
|
-
parameters: { path: event.file.name }
|
|
554
|
+
parameters: { path: event.file.name },
|
|
500
555
|
};
|
|
501
556
|
const layerId = UUID.uuid4();
|
|
502
557
|
this.addSource(sourceId, sourceModel);
|
|
@@ -509,8 +564,8 @@ export class MainView extends React.Component {
|
|
|
509
564
|
color: '#FF0000',
|
|
510
565
|
opacity: 1.0,
|
|
511
566
|
type: 'line',
|
|
512
|
-
source: sourceId
|
|
513
|
-
}
|
|
567
|
+
source: sourceId,
|
|
568
|
+
},
|
|
514
569
|
};
|
|
515
570
|
this.addLayer(layerId, layerModel, this.getLayerIDs().length);
|
|
516
571
|
this._model.addLayer(layerId, layerModel);
|
|
@@ -518,6 +573,7 @@ export class MainView extends React.Component {
|
|
|
518
573
|
this._Map.addInteraction(dragAndDropInteraction);
|
|
519
574
|
this.createSelectInteraction();
|
|
520
575
|
const view = this._Map.getView();
|
|
576
|
+
view.on('change:center', () => this._updateCenter());
|
|
521
577
|
// TODO: Note for the future, will need to update listeners if view changes
|
|
522
578
|
view.on('change:center', throttle(() => {
|
|
523
579
|
var _a;
|
|
@@ -531,7 +587,13 @@ export class MainView extends React.Component {
|
|
|
531
587
|
if (!center || !zoom) {
|
|
532
588
|
return;
|
|
533
589
|
}
|
|
534
|
-
this._model.syncViewport({
|
|
590
|
+
this._model.syncViewport({
|
|
591
|
+
coordinates: {
|
|
592
|
+
x: center[0],
|
|
593
|
+
y: center[1],
|
|
594
|
+
},
|
|
595
|
+
zoom,
|
|
596
|
+
}, this._mainViewModel.id);
|
|
535
597
|
}));
|
|
536
598
|
this._Map.on('postrender', () => {
|
|
537
599
|
if (this.state.annotations) {
|
|
@@ -552,7 +614,7 @@ export class MainView extends React.Component {
|
|
|
552
614
|
longitude: latLng[0],
|
|
553
615
|
bearing,
|
|
554
616
|
projection: projection.getCode(),
|
|
555
|
-
zoom
|
|
617
|
+
zoom,
|
|
556
618
|
};
|
|
557
619
|
updatedOptions.extent = view.calculateExtent();
|
|
558
620
|
this._model.setOptions(Object.assign(Object.assign({}, currentOptions), updatedOptions));
|
|
@@ -583,7 +645,7 @@ export class MainView extends React.Component {
|
|
|
583
645
|
});
|
|
584
646
|
this.setState(old => (Object.assign(Object.assign({}, old), { loading: false, viewProjection: {
|
|
585
647
|
code: view.getProjection().getCode(),
|
|
586
|
-
units: view.getProjection().getUnits()
|
|
648
|
+
units: view.getProjection().getUnits(),
|
|
587
649
|
} })));
|
|
588
650
|
}
|
|
589
651
|
}
|
|
@@ -608,7 +670,7 @@ export class MainView extends React.Component {
|
|
|
608
670
|
minZoom: sourceParameters.minZoom,
|
|
609
671
|
maxZoom: sourceParameters.maxZoom,
|
|
610
672
|
tileSize: 256,
|
|
611
|
-
url: url
|
|
673
|
+
url: url,
|
|
612
674
|
});
|
|
613
675
|
}
|
|
614
676
|
else {
|
|
@@ -616,7 +678,7 @@ export class MainView extends React.Component {
|
|
|
616
678
|
interpolate: sourceParameters.interpolate,
|
|
617
679
|
attributions: sourceParameters.attribution,
|
|
618
680
|
tileSize: 256,
|
|
619
|
-
url: url
|
|
681
|
+
url: url,
|
|
620
682
|
});
|
|
621
683
|
}
|
|
622
684
|
break;
|
|
@@ -626,7 +688,7 @@ export class MainView extends React.Component {
|
|
|
626
688
|
newSource = new ImageTileSource({
|
|
627
689
|
interpolate: sourceParameters.interpolate,
|
|
628
690
|
url: this.computeSourceUrl(source),
|
|
629
|
-
attributions: sourceParameters.attribution
|
|
691
|
+
attributions: sourceParameters.attribution,
|
|
630
692
|
});
|
|
631
693
|
break;
|
|
632
694
|
}
|
|
@@ -640,13 +702,15 @@ export class MainView extends React.Component {
|
|
|
640
702
|
minZoom: sourceParameters.minZoom,
|
|
641
703
|
maxZoom: sourceParameters.maxZoom,
|
|
642
704
|
url: url,
|
|
643
|
-
format: new MVT({
|
|
705
|
+
format: new MVT({
|
|
706
|
+
featureClass: RenderFeature,
|
|
707
|
+
}),
|
|
644
708
|
});
|
|
645
709
|
}
|
|
646
710
|
else {
|
|
647
711
|
newSource = new PMTilesVectorSource({
|
|
648
712
|
attributions: sourceParameters.attribution,
|
|
649
|
-
url: url
|
|
713
|
+
url: url,
|
|
650
714
|
});
|
|
651
715
|
}
|
|
652
716
|
break;
|
|
@@ -656,22 +720,22 @@ export class MainView extends React.Component {
|
|
|
656
720
|
(await loadFile({
|
|
657
721
|
filepath: (_b = source.parameters) === null || _b === void 0 ? void 0 : _b.path,
|
|
658
722
|
type: 'GeoJSONSource',
|
|
659
|
-
model: this._model
|
|
723
|
+
model: this._model,
|
|
660
724
|
}));
|
|
661
725
|
const format = new GeoJSON({
|
|
662
|
-
featureProjection: this._Map.getView().getProjection()
|
|
726
|
+
featureProjection: this._Map.getView().getProjection(),
|
|
663
727
|
});
|
|
664
728
|
// TODO: Don't hardcode projection
|
|
665
729
|
const featureArray = format.readFeatures(data, {
|
|
666
730
|
dataProjection: 'EPSG:4326',
|
|
667
|
-
featureProjection: this._Map.getView().getProjection()
|
|
731
|
+
featureProjection: this._Map.getView().getProjection(),
|
|
668
732
|
});
|
|
669
733
|
const featureCollection = new Collection(featureArray);
|
|
670
734
|
featureCollection.forEach(feature => {
|
|
671
735
|
feature.setId(getUid(feature));
|
|
672
736
|
});
|
|
673
737
|
newSource = new VectorSource({
|
|
674
|
-
features: featureCollection
|
|
738
|
+
features: featureCollection,
|
|
675
739
|
});
|
|
676
740
|
break;
|
|
677
741
|
}
|
|
@@ -680,15 +744,15 @@ export class MainView extends React.Component {
|
|
|
680
744
|
const geojson = await loadFile({
|
|
681
745
|
filepath: parameters.path,
|
|
682
746
|
type: 'ShapefileSource',
|
|
683
|
-
model: this._model
|
|
747
|
+
model: this._model,
|
|
684
748
|
});
|
|
685
749
|
const geojsonData = Array.isArray(geojson) ? geojson[0] : geojson;
|
|
686
750
|
const format = new GeoJSON();
|
|
687
751
|
newSource = new VectorSource({
|
|
688
752
|
features: format.readFeatures(geojsonData, {
|
|
689
753
|
dataProjection: 'EPSG:4326',
|
|
690
|
-
featureProjection: this._Map.getView().getProjection()
|
|
691
|
-
})
|
|
754
|
+
featureProjection: this._Map.getView().getProjection(),
|
|
755
|
+
}),
|
|
692
756
|
});
|
|
693
757
|
break;
|
|
694
758
|
}
|
|
@@ -712,13 +776,13 @@ export class MainView extends React.Component {
|
|
|
712
776
|
const imageUrl = await loadFile({
|
|
713
777
|
filepath: sourceParameters.path,
|
|
714
778
|
type: 'ImageSource',
|
|
715
|
-
model: this._model
|
|
779
|
+
model: this._model,
|
|
716
780
|
});
|
|
717
781
|
newSource = new Static({
|
|
718
782
|
interpolate: sourceParameters.interpolate,
|
|
719
783
|
imageExtent: extent,
|
|
720
784
|
url: imageUrl,
|
|
721
|
-
crossOrigin: ''
|
|
785
|
+
crossOrigin: '',
|
|
722
786
|
});
|
|
723
787
|
break;
|
|
724
788
|
}
|
|
@@ -742,7 +806,7 @@ export class MainView extends React.Component {
|
|
|
742
806
|
const geotiff = await loadFile({
|
|
743
807
|
filepath: (_c = sourceInfo.url) !== null && _c !== void 0 ? _c : '',
|
|
744
808
|
type: 'GeoTiffSource',
|
|
745
|
-
model: this._model
|
|
809
|
+
model: this._model,
|
|
746
810
|
});
|
|
747
811
|
return Object.assign(Object.assign({}, addNoData(sourceInfo)), { min: sourceInfo.min, max: sourceInfo.max, geotiff, url: URL.createObjectURL(geotiff.file) });
|
|
748
812
|
}
|
|
@@ -751,7 +815,7 @@ export class MainView extends React.Component {
|
|
|
751
815
|
interpolate: sourceParameters.interpolate,
|
|
752
816
|
sources,
|
|
753
817
|
normalize: sourceParameters.normalize,
|
|
754
|
-
wrapX: sourceParameters.wrapX
|
|
818
|
+
wrapX: sourceParameters.wrapX,
|
|
755
819
|
});
|
|
756
820
|
break;
|
|
757
821
|
}
|
|
@@ -863,19 +927,25 @@ export class MainView extends React.Component {
|
|
|
863
927
|
*/
|
|
864
928
|
async _buildMapLayer(id, layer) {
|
|
865
929
|
var _a, _b, _c;
|
|
866
|
-
const sourceId = (_a = layer.parameters) === null || _a === void 0 ? void 0 : _a.source;
|
|
867
|
-
const source = this._model.sharedModel.getLayerSource(sourceId);
|
|
868
|
-
if (!source) {
|
|
869
|
-
return;
|
|
870
|
-
}
|
|
871
930
|
this.setState(old => (Object.assign(Object.assign({}, old), { loadingLayer: true })));
|
|
872
931
|
this._loadingLayers.add(id);
|
|
873
|
-
if (!this._sources[sourceId]) {
|
|
874
|
-
await this.addSource(sourceId, source);
|
|
875
|
-
}
|
|
876
|
-
this._loadingLayers.add(id);
|
|
877
932
|
let newMapLayer;
|
|
878
933
|
let layerParameters;
|
|
934
|
+
let sourceId;
|
|
935
|
+
let source;
|
|
936
|
+
if (layer.type !== 'StacLayer') {
|
|
937
|
+
sourceId = (_a = layer.parameters) === null || _a === void 0 ? void 0 : _a.source;
|
|
938
|
+
if (!sourceId) {
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
source = this._model.sharedModel.getLayerSource(sourceId);
|
|
942
|
+
if (!source) {
|
|
943
|
+
return;
|
|
944
|
+
}
|
|
945
|
+
if (!this._sources[sourceId]) {
|
|
946
|
+
await this.addSource(sourceId, source);
|
|
947
|
+
}
|
|
948
|
+
}
|
|
879
949
|
// TODO: OpenLayers provides a bunch of sources for specific tile
|
|
880
950
|
// providers, so maybe set up some way to use those
|
|
881
951
|
switch (layer.type) {
|
|
@@ -884,7 +954,7 @@ export class MainView extends React.Component {
|
|
|
884
954
|
newMapLayer = new TileLayer({
|
|
885
955
|
opacity: layerParameters.opacity,
|
|
886
956
|
visible: layer.visible,
|
|
887
|
-
source: this._sources[layerParameters.source]
|
|
957
|
+
source: this._sources[layerParameters.source],
|
|
888
958
|
});
|
|
889
959
|
break;
|
|
890
960
|
}
|
|
@@ -894,7 +964,7 @@ export class MainView extends React.Component {
|
|
|
894
964
|
opacity: layerParameters.opacity,
|
|
895
965
|
visible: layer.visible,
|
|
896
966
|
source: this._sources[layerParameters.source],
|
|
897
|
-
style: this.vectorLayerStyleRuleBuilder(layer)
|
|
967
|
+
style: this.vectorLayerStyleRuleBuilder(layer),
|
|
898
968
|
});
|
|
899
969
|
break;
|
|
900
970
|
}
|
|
@@ -902,7 +972,8 @@ export class MainView extends React.Component {
|
|
|
902
972
|
layerParameters = layer.parameters;
|
|
903
973
|
newMapLayer = new VectorTileLayer({
|
|
904
974
|
opacity: layerParameters.opacity,
|
|
905
|
-
source: this._sources[layerParameters.source]
|
|
975
|
+
source: this._sources[layerParameters.source],
|
|
976
|
+
style: this.vectorLayerStyleRuleBuilder(layer),
|
|
906
977
|
});
|
|
907
978
|
break;
|
|
908
979
|
}
|
|
@@ -912,8 +983,8 @@ export class MainView extends React.Component {
|
|
|
912
983
|
opacity: 0.3,
|
|
913
984
|
source: this._sources[layerParameters.source],
|
|
914
985
|
style: {
|
|
915
|
-
color: ['color', this.hillshadeMath()]
|
|
916
|
-
}
|
|
986
|
+
color: ['color', this.hillshadeMath()],
|
|
987
|
+
},
|
|
917
988
|
});
|
|
918
989
|
break;
|
|
919
990
|
}
|
|
@@ -921,7 +992,7 @@ export class MainView extends React.Component {
|
|
|
921
992
|
layerParameters = layer.parameters;
|
|
922
993
|
newMapLayer = new ImageLayer({
|
|
923
994
|
opacity: layerParameters.opacity,
|
|
924
|
-
source: this._sources[layerParameters.source]
|
|
995
|
+
source: this._sources[layerParameters.source],
|
|
925
996
|
});
|
|
926
997
|
break;
|
|
927
998
|
}
|
|
@@ -930,10 +1001,12 @@ export class MainView extends React.Component {
|
|
|
930
1001
|
// This is to handle python sending a None for the color
|
|
931
1002
|
const layerOptions = {
|
|
932
1003
|
opacity: layerParameters.opacity,
|
|
933
|
-
source: this._sources[layerParameters.source]
|
|
1004
|
+
source: this._sources[layerParameters.source],
|
|
934
1005
|
};
|
|
935
1006
|
if (layerParameters.color) {
|
|
936
|
-
layerOptions['style'] = {
|
|
1007
|
+
layerOptions['style'] = {
|
|
1008
|
+
color: layerParameters.color,
|
|
1009
|
+
};
|
|
937
1010
|
}
|
|
938
1011
|
newMapLayer = new WebGlTileLayer(layerOptions);
|
|
939
1012
|
break;
|
|
@@ -945,17 +1018,36 @@ export class MainView extends React.Component {
|
|
|
945
1018
|
source: this._sources[layerParameters.source],
|
|
946
1019
|
blur: (_b = layerParameters.blur) !== null && _b !== void 0 ? _b : 15,
|
|
947
1020
|
radius: (_c = layerParameters.radius) !== null && _c !== void 0 ? _c : 8,
|
|
948
|
-
gradient: layerParameters.color
|
|
1021
|
+
gradient: layerParameters.color,
|
|
1022
|
+
});
|
|
1023
|
+
break;
|
|
1024
|
+
}
|
|
1025
|
+
case 'StacLayer': {
|
|
1026
|
+
layerParameters = layer.parameters;
|
|
1027
|
+
newMapLayer = new StacLayer({
|
|
1028
|
+
displayPreview: true,
|
|
1029
|
+
data: layerParameters.data,
|
|
1030
|
+
opacity: layerParameters.opacity,
|
|
1031
|
+
visible: layer.visible,
|
|
1032
|
+
assets: Object.keys(layerParameters.data.assets),
|
|
1033
|
+
extent: layerParameters.data.bbox,
|
|
949
1034
|
});
|
|
1035
|
+
this.setState(old => (Object.assign(Object.assign({}, old), { metadata: layerParameters.data.properties })));
|
|
950
1036
|
break;
|
|
951
1037
|
}
|
|
952
1038
|
}
|
|
953
|
-
await this._waitForSourceReady(newMapLayer);
|
|
954
1039
|
// OpenLayers doesn't have name/id field so add it
|
|
955
1040
|
newMapLayer.set('id', id);
|
|
956
|
-
//
|
|
957
|
-
|
|
958
|
-
|
|
1041
|
+
// STAC layers don't have source
|
|
1042
|
+
if (newMapLayer instanceof Layer) {
|
|
1043
|
+
// we need to keep track of which source has which layers
|
|
1044
|
+
// Only set sourceToLayerMap if 'source' exists on layerParameters
|
|
1045
|
+
if ('source' in layerParameters) {
|
|
1046
|
+
this._sourceToLayerMap.set(layerParameters.source, id);
|
|
1047
|
+
}
|
|
1048
|
+
this.addProjection(newMapLayer);
|
|
1049
|
+
await this._waitForSourceReady(newMapLayer);
|
|
1050
|
+
}
|
|
959
1051
|
this._loadingLayers.delete(id);
|
|
960
1052
|
return newMapLayer;
|
|
961
1053
|
}
|
|
@@ -967,7 +1059,7 @@ export class MainView extends React.Component {
|
|
|
967
1059
|
return;
|
|
968
1060
|
}
|
|
969
1061
|
const projectionCode = sourceProjection.getCode();
|
|
970
|
-
const isProjectionRegistered =
|
|
1062
|
+
const isProjectionRegistered = getProjection(projectionCode);
|
|
971
1063
|
if (!isProjectionRegistered) {
|
|
972
1064
|
// Check if the projection exists in proj4list
|
|
973
1065
|
if (!proj4list[projectionCode]) {
|
|
@@ -1016,7 +1108,7 @@ export class MainView extends React.Component {
|
|
|
1016
1108
|
this.state.loadingErrors.push({
|
|
1017
1109
|
id,
|
|
1018
1110
|
error: error.message || 'invalid file path',
|
|
1019
|
-
index
|
|
1111
|
+
index,
|
|
1020
1112
|
});
|
|
1021
1113
|
this._loadingLayers.delete(id);
|
|
1022
1114
|
}
|
|
@@ -1029,18 +1121,10 @@ export class MainView extends React.Component {
|
|
|
1029
1121
|
*/
|
|
1030
1122
|
async updateLayer(id, layer, mapLayer, oldLayer) {
|
|
1031
1123
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1032
|
-
const sourceId = (_a = layer.parameters) === null || _a === void 0 ? void 0 : _a.source;
|
|
1033
|
-
const source = this._model.sharedModel.getLayerSource(sourceId);
|
|
1034
|
-
if (!source) {
|
|
1035
|
-
return;
|
|
1036
|
-
}
|
|
1037
|
-
if (!this._sources[sourceId]) {
|
|
1038
|
-
await this.addSource(sourceId, source);
|
|
1039
|
-
}
|
|
1040
1124
|
mapLayer.setVisible(layer.visible);
|
|
1041
1125
|
switch (layer.type) {
|
|
1042
1126
|
case 'RasterLayer': {
|
|
1043
|
-
mapLayer.setOpacity(((
|
|
1127
|
+
mapLayer.setOpacity(((_a = layer.parameters) === null || _a === void 0 ? void 0 : _a.opacity) || 1);
|
|
1044
1128
|
break;
|
|
1045
1129
|
}
|
|
1046
1130
|
case 'VectorLayer': {
|
|
@@ -1063,10 +1147,10 @@ export class MainView extends React.Component {
|
|
|
1063
1147
|
break;
|
|
1064
1148
|
}
|
|
1065
1149
|
case 'WebGlLayer': {
|
|
1066
|
-
mapLayer.setOpacity((
|
|
1067
|
-
if ((
|
|
1150
|
+
mapLayer.setOpacity((_b = layer.parameters) === null || _b === void 0 ? void 0 : _b.opacity);
|
|
1151
|
+
if ((_c = layer === null || layer === void 0 ? void 0 : layer.parameters) === null || _c === void 0 ? void 0 : _c.color) {
|
|
1068
1152
|
mapLayer.setStyle({
|
|
1069
|
-
color: layer.parameters.color
|
|
1153
|
+
color: layer.parameters.color,
|
|
1070
1154
|
});
|
|
1071
1155
|
}
|
|
1072
1156
|
break;
|
|
@@ -1074,13 +1158,16 @@ export class MainView extends React.Component {
|
|
|
1074
1158
|
case 'HeatmapLayer': {
|
|
1075
1159
|
const layerParams = layer.parameters;
|
|
1076
1160
|
const heatmap = mapLayer;
|
|
1077
|
-
heatmap.setOpacity((
|
|
1078
|
-
heatmap.setBlur((
|
|
1079
|
-
heatmap.setRadius((
|
|
1080
|
-
heatmap.setGradient((
|
|
1161
|
+
heatmap.setOpacity((_d = layerParams.opacity) !== null && _d !== void 0 ? _d : 1);
|
|
1162
|
+
heatmap.setBlur((_e = layerParams.blur) !== null && _e !== void 0 ? _e : 15);
|
|
1163
|
+
heatmap.setRadius((_f = layerParams.radius) !== null && _f !== void 0 ? _f : 8);
|
|
1164
|
+
heatmap.setGradient((_g = layerParams.color) !== null && _g !== void 0 ? _g : ['#00f', '#0ff', '#0f0', '#ff0', '#f00']);
|
|
1081
1165
|
this.handleTemporalController(id, layer);
|
|
1082
1166
|
break;
|
|
1083
1167
|
}
|
|
1168
|
+
case 'StacLayer':
|
|
1169
|
+
mapLayer.setOpacity(((_h = layer.parameters) === null || _h === void 0 ? void 0 : _h.opacity) || 1);
|
|
1170
|
+
break;
|
|
1084
1171
|
}
|
|
1085
1172
|
}
|
|
1086
1173
|
flyToGeometry(sender, geometry) {
|
|
@@ -1093,7 +1180,7 @@ export class MainView extends React.Component {
|
|
|
1093
1180
|
view.fit(extent, {
|
|
1094
1181
|
padding: [50, 50, 50, 50],
|
|
1095
1182
|
duration: 1000,
|
|
1096
|
-
maxZoom: 16
|
|
1183
|
+
maxZoom: 16,
|
|
1097
1184
|
});
|
|
1098
1185
|
}
|
|
1099
1186
|
highlightFeatureOnMap(sender, featureOrGeometry) {
|
|
@@ -1108,7 +1195,7 @@ export class MainView extends React.Component {
|
|
|
1108
1195
|
const parsedGeometry = isOlGeometry
|
|
1109
1196
|
? geometry
|
|
1110
1197
|
: new GeoJSON().readGeometry(geometry, {
|
|
1111
|
-
featureProjection: this._Map.getView().getProjection()
|
|
1198
|
+
featureProjection: this._Map.getView().getProjection(),
|
|
1112
1199
|
});
|
|
1113
1200
|
const olFeature = new Feature(Object.assign({ geometry: parsedGeometry }, (geometry !== featureOrGeometry ? featureOrGeometry : {})));
|
|
1114
1201
|
if (!this._highlightLayer) {
|
|
@@ -1123,39 +1210,44 @@ export class MainView extends React.Component {
|
|
|
1123
1210
|
return new Style({
|
|
1124
1211
|
image: new Circle({
|
|
1125
1212
|
radius: 6,
|
|
1126
|
-
fill: new Fill({
|
|
1127
|
-
|
|
1128
|
-
|
|
1213
|
+
fill: new Fill({
|
|
1214
|
+
color: 'rgba(255, 255, 0, 0.8)',
|
|
1215
|
+
}),
|
|
1216
|
+
stroke: new Stroke({
|
|
1217
|
+
color: '#ff0',
|
|
1218
|
+
width: 2,
|
|
1219
|
+
}),
|
|
1220
|
+
}),
|
|
1129
1221
|
});
|
|
1130
1222
|
case 'LineString':
|
|
1131
1223
|
case 'MultiLineString':
|
|
1132
1224
|
return new Style({
|
|
1133
1225
|
stroke: new Stroke({
|
|
1134
1226
|
color: 'rgba(255, 255, 0, 0.8)',
|
|
1135
|
-
width: 3
|
|
1136
|
-
})
|
|
1227
|
+
width: 3,
|
|
1228
|
+
}),
|
|
1137
1229
|
});
|
|
1138
1230
|
case 'Polygon':
|
|
1139
1231
|
case 'MultiPolygon':
|
|
1140
1232
|
return new Style({
|
|
1141
1233
|
stroke: new Stroke({
|
|
1142
1234
|
color: '#f00',
|
|
1143
|
-
width: 2
|
|
1235
|
+
width: 2,
|
|
1144
1236
|
}),
|
|
1145
1237
|
fill: new Fill({
|
|
1146
|
-
color: 'rgba(255, 255, 0, 0.8)'
|
|
1147
|
-
})
|
|
1238
|
+
color: 'rgba(255, 255, 0, 0.8)',
|
|
1239
|
+
}),
|
|
1148
1240
|
});
|
|
1149
1241
|
default:
|
|
1150
1242
|
return new Style({
|
|
1151
1243
|
stroke: new Stroke({
|
|
1152
1244
|
color: '#000',
|
|
1153
|
-
width: 2
|
|
1154
|
-
})
|
|
1245
|
+
width: 2,
|
|
1246
|
+
}),
|
|
1155
1247
|
});
|
|
1156
1248
|
}
|
|
1157
1249
|
},
|
|
1158
|
-
zIndex: 999
|
|
1250
|
+
zIndex: 999,
|
|
1159
1251
|
});
|
|
1160
1252
|
this._Map.addLayer(this._highlightLayer);
|
|
1161
1253
|
}
|
|
@@ -1222,7 +1314,7 @@ export class MainView extends React.Component {
|
|
|
1222
1314
|
}
|
|
1223
1315
|
}
|
|
1224
1316
|
async updateOptions(options) {
|
|
1225
|
-
const { projection, extent, useExtent, latitude, longitude, zoom, bearing } = options;
|
|
1317
|
+
const { projection, extent, useExtent, latitude, longitude, zoom, bearing, } = options;
|
|
1226
1318
|
let view = this._Map.getView();
|
|
1227
1319
|
const currentProjection = view.getProjection().getCode();
|
|
1228
1320
|
// Need to recreate view if the projection changes
|
|
@@ -1339,9 +1431,6 @@ export class MainView extends React.Component {
|
|
|
1339
1431
|
}
|
|
1340
1432
|
const mapLayer = this.getLayer(id);
|
|
1341
1433
|
const layerTree = JupyterGISModel.getOrderedLayerIds(this._model);
|
|
1342
|
-
if (!mapLayer) {
|
|
1343
|
-
return;
|
|
1344
|
-
}
|
|
1345
1434
|
if (layerTree.includes(id)) {
|
|
1346
1435
|
this.updateLayer(id, newLayer, mapLayer, oldLayer);
|
|
1347
1436
|
}
|
|
@@ -1416,6 +1505,9 @@ export class MainView extends React.Component {
|
|
|
1416
1505
|
const tileGrid = source.getTileGrid();
|
|
1417
1506
|
extent = tileGrid === null || tileGrid === void 0 ? void 0 : tileGrid.getExtent();
|
|
1418
1507
|
}
|
|
1508
|
+
if (layer instanceof StacLayer) {
|
|
1509
|
+
extent = layer.getExtent();
|
|
1510
|
+
}
|
|
1419
1511
|
if (!extent) {
|
|
1420
1512
|
console.warn('Layer has no extent.');
|
|
1421
1513
|
return;
|
|
@@ -1428,7 +1520,7 @@ export class MainView extends React.Component {
|
|
|
1428
1520
|
: extent;
|
|
1429
1521
|
this._Map.getView().fit(transformedExtent, {
|
|
1430
1522
|
size: this._Map.getSize(),
|
|
1431
|
-
duration: 500
|
|
1523
|
+
duration: 500,
|
|
1432
1524
|
});
|
|
1433
1525
|
}
|
|
1434
1526
|
_moveToPosition(center, zoom, duration = 1000) {
|
|
@@ -1438,7 +1530,10 @@ export class MainView extends React.Component {
|
|
|
1438
1530
|
// Zoom needs to be set before changing center
|
|
1439
1531
|
if (!view.animate === undefined) {
|
|
1440
1532
|
view.animate({ zoom, duration });
|
|
1441
|
-
view.animate({
|
|
1533
|
+
view.animate({
|
|
1534
|
+
center: [center.x, center.y],
|
|
1535
|
+
duration,
|
|
1536
|
+
});
|
|
1442
1537
|
}
|
|
1443
1538
|
}
|
|
1444
1539
|
_flyToPosition(center, zoom, duration = 1000) {
|
|
@@ -1529,7 +1624,7 @@ export class MainView extends React.Component {
|
|
|
1529
1624
|
const screenPosition = this._computeAnnotationPosition(annotation);
|
|
1530
1625
|
return (screenPosition && (React.createElement("div", { key: key, id: key, style: {
|
|
1531
1626
|
left: screenPosition.x,
|
|
1532
|
-
top: screenPosition.y
|
|
1627
|
+
top: screenPosition.y,
|
|
1533
1628
|
}, className: 'jGIS-Popup-Wrapper' },
|
|
1534
1629
|
React.createElement(AnnotationFloater, { itemId: key, annotationModel: this._model.annotationModel }))));
|
|
1535
1630
|
}),
|
|
@@ -1538,14 +1633,14 @@ export class MainView extends React.Component {
|
|
|
1538
1633
|
React.createElement("div", { className: "jGIS-Mainview data-jgis-keybinding", tabIndex: -2, style: {
|
|
1539
1634
|
border: this.state.remoteUser
|
|
1540
1635
|
? `solid 3px ${this.state.remoteUser.color}`
|
|
1541
|
-
: 'unset'
|
|
1636
|
+
: 'unset',
|
|
1542
1637
|
} },
|
|
1543
|
-
React.createElement(
|
|
1638
|
+
React.createElement(LoadingOverlay, { loading: this.state.loading }),
|
|
1544
1639
|
React.createElement(FollowIndicator, { remoteUser: this.state.remoteUser }),
|
|
1545
1640
|
React.createElement(CollaboratorPointers, { clients: this.state.clientPointers }),
|
|
1546
1641
|
React.createElement("div", { ref: this.divRef, style: {
|
|
1547
1642
|
width: '100%',
|
|
1548
|
-
height: '100%'
|
|
1643
|
+
height: '100%',
|
|
1549
1644
|
} })),
|
|
1550
1645
|
React.createElement(StatusBar, { jgisModel: this._model, loading: this.state.loadingLayer, projection: this.state.viewProjection, scale: this.state.scale }))));
|
|
1551
1646
|
}
|