Skip to content

Commit

Permalink
Merge pull request #820 from terrestris/parse-map-interactions
Browse files Browse the repository at this point in the history
Adds method to parse map interactions
  • Loading branch information
KaiVolland authored Nov 8, 2024
2 parents 817c329 + 3c79d85 commit 8433d9c
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 1 deletion.
13 changes: 13 additions & 0 deletions src/model/Application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ import {
DefaultLayerSourceConfig
} from './Layer';

export type MapInteraction = 'DragRotate' |
'DragRotateAndZoom' |
'DblClickDragZoom' |
'DoubleClickZoom' |
'DragPan' |
'PinchRotate' |
'PinchZoom' |
'KeyboardPan' |
'KeyboardZoom' |
'MouseWheelZoom' |
'DragZoom';

export interface DefaultApplicationTheme {
primaryColor?: string;
secondaryColor?: string;
Expand Down Expand Up @@ -59,6 +71,7 @@ export interface DefaultApplicationClientConfig<
ApplicationTheme extends DefaultApplicationTheme = DefaultApplicationTheme
> {
mapView: MapView;
mapInteractions?: MapInteraction[];
description?: string;
legal?: LegalConfig;
theme?: ApplicationTheme;
Expand Down
63 changes: 63 additions & 0 deletions src/parser/SHOGunApplicationUtil.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@ import OlSourceTileWMS from 'ol/source/TileWMS';
import OlSourceVector from 'ol/source/Vector';
import OlSourceXYZ from 'ol/source/XYZ';
import OlTileGrid from 'ol/tilegrid/TileGrid';
import OlCollection from 'ol/Collection';
import OlInteraction from 'ol/interaction/Interaction';
import OlDragPan from 'ol/interaction/DragPan';
import OlDoubleClickZoom from 'ol/interaction/DoubleClickZoom';
import { getUid } from 'ol/util';
import { defaults as DefaultInteractions } from 'ol/interaction/defaults'
import Logger from '@terrestris/base-util/dist/Logger';

import Application, { DefaultLayerTree } from '../model/Application';
import Layer from '../model/Layer';
import SHOGunAPIClient from '../service/SHOGunAPIClient';
import SHOGunApplicationUtil from './SHOGunApplicationUtil';
import { omit } from 'lodash';

describe('SHOGunApplicationUtil', () => {
let util: SHOGunApplicationUtil<Application, Layer>;
Expand Down Expand Up @@ -332,4 +339,60 @@ describe('SHOGunApplicationUtil', () => {
expect(JSON.stringify(layer)).toEqual(JSON.stringify(expected));
});

describe('parseMapInteractions', () => {

it('returns the default interactions if no interactions are configured', async () => {
const defaultInteractions = DefaultInteractions();
const interactions = await util.parseMapInteractions({}) as OlCollection<OlInteraction>;
const interactionsArray = interactions.getArray();
expect(interactions).toBeDefined();
expect(interactionsArray).toHaveLength(defaultInteractions.getLength());

interactionsArray.forEach((interaction, index) => {
const got = omit(interaction, 'ol_uid');
const tar = omit(defaultInteractions.item(index), 'ol_uid');
expect(interaction).toBeInstanceOf(OlInteraction);
expect(JSON.stringify(got)).toEqual(JSON.stringify(tar));
});
});

it('returns the configured interactions if interactions are configured', async () => {
const interactions = await util.parseMapInteractions({
clientConfig: {
mapView: {},
mapInteractions: [
'DragPan',
'DoubleClickZoom'
]
}
}) as OlInteraction[];

expect(interactions).toBeDefined();
expect(interactions).toHaveLength(2);
expect(interactions[0]).toBeInstanceOf(OlDragPan);
expect(interactions[1]).toBeInstanceOf(OlDoubleClickZoom);
});

it('filters invalid interactions and logs a warning', async () => {
const consoleError = jest.spyOn(Logger, 'warn').mockImplementation(() => {});
const interactions = await util.parseMapInteractions({
clientConfig: {
mapView: {},
mapInteractions: [
'DragPan',
// @ts-ignore
'InvalidInteraction'
]
}
}) as OlInteraction[];

expect(interactions).toBeDefined();
expect(interactions).toHaveLength(1);
expect(interactions[0]).toBeInstanceOf(OlDragPan);
expect(consoleError).toHaveBeenCalled();
});


});

});
50 changes: 49 additions & 1 deletion src/parser/SHOGunApplicationUtil.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
import _uniqueBy from 'lodash/uniqBy';
import OlCollection from 'ol/Collection';
import { Extent as OlExtent } from 'ol/extent';
import OlFeature from 'ol/Feature';
import OlFormatGeoJSON from 'ol/format/GeoJSON';
import OlWMTSCapabilities from 'ol/format/WMTSCapabilities';
import OlGeometry from 'ol/geom/Geometry';
import OlImage from 'ol/Image';
import OlImageTile from 'ol/ImageTile';
import OlDblClickDragZoom from 'ol/interaction/DblClickDragZoom.js';
import { defaults as DefaultInteractions } from 'ol/interaction/defaults';
import OlDoubleClickZoom from 'ol/interaction/DoubleClickZoom';
import OlDragPan from 'ol/interaction/DragPan';
import OlDragRotate from 'ol/interaction/DragRotate';
import OlDragRotateAndZoom from 'ol/interaction/DragRotateAndZoom';
import OlDragZoom from 'ol/interaction/DragZoom';
import OlInteraction from 'ol/interaction/Interaction';
import OlKeyboardPan from 'ol/interaction/KeyboardPan';
import OlKeyboardZoom from 'ol/interaction/KeyboardZoom';
import OlMouseWheelZoom from 'ol/interaction/MouseWheelZoom';
import OlPinchRotate from 'ol/interaction/PinchRotate';
import OlPinchZoom from 'ol/interaction/PinchZoom';

import OlLayerBase from 'ol/layer/Base';
import OlLayerGroup from 'ol/layer/Group';
import OlImageLayer from 'ol/layer/Image';
import OlTileLayer from 'ol/layer/Tile';
import OlLayerVector from 'ol/layer/Vector';

import { bbox as olStrategyBbox } from 'ol/loadingstrategy';
import { fromLonLat, ProjectionLike as OlProjectionLike } from 'ol/proj';
import { Units } from 'ol/proj/Units';
Expand Down Expand Up @@ -40,7 +56,7 @@ import { ProjectionUtil, defaultProj4CrsDefinitions } from '@terrestris/ol-util/
import {
allLayersByIds
} from '../graphqlqueries/Layers';
import Application, { DefaultLayerTree } from '../model/Application';
import Application, { DefaultLayerTree, MapInteraction } from '../model/Application';
import Layer from '../model/Layer';
import { getBearerTokenHeader } from '../security/getBearerTokenHeader';
import SHOGunAPIClient from '../service/SHOGunAPIClient';
Expand Down Expand Up @@ -134,6 +150,38 @@ class SHOGunApplicationUtil<
return new OlLayerGroup();
}

async parseMapInteractions(application: T): Promise<OlInteraction[] | OlCollection<OlInteraction>> {
const interactions = application.clientConfig?.mapInteractions;

if (!interactions) {
return DefaultInteractions();
}

const classMap: Record<MapInteraction, any> = {
DragRotate: OlDragRotate,
DragRotateAndZoom: OlDragRotateAndZoom,
DblClickDragZoom: OlDblClickDragZoom,
DoubleClickZoom: OlDoubleClickZoom,
DragPan: OlDragPan,
PinchRotate: OlPinchRotate,
PinchZoom: OlPinchZoom,
KeyboardPan: OlKeyboardPan,
KeyboardZoom: OlKeyboardZoom,
MouseWheelZoom: OlMouseWheelZoom,
DragZoom: OlDragZoom
};

const olInteractions: OlInteraction[] = interactions.map((interaction: keyof typeof classMap) => {
const InteractionClass = classMap[interaction] as typeof OlInteraction;
if (InteractionClass) {
return new InteractionClass();
}
Logger.warn(`Interaction '${interaction}' not supported.`);
}).filter((interaction: OlInteraction | undefined) => interaction !== undefined) as OlInteraction[];

return olInteractions;
}

private async fetchLayers(application: T): Promise<S[]|undefined> {
const layerTree = application.layerTree;

Expand Down

0 comments on commit 8433d9c

Please sign in to comment.