Adding a modal to display inforlation about a location.
This commit is contained in:
parent
0762a4da7a
commit
f9a6fb1d18
|
@ -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;
|
||||||
|
|
|
@ -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;
|
|
@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 />
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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 :',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue