mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-25 02:56:41 +07:00
gpx generation
This commit is contained in:
parent
b28e695fe7
commit
99f76dbe2c
6 changed files with 72 additions and 4 deletions
|
@ -4,7 +4,7 @@ import { GuestButton } from '$components/user/GuestButton';
|
|||
import { DEFAULT_USER, IUser, ROLES } from '$constants/auth';
|
||||
import { UserButton } from '$components/user/UserButton';
|
||||
import { UserMenu } from '$components/user/UserMenu';
|
||||
import { setUser, userLogout, takeAShot, setDialog, gotVkUser, setDialogActive, openMapDialog } from '$redux/user/actions';
|
||||
import { setUser, userLogout, takeAShot, setDialog, gotVkUser, setDialogActive, openMapDialog, getGPXTrack } from '$redux/user/actions';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
import { Icon } from '$components/panels/Icon';
|
||||
|
@ -21,7 +21,8 @@ interface Props extends IRootState {
|
|||
gotVkUser: typeof gotVkUser,
|
||||
takeAShot: typeof takeAShot,
|
||||
openMapDialog: typeof openMapDialog,
|
||||
};
|
||||
getGPXTrack: typeof getGPXTrack,
|
||||
}
|
||||
|
||||
interface State {
|
||||
menuOpened: boolean
|
||||
|
@ -130,6 +131,17 @@ export class Component extends React.PureComponent<Props, State> {
|
|||
<Icon icon="icon-shot-4" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="control-sep" />
|
||||
|
||||
<div className="control-bar">
|
||||
<button
|
||||
className={classnames({ active: false })}
|
||||
onClick={this.props.getGPXTrack}
|
||||
>
|
||||
<Icon icon="icon-gpx-1" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -146,6 +158,7 @@ const mapDispatchToProps = dispatch => bindActionCreators({
|
|||
gotVkUser,
|
||||
setDialogActive,
|
||||
openMapDialog,
|
||||
getGPXTrack,
|
||||
}, dispatch);
|
||||
|
||||
export const UserPanel = connect(mapStateToProps, mapDispatchToProps)(Component);
|
||||
|
|
|
@ -62,3 +62,4 @@ export const searchSetLoading = loading => ({ type: ACTIONS.SEARCH_SET_LOADING,
|
|||
export const searchPutRoutes = payload => ({ type: ACTIONS.SEARCH_PUT_ROUTES, ...payload });
|
||||
|
||||
export const setMarkersShown = markers_shown => ({ type: ACTIONS.SET_MARKERS_SHOWN, markers_shown });
|
||||
export const getGPXTrack = () => ({ type: ACTIONS.GET_GPX_TRACK });
|
||||
|
|
|
@ -68,4 +68,6 @@ export const ACTIONS: IActions = {
|
|||
SET_SPEED: 'SET_SPEED',
|
||||
|
||||
SET_MARKERS_SHOWN: 'SET_MARKERS_SHOWN',
|
||||
|
||||
GET_GPX_TRACK: 'GET_GPX_TRACK',
|
||||
};
|
||||
|
|
|
@ -22,7 +22,7 @@ import {
|
|||
import { getUrlData, parseQuery, pushLoaderState, pushNetworkInitError, pushPath, replacePath } from '$utils/history';
|
||||
import { editor } from '$modules/Editor';
|
||||
import { ACTIONS } from '$redux/user/constants';
|
||||
import { IModes, MODES } from '$constants/modes';
|
||||
import { MODES } from '$constants/modes';
|
||||
import { DEFAULT_USER } from '$constants/auth';
|
||||
import { TIPS } from '$constants/tips';
|
||||
import {
|
||||
|
@ -34,11 +34,12 @@ import {
|
|||
imageFetcher
|
||||
} from '$utils/renderer';
|
||||
import { ILogos, LOGOS } from '$constants/logos';
|
||||
import { DEFAULT_PROVIDER, PROVIDERS } from '$constants/providers';
|
||||
import { DEFAULT_PROVIDER } from '$constants/providers';
|
||||
import { DIALOGS } from '$constants/dialogs';
|
||||
|
||||
import * as ActionCreators from '$redux/user/actions';
|
||||
import { IRootState } from "$redux/user/reducer";
|
||||
import { downloadGPXTrack, getGPXString } from "$utils/gpx";
|
||||
|
||||
const getUser = state => (state.user.user);
|
||||
const getState = state => (state.user);
|
||||
|
@ -558,6 +559,17 @@ function* setTitleSaga({ title }: ReturnType<typeof ActionCreators.setTitle>):Sa
|
|||
if (title) { document.title = `${title} | Редактор маршрутов`; }
|
||||
}
|
||||
|
||||
function* getGPXTrackSaga(): SagaIterator {
|
||||
const { route } = editor.dumpData();
|
||||
const { title, address } = yield select(getState);
|
||||
|
||||
if (!route || route.length <= 0) return;
|
||||
|
||||
const track = getGPXString({ points: route, title: (title || address) });
|
||||
|
||||
return downloadGPXTrack({ track, title });
|
||||
}
|
||||
|
||||
export function* userSaga() {
|
||||
yield takeLatest(REHYDRATE, authCheckSaga);
|
||||
yield takeEvery(ACTIONS.SET_MODE, setModeSaga);
|
||||
|
@ -601,4 +613,6 @@ export function* userSaga() {
|
|||
yield takeLatest(ACTIONS.OPEN_MAP_DIALOG, openMapDialogSaga);
|
||||
yield takeLatest(ACTIONS.SEARCH_SET_TAB, searchSetTabSaga);
|
||||
yield takeLatest(ACTIONS.SET_USER, setUserSaga);
|
||||
|
||||
yield takeLatest(ACTIONS.GET_GPX_TRACK, getGPXTrackSaga)
|
||||
}
|
||||
|
|
|
@ -369,6 +369,11 @@
|
|||
<path d="M12 6c3.79 0 7.17 2.13 8.82 5.5-.59 1.22-1.42 2.27-2.41 3.12l1.41 1.41c1.39-1.23 2.49-2.77 3.18-4.53C21.27 7.11 17 4 12 4c-1.27 0-2.49.2-3.64.57l1.65 1.65C10.66 6.09 11.32 6 12 6zm-1.07 1.14L13 9.21c.57.25 1.03.71 1.28 1.28l2.07 2.07c.08-.34.14-.7.14-1.07C16.5 9.01 14.48 7 12 7c-.37 0-.72.05-1.07.14zM2.01 3.87l2.68 2.68C3.06 7.83 1.77 9.53 1 11.5 2.73 15.89 7 19 12 19c1.52 0 2.98-.29 4.32-.82l3.42 3.42 1.41-1.41L3.42 2.45 2.01 3.87zm7.5 7.5l2.61 2.61c-.04.01-.08.02-.12.02-1.38 0-2.5-1.12-2.5-2.5 0-.05.01-.08.01-.13zm-3.4-3.4l1.75 1.75c-.23.55-.36 1.15-.36 1.78 0 2.48 2.02 4.5 4.5 4.5.63 0 1.23-.13 1.77-.36l.98.98c-.88.24-1.8.38-2.75.38-3.79 0-7.17-2.13-8.82-5.5.7-1.43 1.72-2.61 2.93-3.53z" fill="white" stroke="none" stroke-width="0" transform="translate(4 4)"/>
|
||||
</g>
|
||||
|
||||
<g id="icon-gpx-1" stroke="none">
|
||||
<path stroke="none" fill="black"/>
|
||||
<path d="M8 23h8v-2H8v2zm8-21.99L8 1c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM16 15H8V5h8v10z" fill="white" stroke="none" stroke-width="0" transform="translate(4 4)"/>
|
||||
</g>
|
||||
|
||||
<g id="icon-arrow-up-1" stroke="none">
|
||||
<path stroke="none" fill="black"/>
|
||||
<circle cx="16" cy="16" fill="white" r="4" />
|
||||
|
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 35 KiB |
33
src/utils/gpx.ts
Normal file
33
src/utils/gpx.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
import * as saveAs from 'file-saver';
|
||||
|
||||
export interface IRoutePoint {
|
||||
lat: number,
|
||||
lng: number,
|
||||
}
|
||||
|
||||
interface IGetGPXString {
|
||||
points: Array<IRoutePoint>,
|
||||
title?: string,
|
||||
}
|
||||
|
||||
export const getGPXString = ({ points, title }: IGetGPXString): string => (`
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<gpx>
|
||||
<rte>
|
||||
<name>${title || 'GPX Track'}</name>
|
||||
${
|
||||
points.reduce((cat, { lat, lng }, index) => (
|
||||
`${cat}
|
||||
<rtept lat="${lat}" lon="${lng}"></rtept>`
|
||||
), '')
|
||||
}
|
||||
</rte>
|
||||
</gpx>
|
||||
`);
|
||||
|
||||
export const downloadGPXTrack = ({ track, title }: { track: string, title?: string }) => (
|
||||
saveAs(
|
||||
new Blob([track], { type: 'application/gpx+xml;charset=utf-8' }),
|
||||
`${title || 'track'}.gpx`
|
||||
)
|
||||
);
|
Loading…
Add table
Add a link
Reference in a new issue