Extracting a hierarchy from a list of features (`<Infos/>`)

This commit is contained in:
Eric van der Vlist 2022-12-29 22:55:48 +01:00
parent b14db11938
commit a57968924f
1 changed files with 90 additions and 31 deletions

View File

@ -1,18 +1,18 @@
import { Grid, IconButton } from "@suid/material"; import { Grid, IconButton } from '@suid/material';
import { Feature } from "ol"; import { Feature } from 'ol';
import { Geometry } from "ol/geom"; import { Geometry } from 'ol/geom';
import { getLength } from "ol/sphere"; import { getLength } from 'ol/sphere';
import { Component, createSignal, For, Show } from "solid-js"; import { Component, createSignal, For, Show } from 'solid-js';
import { useI18n } from "@solid-primitives/i18n"; import { useI18n } from '@solid-primitives/i18n';
import EditIcon from "@suid/icons-material/Edit"; import EditIcon from '@suid/icons-material/Edit';
import { Paper, Stack } from "@suid/material"; import { Paper, Stack } from '@suid/material';
import styled from "@suid/material/styles/styled"; import styled from '@suid/material/styles/styled';
import Dialog from "../dialog"; import Dialog from '../dialog';
const Item = styled(Paper)(({ theme }) => ({ const Item = styled(Paper)(({ theme }) => ({
...theme.typography.body2, ...theme.typography.body2,
padding: theme.spacing(1), padding: theme.spacing(1),
textAlign: "center", textAlign: 'center',
color: theme.palette.text.secondary, color: theme.palette.text.secondary,
})); }));
@ -20,23 +20,82 @@ const [open, setOpen] = createSignal(false);
let selectedFeatures: Feature[] = []; let selectedFeatures: Feature[] = [];
const level2Key = (feature: Feature) =>
feature.get('context').wptId ||
feature.get('context').rteId ||
feature.get('context').trkId;
export const clickHandler = (event: any) => { export const clickHandler = (event: any) => {
const pixel = [event.originalEvent.x, event.originalEvent.y]; const pixel = [event.originalEvent.x, event.originalEvent.y];
const features = event.map.getFeaturesAtPixel(pixel, { hitTolerance: 30 }); const features = event.map.getFeaturesAtPixel(pixel, { hitTolerance: 30 });
selectedFeatures.map((feature) => feature.set('isSelected', false));
selectedFeatures = features;
selectedFeatures.sort((f1: Feature, f2: Feature) => {
const ctx1 = f1.get('context');
const ctx2 = f2.get('context');
if (ctx1.gpxId < ctx2.gpxId) {
return 1;
} else if (ctx1.gpxId > ctx2.gpxId) {
return -1;
}
const level2Key1 = level2Key(f1);
const level2Key2 = level2Key(f2);
if (level2Key1 < level2Key2) {
return -1;
}
if (level2Key1 > level2Key2) {
return 1;
}
if (ctx1.trksegId < ctx2.trksegId) {
return -1;
}
if (ctx1.trksegId > ctx2.trksegId) {
return 1;
}
return 0;
});
let hierarchy: any = {};
selectedFeatures.map((feature: Feature<Geometry>) => {
const gpxId = feature.get('context').gpxId;
if (!hierarchy.hasOwnProperty(gpxId)) {
hierarchy[gpxId] = { gpx: feature.get('context').gpx };
}
const l2key = level2Key(feature);
if (!hierarchy[gpxId].hasOwnProperty(l2key)) {
hierarchy[gpxId][l2key] = {
wpt: feature.get('context').wpt,
rte: feature.get('context').rte,
trk: feature.get('context').trk,
};
if (feature.get('type') === 'trkseg') {
hierarchy[gpxId][l2key].type = 'trk';
} else {
hierarchy[gpxId][l2key].type = feature.get('type');
}
}
if (feature.get('type') === 'trkseg') {
const trksegId = feature.get('context').trksegId;
if (!hierarchy[gpxId][l2key].hasOwnProperty(trksegId)) {
hierarchy[gpxId][l2key][trksegId] = {
trksegId,
trkseg: feature.get('context').trkseg,
};
}
}
});
console.log({ console.log({
caller: "<Infos/> / clickHandler", caller: '<Infos/> / clickHandler',
event, event,
features, features,
hierarchy,
}); });
selectedFeatures.map((feature) => feature.set("isSelected", false));
selectedFeatures = features;
features.map((feature: Feature<Geometry>) => { features.map((feature: Feature<Geometry>) => {
const id = feature.get("id"); const id = feature.get('id');
feature.set("isSelected", true); feature.set('isSelected', true);
// const geometry = feature.getGeometry(); // const geometry = feature.getGeometry();
// const length = getLength(geometry, { projection: "EPSG:4326" }); // const length = getLength(geometry, { projection: "EPSG:4326" });
console.log({ console.log({
caller: "<Infos/> / clickHandler / feature", caller: '<Infos/> / clickHandler / feature',
event, event,
feature, feature,
id, id,
@ -70,31 +129,31 @@ const Infos: Component<{}> = (props) => {
}; };
return ( return (
<Dialog closeHandler={handleClick} open={open()} title={t("nearby")}> <Dialog closeHandler={handleClick} open={open()} title={t('nearby')}>
<Stack <Stack
spacing={1} spacing={1}
direction="column" direction='column'
alignItems="center" alignItems='center'
sx={{ width: "calc(100% - 5px)" }} sx={{ width: 'calc(100% - 5px)' }}
> >
<For each={selectedFeatures}> <For each={selectedFeatures}>
{(feature) => { {(feature) => {
const geometry = feature.getGeometry(); const geometry = feature.getGeometry();
const length = geometry const length = geometry
? getLength(geometry, { projection: "EPSG:4326" }) ? getLength(geometry, { projection: 'EPSG:4326' })
: undefined; : undefined;
return ( return (
<Item sx={{ width: "calc(100% - 1px)" }}> <Item sx={{ width: 'calc(100% - 1px)' }}>
<Grid container spacing={2} alignItems="center"> <Grid container spacing={2} alignItems='center'>
<Grid item xs={11}> <Grid item xs={11}>
{feature.get("getTitle") {feature.get('getTitle')
? feature.get("getTitle")() ? feature.get('getTitle')()
: t(feature.get("type"))} : t(feature.get('type'))}
{length ? formatLength(length) : ""} {length ? formatLength(length) : ''}
</Grid> </Grid>
<Grid item xs={1} sx={{ paddingLeft: "0px" }}> <Grid item xs={1} sx={{ paddingLeft: '0px' }}>
<Show when={feature.get("edit")}> <Show when={feature.get('edit')}>
<IconButton onClick={feature.get("edit")}> <IconButton onClick={feature.get('edit')}>
<EditIcon /> <EditIcon />
</IconButton> </IconButton>
</Show> </Show>