Skip to content
Snippets Groups Projects
Commit 9b5c118e authored by Leonardo's avatar Leonardo Committed by Vink, S.A. (Sjoerd)
Browse files

feat(map_nodelink): added nodelink layer

parent dcf3d1ad
No related branches found
No related tags found
1 merge request!151feat(map_nodelink)
This commit is part of merge request !151. Comments created here will be created in the context of that merge request.
import React, { useEffect, useMemo, useCallback, useState } from 'react'; import React, { useEffect, useMemo, useCallback } from 'react';
import DeckGL from '@deck.gl/react'; import DeckGL from '@deck.gl/react';
import { FlyToInterpolator, WebMercatorViewport } from '@deck.gl/core'; import { FlyToInterpolator, WebMercatorViewport } from '@deck.gl/core';
import { SelectionLayer } from '@deck.gl-community/editable-layers'; import { SelectionLayer } from '@deck.gl-community/editable-layers';
import { Coordinate, Layer } from './mapvis.types'; import { Coordinate, Layer } from './mapvis.types';
import { VISComponentType, VisualizationPropTypes } from '../../common'; import { VISComponentType, VisualizationPropTypes } from '../../common';
import { layerTypes, createBaseMap } from './layers'; import { layerTypes } from './components/layers';
import { MapSettings } from './settings'; import { createBaseMap } from './components/BaseMap';
import { MapSettings } from './MapSettings';
import { Node } from '@graphpolaris/shared/lib/data-access/store/graphQueryResultSlice'; import { Node } from '@graphpolaris/shared/lib/data-access/store/graphQueryResultSlice';
import { HighlightAlt, SearchOutlined } from '@mui/icons-material';
import SearchBar from './search';
export type MapProps = { layer: string }; export type MapProps = {
layer: string;
node: undefined | string;
lat: string;
lon: string;
enableBrushing: boolean;
};
const settings: MapProps = { layer: 'node' }; const settings: MapProps = {
layer: 'node',
node: undefined,
lat: 'gp_latitude',
lon: 'gp_longitude',
enableBrushing: false,
};
const INITIAL_VIEW_STATE = { const INITIAL_VIEW_STATE = {
latitude: 52.1006, latitude: 52.1006,
...@@ -26,14 +37,13 @@ const FLY_SPEED = 1000; ...@@ -26,14 +37,13 @@ const FLY_SPEED = 1000;
const baseLayer = createBaseMap(); const baseLayer = createBaseMap();
export const MapVis = ({ data, settings, handleSelect, graphMetadata }: VisualizationPropTypes<MapProps>) => { export const MapVis = ({ data, settings, updateSettings, graphMetadata, handleSelect }: VisualizationPropTypes<MapProps>) => {
const [layer, setLayer] = useState<Layer | undefined>(undefined); const [layer, setLayer] = React.useState<Layer | undefined>(undefined);
const [viewport, setViewport] = useState<Record<string, any>>(INITIAL_VIEW_STATE); const [viewport, setViewport] = React.useState<Record<string, any>>(INITIAL_VIEW_STATE);
const [hoverObject, setHoverObject] = useState<Node | null>(null); const [hoverObject, setHoverObject] = React.useState<Node | null>(null);
const [selected, setSelected] = useState<any[]>([]); const [selected, setSelected] = React.useState<any[]>([]);
const [selectingRectangle, setSelectingRectangle] = useState<boolean>(false); const [isSelecting, setIsSelecting] = React.useState<boolean>(false);
const [layerIds, setLayerIds] = useState<string[]>([]); const [selectingRectangle, setSelectingRectangle] = React.useState<boolean>(false);
const [isSearching, setIsSearching] = useState<boolean>(false);
const getFittedViewport = useCallback( const getFittedViewport = useCallback(
(minLat: number, maxLat: number, minLon: number, maxLon: number) => { (minLat: number, maxLat: number, minLon: number, maxLon: number) => {
...@@ -66,23 +76,33 @@ export const MapVis = ({ data, settings, handleSelect, graphMetadata }: Visualiz ...@@ -66,23 +76,33 @@ export const MapVis = ({ data, settings, handleSelect, graphMetadata }: Visualiz
useEffect(() => { useEffect(() => {
const layerType = settings.layer ? layerTypes?.[settings.layer] : layerTypes.node; const layerType = settings.layer ? layerTypes?.[settings.layer] : layerTypes.node;
const newLayerId = `layer-${Date.now()}`;
setLayer({ setLayer({
id: Date.now(),
name: 'New layer',
type: layerType, type: layerType,
config: settings, config: settings,
visible: true,
}); });
setLayerIds((prevIds) => [...prevIds, newLayerId]);
}, [settings.layer]); }, [settings.layer]);
useEffect(() => {
console.log('configuration.node', settings.node);
}, [settings.node]);
useEffect(() => {
if (settings.node != undefined && !graphMetadata.nodes.labels.includes(settings.node)) {
updateSettings({ node: undefined });
}
}, [graphMetadata.nodes.types, data, settings]);
const dataLayer = useMemo(() => { const dataLayer = useMemo(() => {
if (!layer || !settings.layer) return null; if (!layer || !settings.node || !settings.lat || !settings.lon) return null;
const coordinateLookup: { [id: string]: Coordinate } = data.nodes.reduce( const coordinateLookup: { [id: string]: Coordinate } = data.nodes.reduce(
(acc, node) => { (acc, node) => {
const latitude = settings[node.label].lat ? (node?.attributes?.[settings[node.label].lat] as string) : undefined; const latitude = settings.lat ? (node?.attributes?.[settings.lat] as string) : undefined;
const longitude = settings[node.label].lon ? (node?.attributes?.[settings[node.label].lon] as string) : undefined; const longitude = settings.lon ? (node?.attributes?.[settings.lon] as string) : undefined;
if (!!latitude && !!longitude) { if (!!latitude && !!longitude) {
acc[node._id] = [parseFloat(longitude), parseFloat(latitude)]; acc[node._id] = [parseFloat(longitude), parseFloat(latitude)];
...@@ -94,18 +114,19 @@ export const MapVis = ({ data, settings, handleSelect, graphMetadata }: Visualiz ...@@ -94,18 +114,19 @@ export const MapVis = ({ data, settings, handleSelect, graphMetadata }: Visualiz
); );
return new layer.type({ return new layer.type({
id: `${layer.id}`,
graph: data, graph: data,
metaData: graphMetadata, visible: layer.visible,
config: settings, config: layer.config,
selected: selected, selected: selected,
hoverObject: hoverObject, hoverObject: hoverObject,
getNodeLocation: (d: string) => { isSelecting: isSelecting,
return coordinateLookup[d]; getNodeLocation: (d: Node) => {
return coordinateLookup[d._id];
}, },
flyToBoundingBox: flyToBoundingBox, flyToBoundingBox: flyToBoundingBox,
setLayerIds: (val: string[]) => setLayerIds(val),
}); });
}, [layer, data, selected, hoverObject, settings]); }, [layer, data, selected, hoverObject, isSelecting, settings.lat, settings.lon, settings.node]);
const selectionLayer = useMemo( const selectionLayer = useMemo(
() => () =>
...@@ -113,29 +134,11 @@ export const MapVis = ({ data, settings, handleSelect, graphMetadata }: Visualiz ...@@ -113,29 +134,11 @@ export const MapVis = ({ data, settings, handleSelect, graphMetadata }: Visualiz
new (SelectionLayer as any)({ new (SelectionLayer as any)({
id: 'selection', id: 'selection',
selectionType: 'rectangle', selectionType: 'rectangle',
onSelect: ({ pickingInfos }: { pickingInfos: any[] }) => { onSelect: ({ pickingInfos }: any) => {
if (pickingInfos.length > 0) { setSelected(pickingInfos.map((item: any) => item.object));
const nodes = [];
const edges = [];
for (const selectedItem of pickingInfos) {
const { object } = selectedItem;
if (object._id) {
if (object.from & object.to) {
edges.push(object);
} else {
nodes.push(object);
}
}
}
setSelected(nodes.map((node) => node._id));
handleSelect({ nodes, edges });
} else {
handleSelect();
}
setSelectingRectangle(false); setSelectingRectangle(false);
}, },
layerIds: layerIds, layerIds: [layer?.id ? layer.id : ''],
getTentativeFillColor: () => [22, 37, 67, 100], getTentativeFillColor: () => [22, 37, 67, 100],
}), }),
[selectingRectangle, layer], [selectingRectangle, layer],
...@@ -143,24 +146,8 @@ export const MapVis = ({ data, settings, handleSelect, graphMetadata }: Visualiz ...@@ -143,24 +146,8 @@ export const MapVis = ({ data, settings, handleSelect, graphMetadata }: Visualiz
return ( return (
<div className="w-full h-full flex-grow relative overflow-hidden"> <div className="w-full h-full flex-grow relative overflow-hidden">
<div className="absolute left-0 top-0 z-50 m-1">
<div className="cursor-pointer p-1 bg-white shadow-md rounded mb-1" onClick={() => setSelectingRectangle(true)}>
<HighlightAlt />
</div>
<div className="cursor-pointer p-1 bg-white shadow-md rounded" onClick={() => setIsSearching(!isSearching)}>
<SearchOutlined />
</div>
</div>
{isSearching && (
<SearchBar
onSearch={(boundingbox: [number, number, number, number]) => {
flyToBoundingBox(...boundingbox);
setIsSearching(false);
}}
/>
)}
<DeckGL <DeckGL
layers={[baseLayer, dataLayer, selectionLayer]} layers={[baseLayer, dataLayer]}
controller={true} controller={true}
initialViewState={viewport} initialViewState={viewport}
onViewStateChange={({ viewState }) => setViewport(viewState)} onViewStateChange={({ viewState }) => setViewport(viewState)}
...@@ -168,7 +155,6 @@ export const MapVis = ({ data, settings, handleSelect, graphMetadata }: Visualiz ...@@ -168,7 +155,6 @@ export const MapVis = ({ data, settings, handleSelect, graphMetadata }: Visualiz
if (data) { if (data) {
if (!object) { if (!object) {
handleSelect(); handleSelect();
setSelected([]);
return; return;
} }
if (object.hasOwnProperty('attributes') && object.hasOwnProperty('id') && object.hasOwnProperty('label')) { if (object.hasOwnProperty('attributes') && object.hasOwnProperty('id') && object.hasOwnProperty('label')) {
...@@ -192,12 +178,6 @@ export const MapVis = ({ data, settings, handleSelect, graphMetadata }: Visualiz ...@@ -192,12 +178,6 @@ export const MapVis = ({ data, settings, handleSelect, graphMetadata }: Visualiz
setHoverObject(object !== undefined ? object : null); setHoverObject(object !== undefined ? object : null);
}} }}
/> />
<div className="absolute right-0 top-0 p-1 z-50 bg-white bg-opacity-75 text-xs">
{'© '}
<a className="underline" href="http://www.openstreetmap.org/copyright" target="_blank" rel="noopener noreferrer">
OpenStreetMap
</a>
</div>
</div> </div>
); );
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment