@jupytergis/base 0.7.0 → 0.8.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.
@@ -1,6 +1,46 @@
1
1
  // import { GeoJSONFeature } from 'geojson';
2
2
  import { useEffect, useState } from 'react';
3
3
  import { loadFile } from "../../../tools";
4
+ async function getGeoJsonProperties({ source, model, }) {
5
+ var _a;
6
+ const result = {};
7
+ const data = await loadFile({
8
+ filepath: (_a = source.parameters) === null || _a === void 0 ? void 0 : _a.path,
9
+ type: 'GeoJSONSource',
10
+ model,
11
+ });
12
+ if (!data) {
13
+ throw new Error('Failed to read GeoJSON data');
14
+ }
15
+ data.features.forEach((feature) => {
16
+ if (feature.properties) {
17
+ for (const [key, value] of Object.entries(feature.properties)) {
18
+ if (!result[key]) {
19
+ result[key] = new Set();
20
+ }
21
+ result[key].add(value);
22
+ }
23
+ }
24
+ });
25
+ return result;
26
+ }
27
+ function getVectorTileProperties({ model, sourceId, }) {
28
+ const result = {};
29
+ const features = model.getFeaturesForCurrentTile({ sourceId });
30
+ features.forEach(feature => {
31
+ var _a;
32
+ const props = (_a = feature.getProperties) === null || _a === void 0 ? void 0 : _a.call(feature);
33
+ if (props) {
34
+ for (const [key, value] of Object.entries(props)) {
35
+ if (!result[key]) {
36
+ result[key] = new Set();
37
+ }
38
+ result[key].add(value);
39
+ }
40
+ }
41
+ });
42
+ return result;
43
+ }
4
44
  export const useGetProperties = ({ layerId, model, }) => {
5
45
  const [featureProperties, setFeatureProperties] = useState({});
6
46
  const [isLoading, setIsLoading] = useState(true);
@@ -16,30 +56,24 @@ export const useGetProperties = ({ layerId, model, }) => {
16
56
  if (!source) {
17
57
  throw new Error('Source not found');
18
58
  }
19
- const data = await loadFile({
20
- filepath: (_b = source.parameters) === null || _b === void 0 ? void 0 : _b.path,
21
- type: 'GeoJSONSource',
22
- model: model,
23
- });
24
- if (!data) {
25
- throw new Error('Failed to read GeoJSON data');
59
+ const sourceType = source === null || source === void 0 ? void 0 : source.type;
60
+ let result = {};
61
+ if (sourceType === 'GeoJSONSource') {
62
+ result = await getGeoJsonProperties({ source, model });
63
+ }
64
+ else if (sourceType === 'VectorTileSource') {
65
+ const sourceId = (_b = layer === null || layer === void 0 ? void 0 : layer.parameters) === null || _b === void 0 ? void 0 : _b.source;
66
+ result = getVectorTileProperties({ model, sourceId });
67
+ }
68
+ else {
69
+ throw new Error(`Unsupported source type: ${sourceType}`);
26
70
  }
27
- const result = {};
28
- data.features.forEach((feature) => {
29
- if (feature.properties) {
30
- Object.entries(feature.properties).forEach(([key, value]) => {
31
- if (!(key in result)) {
32
- result[key] = new Set();
33
- }
34
- result[key].add(value);
35
- });
36
- }
37
- });
38
71
  setFeatureProperties(result);
39
- setIsLoading(false);
40
72
  }
41
73
  catch (err) {
42
74
  setError(err);
75
+ }
76
+ finally {
43
77
  setIsLoading(false);
44
78
  }
45
79
  };
@@ -15,19 +15,19 @@ const RENDER_TYPE_OPTIONS = {
15
15
  Canonical: {
16
16
  component: Canonical,
17
17
  attributeChecker: getColorCodeFeatureAttributes,
18
- supportedLayerTypes: ['VectorLayer', 'HeatmapLayer'],
18
+ supportedLayerTypes: ['VectorLayer', 'VectorTileLayer', 'HeatmapLayer'],
19
19
  isTabbed: false,
20
20
  },
21
21
  Graduated: {
22
22
  component: Graduated,
23
23
  attributeChecker: getNumericFeatureAttributes,
24
- supportedLayerTypes: ['VectorLayer', 'HeatmapLayer'],
24
+ supportedLayerTypes: ['VectorLayer', 'VectorTileLayer', 'HeatmapLayer'],
25
25
  isTabbed: true,
26
26
  },
27
27
  Categorized: {
28
28
  component: Categorized,
29
29
  attributeChecker: getNumericFeatureAttributes,
30
- supportedLayerTypes: ['VectorLayer', 'HeatmapLayer'],
30
+ supportedLayerTypes: ['VectorLayer', 'VectorTileLayer', 'HeatmapLayer'],
31
31
  isTabbed: true,
32
32
  },
33
33
  Heatmap: {
@@ -126,13 +126,15 @@ const Graduated = ({ model, state, okSignalPromise, cancel, layerId, symbologyTa
126
126
  });
127
127
  newStyle['fill-color'] = colorExpr;
128
128
  newStyle['circle-fill-color'] = colorExpr;
129
+ newStyle['stroke-color'] = colorExpr;
130
+ newStyle['circle-stroke-color'] = colorExpr;
129
131
  }
130
132
  else {
131
133
  newStyle['fill-color'] = undefined;
132
134
  newStyle['circle-fill-color'] = undefined;
135
+ newStyle['stroke-color'] = colorManualStyleRef.current.strokeColor;
136
+ newStyle['circle-stroke-color'] = colorManualStyleRef.current.strokeColor;
133
137
  }
134
- newStyle['stroke-color'] = colorManualStyleRef.current.strokeColor;
135
- newStyle['circle-stroke-color'] = colorManualStyleRef.current.strokeColor;
136
138
  newStyle['stroke-width'] = colorManualStyleRef.current.strokeWidth;
137
139
  newStyle['circle-stroke-width'] = colorManualStyleRef.current.strokeWidth;
138
140
  // Apply radius symbology
@@ -1,4 +1,5 @@
1
1
  import { IDict } from '@jupytergis/schema';
2
+ import { ISubmitEvent } from '@rjsf/core';
2
3
  import { PathBasedSourcePropertiesForm } from './pathbasedsource';
3
4
  import { ISourceFormProps } from './sourceform';
4
5
  /**
@@ -13,5 +14,6 @@ export declare class GeoJSONSourcePropertiesForm extends PathBasedSourceProperti
13
14
  *
14
15
  * @param path - the path to validate.
15
16
  */
16
- protected _validatePath(path: string): Promise<void>;
17
+ protected _validatePath(path: string | undefined): Promise<void>;
18
+ protected onFormSubmit(e: ISubmitEvent<any>): void;
17
19
  }
@@ -1,4 +1,5 @@
1
1
  import * as geojson from '@jupytergis/schema/src/schema/geojson.json';
2
+ import { showErrorMessage } from '@jupyterlab/apputils';
2
3
  import { Ajv } from 'ajv';
3
4
  import { loadFile } from "../../../tools";
4
5
  import { PathBasedSourcePropertiesForm } from './pathbasedsource';
@@ -17,6 +18,10 @@ export class GeoJSONSourcePropertiesForm extends PathBasedSourcePropertiesForm {
17
18
  if ((data === null || data === void 0 ? void 0 : data.path) !== '') {
18
19
  this.removeFormEntry('data', data, schema, uiSchema);
19
20
  }
21
+ if (this.props.formContext === 'create') {
22
+ schema.properties.path.description =
23
+ 'The local path to a GeoJSON file. (If no path/url is provided, an empty GeoJSON is created.)';
24
+ }
20
25
  super.processSchema(data, schema, uiSchema);
21
26
  }
22
27
  /**
@@ -28,7 +33,7 @@ export class GeoJSONSourcePropertiesForm extends PathBasedSourcePropertiesForm {
28
33
  var _a;
29
34
  const extraErrors = this.state.extraErrors;
30
35
  let error = '';
31
- let valid = false;
36
+ let valid = true;
32
37
  if (path) {
33
38
  try {
34
39
  const geoJSONData = await loadFile({
@@ -45,9 +50,6 @@ export class GeoJSONSourcePropertiesForm extends PathBasedSourcePropertiesForm {
45
50
  error = `"${path}" is not a valid GeoJSON file: ${e}`;
46
51
  }
47
52
  }
48
- else {
49
- error = 'Path is required';
50
- }
51
53
  if (!valid) {
52
54
  extraErrors.path = {
53
55
  __errors: [error],
@@ -64,4 +66,18 @@ export class GeoJSONSourcePropertiesForm extends PathBasedSourcePropertiesForm {
64
66
  this.props.formErrorSignal.emit(!valid);
65
67
  }
66
68
  }
69
+ onFormSubmit(e) {
70
+ var _a, _b, _c;
71
+ if (((_c = (_b = (_a = this.state.extraErrors) === null || _a === void 0 ? void 0 : _a.path) === null || _b === void 0 ? void 0 : _b.__errors) === null || _c === void 0 ? void 0 : _c.length) >= 1) {
72
+ showErrorMessage('Invalid file', this.state.extraErrors.path.__errors[0]);
73
+ return;
74
+ }
75
+ if (!e.formData.path) {
76
+ e.formData.data = {
77
+ type: 'FeatureCollection',
78
+ features: [],
79
+ };
80
+ }
81
+ super.onFormSubmit(e);
82
+ }
67
83
  }
@@ -3,7 +3,7 @@ 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
- import { Collection, Map as OlMap, View, getUid } from 'ol';
6
+ import { Collection, Map as OlMap, View, getUid, } from 'ol';
7
7
  import Feature from 'ol/Feature';
8
8
  import { FullScreen, ScaleLine } from 'ol/control';
9
9
  import { singleClick } from 'ol/events/condition';
@@ -15,9 +15,8 @@ import TileLayer from 'ol/layer/Tile';
15
15
  import { fromLonLat, get as getProjection, toLonLat, transformExtent, } from 'ol/proj';
16
16
  import { register } from 'ol/proj/proj4.js';
17
17
  import RenderFeature from 'ol/render/Feature';
18
- 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, Tile as TileSource, } from 'ol/source';
19
19
  import Static from 'ol/source/ImageStatic';
20
- import TileSource from 'ol/source/Tile';
21
20
  import { Circle, Fill, Stroke, Style } from 'ol/style';
22
21
  //@ts-expect-error no types for ol-pmtiles
23
22
  import { PMTilesRasterSource, PMTilesVectorSource } from 'ol-pmtiles';
@@ -717,6 +716,13 @@ export class MainView extends React.Component {
717
716
  url: url,
718
717
  });
719
718
  }
719
+ newSource.on('tileloadend', (event) => {
720
+ const tile = event.tile;
721
+ const features = tile.getFeatures();
722
+ if (features && features.length > 0) {
723
+ this._model.syncTileFeatures({ sourceId: id, features });
724
+ }
725
+ });
720
726
  break;
721
727
  }
722
728
  case 'GeoJSONSource': {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jupytergis/base",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "A JupyterLab extension for 3D modelling.",
5
5
  "keywords": [
6
6
  "jupyter",
@@ -44,7 +44,7 @@
44
44
  "@jupyter/collaboration": "^3.1.0",
45
45
  "@jupyter/react-components": "^0.16.6",
46
46
  "@jupyter/ydoc": "^2.0.0 || ^3.0.0",
47
- "@jupytergis/schema": "^0.7.0",
47
+ "@jupytergis/schema": "^0.8.0",
48
48
  "@jupyterlab/application": "^4.3.0",
49
49
  "@jupyterlab/apputils": "^4.3.0",
50
50
  "@jupyterlab/completer": "^4.3.0",