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 (
|
||||
<path
|
||||
d={d}
|
||||
className={`track ${props.gpx.subtype}`}
|
||||
onClick={clickHandler}
|
||||
/>
|
||||
);
|
||||
return <path d={d} className={`track ${props.gpx.subtype}`} />;
|
||||
};
|
||||
|
||||
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 React from 'react';
|
||||
import React, { useRef } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { informationCircleOutline } from 'ionicons/icons';
|
||||
import { Point } from '../../lib/geo';
|
||||
import { MapState } from '../../store/map';
|
||||
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 windowState = useSelector(
|
||||
|
@ -65,7 +75,7 @@ const Reticle: React.FC<{}> = () => {
|
|||
);
|
||||
|
||||
return (
|
||||
<g className='reticle'>
|
||||
<g className='reticle' pointerEvents='visible' id='information-request'>
|
||||
<circle
|
||||
cx={center.x}
|
||||
cy={center.y}
|
||||
|
@ -121,9 +131,33 @@ const Reticle: React.FC<{}> = () => {
|
|||
href='#reticle-east'
|
||||
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}`}
|
||||
</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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -27,6 +27,7 @@ import TileServerChooserDialog from './TileServerChooserDialog';
|
|||
import TrackBrowser from './TracksBrowser';
|
||||
import Settings from './Settings';
|
||||
import Reticle from './Reticle';
|
||||
import LocationInfo from './LocationInfo';
|
||||
|
||||
const Map: react.FC<{}> = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
@ -53,6 +54,7 @@ const Map: react.FC<{}> = () => {
|
|||
<IonContent fullscreen={true}>
|
||||
<IonApp>
|
||||
<TileServerChooserDialog />
|
||||
<LocationInfo />
|
||||
<Slippy>
|
||||
<Whiteboard fixedChildren={<Reticle />}>
|
||||
<CurrentLocation />
|
||||
|
|
|
@ -26,7 +26,7 @@ const MouseHandler: react.FC<MouseHandlerProps> = (
|
|||
const genericHandler = (event: any) => {
|
||||
console.log(`Log - Event: ${event.type}`);
|
||||
if (event.pageX !== undefined) {
|
||||
console.log(`Mouse : ${event.pageX}, ${event.pageY}`);
|
||||
console.log(`Mouse : ${event.pageX}, ${event.pageY}, target: ${event.target}`);
|
||||
console.log(
|
||||
`mouseState: ' ${JSON.stringify(mouseState)} (+${
|
||||
Date.now() - mouseState.timestamp
|
||||
|
@ -43,7 +43,7 @@ const MouseHandler: react.FC<MouseHandlerProps> = (
|
|||
};
|
||||
|
||||
const mouseDownHandler = (event: any) => {
|
||||
event.preventDefault();
|
||||
// event.preventDefault();
|
||||
genericHandler(event);
|
||||
setMouseState({
|
||||
down: true,
|
||||
|
@ -54,12 +54,12 @@ const MouseHandler: react.FC<MouseHandlerProps> = (
|
|||
|
||||
const mouseUpHandler = (event: any) => {
|
||||
genericHandler(event);
|
||||
event.preventDefault();
|
||||
// event.preventDefault();
|
||||
setMouseState(initialMouseState);
|
||||
};
|
||||
|
||||
const mouseMoveHandler = (event: any) => {
|
||||
event.preventDefault();
|
||||
// event.preventDefault();
|
||||
if (mouseState.down && Date.now() - mouseState.timestamp > 50) {
|
||||
genericHandler(event);
|
||||
console.log(
|
||||
|
|
|
@ -48,6 +48,14 @@ const strings = new LocalizedStrings({
|
|||
},
|
||||
|
||||
tracks: 'Tracks',
|
||||
|
||||
locationInfo: {
|
||||
title: 'Here',
|
||||
location: 'Location',
|
||||
lat: 'Latitude: ',
|
||||
lon: 'Longitude: ',
|
||||
elevation: 'Elevation:',
|
||||
},
|
||||
},
|
||||
fr: {
|
||||
colonize: (input: string): any => strings.formatString('{0} :', input),
|
||||
|
@ -106,6 +114,14 @@ const strings = new LocalizedStrings({
|
|||
},
|
||||
|
||||
tracks: 'Traces',
|
||||
|
||||
locationInfo: {
|
||||
title: 'Ici',
|
||||
location: 'Position',
|
||||
lat: 'Latitude : ',
|
||||
lon: 'Longitude : ',
|
||||
elevation: 'Altitude :',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ use.reticle,
|
|||
}
|
||||
|
||||
ion-modal {
|
||||
--height: 50%;
|
||||
--height: 100%;
|
||||
--border-radius: 16px;
|
||||
--box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1),
|
||||
0 4px 6px -4px rgb(0 0 0 / 0.1);
|
||||
|
|
Loading…
Reference in New Issue