Improving RteViewer.
This commit is contained in:
parent
c1fe37d0a6
commit
44ce641d6a
|
@ -130,20 +130,6 @@ const Infos: Component<{}> = (props) => {
|
|||
setOpen(false);
|
||||
};
|
||||
|
||||
const formatLength = (length: number) => {
|
||||
if (length > 1000) {
|
||||
const l = length / 1000;
|
||||
return ` ${l.toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})} km`;
|
||||
}
|
||||
return ` ${length.toLocaleString(undefined, {
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 0,
|
||||
})} m`;
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog closeHandler={handleClick} open={open()} title={t('nearby')}>
|
||||
<Stack
|
||||
|
|
|
@ -1,20 +1,53 @@
|
|||
import { Component } from 'solid-js';
|
||||
import { Component, createResource } from 'solid-js';
|
||||
import { peekCachedSignal } from '../../workers/cached-signals';
|
||||
import RteIcon from '../../icons/directions-svgrepo-com.svg?component-solid';
|
||||
import { useI18n } from '@solid-primitives/i18n';
|
||||
|
||||
import Tree from '../tree';
|
||||
import { findAddress, getVillageOrTown } from '../../lib/osm';
|
||||
import { getLength } from 'ol/sphere';
|
||||
import { Geometry, LineString } from 'ol/geom';
|
||||
|
||||
interface Props {
|
||||
rteId: string;
|
||||
}
|
||||
|
||||
const RteViewer: Component<Props> = ({ rteId }) => {
|
||||
const [t, { add, locale, dict }] = useI18n();
|
||||
|
||||
const rte = peekCachedSignal({ id: rteId, method: 'getRte' });
|
||||
console.log({ caller: 'RteViewer', rteId, rte: rte() });
|
||||
const title = () => {
|
||||
return rte().name;
|
||||
};
|
||||
|
||||
const [startAddress] = createResource(rte, (r: Rte) =>
|
||||
findAddress(r.rtept[0].$.lon, r.rtept[0].$.lat, locale)
|
||||
);
|
||||
const [endAddress] = createResource(rte, (r: Rte) =>
|
||||
findAddress(r.rtept.at(-1).$.lon, r.rtept.at(-1).$.lat, locale)
|
||||
);
|
||||
|
||||
const formatLength = (length: number) => {
|
||||
if (length > 1000) {
|
||||
const l = length / 1000;
|
||||
return ` ${l.toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})} km`;
|
||||
}
|
||||
return ` ${length.toLocaleString(undefined, {
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 0,
|
||||
})} m`;
|
||||
};
|
||||
|
||||
const geometry = new LineString(
|
||||
rte().rtept.map((rtept: any) => [rtept.$.lon, rtept.$.lat])
|
||||
);
|
||||
|
||||
const length = getLength(geometry, { projection: 'EPSG:4326' });
|
||||
|
||||
return (
|
||||
<Tree
|
||||
title={
|
||||
|
@ -22,7 +55,13 @@ const RteViewer: Component<Props> = ({ rteId }) => {
|
|||
<RteIcon fill='black' width='24' height='24' /> {title()}
|
||||
</>
|
||||
}
|
||||
content={undefined}
|
||||
content={
|
||||
<>
|
||||
<div>{`${formatLength(length)} ${t('from')} ${getVillageOrTown(
|
||||
startAddress()
|
||||
)} ${t('to')} ${getVillageOrTown(endAddress())} `}</div>
|
||||
</>
|
||||
}
|
||||
subTree={undefined}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -3,6 +3,7 @@ import { peekCachedSignal } from '../../workers/cached-signals';
|
|||
import Tree from '../tree';
|
||||
import TrkIcon from '../../icons/human-footprints-svgrepo-com.svg?component-solid';
|
||||
import { TrksegViewer } from '../trkseg';
|
||||
import { findAddress } from '../../lib/osm';
|
||||
|
||||
interface Props {
|
||||
trkId: string;
|
||||
|
@ -23,7 +24,11 @@ const TrkViewer: Component<Props> = ({ trkId, restrictToHierarchy }) => {
|
|||
<TrkIcon width='24' height='24' /> {title()}
|
||||
</>
|
||||
}
|
||||
content={undefined}
|
||||
content={
|
||||
<div>
|
||||
|
||||
</div>
|
||||
}
|
||||
subTree={
|
||||
<For
|
||||
each={Object.keys(restrictToHierarchy).filter((key: string) =>
|
||||
|
|
|
@ -62,6 +62,9 @@ const dict = {
|
|||
remoteDbUser: 'Remote database user',
|
||||
remoteDbPassword: 'Remote database password',
|
||||
accountSave: 'Save',
|
||||
|
||||
from: 'from ',
|
||||
to: 'to ',
|
||||
};
|
||||
|
||||
export default dict;
|
||||
|
|
|
@ -68,6 +68,9 @@ const dict = {
|
|||
remoteDbPassword: 'Mot de passe de la base de données distante',
|
||||
accountSave: 'Sauvegarder',
|
||||
accountCancel: 'Annuler',
|
||||
|
||||
from: 'de ',
|
||||
to: 'à ',
|
||||
};
|
||||
|
||||
export default dict;
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import memoize from 'memoizee';
|
||||
|
||||
const _findAddress = async (lon: number, lat: number, locale: () => string) => {
|
||||
const response = await fetch(
|
||||
`https://nominatim.openstreetmap.org/reverse?lat=${lat}&lon=${lon}&format=jsonv2&addressdetails=1&extratags=1&namedetails=1&accept-language=${locale()}`,
|
||||
{}
|
||||
);
|
||||
const data = await response.json();
|
||||
console.log({ caller: 'findAddress', lon, lat, data });
|
||||
return data;
|
||||
};
|
||||
|
||||
export const findAddress = memoize(_findAddress, {
|
||||
promise: true,
|
||||
max: 1000,
|
||||
maxAge: 360000000,
|
||||
});
|
||||
|
||||
export const getVillageOrTown = (address: any) => {
|
||||
if (address?.address.village) {
|
||||
return address?.address.village;
|
||||
}
|
||||
return address?.address.town;
|
||||
};
|
Loading…
Reference in New Issue