Skip to content

Commit

Permalink
Use only one form to create a GeoJSON source and its layer
Browse files Browse the repository at this point in the history
  • Loading branch information
brichet committed Jul 10, 2024
1 parent 0f155e6 commit 946750c
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 50 deletions.
38 changes: 19 additions & 19 deletions examples/test.jGIS
Original file line number Diff line number Diff line change
@@ -1,58 +1,58 @@
{
"layers": {
"57ef55ef-facb-48a2-ae1d-c9c824be3e8a": {
"name": "Regions France",
"type": "VectorLayer",
"parameters": {
"opacity": 0.6,
"color": "#e66100",
"source": "7d082e75-69d5-447a-82d8-b05cca5945ba",
"type": "line"
"type": "line",
"color": "#e66100",
"opacity": 0.6
},
"visible": true
"name": "Regions France",
"visible": true,
"type": "VectorLayer"
},
"a0044fd7-f167-445f-b3d1-620a8f94b498": {
"type": "RasterLayer",
"visible": true,
"name": "Open Topo Map",
"parameters": {
"source": "5fd42e3b-4681-4607-b15d-65c3a3e89b32"
},
"visible": true,
"type": "RasterLayer"
}
},
"2467576f-b527-4cb7-998d-fa1d056fb8a1": {
"type": "RasterLayer",
"name": "Open Street Map",
"parameters": {
"source": "699facc9-e7c4-4f38-acf1-1fd7f02d9f36"
},
"type": "RasterLayer",
"name": "Open Street Map",
"visible": true
}
},
"sources": {
"5fd42e3b-4681-4607-b15d-65c3a3e89b32": {
"type": "RasterSource",
"name": "Open Topo Map",
"parameters": {
"minZoom": 0.0,
"url": "https://tile.opentopomap.org/{z}/{x}/{y}.png ",
"maxZoom": 24.0
}
},
"type": "RasterSource"
},
"7d082e75-69d5-447a-82d8-b05cca5945ba": {
"name": "france_regions",
"parameters": {
"valid": true,
"path": "examples/france_regions.json"
"path": "examples/france_regions.json",
"valid": true
},
"type": "GeoJSONSource"
},
"699facc9-e7c4-4f38-acf1-1fd7f02d9f36": {
"name": "Open Street Map",
"type": "RasterSource",
"name": "Open Street Map",
"parameters": {
"minZoom": 0.0,
"maxZoom": 24.0,
"url": "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
"minZoom": 0.0
"url": "https://tile.openstreetmap.org/{z}/{x}/{y}.png"
}
}
},
Expand All @@ -76,4 +76,4 @@
]
}
]
}
}
51 changes: 48 additions & 3 deletions packages/base/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import {
FormDialog
} from './formdialog';
import { geoJSONIcon } from './icons';
import { LayerBrowserWidget } from './layerBrowser/layerBrowserDialog';
import { LayerBrowserWidget } from './dialogs/layerBrowserDialog';
import { GeoJSONLayerDialog } from './dialogs/geoJsonLayerDialog';
import { JupyterGISWidget } from './widget';

/**
Expand All @@ -34,7 +35,8 @@ export namespace CommandIDs {

export const openLayerBrowser = 'jupytergis:openLayerBrowser';

export const newGeoJSONData = 'jupytergis:newGeoJSONData';
export const newGeoJSONLayer = 'jupytergis:newGeoJSONLayer';
export const newGeoJSONSource = 'jupytergis:newGeoJSONSource';
export const newVectorLayer = 'jupytergis:newVectorLayer';
}

Expand Down Expand Up @@ -101,6 +103,17 @@ export function addCommands(
)
});

commands.addCommand(CommandIDs.newGeoJSONLayer, {
label: trans.__('New vector layer'),
isEnabled: () => {
return tracker.currentWidget
? tracker.currentWidget.context.model.sharedModel.editable
: false;
},
iconClass: 'fa fa-vector-square',
execute: Private.createGeoJSONLayer(tracker, formSchemaRegistry)
});

commands.addCommand(CommandIDs.newVectorLayer, {
label: trans.__('New vector layer'),
isEnabled: () => {
Expand All @@ -112,7 +125,7 @@ export function addCommands(
execute: Private.createVectorLayer(tracker)
});

commands.addCommand(CommandIDs.newGeoJSONData, {
commands.addCommand(CommandIDs.newGeoJSONSource, {
label: trans.__('Add GeoJSON data from file'),
isEnabled: () => {
return tracker.currentWidget
Expand Down Expand Up @@ -165,6 +178,33 @@ namespace Private {
};
}

/**
* Command to create a GeoJSON source and vector layer.
*/
export function createGeoJSONLayer(
tracker: WidgetTracker<JupyterGISWidget>,
formSchemaRegistry: IJGISFormSchemaRegistry
) {
return async () => {
const current = tracker.currentWidget;

if (!current) {
return;
}

const dialog = new GeoJSONLayerDialog({
model: current.context.model,
registry: formSchemaRegistry
});
await dialog.launch();
};
}

/**
* Command to create a GeoJSON source.
*
* This is currently not used.
*/
export function createGeoJSONSource(
tracker: WidgetTracker<JupyterGISWidget>
) {
Expand Down Expand Up @@ -239,6 +279,11 @@ namespace Private {
};
}

