@jupytergis/base 0.1.2 → 0.1.3
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/dialogs/components/symbology/Graduated.d.ts +4 -0
- package/lib/dialogs/components/symbology/Graduated.js +188 -0
- package/lib/dialogs/components/symbology/SimpleSymbol.d.ts +4 -0
- package/lib/dialogs/components/symbology/SimpleSymbol.js +108 -0
- package/lib/dialogs/components/symbology/SingleBandPseudoColor.d.ts +0 -4
- package/lib/dialogs/components/symbology/SingleBandPseudoColor.js +19 -23
- package/lib/dialogs/components/symbology/StopRow.d.ts +4 -3
- package/lib/dialogs/components/symbology/StopRow.js +14 -9
- package/lib/dialogs/components/symbology/VectorRendering.d.ts +4 -0
- package/lib/dialogs/components/symbology/VectorRendering.js +55 -0
- package/lib/dialogs/symbologyDialog.d.ts +4 -0
- package/lib/dialogs/symbologyDialog.js +5 -0
- package/lib/formbuilder/objectform/vectorlayerform.js +1 -3
- package/lib/gdal.d.ts +1 -0
- package/lib/gdal.js +15 -0
- package/lib/gdal3WebAssembly.data +97604 -44
- package/lib/gdal3WebAssembly.wasm +0 -0
- package/lib/mainview/mainView.d.ts +5 -3
- package/lib/mainview/mainView.js +49 -67
- package/lib/panelview/components/layers.js +3 -3
- package/lib/tools.d.ts +9 -0
- package/lib/tools.js +38 -0
- package/package.json +6 -5
- package/style/symbologyDialog.css +11 -3
|
Binary file
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { IJGISLayer, IJGISSource } from '@jupytergis/schema';
|
|
2
2
|
import { User } from '@jupyterlab/services';
|
|
3
|
-
import { FeatureLike } from 'ol/Feature';
|
|
4
3
|
import BaseLayer from 'ol/layer/Base';
|
|
5
|
-
import { Style } from 'ol/style';
|
|
6
4
|
import * as React from 'react';
|
|
7
5
|
import { MainViewModel } from './mainviewmodel';
|
|
8
6
|
interface IProps {
|
|
@@ -57,7 +55,11 @@ export declare class MainView extends React.Component<IProps, IStates> {
|
|
|
57
55
|
* @param index - expected index of the layer.
|
|
58
56
|
*/
|
|
59
57
|
addLayer(id: string, layer: IJGISLayer, index: number): Promise<void>;
|
|
60
|
-
|
|
58
|
+
vectorLayerStyleRuleBuilder: (layer: IJGISLayer) => {
|
|
59
|
+
style: import("ol/style/flat").FlatStyle | Array<import("ol/style/flat").FlatStyle>;
|
|
60
|
+
filter?: import("ol/expr/expression").EncodedExpression | undefined;
|
|
61
|
+
else?: boolean | undefined;
|
|
62
|
+
}[] | undefined;
|
|
61
63
|
/**
|
|
62
64
|
* Taken from https://openlayers.org/en/latest/examples/webgl-shaded-relief.html
|
|
63
65
|
* @returns
|
package/lib/mainview/mainView.js
CHANGED
|
@@ -10,7 +10,6 @@ import { fromLonLat, toLonLat } from 'ol/proj';
|
|
|
10
10
|
import Feature from 'ol/render/Feature';
|
|
11
11
|
import { GeoTIFF as GeoTIFFSource, ImageTile as ImageTileSource, Vector as VectorSource, VectorTile as VectorTileSource, XYZ as XYZSource } from 'ol/source';
|
|
12
12
|
import Static from 'ol/source/ImageStatic';
|
|
13
|
-
import { Circle, Fill, Stroke, Style } from 'ol/style';
|
|
14
13
|
//@ts-expect-error no types for ol-pmtiles
|
|
15
14
|
import { PMTilesRasterSource, PMTilesVectorSource } from 'ol-pmtiles';
|
|
16
15
|
import * as React from 'react';
|
|
@@ -20,73 +19,52 @@ import { Spinner } from './spinner';
|
|
|
20
19
|
export class MainView extends React.Component {
|
|
21
20
|
constructor(props) {
|
|
22
21
|
super(props);
|
|
23
|
-
this.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const operators = {
|
|
37
|
-
'>': (a, b) => a > b,
|
|
38
|
-
'<': (a, b) => a < b,
|
|
39
|
-
'>=': (a, b) => a >= b,
|
|
40
|
-
'<=': (a, b) => a <= b,
|
|
41
|
-
'==': (a, b) => a === b,
|
|
42
|
-
'!=': (a, b) => a !== b
|
|
22
|
+
this.vectorLayerStyleRuleBuilder = (layer) => {
|
|
23
|
+
const layerParams = layer.parameters;
|
|
24
|
+
if (!layerParams) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const defaultStyle = {
|
|
28
|
+
'fill-color': 'rgba(255,255,255,0.4)',
|
|
29
|
+
'stroke-color': '#3399CC',
|
|
30
|
+
'stroke-width': 1.25,
|
|
31
|
+
'circle-radius': 5,
|
|
32
|
+
'circle-fill-color': 'rgba(255,255,255,0.4)',
|
|
33
|
+
'circle-stroke-width': 1.25,
|
|
34
|
+
'circle-stroke-color': '#3399CC'
|
|
43
35
|
};
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const style = new Style({
|
|
57
|
-
fill,
|
|
58
|
-
stroke,
|
|
59
|
-
image: new Circle({
|
|
60
|
-
radius: 5,
|
|
61
|
-
fill,
|
|
62
|
-
stroke
|
|
63
|
-
})
|
|
64
|
-
});
|
|
65
|
-
if (layer.filters && ((_a = layer.filters) === null || _a === void 0 ? void 0 : _a.appliedFilters.length) !== 0) {
|
|
66
|
-
const props = currentFeature.getProperties();
|
|
67
|
-
let shouldDisplayFeature = true;
|
|
68
|
-
switch (layer.filters.logicalOp) {
|
|
69
|
-
case 'any': {
|
|
70
|
-
// Display the feature if any filter conditions apply
|
|
71
|
-
shouldDisplayFeature = layer.filters.appliedFilters.some(({ feature, operator, value }) => operators[operator](props[feature], value));
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
case 'all': {
|
|
75
|
-
// Display the feature only if all the filter conditions apply
|
|
76
|
-
shouldDisplayFeature = layer.filters.appliedFilters.every(({ feature, operator, value }) => operators[operator](props[feature], value));
|
|
77
|
-
break;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
if (shouldDisplayFeature) {
|
|
81
|
-
return style;
|
|
36
|
+
const defaultRules = {
|
|
37
|
+
style: defaultStyle
|
|
38
|
+
};
|
|
39
|
+
const layerStyle = Object.assign({}, defaultRules);
|
|
40
|
+
if (layer.filters && layer.filters.appliedFilters.length !== 0) {
|
|
41
|
+
const filterExpr = [];
|
|
42
|
+
// 'Any' and 'All' operators require more than one argument
|
|
43
|
+
// So if there's only one filter, skip that part to avoid error
|
|
44
|
+
if (layer.filters.appliedFilters.length === 1) {
|
|
45
|
+
layer.filters.appliedFilters.forEach(filter => {
|
|
46
|
+
filterExpr.push(filter.operator, ['get', filter.feature], filter.value);
|
|
47
|
+
});
|
|
82
48
|
}
|
|
83
49
|
else {
|
|
84
|
-
|
|
50
|
+
filterExpr.push(layer.filters.logicalOp);
|
|
51
|
+
// Arguments for "Any" and 'All' need to be wrapped in brackets
|
|
52
|
+
layer.filters.appliedFilters.forEach(filter => {
|
|
53
|
+
filterExpr.push([
|
|
54
|
+
filter.operator,
|
|
55
|
+
['get', filter.feature],
|
|
56
|
+
filter.value
|
|
57
|
+
]);
|
|
58
|
+
});
|
|
85
59
|
}
|
|
60
|
+
layerStyle.filter = filterExpr;
|
|
86
61
|
}
|
|
87
|
-
|
|
88
|
-
return
|
|
62
|
+
if (!layerParams.color) {
|
|
63
|
+
return [layerStyle];
|
|
89
64
|
}
|
|
65
|
+
const newStyle = Object.assign(Object.assign({}, defaultStyle), layerParams.color);
|
|
66
|
+
layerStyle.style = newStyle;
|
|
67
|
+
return [layerStyle];
|
|
90
68
|
};
|
|
91
69
|
/**
|
|
92
70
|
* Taken from https://openlayers.org/en/latest/examples/webgl-shaded-relief.html
|
|
@@ -247,6 +225,7 @@ export class MainView extends React.Component {
|
|
|
247
225
|
await this._updateLayersImpl(JupyterGISModel.getOrderedLayerIds(this._model));
|
|
248
226
|
const options = this._model.getOptions();
|
|
249
227
|
this.updateOptions(options);
|
|
228
|
+
this._initializedPosition = true;
|
|
250
229
|
}
|
|
251
230
|
this.setState(old => (Object.assign(Object.assign({}, old), { loading: false })));
|
|
252
231
|
}
|
|
@@ -528,17 +507,20 @@ export class MainView extends React.Component {
|
|
|
528
507
|
opacity: layerParameters.opacity,
|
|
529
508
|
visible: layer.visible,
|
|
530
509
|
source: this._sources[layerParameters.source],
|
|
531
|
-
style:
|
|
510
|
+
style: this.vectorLayerStyleRuleBuilder(layer)
|
|
532
511
|
});
|
|
533
512
|
break;
|
|
534
513
|
}
|
|
535
514
|
case 'VectorTileLayer': {
|
|
536
515
|
layerParameters = layer.parameters;
|
|
516
|
+
if (!layerParameters.color) {
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
537
519
|
newLayer = new VectorTileLayer({
|
|
538
520
|
opacity: layerParameters.opacity,
|
|
539
|
-
source: this._sources[layerParameters.source]
|
|
540
|
-
style: currentFeature => this.vectorLayerStyleFunc(currentFeature, layer)
|
|
521
|
+
source: this._sources[layerParameters.source]
|
|
541
522
|
});
|
|
523
|
+
this.updateLayer(id, layer, newLayer);
|
|
542
524
|
break;
|
|
543
525
|
}
|
|
544
526
|
case 'HillshadeLayer': {
|
|
@@ -633,13 +615,13 @@ export class MainView extends React.Component {
|
|
|
633
615
|
case 'VectorLayer': {
|
|
634
616
|
const layerParams = layer.parameters;
|
|
635
617
|
mapLayer.setOpacity(layerParams.opacity || 1);
|
|
636
|
-
mapLayer.setStyle(
|
|
618
|
+
mapLayer.setStyle(this.vectorLayerStyleRuleBuilder(layer));
|
|
637
619
|
break;
|
|
638
620
|
}
|
|
639
621
|
case 'VectorTileLayer': {
|
|
640
622
|
const layerParams = layer.parameters;
|
|
641
623
|
mapLayer.setOpacity(layerParams.opacity || 1);
|
|
642
|
-
mapLayer.setStyle(
|
|
624
|
+
mapLayer.setStyle(this.vectorLayerStyleRuleBuilder(layer));
|
|
643
625
|
break;
|
|
644
626
|
}
|
|
645
627
|
case 'HillshadeLayer': {
|
|
@@ -132,8 +132,8 @@ function LayerGroupComponent(props) {
|
|
|
132
132
|
setId(DOMUtils.createDomID());
|
|
133
133
|
const getExpandedState = async () => {
|
|
134
134
|
var _a;
|
|
135
|
-
const groupState = await state.fetch(group.name);
|
|
136
|
-
setOpen(
|
|
135
|
+
const groupState = await state.fetch(`jupytergis:${group.name}`);
|
|
136
|
+
setOpen((_a = groupState.expanded) !== null && _a !== void 0 ? _a : false);
|
|
137
137
|
};
|
|
138
138
|
getExpandedState();
|
|
139
139
|
}, []);
|
|
@@ -156,7 +156,7 @@ function LayerGroupComponent(props) {
|
|
|
156
156
|
onClick({ type: 'group', item: name, nodeId: childId, event });
|
|
157
157
|
};
|
|
158
158
|
const handleExpand = async () => {
|
|
159
|
-
state.save(group.name
|
|
159
|
+
state.save(`jupytergis:${group.name}`, { expanded: !open });
|
|
160
160
|
setOpen(!open);
|
|
161
161
|
};
|
|
162
162
|
return (React.createElement("div", { className: `${LAYER_ITEM_CLASS} ${LAYER_GROUP_CLASS}`, draggable: true, onDragStart: Private.onDragStart, onDragEnd: Private.onDragEnd, "data-id": name },
|
package/lib/tools.d.ts
CHANGED
|
@@ -23,3 +23,12 @@ export declare function deepCopy<T = IDict<any>>(value: T): T;
|
|
|
23
23
|
export declare function createDefaultLayerRegistry(layerBrowserRegistry: IJGISLayerBrowserRegistry): void;
|
|
24
24
|
export declare function getLayerTileInfo(tileUrl: string, mapOptions: Pick<IJGISOptions, 'latitude' | 'longitude' | 'extent' | 'zoom'>, urlParameters?: IDict<string>): Promise<VectorTile>;
|
|
25
25
|
export declare function getSourceLayerNames(tileUrl: string, urlParameters?: IDict<string>): Promise<string[]>;
|
|
26
|
+
export interface IParsedStyle {
|
|
27
|
+
fillColor: string;
|
|
28
|
+
strokeColor: string;
|
|
29
|
+
strokeWidth: number;
|
|
30
|
+
joinStyle: string;
|
|
31
|
+
capStyle: string;
|
|
32
|
+
radius?: number;
|
|
33
|
+
}
|
|
34
|
+
export declare function parseColor(type: string, style: any): IParsedStyle | undefined;
|
package/lib/tools.js
CHANGED
|
@@ -170,6 +170,10 @@ function getTileCoordinates(latDeg, lonDeg, zoom) {
|
|
|
170
170
|
const n = 1 << zoom;
|
|
171
171
|
const xTile = Math.floor(((lonDeg + 180.0) / 360.0) * n);
|
|
172
172
|
const yTile = Math.floor((n * (1 - Math.log(Math.tan(latRad) + 1 / Math.cos(latRad)) / Math.PI)) / 2);
|
|
173
|
+
// Check if either xTile or yTile is NaN
|
|
174
|
+
if (isNaN(xTile) || isNaN(yTile)) {
|
|
175
|
+
return { xTile: 0, yTile: 0 };
|
|
176
|
+
}
|
|
173
177
|
return { xTile, yTile };
|
|
174
178
|
}
|
|
175
179
|
export async function getLayerTileInfo(tileUrl, mapOptions, urlParameters) {
|
|
@@ -213,3 +217,37 @@ export async function getSourceLayerNames(tileUrl, urlParameters) {
|
|
|
213
217
|
const layerNames = Object.keys(tile.layers);
|
|
214
218
|
return layerNames;
|
|
215
219
|
}
|
|
220
|
+
export function parseColor(type, style) {
|
|
221
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
222
|
+
if (!type || !style) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const type2 = type === 'circle' ? 'circle' : 'default';
|
|
226
|
+
const shapeStyles = {
|
|
227
|
+
circle: {
|
|
228
|
+
radius: (_a = style['circle-radius']) !== null && _a !== void 0 ? _a : 5,
|
|
229
|
+
fillColor: (_b = style['circle-fill-color']) !== null && _b !== void 0 ? _b : '#3399CC',
|
|
230
|
+
strokeColor: (_c = style['circle-stroke-color']) !== null && _c !== void 0 ? _c : '#3399CC',
|
|
231
|
+
strokeWidth: (_d = style['circle-stroke-width']) !== null && _d !== void 0 ? _d : 1.25,
|
|
232
|
+
joinStyle: (_e = style['circle-stroke-line-join']) !== null && _e !== void 0 ? _e : 'round',
|
|
233
|
+
capStyle: (_f = style['circle-stroke-line-cap']) !== null && _f !== void 0 ? _f : 'round'
|
|
234
|
+
},
|
|
235
|
+
default: {
|
|
236
|
+
fillColor: (_g = style['fill-color']) !== null && _g !== void 0 ? _g : '[255, 255, 255, 0.4]',
|
|
237
|
+
strokeColor: (_h = style['stroke-color']) !== null && _h !== void 0 ? _h : '#3399CC',
|
|
238
|
+
strokeWidth: (_j = style['stroke-width']) !== null && _j !== void 0 ? _j : 1.25,
|
|
239
|
+
capStyle: (_k = style['stroke-line-cap']) !== null && _k !== void 0 ? _k : 'round',
|
|
240
|
+
joinStyle: (_l = style['stroke-line-join']) !== null && _l !== void 0 ? _l : 'round'
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
const parsedStyle = shapeStyles[type2];
|
|
244
|
+
Object.assign(parsedStyle, {
|
|
245
|
+
radius: parsedStyle.radius,
|
|
246
|
+
fillColor: parsedStyle.fillColor,
|
|
247
|
+
strokeColor: parsedStyle.strokeColor,
|
|
248
|
+
strokeWidth: parsedStyle.strokeWidth,
|
|
249
|
+
joinStyle: parsedStyle.joinStyle,
|
|
250
|
+
capStyle: parsedStyle.capStyle
|
|
251
|
+
});
|
|
252
|
+
return parsedStyle;
|
|
253
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jupytergis/base",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "A JupyterLab extension for 3D modelling.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jupyter",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"name": "JupyterGIS contributors"
|
|
17
17
|
},
|
|
18
18
|
"files": [
|
|
19
|
-
"lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}",
|
|
19
|
+
"lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf,data,wasm}",
|
|
20
20
|
"style/**/*.{css,js,eot,gif,html,jpg,json,png,svg,woff2,ttf}"
|
|
21
21
|
],
|
|
22
22
|
"main": "lib/index.js",
|
|
@@ -27,10 +27,11 @@
|
|
|
27
27
|
"url": "https://github.com/geojupyter/jupytergis.git"
|
|
28
28
|
},
|
|
29
29
|
"scripts": {
|
|
30
|
-
"build": "jlpm run build:gallery && tsc -b",
|
|
30
|
+
"build": "jlpm run build:gallery && tsc -b && jlpm run cp:gdal",
|
|
31
31
|
"build:gallery": "python rasterlayer_gallery_generator.py",
|
|
32
|
+
"cp:gdal": "cp ../../node_modules/gdal3.js/dist/package/gdal3WebAssembly.data lib && cp ../../node_modules/gdal3.js/dist/package/gdal3WebAssembly.wasm lib",
|
|
32
33
|
"build:prod": "jlpm run clean && jlpm run build",
|
|
33
|
-
"build:dev": "tsc -b",
|
|
34
|
+
"build:dev": "tsc -b && jlpm run cp:gdal",
|
|
34
35
|
"clean": "rimraf tsconfig.tsbuildinfo",
|
|
35
36
|
"clean:lib": "rimraf lib tsconfig.tsbuildinfo",
|
|
36
37
|
"clean:all": "jlpm run clean:lib",
|
|
@@ -40,7 +41,7 @@
|
|
|
40
41
|
"@deathbeds/jupyterlab-rjsf": "^1.1.0",
|
|
41
42
|
"@jupyter/docprovider": "^2.0.0",
|
|
42
43
|
"@jupyter/ydoc": "^1.0.0",
|
|
43
|
-
"@jupytergis/schema": "^0.1.
|
|
44
|
+
"@jupytergis/schema": "^0.1.3",
|
|
44
45
|
"@jupyterlab/application": "^4.0.0",
|
|
45
46
|
"@jupyterlab/apputils": "^4.0.0",
|
|
46
47
|
"@jupyterlab/completer": "^4.2.4",
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
flex: 0 1 20%;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
.jp-gis-symbology-row > .jp-select-wrapper
|
|
24
|
+
.jp-gis-symbology-row > .jp-select-wrapper,
|
|
25
|
+
.jp-gis-symbology-row > .jp-mod-styled {
|
|
25
26
|
flex: 1 0 50%;
|
|
26
27
|
max-width: 50%;
|
|
27
28
|
}
|
|
@@ -35,6 +36,13 @@
|
|
|
35
36
|
.jp-gis-layer-symbology-container {
|
|
36
37
|
display: flex;
|
|
37
38
|
flex-direction: column;
|
|
39
|
+
gap: 13px;
|
|
40
|
+
border-top: 1px solid var(--jp-border-color2);
|
|
41
|
+
padding-top: 8px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.jp-gis-layer-symbology-container .jp-select-wrapper {
|
|
45
|
+
margin-bottom: unset;
|
|
38
46
|
}
|
|
39
47
|
|
|
40
48
|
.jp-gis-band-container .jp-gis-symbology-row:last-child {
|
|
@@ -66,12 +74,12 @@
|
|
|
66
74
|
height: 32px;
|
|
67
75
|
}
|
|
68
76
|
|
|
69
|
-
.jp-gis-color-row
|
|
77
|
+
.jp-gis-color-row-value-input {
|
|
70
78
|
flex: 0 1 18%;
|
|
71
79
|
min-width: 0px;
|
|
72
80
|
}
|
|
73
81
|
|
|
74
|
-
.jp-gis-color-row
|
|
82
|
+
.jp-gis-color-row-output-input {
|
|
75
83
|
flex-grow: 1;
|
|
76
84
|
}
|
|
77
85
|
|