dyomedea/src/components/finder/Finder.tsx

166 lines
4.5 KiB
TypeScript
Raw Normal View History

import { Coordinate } from 'ol/coordinate';
2023-01-31 17:49:51 +00:00
import { Component, createEffect, createSignal } from 'solid-js';
import { useNavigate } from '@solidjs/router';
import SearchIcon from '@suid/icons-material/Search';
import { useI18n } from '@solid-primitives/i18n';
import proj4 from 'proj4';
import style from './Finder.module.css';
import { Box, Button, IconButton, TextField } from '@suid/material';
import Dialog from '../dialog';
2023-01-31 17:49:51 +00:00
import { getMap, getState } from '../map';
import { Overlay } from 'ol';
import { fromLonLat } from 'ol/proj';
import WptEditDialog from '../wpt/WptEditDialog';
interface Props {}
const Finder: Component<Props> = (props) => {
const [open, setOpen] = createSignal(false);
const [searchString, setSearchString] = createSignal('');
2023-01-31 20:39:07 +00:00
const [popupContent, setPopupContent] = createSignal(<></>);
const navigate = useNavigate();
const [t, { add, locale, dict }] = useI18n();
const [popup, setPopup] = createSignal<Overlay>();
const [coordinate, setCoordinate] = createSignal<Coordinate>();
const searchStringChangeHandler = (event: any) => {
setSearchString(event.target.value);
};
const popupCloseHandler = () => {
popup()?.setMap(null);
};
let popupElement: HTMLElement;
const submitHandler = () => {
2023-01-31 20:39:07 +00:00
const latLonRegExp = /(-?[0-9]+.[0-9]+)\s*,\s*(-?[0-9]+.[0-9]+)/;
const latLonMatch = searchString().match(latLonRegExp);
if (!!latLonMatch) {
setCoordinate([+latLonMatch[2], +latLonMatch[1]]);
2023-01-31 20:39:07 +00:00
setPopupContent(<>{latLonMatch[0]}</>);
console.log({
caller: 'Finder / submitHandler',
searchString: searchString(),
latLonMatch,
coordinate: coordinate(),
2023-01-31 20:39:07 +00:00
});
} else {
const utmRegExp = /([0-6]?[0-9])\s*([C-X])\s*([0-9]+)\s*([0-9]+)/;
const utmMatch = searchString().match(utmRegExp);
if (!!utmMatch) {
const utm = `+proj=utm +zone=${utmMatch[1]}`;
setCoordinate(proj4(utm, 'EPSG:4326', [+utmMatch[3], +utmMatch[4]]));
2023-01-31 20:39:07 +00:00
setPopupContent(
<>{`${coordinate()[0]}, ${coordinate()[1]} (UTM ${utmMatch[0]})`}</>
2023-01-31 20:39:07 +00:00
);
}
console.log({
caller: 'Finder / submitHandler',
searchString: searchString(),
utmMatch,
coordinate: coordinate(),
2023-01-31 20:39:07 +00:00
});
}
if (!!coordinate()) {
setOpen(false);
if (popup() === undefined) {
setPopup(
new Overlay({
element: popupElement,
positioning: 'center-center',
})
);
2023-01-31 20:39:07 +00:00
}
console.log({
caller: 'Finder / submitHandler / popup',
searchString: searchString(),
coordinate: coordinate(),
popup: popup(),
popupElement,
});
popup().setMap(getMap());
popup().setPosition(fromLonLat(coordinate()));
getMap()?.addOverlay(popup());
2023-01-31 17:49:51 +00:00
navigate(
`/map/${getState().provider}/${coordinate()[0]}/${coordinate()[1]}/16/${
getState().rotation
}`
);
}
};
const [openCreateWptDialog, setOpenCreateWptDialog] = createSignal(false);
const createWptCloseHandler = () => {
setOpenCreateWptDialog(false);
popupCloseHandler();
};
return (
<>
<div class={style.control}>
<IconButton
onClick={() => {
setOpen(true);
}}
>
<SearchIcon />
</IconButton>
</div>
<Dialog
closeHandler={() => {
setOpen(false);
}}
open={open()}
title={t('search')}
>
<Box
component='form'
sx={{
width: '100%',
'& .MuiTextField-root': { m: 1, width: '100%' },
paddingTop: '5px',
}}
noValidate
autoComplete='off'
onSubmit={submitHandler}
method='dialog'
>
<TextField onChange={searchStringChangeHandler} />
</Box>
</Dialog>
<div class={style.ol_popup} ref={popupElement}>
2023-01-31 20:39:07 +00:00
<a
href='#'
onclick={popupCloseHandler}
class={style.ol_popup_closer}
></a>
<div>
<div>{popupContent()}</div>
<div>
<Button
onClick={() => {
setOpenCreateWptDialog(true);
}}
>
New waypoint
</Button>
</div>
<WptEditDialog
open={openCreateWptDialog}
closeHandler={createWptCloseHandler}
coordinate={coordinate}
/>
</div>
2023-01-31 17:49:51 +00:00
</div>
</>
);
};
export default Finder;