/**
* Command to create a Vector layer.
*
* This is currently not used.
*/
export function createVectorLayer(tracker: WidgetTracker<JupyterGISWidget>) {
return async (arg: any) => {
const current = tracker.currentWidget;
Expand Down
125 changes: 125 additions & 0 deletions packages/base/src/dialogs/geoJsonLayerDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import {
IDict,
IJGISFormSchemaRegistry,
IJGISLayer,
IJGISSource,
IJupyterGISModel
} from '@jupytergis/schema';
import { Dialog } from '@jupyterlab/apputils';
import { PathExt } from '@jupyterlab/coreutils';
import { UUID } from '@lumino/coreutils';
import * as React from 'react';

import { GeoJSONLayerPropertiesForm } from '../panelview/formbuilder';
import { deepCopy } from '../tools';

/**
* Properties for the component to create GeoJSON layer.
*/
export interface IGeoJSONLayerComponentProps {
model: IJupyterGISModel;
formSchemaRegistry: IJGISFormSchemaRegistry;
cancel: () => void;
}

/**
* React component returning a form dedicated to GeoJSON layer (and source) creation.
*/
export const GeoJSONLayerComponent = ({
model,
formSchemaRegistry,
cancel
}: IGeoJSONLayerComponentProps) => {
const schema = deepCopy(formSchemaRegistry.getSchemas().get('VectorLayer'));
if (!schema) {
return;
}

delete schema.properties?.source;
schema['properties'] = {
name: { type: 'string', description: 'The name of the vector layer' },
path: { type: 'string', description: 'The path to the GeoJSON file' },
...schema['properties']
};

schema.required = ['name', 'path'];

const syncData = (props: IDict) => {
const sharedModel = model.sharedModel;
if (!sharedModel) {
return;
}
const { name, path, ...parameters } = props;
const sourceId = UUID.uuid4();

const sourceName = PathExt.basename(path, '.json');
const sourceModel: IJGISSource = {
type: 'GeoJSONSource',
name: sourceName,
parameters: {
path
}
};

const layerModel: IJGISLayer = {
type: 'VectorLayer',
parameters: {
source: sourceId,
type: parameters.type,
color: parameters.color,
opacity: parameters.opacity
},
visible: true,
name: name
};

sharedModel.addSource(sourceId, sourceModel);
model.addLayer(UUID.uuid4(), layerModel);
};

return (
<GeoJSONLayerPropertiesForm
formContext={'create'}
model={model}
schema={schema}
sourceData={{
name: 'Vector Layer'
}}
syncData={syncData}
cancel={cancel}
/>
);
};

/**
* Options for the dialog to create GeoJSON layer.
*/
export interface IGeoJSONLayerOptions {
model: IJupyterGISModel;
registry: IJGISFormSchemaRegistry;
}

/**
* The widget included in the Dialog shown when creating a GeoJSON layer (and source).
*/
export class GeoJSONLayerDialog extends Dialog<boolean> {
constructor(options: IGeoJSONLayerOptions) {
let cancelCallback: (() => void) | undefined = undefined;
cancelCallback = () => {
this.resolve(0);
};

const body = (
<GeoJSONLayerComponent
model={options.model}
formSchemaRegistry={options.registry}
cancel={cancelCallback}
/>
);

super({ body, buttons: [Dialog.cancelButton(), Dialog.okButton()] });

this.addClass('jGIS-geoJSONLayer-FormDialog');
this.id = 'jupytergis::geoJSONLayerDialog';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import {
IJupyterGISModel,
IRasterLayerGalleryEntry
} from '@jupytergis/schema';
import { Dialog } from '@jupyterlab/apputils';
import { UUID } from '@lumino/coreutils';
import React, { ChangeEvent, MouseEvent, useEffect, useState } from 'react';
import { RasterSourcePropertiesForm } from '../panelview';
import { deepCopy } from '../tools';
import { Dialog } from '@jupyterlab/apputils';

import CUSTOM_RASTER_IMAGE from '../../rasterlayer_gallery/custom_raster.png';

Expand Down
22 changes: 22 additions & 0 deletions packages/base/src/panelview/formbuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,9 @@ export class RasterSourcePropertiesForm extends ObjectPropertiesForm {
}
}

/**
* The form to modify a vector layer.
*/
export class VectorLayerPropertiesForm extends LayerPropertiesForm {
protected processSchema(
data: IDict<any> | undefined,
Expand All @@ -364,6 +367,9 @@ export class VectorLayerPropertiesForm extends LayerPropertiesForm {
}
}

/**
* The form to modify a GeoJSON source.
*/
export class GeoJSONSourcePropertiesForm extends ObjectPropertiesForm {
constructor(props: IProps) {
super(props);
Expand Down Expand Up @@ -427,3 +433,19 @@ export class GeoJSONSourcePropertiesForm extends ObjectPropertiesForm {

private _validate: ValidateFunction;
}

/**
* The form to create a GeoJSON layer.
*/
export class GeoJSONLayerPropertiesForm extends GeoJSONSourcePropertiesForm {
protected processSchema(
data: IDict<any> | undefined,
schema: IDict,
uiSchema: IDict
) {
super.processSchema(data, schema, uiSchema);
uiSchema['color'] = {
'ui:widget': 'color'
};
}
}
Loading

0 comments on commit 946750c

Please sign in to comment.