Adding a modal to display inforlation about a location.

This commit is contained in:
Eric van der Vlist 2022-10-09 18:55:21 +02:00
parent 0762a4da7a
commit f9a6fb1d18
7 changed files with 139 additions and 15 deletions

View File

@ -40,13 +40,7 @@ const Gpx: React.FC<{ gpx: any }> = (props) => {
)}`; )}`;
}, ''); }, '');
return ( return <path d={d} className={`track ${props.gpx.subtype}`} />;
<path
d={d}
className={`track ${props.gpx.subtype}`}
onClick={clickHandler}
/>
);
}; };
export default Gpx; export default Gpx;

View File

@ -0,0 +1,78 @@
import {
IonModal,
IonToolbar,
IonTitle,
IonButtons,
IonButton,
IonContent,
IonLabel,
IonList,
IonListHeader,
IonItem,
IonSpinner,
} from '@ionic/react';
import React, { useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import i18n from '../../i18n';
import { MapState } from '../../store/map';
const LocationInfo: React.FC<{}> = () => {
const scope = useSelector((state: { map: MapState }) => state.map.scope);
const modal = useRef<HTMLIonModalElement>(null);
const dismiss = () => {
modal.current?.dismiss();
};
const [elevation, setElevation] = useState(undefined);
const ionModalWillPresentHandler = async () => {
setElevation(undefined);
console.log('ionModalWillPresentHandler');
const response = await fetch(
// `https://api.opentopodata.org/v1/mapzen?locations=${scope.center.lat},${scope.center.lon}`,
`https://api.open-meteo.com/v1/elevation?latitude=${scope.center.lat}&longitude=${scope.center.lon}`,
{}
);
const data = await response.json();
setElevation(data.elevation[0]);
};
return (
<IonModal
trigger='information-request'
ref={modal}
onIonModalWillPresent={ionModalWillPresentHandler}
>
<IonToolbar>
<IonTitle>{i18n.locationInfo!.title}</IonTitle>
<IonButtons slot='end'>
<IonButton onClick={() => dismiss()}>{i18n.close}</IonButton>
</IonButtons>
</IonToolbar>
<IonContent>
<IonList lines='full' class='ion-no-margin'>
<IonListHeader lines='full'>
<IonLabel>{i18n.locationInfo!.location}</IonLabel>
</IonListHeader>
<IonItem>
<IonLabel>{i18n.locationInfo!.lat}</IonLabel>
{scope.center.lat} N
</IonItem>
<IonItem>
<IonLabel>{i18n.locationInfo!.lon}</IonLabel>
{scope.center.lon} E
</IonItem>
<IonItem>
<IonLabel>{i18n.locationInfo!.elevation}</IonLabel>
{elevation === undefined && <IonSpinner name='lines' />}
{elevation !== undefined && <>{elevation} m</>}
</IonItem>
</IonList>
</IonContent>{' '}
</IonModal>
);
};
export default LocationInfo;

View File

@ -1,9 +1,19 @@
import _ from 'lodash'; import _ from 'lodash';
import React from 'react'; import React, { useRef } from 'react';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { informationCircleOutline } from 'ionicons/icons';
import { Point } from '../../lib/geo'; import { Point } from '../../lib/geo';
import { MapState } from '../../store/map'; import { MapState } from '../../store/map';
import '../../theme/map.css'; import '../../theme/map.css';
import {
IonButton,
IonButtons,
IonModal,
IonTitle,
IonToolbar,
} from '@ionic/react';
import i18n from '../../i18n';
import eventBus from '../../lib/pubsub';
const Reticle: React.FC<{}> = () => { const Reticle: React.FC<{}> = () => {
const windowState = useSelector( const windowState = useSelector(
@ -65,7 +75,7 @@ const Reticle: React.FC<{}> = () => {
); );
return ( return (
<g className='reticle'> <g className='reticle' pointerEvents='visible' id='information-request'>
<circle <circle
cx={center.x} cx={center.x}
cy={center.y} cy={center.y}
@ -121,9 +131,33 @@ const Reticle: React.FC<{}> = () => {
href='#reticle-east' href='#reticle-east'
transform={`rotate(-90, ${center.x}, ${center.y})`} transform={`rotate(-90, ${center.x}, ${center.y})`}
/> />
<text x={center.x + unitPxStep * nbUnits - 15} y={center.y - 20}> <text
x={center.x + unitPxStep * nbUnits - 15}
y={center.y - 10}
cursor='pointer'
>
{`${radiusUnitValue * nbUnits} ${radiusUnit}`} {`${radiusUnitValue * nbUnits} ${radiusUnit}`}
</text> </text>
<circle
cx={center.x + unitPxStep * nbUnits - 15}
cy={center.y - 32}
r={10}
fill='white'
opacity={0.8}
strokeWidth={1}
stroke='black'
cursor='pointer'
pointerEvents='visible'
/>
<text
cursor='pointer'
x={center.x + unitPxStep * nbUnits - 17}
y={center.y - 27}
style={{ fontFamily: 'fixed', fontSize: 17, fontWeight: 'bolder' }}
pointerEvents='none'
>
i
</text>
</g> </g>
); );
}; };

View File

@ -27,6 +27,7 @@ import TileServerChooserDialog from './TileServerChooserDialog';
import TrackBrowser from './TracksBrowser'; import TrackBrowser from './TracksBrowser';
import Settings from './Settings'; import Settings from './Settings';
import Reticle from './Reticle'; import Reticle from './Reticle';
import LocationInfo from './LocationInfo';
const Map: react.FC<{}> = () => { const Map: react.FC<{}> = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -53,6 +54,7 @@ const Map: react.FC<{}> = () => {
<IonContent fullscreen={true}> <IonContent fullscreen={true}>
<IonApp> <IonApp>
<TileServerChooserDialog /> <TileServerChooserDialog />
<LocationInfo />
<Slippy> <Slippy>
<Whiteboard fixedChildren={<Reticle />}> <Whiteboard fixedChildren={<Reticle />}>
<CurrentLocation /> <CurrentLocation />

View File

@ -26,7 +26,7 @@ const MouseHandler: react.FC<MouseHandlerProps> = (
const genericHandler = (event: any) => { const genericHandler = (event: any) => {
console.log(`Log - Event: ${event.type}`); console.log(`Log - Event: ${event.type}`);
if (event.pageX !== undefined) { if (event.pageX !== undefined) {
console.log(`Mouse : ${event.pageX}, ${event.pageY}`); console.log(`Mouse : ${event.pageX}, ${event.pageY}, target: ${event.target}`);
console.log( console.log(
`mouseState: ' ${JSON.stringify(mouseState)} (+${ `mouseState: ' ${JSON.stringify(mouseState)} (+${
Date.now() - mouseState.timestamp Date.now() - mouseState.timestamp
@ -43,7 +43,7 @@ const MouseHandler: react.FC<MouseHandlerProps> = (
}; };
const mouseDownHandler = (event: any) => { const mouseDownHandler = (event: any) => {
event.preventDefault(); // event.preventDefault();
genericHandler(event); genericHandler(event);
setMouseState({ setMouseState({
down: true, down: true,
@ -54,12 +54,12 @@ const MouseHandler: react.FC<MouseHandlerProps> = (
const mouseUpHandler = (event: any) => { const mouseUpHandler = (event: any) => {
genericHandler(event); genericHandler(event);
event.preventDefault(); // event.preventDefault();
setMouseState(initialMouseState); setMouseState(initialMouseState);
}; };
const mouseMoveHandler = (event: any) => { const mouseMoveHandler = (event: any) => {
event.preventDefault(); // event.preventDefault();
if (mouseState.down && Date.now() - mouseState.timestamp > 50) { if (mouseState.down && Date.now() - mouseState.timestamp > 50) {
genericHandler(event); genericHandler(event);
console.log( console.log(

View File

@ -48,6 +48,14 @@ const strings = new LocalizedStrings({
}, },
tracks: 'Tracks', tracks: 'Tracks',
locationInfo: {
title: 'Here',
location: 'Location',
lat: 'Latitude: ',
lon: 'Longitude: ',
elevation: 'Elevation:',
},
}, },
fr: { fr: {
colonize: (input: string): any => strings.formatString('{0} :', input), colonize: (input: string): any => strings.formatString('{0} :', input),
@ -106,6 +114,14 @@ const strings = new LocalizedStrings({
}, },
tracks: 'Traces', tracks: 'Traces',
locationInfo: {
title: 'Ici',
location: 'Position',
lat: 'Latitude : ',
lon: 'Longitude : ',
elevation: 'Altitude :',
},
}, },
}); });

View File

@ -55,7 +55,7 @@ use.reticle,
} }
ion-modal { ion-modal {
--height: 50%; --height: 100%;
--border-radius: 16px; --border-radius: 16px;
--box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), --box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1),
0 4px 6px -4px rgb(0 0 0 / 0.1); 0 4px 6px -4px rgb(0 0 0 / 0.1);