Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions packages/base/src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,9 @@ export function addCommands(
isEnabled: () => {
const selectedLayer = getSingleSelectedLayer(tracker);
return selectedLayer
? ['VectorLayer', 'ShapefileLayer'].includes(selectedLayer.type)
? ['VectorLayer', 'ShapefileLayer', 'VectorTileLayer'].includes(
selectedLayer.type,
)
: false;
},
execute: async () => {
Expand Down Expand Up @@ -800,7 +802,11 @@ export function addCommands(
const sourceId = selectedLayer.parameters.source;
const source = sources[sourceId];

const geojsonString = await getGeoJSONDataFromLayerSource(source, model);
const geojsonString = await getGeoJSONDataFromLayerSource(
selectedLayer,
source,
model,
);
if (!geojsonString) {
return;
}
Expand Down
36 changes: 31 additions & 5 deletions packages/base/src/mainview/mainView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ import {
transformExtent,
} from 'ol/proj';
import { register } from 'ol/proj/proj4.js';
import RenderFeature from 'ol/render/Feature';
import RenderFeature, { toGeometry } from 'ol/render/Feature';
import {
GeoTIFF as GeoTIFFSource,
ImageTile as ImageTileSource,
Expand Down Expand Up @@ -643,10 +643,15 @@ export class MainView extends React.Component<IProps, IStates> {

newSource.on('tileloadend', (event: TileSourceEvent) => {
const tile = event.tile as VectorTile<FeatureLike>;
const features = tile.getFeatures();

if (features && features.length > 0) {
this._model.syncTileFeatures({ sourceId: id, features });
const rawFeatures = tile.getFeatures() as RenderFeature[];

if (rawFeatures && rawFeatures.length > 0) {
const realFeatures =
this.convertRenderFeaturesToFeatures(rawFeatures);
this._model.syncTileFeatures({
sourceId: id,
features: realFeatures,
});
}
});

Expand Down Expand Up @@ -828,6 +833,27 @@ export class MainView extends React.Component<IProps, IStates> {
this._sources[id] = newSource;
}

private convertRenderFeaturesToFeatures(
renderFeatures: RenderFeature[],
): Feature<Geometry>[] {
const features: Feature<Geometry>[] = [];

for (const rf of renderFeatures) {
const properties = rf.getProperties();
const geometry = toGeometry(rf);

if (!geometry) {
continue;
}

const feature = new Feature<Geometry>({ ...properties });
feature.setGeometry(geometry);
features.push(feature);
Comment on lines +843 to +851
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does OL's toFeature method work here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going to try this

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you had the time to try it? Is it ready for another review/merge?

}

return features;
}

private computeSourceUrl(source: IJGISSource): string {
const parameters = source.parameters as IRasterSource;
const urlParameters = parameters.urlParameters || {};
Expand Down
2 changes: 1 addition & 1 deletion packages/base/src/processing/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export async function getLayerGeoJSON(
return null;
}

return await getGeoJSONDataFromLayerSource(source, model);
return await getGeoJSONDataFromLayerSource(layer, source, model);
}

export type GdalFunctions =
Expand Down
20 changes: 19 additions & 1 deletion packages/base/src/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
IJGISLayerBrowserRegistry,
IJGISOptions,
IJGISSource,
IJGISLayer,
IJupyterGISModel,
IRasterLayerGalleryEntry,
SourceType,
Expand All @@ -13,6 +14,8 @@ import { Contents, ServerConnection } from '@jupyterlab/services';
import { VectorTile } from '@mapbox/vector-tile';
import * as d3Color from 'd3-color';
import { compressors } from 'hyparquet-compressors';
import Feature from 'ol/Feature';
import GeoJSON from 'ol/format/GeoJSON';
import Protobuf from 'pbf';
import shp from 'shpjs';

Expand Down Expand Up @@ -949,10 +952,15 @@ export function downloadFile(
}

export async function getGeoJSONDataFromLayerSource(
selectedLayer: IJGISLayer,
source: IJGISSource,
model: IJupyterGISModel,
): Promise<string | null> {
const vectorSourceTypes: SourceType[] = ['GeoJSONSource', 'ShapefileSource'];
const vectorSourceTypes: SourceType[] = [
'GeoJSONSource',
'ShapefileSource',
'VectorTileSource',
];

if (!vectorSourceTypes.includes(source.type as SourceType)) {
console.error(
Expand All @@ -961,6 +969,16 @@ export async function getGeoJSONDataFromLayerSource(
return null;
}

const sourceId = selectedLayer.parameters?.source;
if (source.type === 'VectorTileSource' && sourceId) {
const features = model.getFeaturesForCurrentTile({ sourceId });

const format = new GeoJSON();
const geojson = format.writeFeaturesObject(features as Feature[]);

return JSON.stringify(geojson);
}

if (!source.parameters) {
console.error('Source parameters are missing.');
return null;
Expand Down